Chromium Code Reviews| Index: src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
| diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
| index d44c193260dac3f674c62a52db885206b2486a13..2a4b65e7b7ab82abb3f35f4f6c68fba9eb66c01b 100755 |
| --- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
| +++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp |
| @@ -51,16 +51,6 @@ public: |
| // emit attributes |
| vsBuilder->emitAttributes(dfTexEffect); |
| - GrGLVertToFrag st(kVec2f_GrSLType); |
| - args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); |
| - vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); |
| - |
| - GrGLVertToFrag uv(kVec2f_GrSLType); |
| - args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
| - // this is only used with text, so our texture bounds always match the glyph atlas |
| - vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " |
| - GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), |
| - dfTexEffect.inTextureCoords()->fName); |
| #ifdef SK_GAMMA_APPLY_TO_A8 |
| // adjust based on gamma |
| const char* distanceAdjustUniName = NULL; |
| @@ -81,6 +71,30 @@ public: |
| this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, |
| dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut); |
| + // add varyings |
| + GrGLVertToFrag recipScale(kFloat_GrSLType); |
| + GrGLVertToFrag st(kVec2f_GrSLType); |
| + bool isSimilarity = !!(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag); |
|
bsalomon
2015/04/03 21:16:30
SkToBool?
jvanverth1
2015/04/06 14:14:47
Done.
|
| + const char* viewMatrixName = this->uViewM(); |
| + if (isSimilarity && viewMatrixName) { |
| + args.fPB->addVarying("RecipScale", &recipScale, kHigh_GrSLPrecision); |
| + vsBuilder->codeAppendf("vec2 tx = vec2(%s[0][0], %s[1][0]);", |
| + viewMatrixName, viewMatrixName); |
| + vsBuilder->codeAppend("float tx2 = dot(tx, tx);"); |
| + vsBuilder->codeAppendf("%s = inversesqrt(tx2);", recipScale.vsOut()); |
| + } else { |
| + args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); |
| + vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); |
| + } |
| + |
| + GrGLVertToFrag uv(kVec2f_GrSLType); |
| + args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
| + // this is only used with text, so our texture bounds always match the glyph atlas |
| + vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " |
| + GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), |
| + dfTexEffect.inTextureCoords()->fName); |
| + |
| + |
| // Use highp to work around aliasing issues |
| fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, |
| pb->ctxInfo().standard())); |
| @@ -100,16 +114,23 @@ public: |
| fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, |
| pb->ctxInfo().standard())); |
| - fsBuilder->codeAppendf("vec2 st = %s;", st.fsIn()); |
| fsBuilder->codeAppend("float afwidth;"); |
| - if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { |
| + if (isSimilarity) { |
| // For uniform scale, we adjust for the effect of the transformation on the distance |
| + // either by using the inverse scale in the view matrix, or (if there is no view matrix) |
| // 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. |
| + // with the latter to ensure we're mapping 1:1 from texel space to pixel space. |
| // this gives us a smooth step across approximately one fragment |
| - fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(st.x));"); |
| + if (viewMatrixName) { |
| + fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*%s);", |
| + recipScale.fsIn()); |
| + } else { |
| + fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdx(%s.x));", |
| + st.fsIn()); |
| + } |
| } else { |
| + fsBuilder->codeAppendf("vec2 st = %s;", st.fsIn()); |
| // For general transforms, to determine the amount of correction we multiply a unit |
| // vector pointing along the SDF gradient direction by the Jacobian of the st coords |
| // (which is the inverse transform for this fragment) and take the length of the result. |
| @@ -188,13 +209,14 @@ private: |
| GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color, |
| const SkMatrix& viewMatrix, |
| + const SkMatrix& localMatrix, |
| GrTexture* texture, |
| const GrTextureParams& params, |
| #ifdef SK_GAMMA_APPLY_TO_A8 |
| float distanceAdjust, |
| #endif |
| uint32_t flags, bool opaqueVertexColors) |
| - : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors) |
| + : INHERITED(color, viewMatrix, localMatrix, opaqueVertexColors) |
| , fTextureAccess(texture, params) |
| #ifdef SK_GAMMA_APPLY_TO_A8 |
| , fDistanceAdjust(distanceAdjust) |
| @@ -281,6 +303,7 @@ GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, |
| return GrDistanceFieldTextureEffect::Create(GrRandomColor(random), |
| GrProcessorUnitTest::TestMatrix(random), |
| + GrProcessorUnitTest::TestMatrix(random), |
| textures[texIdx], params, |
| #ifdef SK_GAMMA_APPLY_TO_A8 |
| random->nextF(), |
| @@ -564,17 +587,6 @@ public: |
| // emit attributes |
| vsBuilder->emitAttributes(dfTexEffect); |
| - GrGLVertToFrag st(kVec2f_GrSLType); |
| - args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); |
| - vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); |
| - |
| - GrGLVertToFrag uv(kVec2f_GrSLType); |
| - args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
| - // this is only used with text, so our texture bounds always match the glyph atlas |
| - vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " |
| - GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), |
| - dfTexEffect.inTextureCoords()->fName); |
| - |
| // setup pass through color |
| this->setupColorPassThrough(pb, local.fInputColorType, args.fOutputColor, NULL, |
| &fColorUniform); |
| @@ -586,6 +598,30 @@ public: |
| this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosition()->fName, |
| dfTexEffect.localMatrix(), args.fTransformsIn, args.fTransformsOut); |
| + // set up varyings |
| + bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask); |
|
bsalomon
2015/04/03 21:16:30
SkToBool?
jvanverth1
2015/04/06 14:14:47
Done.
|
| + GrGLVertToFrag recipScale(kFloat_GrSLType); |
| + GrGLVertToFrag st(kVec2f_GrSLType); |
| + const char* viewMatrixName = this->uViewM(); |
| + if (isUniformScale && viewMatrixName) { |
| + args.fPB->addVarying("RecipScale", &recipScale, kHigh_GrSLPrecision); |
| + vsBuilder->codeAppendf("vec2 tx = vec2(%s[0][0], %s[1][0]);", |
| + viewMatrixName, viewMatrixName); |
| + vsBuilder->codeAppend("float tx2 = dot(tx, tx);"); |
| + vsBuilder->codeAppendf("%s = inversesqrt(tx2);", recipScale.vsOut()); |
| + } else { |
| + args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); |
| + vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoords()->fName); |
| + } |
| + |
| + GrGLVertToFrag uv(kVec2f_GrSLType); |
| + args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
| + // this is only used with text, so our texture bounds always match the glyph atlas |
| + vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " |
| + GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), |
| + dfTexEffect.inTextureCoords()->fName); |
| + |
| + // add frag shader code |
| GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| SkAssertResult(fsBuilder->enableFeature( |
| @@ -598,21 +634,24 @@ public: |
| fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); |
| fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision, |
| pb->ctxInfo().standard())); |
| - fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); |
| - bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask); |
| - |
| if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { |
| fsBuilder->codeAppend("float delta = -" GR_FONT_ATLAS_LCD_DELTA ";\n"); |
| } else { |
| fsBuilder->codeAppend("float delta = " GR_FONT_ATLAS_LCD_DELTA ";\n"); |
| } |
| if (isUniformScale) { |
| - fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n"); |
| - fsBuilder->codeAppend("\tvec2 offset = vec2(dx*delta, 0.0);\n"); |
| + if (viewMatrixName) { |
| + fsBuilder->codeAppendf("float dx = %s;", recipScale.fsIn()); |
| + } else { |
| + fsBuilder->codeAppendf("float dx = dFdx(%s.x);", st.fsIn()); |
| + } |
| + fsBuilder->codeAppend("vec2 offset = vec2(dx*delta, 0.0);"); |
| } else { |
| - fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); |
| - fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); |
| - fsBuilder->codeAppend("\tvec2 offset = delta*Jdx;\n"); |
| + fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); |
| + |
| + fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); |
| + fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); |
| + fsBuilder->codeAppend("vec2 offset = delta*Jdx;"); |
| } |
| // green is distance to uv center |
| @@ -737,10 +776,11 @@ private: |
| GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect( |
| GrColor color, const SkMatrix& viewMatrix, |
| + const SkMatrix& localMatrix, |
| GrTexture* texture, const GrTextureParams& params, |
| DistanceAdjust distanceAdjust, |
| uint32_t flags) |
| - : INHERITED(color, viewMatrix, SkMatrix::I()) |
| + : INHERITED(color, viewMatrix, localMatrix) |
| , fTextureAccess(texture, params) |
| , fDistanceAdjust(distanceAdjust) |
| , fFlags(flags & kLCD_DistanceFieldEffectMask){ |
| @@ -821,6 +861,7 @@ GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* rando |
| flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
| return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random), |
| GrProcessorUnitTest::TestMatrix(random), |
| + GrProcessorUnitTest::TestMatrix(random), |
| textures[texIdx], params, |
| wa, |
| flags); |