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" | |
17 #include "glsl/GrGLSLProgramDataManager.h" | 16 #include "glsl/GrGLSLProgramDataManager.h" |
| 17 #include "glsl/GrGLSLUniformHandler.h" |
18 #include "glsl/GrGLSLUtil.h" | 18 #include "glsl/GrGLSLUtil.h" |
19 #include "glsl/GrGLSLVarying.h" | 19 #include "glsl/GrGLSLVarying.h" |
20 #include "glsl/GrGLSLVertexShaderBuilder.h" | 20 #include "glsl/GrGLSLVertexShaderBuilder.h" |
21 | 21 |
22 // 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 |
23 #define SK_DistanceFieldAAFactor "0.65" | 23 #define SK_DistanceFieldAAFactor "0.65" |
24 | 24 |
25 class GrGLDistanceFieldA8TextGeoProc : public GrGLSLGeometryProcessor { | 25 class GrGLDistanceFieldA8TextGeoProc : public GrGLSLGeometryProcessor { |
26 public: | 26 public: |
27 GrGLDistanceFieldA8TextGeoProc() | 27 GrGLDistanceFieldA8TextGeoProc() |
28 : fViewMatrix(SkMatrix::InvalidMatrix()) | 28 : fViewMatrix(SkMatrix::InvalidMatrix()) |
29 , fColor(GrColor_ILLEGAL) | 29 , fColor(GrColor_ILLEGAL) |
30 #ifdef SK_GAMMA_APPLY_TO_A8 | 30 #ifdef SK_GAMMA_APPLY_TO_A8 |
31 , fDistanceAdjust(-1.0f) | 31 , fDistanceAdjust(-1.0f) |
32 #endif | 32 #endif |
33 {} | 33 {} |
34 | 34 |
35 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 35 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
36 const GrDistanceFieldA8TextGeoProc& dfTexEffect = | 36 const GrDistanceFieldA8TextGeoProc& dfTexEffect = |
37 args.fGP.cast<GrDistanceFieldA8TextGeoProc>(); | 37 args.fGP.cast<GrDistanceFieldA8TextGeoProc>(); |
38 GrGLSLGPBuilder* pb = args.fPB; | |
39 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | 38 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
40 SkAssertResult(fragBuilder->enableFeature( | 39 SkAssertResult(fragBuilder->enableFeature( |
41 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 40 GrGLSLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
42 | 41 |
43 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; | 42 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
44 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; | 43 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; |
| 44 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
45 | 45 |
46 // emit attributes | 46 // emit attributes |
47 varyingHandler->emitAttributes(dfTexEffect); | 47 varyingHandler->emitAttributes(dfTexEffect); |
48 | 48 |
49 #ifdef SK_GAMMA_APPLY_TO_A8 | 49 #ifdef SK_GAMMA_APPLY_TO_A8 |
50 // adjust based on gamma | 50 // adjust based on gamma |
51 const char* distanceAdjustUniName = nullptr; | 51 const char* distanceAdjustUniName = nullptr; |
52 // width, height, 1/(3*width) | 52 // width, height, 1/(3*width) |
53 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi
bility, | 53 fDistanceAdjustUni = uniformHandler->addUniform(GrGLSLUniformHandler::kF
ragment_Visibility, |
54 kFloat_GrSLType, kDefault_GrSLPrecision, | 54 kFloat_GrSLType, kDefaul
t_GrSLPrecision, |
55 "DistanceAdjust", &distanceAdjustUniName); | 55 "DistanceAdjust", &dista
nceAdjustUniName); |
56 #endif | 56 #endif |
57 | 57 |
58 // Setup pass through color | 58 // Setup pass through color |
59 if (!dfTexEffect.colorIgnored()) { | 59 if (!dfTexEffect.colorIgnored()) { |
60 if (dfTexEffect.hasVertexColor()) { | 60 if (dfTexEffect.hasVertexColor()) { |
61 varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), a
rgs.fOutputColor); | 61 varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), a
rgs.fOutputColor); |
62 } else { | 62 } else { |
63 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fCo
lorUniform); | 63 this->setupUniformColor(fragBuilder, uniformHandler, args.fOutpu
tColor, |
| 64 &fColorUniform); |
64 } | 65 } |
65 } | 66 } |
66 | 67 |
67 // Setup position | 68 // Setup position |
68 this->setupPosition(pb, | 69 this->setupPosition(vertBuilder, |
69 vertBuilder, | 70 uniformHandler, |
70 gpArgs, | 71 gpArgs, |
71 dfTexEffect.inPosition()->fName, | 72 dfTexEffect.inPosition()->fName, |
72 dfTexEffect.viewMatrix(), | 73 dfTexEffect.viewMatrix(), |
73 &fViewMatrixUniform); | 74 &fViewMatrixUniform); |
74 | 75 |
75 // emit transforms | 76 // emit transforms |
76 this->emitTransforms(pb, | 77 this->emitTransforms(vertBuilder, |
77 vertBuilder, | |
78 varyingHandler, | 78 varyingHandler, |
| 79 uniformHandler, |
79 gpArgs->fPositionVar, | 80 gpArgs->fPositionVar, |
80 dfTexEffect.inPosition()->fName, | 81 dfTexEffect.inPosition()->fName, |
81 args.fTransformsIn, | 82 args.fTransformsIn, |
82 args.fTransformsOut); | 83 args.fTransformsOut); |
83 | 84 |
84 // add varyings | 85 // add varyings |
85 GrGLSLVertToFrag recipScale(kFloat_GrSLType); | 86 GrGLSLVertToFrag recipScale(kFloat_GrSLType); |
86 GrGLSLVertToFrag st(kVec2f_GrSLType); | 87 GrGLSLVertToFrag st(kVec2f_GrSLType); |
87 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); | 88 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); |
88 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision)
; | 89 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision)
; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 class GrGLDistanceFieldPathGeoProc : public GrGLSLGeometryProcessor { | 290 class GrGLDistanceFieldPathGeoProc : public GrGLSLGeometryProcessor { |
290 public: | 291 public: |
291 GrGLDistanceFieldPathGeoProc() | 292 GrGLDistanceFieldPathGeoProc() |
292 : fViewMatrix(SkMatrix::InvalidMatrix()) | 293 : fViewMatrix(SkMatrix::InvalidMatrix()) |
293 , fColor(GrColor_ILLEGAL) | 294 , fColor(GrColor_ILLEGAL) |
294 , fTextureSize(SkISize::Make(-1, -1)) {} | 295 , fTextureSize(SkISize::Make(-1, -1)) {} |
295 | 296 |
296 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 297 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
297 const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistance
FieldPathGeoProc>(); | 298 const GrDistanceFieldPathGeoProc& dfTexEffect = args.fGP.cast<GrDistance
FieldPathGeoProc>(); |
298 | 299 |
299 GrGLSLGPBuilder* pb = args.fPB; | |
300 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | 300 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
301 SkAssertResult(fragBuilder->enableFeature( | 301 SkAssertResult(fragBuilder->enableFeature( |
302 GrGLSLFragmentShaderBuilder::kStandardDeriv
atives_GLSLFeature)); | 302 GrGLSLFragmentShaderBuilder::kStandardDeriv
atives_GLSLFeature)); |
303 | 303 |
304 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; | 304 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
305 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; | 305 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; |
| 306 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
306 | 307 |
307 // emit attributes | 308 // emit attributes |
308 varyingHandler->emitAttributes(dfTexEffect); | 309 varyingHandler->emitAttributes(dfTexEffect); |
309 | 310 |
310 GrGLSLVertToFrag v(kVec2f_GrSLType); | 311 GrGLSLVertToFrag v(kVec2f_GrSLType); |
311 varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); | 312 varyingHandler->addVarying("TextureCoords", &v, kHigh_GrSLPrecision); |
312 | 313 |
313 // setup pass through color | 314 // setup pass through color |
314 if (!dfTexEffect.colorIgnored()) { | 315 if (!dfTexEffect.colorIgnored()) { |
315 if (dfTexEffect.hasVertexColor()) { | 316 if (dfTexEffect.hasVertexColor()) { |
316 varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), a
rgs.fOutputColor); | 317 varyingHandler->addPassThroughAttribute(dfTexEffect.inColor(), a
rgs.fOutputColor); |
317 } else { | 318 } else { |
318 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fCo
lorUniform); | 319 this->setupUniformColor(fragBuilder, uniformHandler, args.fOutpu
tColor, |
| 320 &fColorUniform); |
319 } | 321 } |
320 } | 322 } |
321 vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoo
rds()->fName); | 323 vertBuilder->codeAppendf("%s = %s;", v.vsOut(), dfTexEffect.inTextureCoo
rds()->fName); |
322 | 324 |
323 // Setup position | 325 // Setup position |
324 this->setupPosition(pb, | 326 this->setupPosition(vertBuilder, |
325 vertBuilder, | 327 uniformHandler, |
326 gpArgs, | 328 gpArgs, |
327 dfTexEffect.inPosition()->fName, | 329 dfTexEffect.inPosition()->fName, |
328 dfTexEffect.viewMatrix(), | 330 dfTexEffect.viewMatrix(), |
329 &fViewMatrixUniform); | 331 &fViewMatrixUniform); |
330 | 332 |
331 // emit transforms | 333 // emit transforms |
332 this->emitTransforms(pb, | 334 this->emitTransforms(vertBuilder, |
333 vertBuilder, | |
334 varyingHandler, | 335 varyingHandler, |
| 336 uniformHandler, |
335 gpArgs->fPositionVar, | 337 gpArgs->fPositionVar, |
336 dfTexEffect.inPosition()->fName, | 338 dfTexEffect.inPosition()->fName, |
337 args.fTransformsIn, | 339 args.fTransformsIn, |
338 args.fTransformsOut); | 340 args.fTransformsOut); |
339 | 341 |
340 const char* textureSizeUniName = nullptr; | 342 const char* textureSizeUniName = nullptr; |
341 fTextureSizeUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visibil
ity, | 343 fTextureSizeUni = uniformHandler->addUniform(GrGLSLUniformHandler::kFrag
ment_Visibility, |
342 kVec2f_GrSLType, kDefault_GrSLPrecision
, | 344 kVec2f_GrSLType, kDefault_G
rSLPrecision, |
343 "TextureSize", &textureSizeUniName); | 345 "TextureSize", &textureSize
UniName); |
344 | 346 |
345 // Use highp to work around aliasing issues | 347 // Use highp to work around aliasing issues |
346 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps, | 348 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps, |
347 kHigh_GrSLPreci
sion)); | 349 kHigh_GrSLPreci
sion)); |
348 fragBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); | 350 fragBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); |
349 | 351 |
350 fragBuilder->codeAppend("float texColor = "); | 352 fragBuilder->codeAppend("float texColor = "); |
351 fragBuilder->appendTextureLookup(args.fSamplers[0], | 353 fragBuilder->appendTextureLookup(args.fSamplers[0], |
352 "uv", | 354 "uv", |
353 kVec2f_GrSLType); | 355 kVec2f_GrSLType); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 class GrGLDistanceFieldLCDTextGeoProc : public GrGLSLGeometryProcessor { | 516 class GrGLDistanceFieldLCDTextGeoProc : public GrGLSLGeometryProcessor { |
515 public: | 517 public: |
516 GrGLDistanceFieldLCDTextGeoProc() | 518 GrGLDistanceFieldLCDTextGeoProc() |
517 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) { | 519 : fViewMatrix(SkMatrix::InvalidMatrix()), fColor(GrColor_ILLEGAL) { |
518 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.
0f, 1.0f, 1.0f); | 520 fDistanceAdjust = GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(1.
0f, 1.0f, 1.0f); |
519 } | 521 } |
520 | 522 |
521 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ | 523 void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override{ |
522 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = | 524 const GrDistanceFieldLCDTextGeoProc& dfTexEffect = |
523 args.fGP.cast<GrDistanceFieldLCDTextGeoProc>(); | 525 args.fGP.cast<GrDistanceFieldLCDTextGeoProc>(); |
524 GrGLSLGPBuilder* pb = args.fPB; | |
525 | 526 |
526 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; | 527 GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; |
527 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; | 528 GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; |
| 529 GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; |
528 | 530 |
529 // emit attributes | 531 // emit attributes |
530 varyingHandler->emitAttributes(dfTexEffect); | 532 varyingHandler->emitAttributes(dfTexEffect); |
531 | 533 |
532 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; | 534 GrGLSLFragmentBuilder* fragBuilder = args.fFragBuilder; |
533 | 535 |
534 // setup pass through color | 536 // setup pass through color |
535 if (!dfTexEffect.colorIgnored()) { | 537 if (!dfTexEffect.colorIgnored()) { |
536 this->setupUniformColor(pb, fragBuilder, args.fOutputColor, &fColorU
niform); | 538 this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputCol
or, &fColorUniform); |
537 } | 539 } |
538 | 540 |
539 // Setup position | 541 // Setup position |
540 this->setupPosition(pb, | 542 this->setupPosition(vertBuilder, |
541 vertBuilder, | 543 uniformHandler, |
542 gpArgs, | 544 gpArgs, |
543 dfTexEffect.inPosition()->fName, | 545 dfTexEffect.inPosition()->fName, |
544 dfTexEffect.viewMatrix(), | 546 dfTexEffect.viewMatrix(), |
545 &fViewMatrixUniform); | 547 &fViewMatrixUniform); |
546 | 548 |
547 // emit transforms | 549 // emit transforms |
548 this->emitTransforms(pb, | 550 this->emitTransforms(vertBuilder, |
549 vertBuilder, | |
550 varyingHandler, | 551 varyingHandler, |
| 552 uniformHandler, |
551 gpArgs->fPositionVar, | 553 gpArgs->fPositionVar, |
552 dfTexEffect.inPosition()->fName, | 554 dfTexEffect.inPosition()->fName, |
553 args.fTransformsIn, | 555 args.fTransformsIn, |
554 args.fTransformsOut); | 556 args.fTransformsOut); |
555 | 557 |
556 // set up varyings | 558 // set up varyings |
557 bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_Di
stanceFieldEffectMask); | 559 bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_Di
stanceFieldEffectMask); |
558 GrGLSLVertToFrag recipScale(kFloat_GrSLType); | 560 GrGLSLVertToFrag recipScale(kFloat_GrSLType); |
559 GrGLSLVertToFrag st(kVec2f_GrSLType); | 561 GrGLSLVertToFrag st(kVec2f_GrSLType); |
560 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision)
; | 562 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision)
; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 fragBuilder->codeAppend("\ttexColor = "); | 623 fragBuilder->codeAppend("\ttexColor = "); |
622 fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2
f_GrSLType); | 624 fragBuilder->appendTextureLookup(args.fSamplers[0], "uv_adjusted", kVec2
f_GrSLType); |
623 fragBuilder->codeAppend(";\n"); | 625 fragBuilder->codeAppend(";\n"); |
624 fragBuilder->codeAppend("\tdistance.z = texColor.r;\n"); | 626 fragBuilder->codeAppend("\tdistance.z = texColor.r;\n"); |
625 | 627 |
626 fragBuilder->codeAppend("\tdistance = " | 628 fragBuilder->codeAppend("\tdistance = " |
627 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceF
ieldThreshold"));"); | 629 "vec3(" SK_DistanceFieldMultiplier ")*(distance - vec3(" SK_DistanceF
ieldThreshold"));"); |
628 | 630 |
629 // adjust width based on gamma | 631 // adjust width based on gamma |
630 const char* distanceAdjustUniName = nullptr; | 632 const char* distanceAdjustUniName = nullptr; |
631 fDistanceAdjustUni = pb->addUniform(GrGLSLProgramBuilder::kFragment_Visi
bility, | 633 fDistanceAdjustUni = uniformHandler->addUniform(GrGLSLUniformHandler::kF
ragment_Visibility, |
632 kVec3f_GrSLType, kDefault_GrSLPrecision, | 634 kVec3f_GrSLType, kDefaul
t_GrSLPrecision, |
633 "DistanceAdjust", &distanceAdjustUniName); | 635 "DistanceAdjust", &dista
nceAdjustUniName); |
634 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); | 636 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); |
635 | 637 |
636 // To be strictly correct, we should compute the anti-aliasing factor se
parately | 638 // To be strictly correct, we should compute the anti-aliasing factor se
parately |
637 // for each color component. However, this is only important when using
perspective | 639 // for each color component. However, this is only important when using
perspective |
638 // transformations, and even then using a single factor seems like a rea
sonable | 640 // transformations, and even then using a single factor seems like a rea
sonable |
639 // trade-off between quality and speed. | 641 // trade-off between quality and speed. |
640 fragBuilder->codeAppend("float afwidth;"); | 642 fragBuilder->codeAppend("float afwidth;"); |
641 if (isUniformScale) { | 643 if (isUniformScale) { |
642 // For uniform scale, we adjust for the effect of the transformation
on the distance | 644 // For uniform scale, we adjust for the effect of the transformation
on the distance |
643 // by using the length of the gradient of the texture coordinates. W
e use st coordinates | 645 // by using the length of the gradient of the texture coordinates. W
e use st coordinates |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; | 786 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; |
785 flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; | 787 flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; |
786 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 788 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
787 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), | 789 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), |
788 GrTest::TestMatrix(d->fRandom), | 790 GrTest::TestMatrix(d->fRandom), |
789 d->fTextures[texIdx], params, | 791 d->fTextures[texIdx], params, |
790 wa, | 792 wa, |
791 flags, | 793 flags, |
792 d->fRandom->nextBool()); | 794 d->fRandom->nextBool()); |
793 } | 795 } |
OLD | NEW |