Some improvements to reduce the number of pixels touched in generating alpha clip masks
Review URL: https://codereview.appspot.com/6828043
git-svn-id: http://skia.googlecode.com/svn/trunk@6329 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp
index 823b072..e500fad 100644
--- a/src/gpu/effects/GrTextureDomainEffect.cpp
+++ b/src/gpu/effects/GrTextureDomainEffect.cpp
@@ -43,28 +43,40 @@
}
void GrGLTextureDomainEffect::emitCode(GrGLShaderBuilder* builder,
- const GrEffectStage&,
+ const GrEffectStage& stage,
EffectKey key,
const char* vertexCoords,
const char* outputColor,
const char* inputColor,
const TextureSamplerArray& samplers) {
+ const GrTextureDomainEffect& effect =
+ static_cast<const GrTextureDomainEffect&>(*stage.getEffect());
+
const char* coords;
fEffectMatrix.emitCodeMakeFSCoords2D(builder, key, vertexCoords, &coords);
+ const char* domain;
fNameUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
- kVec4f_GrSLType, "TexDom");
+ kVec4f_GrSLType, "TexDom", &domain);
+ if (GrTextureDomainEffect::kClamp_WrapMode == effect.wrapMode()) {
- builder->fFSCode.appendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n",
- coords,
- builder->getUniformCStr(fNameUni),
- builder->getUniformCStr(fNameUni));
+ builder->fFSCode.appendf("\tvec2 clampCoord = clamp(%s, %s.xy, %s.zw);\n",
+ coords, domain, domain);
- builder->fFSCode.appendf("\t%s = ", outputColor);
- builder->appendTextureLookupAndModulate(&builder->fFSCode,
- inputColor,
- samplers[0],
- "clampCoord");
- builder->fFSCode.append(";\n");
+ builder->fFSCode.appendf("\t%s = ", outputColor);
+ builder->appendTextureLookupAndModulate(&builder->fFSCode,
+ inputColor,
+ samplers[0],
+ "clampCoord");
+ builder->fFSCode.append(";\n");
+ } else {
+ GrAssert(GrTextureDomainEffect::kDecal_WrapMode == effect.wrapMode());
+ builder->fFSCode.append("\tbvec4 outside;\n");
+ builder->fFSCode.appendf("\toutside.xy = lessThan(%s, %s.xy);\n", coords, domain);
+ builder->fFSCode.appendf("\toutside.zw = greaterThan(%s, %s.zw);\n", coords, domain);
+ builder->fFSCode.appendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ", outputColor);
+ builder->appendTextureLookupAndModulate(&builder->fFSCode, inputColor, samplers[0], coords);
+ builder->fFSCode.append(";\n");
+ }
}
void GrGLTextureDomainEffect::setData(const GrGLUniformManager& uman, const GrEffectStage& stage) {
@@ -98,21 +110,41 @@
GrGLEffect::EffectKey GrGLTextureDomainEffect::GenKey(const GrEffectStage& stage, const GrGLCaps&) {
const GrTextureDomainEffect& effect =
static_cast<const GrTextureDomainEffect&>(*stage.getEffect());
- return GrGLEffectMatrix::GenKey(effect.getMatrix(), stage.getCoordChangeMatrix(), effect.texture(0));
+ EffectKey key = effect.wrapMode();
+ key <<= GrGLEffectMatrix::kKeyBits;
+ EffectKey matrixKey = GrGLEffectMatrix::GenKey(effect.getMatrix(),
+ stage.getCoordChangeMatrix(),
+ effect.texture(0));
+ return key | matrixKey;
}
///////////////////////////////////////////////////////////////////////////////
-GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, const GrRect& domain)
- : GrSingleTextureEffect(texture)
- , fTextureDomain(domain) {
+GrEffect* GrTextureDomainEffect::Create(GrTexture* texture,
+ const SkMatrix& matrix,
+ const GrRect& domain,
+ WrapMode wrapMode,
+ bool bilerp) {
+ static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1};
+ if (kClamp_WrapMode == wrapMode && domain.contains(kFullRect)) {
+ return SkNEW_ARGS(GrSingleTextureEffect, (texture, matrix, bilerp));
+ } else {
+ SkRect clippedDomain;
+ // We don't currently handle domains that are empty or don't intersect the texture.
+ SkAssertResult(clippedDomain.intersect(kFullRect, domain));
+ return SkNEW_ARGS(GrTextureDomainEffect,
+ (texture, matrix, clippedDomain, wrapMode, bilerp));
+ }
}
GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture,
+ const SkMatrix& matrix,
const GrRect& domain,
- const GrTextureParams& params)
- : GrSingleTextureEffect(texture, params)
+ WrapMode wrapMode,
+ bool bilerp)
+ : GrSingleTextureEffect(texture, matrix, bilerp)
+ , fWrapMode(wrapMode)
, fTextureDomain(domain) {
}
@@ -143,5 +175,7 @@
domain.fRight = random->nextRangeScalar(domain.fLeft, SK_Scalar1);
domain.fTop = random->nextUScalar1();
domain.fBottom = random->nextRangeScalar(domain.fTop, SK_Scalar1);
- return SkNEW_ARGS(GrTextureDomainEffect, (textures[texIdx], domain));
+ WrapMode wrapMode = random->nextBool() ? kClamp_WrapMode : kDecal_WrapMode;
+ const SkMatrix& matrix = GrEffectUnitTest::TestMatrix(random);
+ return GrTextureDomainEffect::Create(textures[texIdx], matrix, domain, wrapMode);
}