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); |