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 |