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" |
11 | 11 |
12 #include "SkDistanceFieldGen.h" | 12 #include "SkDistanceFieldGen.h" |
13 | 13 |
14 #include "glsl/GrGLSLFragmentShaderBuilder.h" | 14 #include "glsl/GrGLSLFragmentShaderBuilder.h" |
15 #include "glsl/GrGLSLGeometryProcessor.h" | 15 #include "glsl/GrGLSLGeometryProcessor.h" |
16 #include "glsl/GrGLSLProgramBuilder.h" | 16 #include "glsl/GrGLSLProgramBuilder.h" |
17 #include "glsl/GrGLSLProgramDataManager.h" | 17 #include "glsl/GrGLSLProgramDataManager.h" |
| 18 #include "glsl/GrGLSLUtil.h" |
| 19 #include "glsl/GrGLSLVarying.h" |
18 #include "glsl/GrGLSLVertexShaderBuilder.h" | 20 #include "glsl/GrGLSLVertexShaderBuilder.h" |
19 #include "glsl/GrGLSLUtil.h" | |
20 | 21 |
21 // Assuming a radius of a little less than the diagonal of the fragment | 22 // Assuming a radius of a little less than the diagonal of the fragment |
22 #define SK_DistanceFieldAAFactor "0.65" | 23 #define SK_DistanceFieldAAFactor "0.65" |
23 | 24 |
24 class GrGLDistanceFieldA8TextGeoProc : public GrGLSLGeometryProcessor { | 25 class GrGLDistanceFieldA8TextGeoProc : public GrGLSLGeometryProcessor { |
25 public: | 26 public: |
26 GrGLDistanceFieldA8TextGeoProc() | 27 GrGLDistanceFieldA8TextGeoProc() |
27 : fViewMatrix(SkMatrix::InvalidMatrix()) | 28 : fViewMatrix(SkMatrix::InvalidMatrix()) |
28 , fColor(GrColor_ILLEGAL) | 29 , fColor(GrColor_ILLEGAL) |
29 #ifdef SK_GAMMA_APPLY_TO_A8 | 30 #ifdef SK_GAMMA_APPLY_TO_A8 |
30 , fDistanceAdjust(-1.0f) | 31 , fDistanceAdjust(-1.0f) |
31 #endif | 32 #endif |
32 {} | 33 {} |
33 | 34 |
34 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 35 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
35 const GrDistanceFieldA8TextGeoProc& dfTexEffect = | 36 const GrDistanceFieldA8TextGeoProc& dfTexEffect = |
36 args.fGP.cast<GrDistanceFieldA8TextGeoProc>(); | 37 args.fGP.cast<GrDistanceFieldA8TextGeoProc>(); |
37 GrGLSLGPBuilder* pb = args.fPB; | 38 GrGLSLGPBuilder* pb = args.fPB; |
38 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | 39 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
39 SkAssertResult(fragBuilder->enableFeature( | 40 SkAssertResult(fragBuilder->enableFeature( |
40 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 41 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
41 | 42 |
42 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; | 43 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
| 44 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; |
43 | 45 |
44 // emit attributes | 46 // emit attributes |
45 vertBuilder->emitAttributes(dfTexEffect); | 47 varyingHandler->emitAttributes(dfTexEffect); |
46 | 48 |
47 #ifdef SK_GAMMA_APPLY_TO_A8 | 49 #ifdef SK_GAMMA_APPLY_TO_A8 |
48 // adjust based on gamma | 50 // adjust based on gamma |
49 const char* distanceAdjustUniName = nullptr; | 51 const char* distanceAdjustUniName = nullptr; |
50 // width, height, 1/(3*width) | 52 // width, height, 1/(3*width) |
51 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi
bility, | 53 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi
bility, |
52 kFloat_GrSLType, kDefault_GrSLPrecision, | 54 kFloat_GrSLType, kDefault_GrSLPrecision, |
53 "DistanceAdjust", &distanceAdjustUniName); | 55 "DistanceAdjust", &distanceAdjustUniName); |
54 #endif | 56 #endif |
55 | 57 |
56 // Setup pass through color | 58 // Setup pass through color |
57 if (!dfTexEffect.colorIgnored()) { | 59 if (!dfTexEffect.colorIgnored()) { |
58 if (dfTexEffect.hasVertexColor()) { | 60 if (dfTexEffect.hasVertexColor()) { |
59 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC
olor); | 61 varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), a
rgs.fOutputColor); |
60 } else { | 62 } else { |
61 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fCo
lorUniform); | 63 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fCo
lorUniform); |
62 } | 64 } |
63 } | 65 } |
64 | 66 |
65 // Setup position | 67 // Setup position |
66 this->setupPosition(pb, | 68 this->setupPosition(pb, |
67 vertBuilder, | 69 vertBuilder, |
68 gpArgs, | 70 gpArgs, |
69 dfTexEffect.inPosition()->fName, | 71 dfTexEffect.inPosition()->fName, |
70 dfTexEffect.viewMatrix(), | 72 dfTexEffect.viewMatrix(), |
71 &fViewMatrixUniform); | 73 &fViewMatrixUniform); |
72 | 74 |
73 // emit transforms | 75 // emit transforms |
74 this->emitTransforms(pb, | 76 this->emitTransforms(pb, |
75 vertBuilder, | 77 vertBuilder, |
| 78 varyingHandler, |
76 gpArgs->fPositionVar, | 79 gpArgs->fPositionVar, |
77 dfTexEffect.inPosition()->fName, | 80 dfTexEffect.inPosition()->fName, |
78 args.fTransformsIn, | 81 args.fTransformsIn, |
79 args.fTransformsOut); | 82 args.fTransformsOut); |
80 | 83 |
81 // add varyings | 84 // add varyings |
82 GrGLSLVertToFrag recipScale(kFloat_GrSLType); | 85 GrGLSLVertToFrag recipScale(kFloat_GrSLType); |
83 GrGLSLVertToFrag st(kVec2f_GrSLType); | 86 GrGLSLVertToFrag st(kVec2f_GrSLType); |
84 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); | 87 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); |
85 pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); | 88 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision)
; |
86 vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCo
ords()->fName); | 89 vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCo
ords()->fName); |
87 | 90 |
88 // compute numbers to be hardcoded to convert texture coordinates from i
nt to float | 91 // compute numbers to be hardcoded to convert texture coordinates from i
nt to float |
89 SkASSERT(dfTexEffect.numTextures() == 1); | 92 SkASSERT(dfTexEffect.numTextures() == 1); |
90 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); | 93 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); |
91 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()))
; | 94 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()))
; |
92 SkScalar recipWidth = 1.0f / atlas->width(); | 95 SkScalar recipWidth = 1.0f / atlas->width(); |
93 SkScalar recipHeight = 1.0f / atlas->height(); | 96 SkScalar recipHeight = 1.0f / atlas->height(); |
94 | 97 |
95 GrGLSLVertToFrag uv(kVec2f_GrSLType); | 98 GrGLSLVertToFrag uv(kVec2f_GrSLType); |
96 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); | 99 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
97 vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), | 100 vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), |
98 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, | 101 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, |
99 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, | 102 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, |
100 dfTexEffect.inTextureCoords()->fName); | 103 dfTexEffect.inTextureCoords()->fName); |
101 | 104 |
102 // Use highp to work around aliasing issues | 105 // Use highp to work around aliasing issues |
103 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps, | 106 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps, |
104 kHigh_GrSLPreci
sion)); | 107 kHigh_GrSLPreci
sion)); |
105 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); | 108 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); |
106 | 109 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 | 295 |
293 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 296 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
294 const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistance
FieldPathGeoProc>(); | 297 const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistance
FieldPathGeoProc>(); |
295 | 298 |
296 GrGLSLGPBuilder* pb = args.fPB; | 299 GrGLSLGPBuilder* pb = args.fPB; |
297 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | 300 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
298 SkAssertResult(fragBuilder->enableFeature( | 301 SkAssertResult(fragBuilder->enableFeature( |
299 GrGLSLFragmentShaderBuilder::kStandardDeriv
atives_GLSLFeature)); | 302 GrGLSLFragmentShaderBuilder::kStandardDeriv
atives_GLSLFeature)); |
300 | 303 |
301 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; | 304 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
| 305 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; |
302 | 306 |
303 // emit attributes | 307 // emit attributes |
304 vertBuilder->emitAttributes(dfTexEffect); | 308 varyingHandler->emitAttributes(dfTexEffect); |
305 | 309 |
306 GrGLSLVertToFrag v(kVec2f_GrSLType); | 310 GrGLSLVertToFrag v(kVec2f_GrSLType); |
307 pb->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); | 311 varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); |
308 | 312 |
309 // setup pass through color | 313 // setup pass through color |
310 if (!dfTexEffect.colorIgnored()) { | 314 if (!dfTexEffect.colorIgnored()) { |
311 if (dfTexEffect.hasVertexColor()) { | 315 if (dfTexEffect.hasVertexColor()) { |
312 pb->addPassThroughAttribute(dfTexEffect.inColor(), args.fOutputC
olor); | 316 varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), a
rgs.fOutputColor); |
313 } else { | 317 } else { |
314 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fCo
lorUniform); | 318 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fCo
lorUniform); |
315 } | 319 } |
316 } | 320 } |
317 vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoo
rds()->fName); | 321 vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoo
rds()->fName); |
318 | 322 |
319 // Setup position | 323 // Setup position |
320 this->setupPosition(pb, | 324 this->setupPosition(pb, |
321 vertBuilder, | 325 vertBuilder, |
322 gpArgs, | 326 gpArgs, |
323 dfTexEffect.inPosition()->fName, | 327 dfTexEffect.inPosition()->fName, |
324 dfTexEffect.viewMatrix(), | 328 dfTexEffect.viewMatrix(), |
325 &fViewMatrixUniform); | 329 &fViewMatrixUniform); |
326 | 330 |
327 // emit transforms | 331 // emit transforms |
328 this->emitTransforms(pb, | 332 this->emitTransforms(pb, |
329 vertBuilder, | 333 vertBuilder, |
| 334 varyingHandler, |
330 gpArgs->fPositionVar, | 335 gpArgs->fPositionVar, |
331 dfTexEffect.inPosition()->fName, | 336 dfTexEffect.inPosition()->fName, |
332 args.fTransformsIn, | 337 args.fTransformsIn, |
333 args.fTransformsOut); | 338 args.fTransformsOut); |
334 | 339 |
335 const char* textureSizeUniName = nullptr; | 340 const char* textureSizeUniName = nullptr; |
336 fTextureSizeUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibil
ity, | 341 fTextureSizeUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibil
ity, |
337 kVec2f_GrSLType, kDefault_GrSLPrecision
, | 342 kVec2f_GrSLType, kDefault_GrSLPrecision
, |
338 "TextureSize", &textureSizeUniName); | 343 "TextureSize", &textureSizeUniName); |
339 | 344 |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) { | 517 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) { |
513 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.
0f, 1.0f, 1.0f); | 518 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.
0f, 1.0f, 1.0f); |
514 } | 519 } |
515 | 520 |
516 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 521 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
517 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = | 522 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = |
518 args.fGP.cast<GrDistanceFieldLCDTextGeoProc>(); | 523 args.fGP.cast<GrDistanceFieldLCDTextGeoProc>(); |
519 GrGLSLGPBuilder* pb = args.fPB; | 524 GrGLSLGPBuilder* pb = args.fPB; |
520 | 525 |
521 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; | 526 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
| 527 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; |
522 | 528 |
523 // emit attributes | 529 // emit attributes |
524 vertBuilder->emitAttributes(dfTexEffect); | 530 varyingHandler->emitAttributes(dfTexEffect); |
525 | 531 |
526 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | 532 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
527 | 533 |
528 // setup pass through color | 534 // setup pass through color |
529 if (!dfTexEffect.colorIgnored()) { | 535 if (!dfTexEffect.colorIgnored()) { |
530 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorU
niform); | 536 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorU
niform); |
531 } | 537 } |
532 | 538 |
533 // Setup position | 539 // Setup position |
534 this->setupPosition(pb, | 540 this->setupPosition(pb, |
535 vertBuilder, | 541 vertBuilder, |
536 gpArgs, | 542 gpArgs, |
537 dfTexEffect.inPosition()->fName, | 543 dfTexEffect.inPosition()->fName, |
538 dfTexEffect.viewMatrix(), | 544 dfTexEffect.viewMatrix(), |
539 &fViewMatrixUniform); | 545 &fViewMatrixUniform); |
540 | 546 |
541 // emit transforms | 547 // emit transforms |
542 this->emitTransforms(pb, | 548 this->emitTransforms(pb, |
543 vertBuilder, | 549 vertBuilder, |
| 550 varyingHandler, |
544 gpArgs->fPositionVar, | 551 gpArgs->fPositionVar, |
545 dfTexEffect.inPosition()->fName, | 552 dfTexEffect.inPosition()->fName, |
546 args.fTransformsIn, | 553 args.fTransformsIn, |
547 args.fTransformsOut); | 554 args.fTransformsOut); |
548 | 555 |
549 // set up varyings | 556 // set up varyings |
550 bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_Di
stanceFieldEffectMask); | 557 bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_Di
stanceFieldEffectMask); |
551 GrGLSLVertToFrag recipScale(kFloat_GrSLType); | 558 GrGLSLVertToFrag recipScale(kFloat_GrSLType); |
552 GrGLSLVertToFrag st(kVec2f_GrSLType); | 559 GrGLSLVertToFrag st(kVec2f_GrSLType); |
553 pb->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision); | 560 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision)
; |
554 vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCo
ords()->fName); | 561 vertBuilder->codeAppendf("%s = %s;", st.vsOut(), dfTexEffect.inTextureCo
ords()->fName); |
555 | 562 |
556 // compute numbers to be hardcoded to convert texture coordinates from i
nt to float | 563 // compute numbers to be hardcoded to convert texture coordinates from i
nt to float |
557 SkASSERT(dfTexEffect.numTextures() == 1); | 564 SkASSERT(dfTexEffect.numTextures() == 1); |
558 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); | 565 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); |
559 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()))
; | 566 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()))
; |
560 SkScalar recipWidth = 1.0f / atlas->width(); | 567 SkScalar recipWidth = 1.0f / atlas->width(); |
561 SkScalar recipHeight = 1.0f / atlas->height(); | 568 SkScalar recipHeight = 1.0f / atlas->height(); |
562 | 569 |
563 GrGLSLVertToFrag uv(kVec2f_GrSLType); | 570 GrGLSLVertToFrag uv(kVec2f_GrSLType); |
564 pb->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); | 571 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
565 vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), | 572 vertBuilder->codeAppendf("%s = vec2(%.*f, %.*f) * %s;", uv.vsOut(), |
566 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, | 573 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipWidth, |
567 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, | 574 GR_SIGNIFICANT_POW2_DECIMAL_DIG, recipHeight, |
568 dfTexEffect.inTextureCoords()->fName); | 575 dfTexEffect.inTextureCoords()->fName); |
569 | 576 |
570 // add frag shader code | 577 // add frag shader code |
571 | 578 |
572 SkAssertResult(fragBuilder->enableFeature( | 579 SkAssertResult(fragBuilder->enableFeature( |
573 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 580 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
574 | 581 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
777 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; | 784 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; |
778 flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; | 785 flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; |
779 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 786 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
780 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), | 787 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), |
781 GrTest::TestMatrix(d->fRandom), | 788 GrTest::TestMatrix(d->fRandom), |
782 d->fTextures[texIdx], params, | 789 d->fTextures[texIdx], params, |
783 wa, | 790 wa, |
784 flags, | 791 flags, |
785 d->fRandom->nextBool()); | 792 d->fRandom->nextBool()); |
786 } | 793 } |
OLD | NEW |