| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrDistanceFieldGeoProc.h" | 8 #include "GrDistanceFieldGeoProc.h" |
| 9 #include "GrFontAtlasSizes.h" | 9 #include "GrFontAtlasSizes.h" |
| 10 #include "GrInvariantOutput.h" | 10 #include "GrInvariantOutput.h" |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 | 69 |
| 70 // emit transforms | 70 // emit transforms |
| 71 const SkMatrix& localMatrix = dfTexEffect.localMatrix(); | 71 const SkMatrix& localMatrix = dfTexEffect.localMatrix(); |
| 72 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosit
ion()->fName, | 72 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosit
ion()->fName, |
| 73 localMatrix, args.fTransformsIn, args.fTransformsOu
t); | 73 localMatrix, args.fTransformsIn, args.fTransformsOu
t); |
| 74 | 74 |
| 75 // add varyings | 75 // add varyings |
| 76 GrGLVertToFrag recipScale(kFloat_GrSLType); | 76 GrGLVertToFrag recipScale(kFloat_GrSLType); |
| 77 GrGLVertToFrag st(kVec2f_GrSLType); | 77 GrGLVertToFrag st(kVec2f_GrSLType); |
| 78 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); | 78 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); |
| 79 const char* viewMatrixName = this->uViewM(); | 79 args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); |
| 80 // view matrix name is NULL if identity matrix | 80 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoor
ds()->fName); |
| 81 bool useInverseScale = !localMatrix.isIdentity() && viewMatrixName; | |
| 82 if (isSimilarity && useInverseScale) { | |
| 83 args.fPB->addVarying("RecipScale", &recipScale, kHigh_GrSLPrecision)
; | |
| 84 vsBuilder->codeAppendf("vec2 tx = vec2(%s[0][0], %s[1][0]);", | |
| 85 viewMatrixName, viewMatrixName); | |
| 86 vsBuilder->codeAppend("float tx2 = dot(tx, tx);"); | |
| 87 vsBuilder->codeAppendf("%s = inversesqrt(tx2);", recipScale.vsOut())
; | |
| 88 } else { | |
| 89 args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); | |
| 90 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTexture
Coords()->fName); | |
| 91 } | |
| 92 | 81 |
| 93 GrGLVertToFrag uv(kVec2f_GrSLType); | 82 GrGLVertToFrag uv(kVec2f_GrSLType); |
| 94 args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); | 83 args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
| 95 // this is only used with text, so our texture bounds always match the g
lyph atlas | 84 // this is only used with text, so our texture bounds always match the g
lyph atlas |
| 96 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " | 85 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " |
| 97 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), | 86 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), |
| 98 dfTexEffect.inTextureCoords()->fName); | 87 dfTexEffect.inTextureCoords()->fName); |
| 99 | 88 |
| 100 // Use highp to work around aliasing issues | 89 // Use highp to work around aliasing issues |
| 101 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, | 90 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, |
| 102 pb->ctxInfo().stand
ard())); | 91 pb->ctxInfo().stand
ard())); |
| 103 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); | 92 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); |
| 104 | 93 |
| 105 fsBuilder->codeAppend("\tfloat texColor = "); | 94 fsBuilder->codeAppend("\tfloat texColor = "); |
| 106 fsBuilder->appendTextureLookup(args.fSamplers[0], | 95 fsBuilder->appendTextureLookup(args.fSamplers[0], |
| 107 "uv", | 96 "uv", |
| 108 kVec2f_GrSLType); | 97 kVec2f_GrSLType); |
| 109 fsBuilder->codeAppend(".r;\n"); | 98 fsBuilder->codeAppend(".r;\n"); |
| 110 fsBuilder->codeAppend("\tfloat distance = " | 99 fsBuilder->codeAppend("\tfloat distance = " |
| 111 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie
ldThreshold ");"); | 100 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie
ldThreshold ");"); |
| 112 #ifdef SK_GAMMA_APPLY_TO_A8 | 101 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 113 // adjust width based on gamma | 102 // adjust width based on gamma |
| 114 fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); | 103 fsBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); |
| 115 #endif | 104 #endif |
| 116 | 105 |
| 117 fsBuilder->codeAppend("float afwidth;"); | 106 fsBuilder->codeAppend("float afwidth;"); |
| 118 if (isSimilarity) { | 107 if (isSimilarity) { |
| 119 // For uniform scale, we adjust for the effect of the transformation
on the distance | 108 // For uniform scale, we adjust for the effect of the transformation
on the distance |
| 120 // either by using the inverse scale in the view matrix, or (if ther
e is no view matrix) | |
| 121 // by using the length of the gradient of the texture coordinates. W
e use st coordinates | 109 // by using the length of the gradient of the texture coordinates. W
e use st coordinates |
| 122 // with the latter to ensure we're mapping 1:1 from texel space to p
ixel space. | 110 // to ensure we're mapping 1:1 from texel space to pixel space. |
| 123 | 111 |
| 124 // this gives us a smooth step across approximately one fragment | 112 // this gives us a smooth step across approximately one fragment |
| 125 if (useInverseScale) { | 113 // we use y to work around a Mali400 bug in the x direction |
| 126 fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor
"*%s);", | 114 fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*d
Fdy(%s.y));", |
| 127 recipScale.fsIn()); | |
| 128 } else { | |
| 129 fsBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor
"*dFdx(%s.x));", | |
| 130 st.fsIn()); | 115 st.fsIn()); |
| 131 } | |
| 132 } else { | 116 } else { |
| 133 // For general transforms, to determine the amount of correction we
multiply a unit | 117 // For general transforms, to determine the amount of correction we
multiply a unit |
| 134 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords | 118 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords |
| 135 // (which is the inverse transform for this fragment) and take the l
ength of the result. | 119 // (which is the inverse transform for this fragment) and take the l
ength of the result. |
| 136 fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(di
stance));"); | 120 fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(di
stance));"); |
| 137 // the length of the gradient may be 0, so we need to check for this | 121 // the length of the gradient may be 0, so we need to check for this |
| 138 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 | 122 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 |
| 139 fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); | 123 fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); |
| 140 fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); | 124 fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); |
| 141 fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); | 125 fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 static inline void GenKey(const GrGeometryProcessor& gp, | 166 static inline void GenKey(const GrGeometryProcessor& gp, |
| 183 const GrBatchTracker& bt, | 167 const GrBatchTracker& bt, |
| 184 const GrGLCaps&, | 168 const GrGLCaps&, |
| 185 GrProcessorKeyBuilder* b) { | 169 GrProcessorKeyBuilder* b) { |
| 186 const GrDistanceFieldA8TextGeoProc& dfTexEffect = gp.cast<GrDistanceFiel
dA8TextGeoProc>(); | 170 const GrDistanceFieldA8TextGeoProc& dfTexEffect = gp.cast<GrDistanceFiel
dA8TextGeoProc>(); |
| 187 const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTrack
er>(); | 171 const DistanceFieldBatchTracker& local = bt.cast<DistanceFieldBatchTrack
er>(); |
| 188 uint32_t key = dfTexEffect.getFlags(); | 172 uint32_t key = dfTexEffect.getFlags(); |
| 189 key |= local.fInputColorType << 16; | 173 key |= local.fInputColorType << 16; |
| 190 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1
<< 24: 0x0; | 174 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1
<< 24: 0x0; |
| 191 key |= ComputePosKey(gp.viewMatrix()) << 25; | 175 key |= ComputePosKey(gp.viewMatrix()) << 25; |
| 192 key |= (!gp.viewMatrix().isIdentity() && !gp.localMatrix().isIdentity())
? 0x1 << 27 : 0x0; | |
| 193 b->add32(key); | 176 b->add32(key); |
| 194 } | 177 } |
| 195 | 178 |
| 196 private: | 179 private: |
| 197 GrColor fColor; | 180 GrColor fColor; |
| 198 UniformHandle fColorUniform; | 181 UniformHandle fColorUniform; |
| 199 #ifdef SK_GAMMA_APPLY_TO_A8 | 182 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 200 float fDistanceAdjust; | 183 float fDistanceAdjust; |
| 201 UniformHandle fDistanceAdjustUni; | 184 UniformHandle fDistanceAdjustUni; |
| 202 #endif | 185 #endif |
| 203 | 186 |
| 204 typedef GrGLGeometryProcessor INHERITED; | 187 typedef GrGLGeometryProcessor INHERITED; |
| 205 }; | 188 }; |
| 206 | 189 |
| 207 /////////////////////////////////////////////////////////////////////////////// | 190 /////////////////////////////////////////////////////////////////////////////// |
| 208 | 191 |
| 209 GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color, | 192 GrDistanceFieldA8TextGeoProc::GrDistanceFieldA8TextGeoProc(GrColor color, |
| 210 const SkMatrix& viewM
atrix, | 193 const SkMatrix& viewM
atrix, |
| 211 const SkMatrix& local
Matrix, | |
| 212 GrTexture* texture, | 194 GrTexture* texture, |
| 213 const GrTextureParams
& params, | 195 const GrTextureParams
& params, |
| 214 #ifdef SK_GAMMA_APPLY_TO_A8 | 196 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 215 float distanceAdjust, | 197 float distanceAdjust, |
| 216 #endif | 198 #endif |
| 217 uint32_t flags, bool
opaqueVertexColors) | 199 uint32_t flags, bool
opaqueVertexColors) |
| 218 : INHERITED(color, viewMatrix, localMatrix, opaqueVertexColors) | 200 : INHERITED(color, viewMatrix, SkMatrix::I(), opaqueVertexColors) |
| 219 , fTextureAccess(texture, params) | 201 , fTextureAccess(texture, params) |
| 220 #ifdef SK_GAMMA_APPLY_TO_A8 | 202 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 221 , fDistanceAdjust(distanceAdjust) | 203 , fDistanceAdjust(distanceAdjust) |
| 222 #endif | 204 #endif |
| 223 , fFlags(flags & kNonLCD_DistanceFieldEffectMask) | 205 , fFlags(flags & kNonLCD_DistanceFieldEffectMask) |
| 224 , fInColor(NULL) { | 206 , fInColor(NULL) { |
| 225 SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); | 207 SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); |
| 226 this->initClassID<GrDistanceFieldA8TextGeoProc>(); | 208 this->initClassID<GrDistanceFieldA8TextGeoProc>(); |
| 227 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex
AttribType)); | 209 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex
AttribType)); |
| 228 if (flags & kColorAttr_DistanceFieldEffectFlag) { | 210 if (flags & kColorAttr_DistanceFieldEffectFlag) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 }; | 277 }; |
| 296 SkShader::TileMode tileModes[] = { | 278 SkShader::TileMode tileModes[] = { |
| 297 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], | 279 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], |
| 298 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], | 280 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], |
| 299 }; | 281 }; |
| 300 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil
erp_FilterMode : | 282 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil
erp_FilterMode : |
| 301 GrTextureParams::kNon
e_FilterMode); | 283 GrTextureParams::kNon
e_FilterMode); |
| 302 | 284 |
| 303 return GrDistanceFieldA8TextGeoProc::Create(GrRandomColor(random), | 285 return GrDistanceFieldA8TextGeoProc::Create(GrRandomColor(random), |
| 304 GrProcessorUnitTest::TestMatrix(
random), | 286 GrProcessorUnitTest::TestMatrix(
random), |
| 305 GrProcessorUnitTest::TestMatrix(
random), | |
| 306 textures[texIdx], params, | 287 textures[texIdx], params, |
| 307 #ifdef SK_GAMMA_APPLY_TO_A8 | 288 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 308 random->nextF(), | 289 random->nextF(), |
| 309 #endif | 290 #endif |
| 310 random->nextBool() ? | 291 random->nextBool() ? |
| 311 kSimilarity_DistanceFieldEff
ectFlag : 0, | 292 kSimilarity_DistanceFieldEff
ectFlag : 0, |
| 312 random->nextBool()); | 293 random->nextBool()); |
| 313 } | 294 } |
| 314 | 295 |
| 315 /////////////////////////////////////////////////////////////////////////////// | 296 /////////////////////////////////////////////////////////////////////////////// |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 | 569 |
| 589 // emit transforms | 570 // emit transforms |
| 590 const SkMatrix& localMatrix = dfTexEffect.localMatrix(); | 571 const SkMatrix& localMatrix = dfTexEffect.localMatrix(); |
| 591 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosit
ion()->fName, | 572 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosit
ion()->fName, |
| 592 localMatrix, args.fTransformsIn, args.fTransformsOu
t); | 573 localMatrix, args.fTransformsIn, args.fTransformsOu
t); |
| 593 | 574 |
| 594 // set up varyings | 575 // set up varyings |
| 595 bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_Di
stanceFieldEffectMask); | 576 bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_Di
stanceFieldEffectMask); |
| 596 GrGLVertToFrag recipScale(kFloat_GrSLType); | 577 GrGLVertToFrag recipScale(kFloat_GrSLType); |
| 597 GrGLVertToFrag st(kVec2f_GrSLType); | 578 GrGLVertToFrag st(kVec2f_GrSLType); |
| 598 const char* viewMatrixName = this->uViewM(); | 579 args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); |
| 599 // view matrix name is NULL if identity matrix | 580 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCoor
ds()->fName); |
| 600 bool useInverseScale = !localMatrix.isIdentity() && viewMatrixName; | |
| 601 if (isUniformScale && useInverseScale) { | |
| 602 args.fPB->addVarying("RecipScale", &recipScale, kHigh_GrSLPrecision)
; | |
| 603 vsBuilder->codeAppendf("vec2 tx = vec2(%s[0][0], %s[1][0]);", | |
| 604 viewMatrixName, viewMatrixName); | |
| 605 vsBuilder->codeAppend("float tx2 = dot(tx, tx);"); | |
| 606 vsBuilder->codeAppendf("%s = inversesqrt(tx2);", recipScale.vsOut())
; | |
| 607 } else { | |
| 608 args.fPB->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); | |
| 609 vsBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTexture
Coords()->fName); | |
| 610 } | |
| 611 | 581 |
| 612 GrGLVertToFrag uv(kVec2f_GrSLType); | 582 GrGLVertToFrag uv(kVec2f_GrSLType); |
| 613 args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); | 583 args.fPB->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
| 614 // this is only used with text, so our texture bounds always match the g
lyph atlas | 584 // this is only used with text, so our texture bounds always match the g
lyph atlas |
| 615 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " | 585 vsBuilder->codeAppendf("%s = vec2(" GR_FONT_ATLAS_A8_RECIP_WIDTH ", " |
| 616 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), | 586 GR_FONT_ATLAS_RECIP_HEIGHT ")*%s;", uv.vsOut(), |
| 617 dfTexEffect.inTextureCoords()->fName); | 587 dfTexEffect.inTextureCoords()->fName); |
| 618 | 588 |
| 619 // add frag shader code | 589 // add frag shader code |
| 620 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 590 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| 621 | 591 |
| 622 SkAssertResult(fsBuilder->enableFeature( | 592 SkAssertResult(fsBuilder->enableFeature( |
| 623 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 593 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
| 624 | 594 |
| 625 // create LCD offset adjusted by inverse of transform | 595 // create LCD offset adjusted by inverse of transform |
| 626 // Use highp to work around aliasing issues | 596 // Use highp to work around aliasing issues |
| 627 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, | 597 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, |
| 628 pb->ctxInfo().stand
ard())); | 598 pb->ctxInfo().stand
ard())); |
| 629 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); | 599 fsBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); |
| 630 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, | 600 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, |
| 631 pb->ctxInfo().stand
ard())); | 601 pb->ctxInfo().stand
ard())); |
| 632 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { | 602 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { |
| 633 fsBuilder->codeAppend("float delta = -" GR_FONT_ATLAS_LCD_DELTA ";\n
"); | 603 fsBuilder->codeAppend("float delta = -" GR_FONT_ATLAS_LCD_DELTA ";\n
"); |
| 634 } else { | 604 } else { |
| 635 fsBuilder->codeAppend("float delta = " GR_FONT_ATLAS_LCD_DELTA ";\n"
); | 605 fsBuilder->codeAppend("float delta = " GR_FONT_ATLAS_LCD_DELTA ";\n"
); |
| 636 } | 606 } |
| 637 if (isUniformScale) { | 607 if (isUniformScale) { |
| 638 if (useInverseScale) { | 608 fsBuilder->codeAppendf("float dy = dFdy(%s.y);", st.fsIn()); |
| 639 fsBuilder->codeAppendf("float dx = %s;", recipScale.fsIn()); | 609 fsBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);"); |
| 640 } else { | |
| 641 fsBuilder->codeAppendf("float dx = dFdx(%s.x);", st.fsIn()); | |
| 642 } | |
| 643 fsBuilder->codeAppend("vec2 offset = vec2(dx*delta, 0.0);"); | |
| 644 } else { | 610 } else { |
| 645 fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); | 611 fsBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); |
| 646 | 612 |
| 647 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); | 613 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); |
| 648 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); | 614 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); |
| 649 fsBuilder->codeAppend("vec2 offset = delta*Jdx;"); | 615 fsBuilder->codeAppend("vec2 offset = delta*Jdx;"); |
| 650 } | 616 } |
| 651 | 617 |
| 652 // green is distance to uv center | 618 // green is distance to uv center |
| 653 fsBuilder->codeAppend("\tvec4 texColor = "); | 619 fsBuilder->codeAppend("\tvec4 texColor = "); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 682 // for each color component. However, this is only important when using
perspective | 648 // for each color component. However, this is only important when using
perspective |
| 683 // transformations, and even then using a single factor seems like a rea
sonable | 649 // transformations, and even then using a single factor seems like a rea
sonable |
| 684 // trade-off between quality and speed. | 650 // trade-off between quality and speed. |
| 685 fsBuilder->codeAppend("float afwidth;"); | 651 fsBuilder->codeAppend("float afwidth;"); |
| 686 if (isUniformScale) { | 652 if (isUniformScale) { |
| 687 // For uniform scale, we adjust for the effect of the transformation
on the distance | 653 // For uniform scale, we adjust for the effect of the transformation
on the distance |
| 688 // by using the length of the gradient of the texture coordinates. W
e use st coordinates | 654 // by using the length of the gradient of the texture coordinates. W
e use st coordinates |
| 689 // to ensure we're mapping 1:1 from texel space to pixel space. | 655 // to ensure we're mapping 1:1 from texel space to pixel space. |
| 690 | 656 |
| 691 // this gives us a smooth step across approximately one fragment | 657 // this gives us a smooth step across approximately one fragment |
| 692 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dx
);"); | 658 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dy
);"); |
| 693 } else { | 659 } else { |
| 694 // For general transforms, to determine the amount of correction we
multiply a unit | 660 // For general transforms, to determine the amount of correction we
multiply a unit |
| 695 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords | 661 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords |
| 696 // (which is the inverse transform for this fragment) and take the l
ength of the result. | 662 // (which is the inverse transform for this fragment) and take the l
ength of the result. |
| 697 fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(
distance.r));"); | 663 fsBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFdy(
distance.r));"); |
| 698 // the length of the gradient may be 0, so we need to check for this | 664 // the length of the gradient may be 0, so we need to check for this |
| 699 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 | 665 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 |
| 700 fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); | 666 fsBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"); |
| 701 fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); | 667 fsBuilder->codeAppend("if (dg_len2 < 0.0001) {"); |
| 702 fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); | 668 fsBuilder->codeAppend("dist_grad = vec2(0.7071, 0.7071);"); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 const GrBatchTracker& bt, | 713 const GrBatchTracker& bt, |
| 748 const GrGLCaps&, | 714 const GrGLCaps&, |
| 749 GrProcessorKeyBuilder* b) { | 715 GrProcessorKeyBuilder* b) { |
| 750 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = gp.cast<GrDistanceFie
ldLCDTextGeoProc>(); | 716 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = gp.cast<GrDistanceFie
ldLCDTextGeoProc>(); |
| 751 | 717 |
| 752 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatc
hTracker>(); | 718 const DistanceFieldLCDBatchTracker& local = bt.cast<DistanceFieldLCDBatc
hTracker>(); |
| 753 uint32_t key = dfTexEffect.getFlags(); | 719 uint32_t key = dfTexEffect.getFlags(); |
| 754 key |= local.fInputColorType << 16; | 720 key |= local.fInputColorType << 16; |
| 755 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1
<< 24: 0x0; | 721 key |= local.fUsesLocalCoords && gp.localMatrix().hasPerspective() ? 0x1
<< 24: 0x0; |
| 756 key |= ComputePosKey(gp.viewMatrix()) << 25; | 722 key |= ComputePosKey(gp.viewMatrix()) << 25; |
| 757 key |= (!gp.viewMatrix().isIdentity() && !gp.localMatrix().isIdentity())
? 0x1 << 27 : 0x0; | |
| 758 b->add32(key); | 723 b->add32(key); |
| 759 } | 724 } |
| 760 | 725 |
| 761 private: | 726 private: |
| 762 GrColor fColor; | 727 GrColor fColor; |
| 763 UniformHandle fColorUniform; | 728 UniformHandle fColorUniform; |
| 764 GrDistanceFieldLCDTextGeoProc::DistanceAdjust fDistanceAdjust; | 729 GrDistanceFieldLCDTextGeoProc::DistanceAdjust fDistanceAdjust; |
| 765 UniformHandle fDistanceAdjustUni; | 730 UniformHandle fDistanceAdjustUni; |
| 766 | 731 |
| 767 typedef GrGLGeometryProcessor INHERITED; | 732 typedef GrGLGeometryProcessor INHERITED; |
| 768 }; | 733 }; |
| 769 | 734 |
| 770 /////////////////////////////////////////////////////////////////////////////// | 735 /////////////////////////////////////////////////////////////////////////////// |
| 771 | 736 |
| 772 GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc( | 737 GrDistanceFieldLCDTextGeoProc::GrDistanceFieldLCDTextGeoProc( |
| 773 GrColor color, const SkMatrix&
viewMatrix, | 738 GrColor color, const SkMatrix&
viewMatrix, |
| 774 const SkMatrix& localMatrix, | |
| 775 GrTexture* texture, const GrTe
xtureParams& params, | 739 GrTexture* texture, const GrTe
xtureParams& params, |
| 776 DistanceAdjust distanceAdjust, | 740 DistanceAdjust distanceAdjust, |
| 777 uint32_t flags) | 741 uint32_t flags) |
| 778 : INHERITED(color, viewMatrix, localMatrix) | 742 : INHERITED(color, viewMatrix, SkMatrix::I()) |
| 779 , fTextureAccess(texture, params) | 743 , fTextureAccess(texture, params) |
| 780 , fDistanceAdjust(distanceAdjust) | 744 , fDistanceAdjust(distanceAdjust) |
| 781 , fFlags(flags & kLCD_DistanceFieldEffectMask){ | 745 , fFlags(flags & kLCD_DistanceFieldEffectMask){ |
| 782 SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_Distan
ceFieldEffectFlag)); | 746 SkASSERT(!(flags & ~kLCD_DistanceFieldEffectMask) && (flags & kUseLCD_Distan
ceFieldEffectFlag)); |
| 783 this->initClassID<GrDistanceFieldLCDTextGeoProc>(); | 747 this->initClassID<GrDistanceFieldLCDTextGeoProc>(); |
| 784 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex
AttribType)); | 748 fInPosition = &this->addVertexAttrib(Attribute("inPosition", kVec2f_GrVertex
AttribType)); |
| 785 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", | 749 fInTextureCoords = &this->addVertexAttrib(Attribute("inTextureCoords", |
| 786 kVec2s_GrVertexAttribT
ype)); | 750 kVec2s_GrVertexAttribT
ype)); |
| 787 this->addTextureAccess(&fTextureAccess); | 751 this->addTextureAccess(&fTextureAccess); |
| 788 } | 752 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], | 812 kTileModes[random->nextULessThan(SK_ARRAY_COUNT(kTileModes))], |
| 849 }; | 813 }; |
| 850 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil
erp_FilterMode : | 814 GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBil
erp_FilterMode : |
| 851 GrTextureParams::kNone_FilterMode); | 815 GrTextureParams::kNone_FilterMode); |
| 852 DistanceAdjust wa = { 0.0f, 0.1f, -0.1f }; | 816 DistanceAdjust wa = { 0.0f, 0.1f, -0.1f }; |
| 853 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; | 817 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; |
| 854 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; | 818 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; |
| 855 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 819 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
| 856 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(random), | 820 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(random), |
| 857 GrProcessorUnitTest::TestMatrix
(random), | 821 GrProcessorUnitTest::TestMatrix
(random), |
| 858 GrProcessorUnitTest::TestMatrix
(random), | |
| 859 textures[texIdx], params, | 822 textures[texIdx], params, |
| 860 wa, | 823 wa, |
| 861 flags); | 824 flags); |
| 862 } | 825 } |
| OLD | NEW |