Index: src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
index d5d334805c105eb56012bf8729353df9b1b99655..54287e52bd7baf245b596304fb26904ed2a56f24 100755 |
--- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
+++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
@@ -261,6 +261,184 @@ GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, |
/////////////////////////////////////////////////////////////////////////////// |
+class GrGLDistanceFieldNoGammaTextureEffect : public GrGLGeometryProcessor { |
+public: |
+ GrGLDistanceFieldNoGammaTextureEffect(const GrBackendProcessorFactory& factory, |
robertphillips
2014/09/26 14:00:31
line this up ?
jvanverth1
2014/10/03 17:28:23
Done.
|
+ const GrProcessor& effect) |
+ : INHERITED(factory) |
+ , fTextureSize(SkISize::Make(-1, -1)) |
robertphillips
2014/09/26 14:00:30
Have you switched over to Mike R.'s bracket style
jvanverth1
2014/10/03 17:28:23
Done.
|
+ {} |
+ |
+ virtual void emitCode(GrGLFullProgramBuilder* builder, |
robertphillips
2014/09/26 14:00:31
line up ?
jvanverth1
2014/10/03 17:28:23
Done.
|
+ const GrGeometryProcessor& effect, |
+ const GrProcessorKey& key, |
+ const char* outputColor, |
+ const char* inputColor, |
+ const TransformedCoordsArray&, |
+ const TextureSamplerArray& samplers) SK_OVERRIDE{ |
+ const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = |
robertphillips
2014/09/26 14:00:31
tab over ?
jvanverth1
2014/10/03 17:28:23
Done.
|
+ effect.cast<GrDistanceFieldNoGammaTextureEffect>(); |
+ SkASSERT(1 == dfTexEffect.getVertexAttribs().count()); |
+ |
+ GrGLProcessorFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); |
+ SkAssertResult(fsBuilder->enableFeature( |
+ GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
+ |
+ SkString fsCoordName; |
+ const char* vsCoordName; |
+ const char* fsCoordNamePtr; |
+ builder->addVarying(kVec2f_GrSLType, "textureCoords", &vsCoordName, &fsCoordNamePtr); |
+ fsCoordName = fsCoordNamePtr; |
+ |
+ GrGLVertexShaderBuilder* vsBuilder = builder->getVertexShaderBuilder(); |
robertphillips
2014/09/26 14:00:30
rm '\t's and '\n's ?
jvanverth1
2014/10/03 17:28:24
Done.
|
+ vsBuilder->codeAppendf("\t%s = %s;\n", vsCoordName, dfTexEffect.inTextureCoords().c_str()); |
+ |
+ const char* textureSizeUniName = NULL; |
+ fTextureSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
robertphillips
2014/09/26 14:00:30
line up ?
jvanverth1
2014/10/03 17:28:23
Done.
|
+ kVec2f_GrSLType, "TextureSize", |
+ &textureSizeUniName); |
+ |
+ fsBuilder->codeAppend("\tvec4 texColor = "); |
+ fsBuilder->appendTextureLookup(samplers[0], |
+ fsCoordName.c_str(), |
+ kVec2f_GrSLType); |
+ fsBuilder->codeAppend(";\n"); |
+ fsBuilder->codeAppend("\tfloat distance = " |
+ SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThreshold ")" |
+ "+ " SK_DistanceFieldNonLCDFactor ";\n"); |
+ |
+ // we adjust for the effect of the transformation on the distance by using |
+ // the length of the gradient of the texture coordinates. We use st coordinates |
+ // to ensure we're mapping 1:1 from texel space to pixel space. |
+ fsBuilder->codeAppendf("\tvec2 uv = %s;\n", fsCoordName.c_str()); |
+ fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); |
+ fsBuilder->codeAppend("\tfloat afwidth;\n"); |
+ if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { |
+ // this gives us a smooth step across approximately one fragment |
+ fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*dFdx(st.x);\n"); |
+ } |
+ else { |
+ fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); |
+ fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); |
+ |
+ fsBuilder->codeAppend("\tvec2 uv_grad;\n"); |
+ if (builder->ctxInfo().caps()->dropsTileOnZeroDivide()) { |
+ // this is to compensate for the Adreno, which likes to drop tiles on division by 0 |
+ fsBuilder->codeAppend("\tfloat uv_len2 = dot(uv, uv);\n"); |
+ fsBuilder->codeAppend("\tif (uv_len2 < 0.0001) {\n"); |
+ fsBuilder->codeAppend("\t\tuv_grad = vec2(0.7071, 0.7071);\n"); |
+ fsBuilder->codeAppend("\t} else {\n"); |
+ fsBuilder->codeAppend("\t\tuv_grad = uv*inversesqrt(uv_len2);\n"); |
+ fsBuilder->codeAppend("\t}\n"); |
+ } |
+ else { |
+ fsBuilder->codeAppend("\tuv_grad = normalize(uv);\n"); |
+ } |
+ fsBuilder->codeAppend("\tvec2 grad = vec2(uv_grad.x*Jdx.x + uv_grad.y*Jdy.x,\n"); |
+ fsBuilder->codeAppend("\t uv_grad.x*Jdx.y + uv_grad.y*Jdy.y);\n"); |
+ |
+ // this gives us a smooth step across approximately one fragment |
+ fsBuilder->codeAppend("\tafwidth = " SK_DistanceFieldAAFactor "*length(grad);\n"); |
+ } |
+ fsBuilder->codeAppend("\tfloat val = smoothstep(-afwidth, afwidth, distance);\n"); |
+ |
+ fsBuilder->codeAppendf("\t%s = %s;\n", outputColor, |
+ (GrGLSLExpr4(inputColor) * GrGLSLExpr1("val")).c_str()); |
+ } |
+ |
+ virtual void setData(const GrGLProgramDataManager& pdman, |
robertphillips
2014/09/26 14:00:31
line up ?
jvanverth1
2014/10/03 17:28:24
Done.
|
+ const GrProcessor& effect) SK_OVERRIDE{ |
+ SkASSERT(fTextureSizeUni.isValid()); |
+ |
+ GrTexture* texture = effect.texture(0); |
robertphillips
2014/09/26 14:00:31
one line ?
jvanverth1
2014/10/03 17:28:23
Too wide...
|
+ if (texture->width() != fTextureSize.width() || |
+ texture->height() != fTextureSize.height()) { |
+ fTextureSize = SkISize::Make(texture->width(), texture->height()); |
+ pdman.set2f(fTextureSizeUni, |
robertphillips
2014/09/26 14:00:31
line up ?
jvanverth1
2014/10/03 17:28:23
Done.
|
+ SkIntToScalar(fTextureSize.width()), |
+ SkIntToScalar(fTextureSize.height())); |
+ } |
+ } |
+ |
+ static inline void GenKey(const GrProcessor& effect, const GrGLCaps&, |
robertphillips
2014/09/26 14:00:31
line up ?
jvanverth1
2014/10/03 17:28:23
Done.
|
+ GrProcessorKeyBuilder* b) { |
+ const GrDistanceFieldNoGammaTextureEffect& dfTexEffect = |
+ effect.cast<GrDistanceFieldNoGammaTextureEffect>(); |
+ |
+ b->add32(dfTexEffect.getFlags()); |
+ } |
+ |
+private: |
+ GrGLProgramDataManager::UniformHandle fTextureSizeUni; |
+ SkISize fTextureSize; |
+ |
+ typedef GrGLGeometryProcessor INHERITED; |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(GrTexture* texture, |
+ const GrTextureParams& params, |
+ uint32_t flags) |
+ : fTextureAccess(texture, params) |
+ , fFlags(flags & kNonLCD_DistanceFieldEffectMask) |
+ , fInTextureCoords(this->addVertexAttrib(GrShaderVar("inTextureCoords", |
robertphillips
2014/09/26 14:00:31
this indenting (or lack thereof) is confusing.
jvanverth1
2014/10/03 17:28:23
Done.
|
+ kVec2f_GrSLType, |
+ GrShaderVar::kAttribute_TypeModifier))) { |
+ SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); |
+ this->addTextureAccess(&fTextureAccess); |
+} |
+ |
+bool GrDistanceFieldNoGammaTextureEffect::onIsEqual(const GrProcessor& other) const { |
+ const GrDistanceFieldNoGammaTextureEffect& cte = other.cast<GrDistanceFieldNoGammaTextureEffect>(); |
egdaniel
2014/09/26 13:30:25
line wrap
jvanverth1
2014/10/03 17:28:24
Done.
|
+ return fTextureAccess == cte.fTextureAccess && |
robertphillips
2014/09/26 14:00:31
one line ?
jvanverth1
2014/10/03 17:28:23
Done.
|
+ fFlags == cte.fFlags; |
+} |
+ |
+void GrDistanceFieldNoGammaTextureEffect::getConstantColorComponents(GrColor* color, |
robertphillips
2014/09/26 14:00:31
line up?
jvanverth1
2014/10/03 17:28:23
Done.
|
+ uint32_t* validFlags) const { |
+ if ((*validFlags & kA_GrColorComponentFlag) && 0xFF == GrColorUnpackA(*color) && |
+ GrPixelConfigIsOpaque(this->texture(0)->config())) { |
+ *validFlags = kA_GrColorComponentFlag; |
+ } |
robertphillips
2014/09/26 14:00:31
put else on prior line ?
jvanverth1
2014/10/03 17:28:23
Done.
|
+ else { |
+ *validFlags = 0; |
+ } |
+} |
+ |
+const GrBackendGeometryProcessorFactory& GrDistanceFieldNoGammaTextureEffect::getFactory() const { |
+ return GrTBackendGeometryProcessorFactory<GrDistanceFieldNoGammaTextureEffect>::getInstance(); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
+GR_DEFINE_GEOMETRY_PROCESSOR_TEST(GrDistanceFieldNoGammaTextureEffect); |
+ |
+GrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* random, |
robertphillips
2014/09/26 14:00:31
line up ?
jvanverth1
2014/10/03 17:28:23
Done.
|
+ GrContext*, |
+ const GrDrawTargetCaps&, |
+ GrTexture* textures[]) { |
robertphillips
2014/09/26 14:00:30
put ':' on next line and line up with '?' ?
jvanverth1
2014/10/03 17:28:23
Done.
|
+ int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : |
+ GrProcessorUnitTest::kAlphaTextureIdx; |
+ static const SkShader::TileMode kTileModes[] = { |
+ SkShader::kClamp_TileMode, |
+ SkShader::kRepeat_TileMode, |
+ SkShader::kMirror_TileMode, |
+ }; |
+ SkShader::TileMode tileModes[] = { |
+ kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], |
+ kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], |
+ }; |
+ GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : |
robertphillips
2014/09/26 14:00:30
same here with ':' and '?' ?
jvanverth1
2014/10/03 17:28:24
Done.
|
+ GrTextureParams::kNone_FilterMode); |
+ |
+ return GrDistanceFieldNoGammaTextureEffect::Create(textures[texIdx], params, |
+ random->nextBool() ? |
+ kSimilarity_DistanceFieldEffectFlag : 0); |
+} |
+ |
+/////////////////////////////////////////////////////////////////////////////// |
+ |
class GrGLDistanceFieldLCDTextureEffect : public GrGLGeometryProcessor { |
public: |
GrGLDistanceFieldLCDTextureEffect(const GrBackendProcessorFactory& factory, |