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 "GrInvariantOutput.h" | 9 #include "GrInvariantOutput.h" |
10 #include "GrTexture.h" | 10 #include "GrTexture.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 dfTexEffect.inPosition()->fName, | 66 dfTexEffect.inPosition()->fName, |
67 dfTexEffect.viewMatrix(), | 67 dfTexEffect.viewMatrix(), |
68 &fViewMatrixUniform); | 68 &fViewMatrixUniform); |
69 | 69 |
70 // emit transforms | 70 // emit transforms |
71 this->emitTransforms(vertBuilder, | 71 this->emitTransforms(vertBuilder, |
72 varyingHandler, | 72 varyingHandler, |
73 uniformHandler, | 73 uniformHandler, |
74 gpArgs->fPositionVar, | 74 gpArgs->fPositionVar, |
75 dfTexEffect.inPosition()->fName, | 75 dfTexEffect.inPosition()->fName, |
76 args.fFPCoordTransformHandler); | 76 args.fTransformsIn, |
| 77 args.fTransformsOut); |
77 | 78 |
78 // add varyings | 79 // add varyings |
79 GrGLSLVertToFrag recipScale(kFloat_GrSLType); | 80 GrGLSLVertToFrag recipScale(kFloat_GrSLType); |
80 GrGLSLVertToFrag uv(kVec2f_GrSLType); | 81 GrGLSLVertToFrag uv(kVec2f_GrSLType); |
81 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi
eldEffectMask) == | 82 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi
eldEffectMask) == |
82 kUniformScale_DistanceFieldEffectMask; | 83 kUniformScale_DistanceFieldEffectMask; |
83 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); | 84 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); |
84 bool isGammaCorrect = | 85 bool isGammaCorrect = |
85 SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectF
lag); | 86 SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectF
lag); |
86 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); | 87 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 if (isGammaCorrect) { | 172 if (isGammaCorrect) { |
172 fragBuilder->codeAppend( | 173 fragBuilder->codeAppend( |
173 "float val = clamp(distance + afwidth / (2.0 * afwidth), 0.0, 1.
0);"); | 174 "float val = clamp(distance + afwidth / (2.0 * afwidth), 0.0, 1.
0);"); |
174 } else { | 175 } else { |
175 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, d
istance);"); | 176 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, d
istance);"); |
176 } | 177 } |
177 | 178 |
178 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 179 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
179 } | 180 } |
180 | 181 |
181 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess
or& proc, | 182 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess
or& proc) override { |
182 FPCoordTransformIter&& transformIter) override { | |
183 #ifdef SK_GAMMA_APPLY_TO_A8 | 183 #ifdef SK_GAMMA_APPLY_TO_A8 |
184 const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFi
eldA8TextGeoProc>(); | 184 const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFi
eldA8TextGeoProc>(); |
185 float distanceAdjust = dfTexEffect.getDistanceAdjust(); | 185 float distanceAdjust = dfTexEffect.getDistanceAdjust(); |
186 if (distanceAdjust != fDistanceAdjust) { | 186 if (distanceAdjust != fDistanceAdjust) { |
187 pdman.set1f(fDistanceAdjustUni, distanceAdjust); | 187 pdman.set1f(fDistanceAdjustUni, distanceAdjust); |
188 fDistanceAdjust = distanceAdjust; | 188 fDistanceAdjust = distanceAdjust; |
189 } | 189 } |
190 #endif | 190 #endif |
191 const GrDistanceFieldA8TextGeoProc& dfa8gp = proc.cast<GrDistanceFieldA8
TextGeoProc>(); | 191 const GrDistanceFieldA8TextGeoProc& dfa8gp = proc.cast<GrDistanceFieldA8
TextGeoProc>(); |
192 | 192 |
193 if (!dfa8gp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dfa8g
p.viewMatrix())) { | 193 if (!dfa8gp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dfa8g
p.viewMatrix())) { |
194 fViewMatrix = dfa8gp.viewMatrix(); | 194 fViewMatrix = dfa8gp.viewMatrix(); |
195 float viewMatrix[3 * 3]; | 195 float viewMatrix[3 * 3]; |
196 GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); | 196 GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); |
197 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); | 197 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); |
198 } | 198 } |
199 this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); | |
200 } | 199 } |
201 | 200 |
202 static inline void GenKey(const GrGeometryProcessor& gp, | 201 static inline void GenKey(const GrGeometryProcessor& gp, |
203 const GrGLSLCaps&, | 202 const GrGLSLCaps&, |
204 GrProcessorKeyBuilder* b) { | 203 GrProcessorKeyBuilder* b) { |
205 const GrDistanceFieldA8TextGeoProc& dfTexEffect = gp.cast<GrDistanceFiel
dA8TextGeoProc>(); | 204 const GrDistanceFieldA8TextGeoProc& dfTexEffect = gp.cast<GrDistanceFiel
dA8TextGeoProc>(); |
206 uint32_t key = dfTexEffect.getFlags(); | 205 uint32_t key = dfTexEffect.getFlags(); |
207 key |= dfTexEffect.colorIgnored() << 16; | 206 key |= dfTexEffect.colorIgnored() << 16; |
208 key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25; | 207 key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25; |
209 b->add32(key); | 208 b->add32(key); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 dfTexEffect.inPosition()->fName, | 338 dfTexEffect.inPosition()->fName, |
340 dfTexEffect.viewMatrix(), | 339 dfTexEffect.viewMatrix(), |
341 &fViewMatrixUniform); | 340 &fViewMatrixUniform); |
342 | 341 |
343 // emit transforms | 342 // emit transforms |
344 this->emitTransforms(vertBuilder, | 343 this->emitTransforms(vertBuilder, |
345 varyingHandler, | 344 varyingHandler, |
346 uniformHandler, | 345 uniformHandler, |
347 gpArgs->fPositionVar, | 346 gpArgs->fPositionVar, |
348 dfTexEffect.inPosition()->fName, | 347 dfTexEffect.inPosition()->fName, |
349 args.fFPCoordTransformHandler); | 348 args.fTransformsIn, |
| 349 args.fTransformsOut); |
350 | 350 |
351 const char* textureSizeUniName = nullptr; | 351 const char* textureSizeUniName = nullptr; |
352 fTextureSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag, | 352 fTextureSizeUni = uniformHandler->addUniform(kFragment_GrShaderFlag, |
353 kVec2f_GrSLType, kDefault_G
rSLPrecision, | 353 kVec2f_GrSLType, kDefault_G
rSLPrecision, |
354 "TextureSize", &textureSize
UniName); | 354 "TextureSize", &textureSize
UniName); |
355 | 355 |
356 // Use highp to work around aliasing issues | 356 // Use highp to work around aliasing issues |
357 fragBuilder->appendPrecisionModifier(kHigh_GrSLPrecision); | 357 fragBuilder->appendPrecisionModifier(kHigh_GrSLPrecision); |
358 fragBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); | 358 fragBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); |
359 | 359 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 if (isGammaCorrect) { | 426 if (isGammaCorrect) { |
427 fragBuilder->codeAppend( | 427 fragBuilder->codeAppend( |
428 "float val = clamp(distance + afwidth / (2.0 * afwidth), 0.0, 1.
0);"); | 428 "float val = clamp(distance + afwidth / (2.0 * afwidth), 0.0, 1.
0);"); |
429 } else { | 429 } else { |
430 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, d
istance);"); | 430 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, d
istance);"); |
431 } | 431 } |
432 | 432 |
433 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 433 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
434 } | 434 } |
435 | 435 |
436 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess
or& proc, | 436 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess
or& proc) override { |
437 FPCoordTransformIter&& transformIter) override { | |
438 SkASSERT(fTextureSizeUni.isValid()); | 437 SkASSERT(fTextureSizeUni.isValid()); |
439 | 438 |
440 GrTexture* texture = proc.texture(0); | 439 GrTexture* texture = proc.texture(0); |
441 if (texture->width() != fTextureSize.width() || | 440 if (texture->width() != fTextureSize.width() || |
442 texture->height() != fTextureSize.height()) { | 441 texture->height() != fTextureSize.height()) { |
443 fTextureSize = SkISize::Make(texture->width(), texture->height()); | 442 fTextureSize = SkISize::Make(texture->width(), texture->height()); |
444 pdman.set2f(fTextureSizeUni, | 443 pdman.set2f(fTextureSizeUni, |
445 SkIntToScalar(fTextureSize.width()), | 444 SkIntToScalar(fTextureSize.width()), |
446 SkIntToScalar(fTextureSize.height())); | 445 SkIntToScalar(fTextureSize.height())); |
447 } | 446 } |
448 | 447 |
449 const GrDistanceFieldPathGeoProc& dfpgp = proc.cast<GrDistanceFieldPathG
eoProc>(); | 448 const GrDistanceFieldPathGeoProc& dfpgp = proc.cast<GrDistanceFieldPathG
eoProc>(); |
450 | 449 |
451 if (!dfpgp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dfpgp.
viewMatrix())) { | 450 if (!dfpgp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dfpgp.
viewMatrix())) { |
452 fViewMatrix = dfpgp.viewMatrix(); | 451 fViewMatrix = dfpgp.viewMatrix(); |
453 float viewMatrix[3 * 3]; | 452 float viewMatrix[3 * 3]; |
454 GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); | 453 GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); |
455 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); | 454 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); |
456 } | 455 } |
457 this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); | |
458 } | 456 } |
459 | 457 |
460 static inline void GenKey(const GrGeometryProcessor& gp, | 458 static inline void GenKey(const GrGeometryProcessor& gp, |
461 const GrGLSLCaps&, | 459 const GrGLSLCaps&, |
462 GrProcessorKeyBuilder* b) { | 460 GrProcessorKeyBuilder* b) { |
463 const GrDistanceFieldPathGeoProc& dfTexEffect = gp.cast<GrDistanceFieldP
athGeoProc>(); | 461 const GrDistanceFieldPathGeoProc& dfTexEffect = gp.cast<GrDistanceFieldP
athGeoProc>(); |
464 | 462 |
465 uint32_t key = dfTexEffect.getFlags(); | 463 uint32_t key = dfTexEffect.getFlags(); |
466 key |= dfTexEffect.colorIgnored() << 16; | 464 key |= dfTexEffect.colorIgnored() << 16; |
467 key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25; | 465 key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 dfTexEffect.inPosition()->fName, | 575 dfTexEffect.inPosition()->fName, |
578 dfTexEffect.viewMatrix(), | 576 dfTexEffect.viewMatrix(), |
579 &fViewMatrixUniform); | 577 &fViewMatrixUniform); |
580 | 578 |
581 // emit transforms | 579 // emit transforms |
582 this->emitTransforms(vertBuilder, | 580 this->emitTransforms(vertBuilder, |
583 varyingHandler, | 581 varyingHandler, |
584 uniformHandler, | 582 uniformHandler, |
585 gpArgs->fPositionVar, | 583 gpArgs->fPositionVar, |
586 dfTexEffect.inPosition()->fName, | 584 dfTexEffect.inPosition()->fName, |
587 args.fFPCoordTransformHandler); | 585 args.fTransformsIn, |
| 586 args.fTransformsOut); |
588 | 587 |
589 // set up varyings | 588 // set up varyings |
590 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi
eldEffectMask) == | 589 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi
eldEffectMask) == |
591 kUniformScale_DistanceFieldEffectMask; | 590 kUniformScale_DistanceFieldEffectMask; |
592 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); | 591 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); |
593 bool isGammaCorrect = | 592 bool isGammaCorrect = |
594 SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectF
lag); | 593 SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectF
lag); |
595 GrGLSLVertToFrag recipScale(kFloat_GrSLType); | 594 GrGLSLVertToFrag recipScale(kFloat_GrSLType); |
596 GrGLSLVertToFrag uv(kVec2f_GrSLType); | 595 GrGLSLVertToFrag uv(kVec2f_GrSLType); |
597 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); | 596 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 fragBuilder->codeAppend( | 725 fragBuilder->codeAppend( |
727 "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), dista
nce), 1.0);"); | 726 "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), dista
nce), 1.0);"); |
728 } | 727 } |
729 | 728 |
730 // set alpha to be max of rgb coverage | 729 // set alpha to be max of rgb coverage |
731 fragBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);"); | 730 fragBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);"); |
732 | 731 |
733 fragBuilder->codeAppendf("%s = val;", args.fOutputCoverage); | 732 fragBuilder->codeAppendf("%s = val;", args.fOutputCoverage); |
734 } | 733 } |
735 | 734 |
736 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess
or& processor, | 735 void setData(const GrGLSLProgramDataManager& pdman, |
737 FPCoordTransformIter&& transformIter) override { | 736 const GrPrimitiveProcessor& processor) override { |
738 SkASSERT(fDistanceAdjustUni.isValid()); | 737 SkASSERT(fDistanceAdjustUni.isValid()); |
739 | 738 |
740 const GrDistanceFieldLCDTextGeoProc& dflcd = processor.cast<GrDistanceFi
eldLCDTextGeoProc>(); | 739 const GrDistanceFieldLCDTextGeoProc& dflcd = processor.cast<GrDistanceFi
eldLCDTextGeoProc>(); |
741 GrDistanceFieldLCDTextGeoProc::DistanceAdjust wa = dflcd.getDistanceAdju
st(); | 740 GrDistanceFieldLCDTextGeoProc::DistanceAdjust wa = dflcd.getDistanceAdju
st(); |
742 if (wa != fDistanceAdjust) { | 741 if (wa != fDistanceAdjust) { |
743 pdman.set3f(fDistanceAdjustUni, | 742 pdman.set3f(fDistanceAdjustUni, |
744 wa.fR, | 743 wa.fR, |
745 wa.fG, | 744 wa.fG, |
746 wa.fB); | 745 wa.fB); |
747 fDistanceAdjust = wa; | 746 fDistanceAdjust = wa; |
748 } | 747 } |
749 | 748 |
750 if (!dflcd.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dflcd.
viewMatrix())) { | 749 if (!dflcd.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dflcd.
viewMatrix())) { |
751 fViewMatrix = dflcd.viewMatrix(); | 750 fViewMatrix = dflcd.viewMatrix(); |
752 float viewMatrix[3 * 3]; | 751 float viewMatrix[3 * 3]; |
753 GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); | 752 GrGLSLGetMatrix<3>(viewMatrix, fViewMatrix); |
754 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); | 753 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); |
755 } | 754 } |
756 this->setTransformDataHelper(SkMatrix::I(), pdman, &transformIter); | |
757 } | 755 } |
758 | 756 |
759 static inline void GenKey(const GrGeometryProcessor& gp, | 757 static inline void GenKey(const GrGeometryProcessor& gp, |
760 const GrGLSLCaps&, | 758 const GrGLSLCaps&, |
761 GrProcessorKeyBuilder* b) { | 759 GrProcessorKeyBuilder* b) { |
762 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = gp.cast<GrDistanceFie
ldLCDTextGeoProc>(); | 760 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = gp.cast<GrDistanceFie
ldLCDTextGeoProc>(); |
763 | 761 |
764 uint32_t key = dfTexEffect.getFlags(); | 762 uint32_t key = dfTexEffect.getFlags(); |
765 key |= dfTexEffect.colorIgnored() << 16; | 763 key |= dfTexEffect.colorIgnored() << 16; |
766 key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25; | 764 key |= ComputePosKey(dfTexEffect.viewMatrix()) << 25; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0
; | 839 flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0
; |
842 } | 840 } |
843 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 841 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
844 return GrDistanceFieldLCDTextGeoProc::Make(GrRandomColor(d->fRandom), | 842 return GrDistanceFieldLCDTextGeoProc::Make(GrRandomColor(d->fRandom), |
845 GrTest::TestMatrix(d->fRandom), | 843 GrTest::TestMatrix(d->fRandom), |
846 d->fTextures[texIdx], params, | 844 d->fTextures[texIdx], params, |
847 wa, | 845 wa, |
848 flags, | 846 flags, |
849 d->fRandom->nextBool()); | 847 d->fRandom->nextBool()); |
850 } | 848 } |
OLD | NEW |