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 "GrDistanceFieldTextureEffect.h" | 8 #include "GrDistanceFieldTextureEffect.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 | 66 |
67 // emit transforms | 67 // emit transforms |
68 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosit
ion()->fName, | 68 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosit
ion()->fName, |
69 dfTexEffect.localMatrix(), args.fTransformsIn, args
.fTransformsOut); | 69 dfTexEffect.localMatrix(), args.fTransformsIn, args
.fTransformsOut); |
70 | 70 |
71 const char* textureSizeUniName = NULL; | 71 const char* textureSizeUniName = NULL; |
72 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, | 72 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, |
73 kVec2f_GrSLType, kDefault_GrSLPre
cision, | 73 kVec2f_GrSLType, kDefault_GrSLPre
cision, |
74 "TextureSize", &textureSizeUniNam
e); | 74 "TextureSize", &textureSizeUniNam
e); |
75 | 75 |
76 fsBuilder->codeAppend("\tvec4 texColor = "); | 76 // Use highp to work around aliasing issues |
| 77 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, |
| 78 pb->ctxInfo().stand
ard())); |
| 79 fsBuilder->codeAppendf("vec2 uv = %s;\n", v.fsIn()); |
| 80 |
| 81 fsBuilder->codeAppend("\tfloat texColor = "); |
77 fsBuilder->appendTextureLookup(args.fSamplers[0], | 82 fsBuilder->appendTextureLookup(args.fSamplers[0], |
78 v.fsIn(), | 83 "uv", |
79 kVec2f_GrSLType); | 84 kVec2f_GrSLType); |
80 fsBuilder->codeAppend(";\n"); | 85 fsBuilder->codeAppend(".r;\n"); |
81 fsBuilder->codeAppend("\tfloat distance = " | 86 fsBuilder->codeAppend("\tfloat distance = " |
82 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceF
ieldThreshold ");"); | 87 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie
ldThreshold ");"); |
83 | 88 |
84 // we adjust for the effect of the transformation on the distance by usi
ng | 89 // we adjust for the effect of the transformation on the distance by usi
ng |
85 // the length of the gradient of the texture coordinates. We use st coor
dinates | 90 // the length of the gradient of the texture coordinates. We use st coor
dinates |
86 // to ensure we're mapping 1:1 from texel space to pixel space. | 91 // to ensure we're mapping 1:1 from texel space to pixel space. |
87 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", v.fsIn()); | 92 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, |
88 fsBuilder->codeAppendf("\tvec2 st = uv*%s;\n", textureSizeUniName); | 93 pb->ctxInfo().stand
ard())); |
| 94 fsBuilder->codeAppendf("vec2 st = uv*%s;\n", textureSizeUniName); |
89 fsBuilder->codeAppend("\tfloat afwidth;\n"); | 95 fsBuilder->codeAppend("\tfloat afwidth;\n"); |
90 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { | 96 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { |
91 // this gives us a smooth step across approximately one fragment | 97 // this gives us a smooth step across approximately one fragment |
92 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*
dFdx(st.x));\n"); | 98 fsBuilder->codeAppend("\tafwidth = abs(" SK_DistanceFieldAAFactor "*
dFdx(st.x));\n"); |
93 } else { | 99 } else { |
94 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); | 100 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); |
95 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); | 101 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); |
96 | 102 |
97 fsBuilder->codeAppend("\tvec2 uv_grad;\n"); | 103 fsBuilder->codeAppend("\tvec2 uv_grad;\n"); |
98 if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) { | 104 if (args.fPB->ctxInfo().caps()->dropsTileOnZeroDivide()) { |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 | 366 |
361 // emit transforms | 367 // emit transforms |
362 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosit
ion()->fName, | 368 this->emitTransforms(args.fPB, gpArgs->fPositionVar, dfTexEffect.inPosit
ion()->fName, |
363 dfTexEffect.localMatrix(), args.fTransformsIn, args
.fTransformsOut); | 369 dfTexEffect.localMatrix(), args.fTransformsIn, args
.fTransformsOut); |
364 | 370 |
365 const char* textureSizeUniName = NULL; | 371 const char* textureSizeUniName = NULL; |
366 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, | 372 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, |
367 kVec2f_GrSLType, kDefault_GrSLPrec
ision, | 373 kVec2f_GrSLType, kDefault_GrSLPrec
ision, |
368 "TextureSize", &textureSizeUniName
); | 374 "TextureSize", &textureSizeUniName
); |
369 | 375 |
370 fsBuilder->codeAppend("vec4 texColor = "); | 376 // Use highp to work around aliasing issues |
| 377 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, |
| 378 pb->ctxInfo().stand
ard())); |
| 379 fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); |
| 380 |
| 381 fsBuilder->codeAppend("float texColor = "); |
371 fsBuilder->appendTextureLookup(args.fSamplers[0], | 382 fsBuilder->appendTextureLookup(args.fSamplers[0], |
372 v.fsIn(), | 383 "uv", |
373 kVec2f_GrSLType); | 384 kVec2f_GrSLType); |
374 fsBuilder->codeAppend(";"); | 385 fsBuilder->codeAppend(".r;"); |
375 fsBuilder->codeAppend("float distance = " | 386 fsBuilder->codeAppend("float distance = " |
376 SK_DistanceFieldMultiplier "*(texColor.r - " SK_DistanceFieldThresho
ld ");"); | 387 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFieldThreshold
");"); |
377 | 388 |
378 // we adjust for the effect of the transformation on the distance by usi
ng | 389 // we adjust for the effect of the transformation on the distance by usi
ng |
379 // the length of the gradient of the texture coordinates. We use st coor
dinates | 390 // the length of the gradient of the texture coordinates. We use st coor
dinates |
380 // to ensure we're mapping 1:1 from texel space to pixel space. | 391 // to ensure we're mapping 1:1 from texel space to pixel space. |
381 fsBuilder->codeAppendf("vec2 uv = %s;", v.fsIn()); | 392 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, |
| 393 pb->ctxInfo().stand
ard())); |
382 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); | 394 fsBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); |
383 fsBuilder->codeAppend("float afwidth;"); | 395 fsBuilder->codeAppend("float afwidth;"); |
384 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { | 396 if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) { |
385 // this gives us a smooth step across approximately one fragment | 397 // this gives us a smooth step across approximately one fragment |
386 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dF
dx(st.x));"); | 398 fsBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dF
dx(st.x));"); |
387 } else { | 399 } else { |
388 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); | 400 fsBuilder->codeAppend("vec2 Jdx = dFdx(st);"); |
389 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); | 401 fsBuilder->codeAppend("vec2 Jdy = dFdy(st);"); |
390 | 402 |
391 fsBuilder->codeAppend("vec2 uv_grad;"); | 403 fsBuilder->codeAppend("vec2 uv_grad;"); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, | 618 fTextureSizeUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Vis
ibility, |
607 kVec3f_GrSLType, kDefault_GrSLPrec
ision, | 619 kVec3f_GrSLType, kDefault_GrSLPrec
ision, |
608 "TextureSize", &textureSizeUniName
); | 620 "TextureSize", &textureSizeUniName
); |
609 | 621 |
610 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 622 GrGLGPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
611 | 623 |
612 SkAssertResult(fsBuilder->enableFeature( | 624 SkAssertResult(fsBuilder->enableFeature( |
613 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); | 625 GrGLFragmentShaderBuilder::kStandardDerivatives_GLSLFeature)); |
614 | 626 |
615 // create LCD offset adjusted by inverse of transform | 627 // create LCD offset adjusted by inverse of transform |
616 fsBuilder->codeAppendf("\tvec2 uv = %s;\n", v.fsIn()); | 628 // Use highp to work around aliasing issues |
617 fsBuilder->codeAppendf("\tvec2 st = uv*%s.xy;\n", textureSizeUniName); | 629 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, |
| 630 pb->ctxInfo().stand
ard())); |
| 631 fsBuilder->codeAppendf("vec2 uv = %s;\n", v.fsIn()); |
| 632 fsBuilder->codeAppend(GrGLShaderVar::PrecisionString(kHigh_GrSLPrecision
, |
| 633 pb->ctxInfo().stand
ard())); |
| 634 fsBuilder->codeAppendf("vec2 st = uv*%s.xy;\n", textureSizeUniName); |
618 bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_Distance
FieldEffectMask); | 635 bool isUniformScale = !!(dfTexEffect.getFlags() & kUniformScale_Distance
FieldEffectMask); |
619 if (isUniformScale) { | 636 if (isUniformScale) { |
620 fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n"); | 637 fsBuilder->codeAppend("\tfloat dx = dFdx(st.x);\n"); |
621 fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", text
ureSizeUniName); | 638 fsBuilder->codeAppendf("\tvec2 offset = vec2(dx*%s.z, 0.0);\n", text
ureSizeUniName); |
622 } else { | 639 } else { |
623 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); | 640 fsBuilder->codeAppend("\tvec2 Jdx = dFdx(st);\n"); |
624 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); | 641 fsBuilder->codeAppend("\tvec2 Jdy = dFdy(st);\n"); |
625 fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni
Name); | 642 fsBuilder->codeAppendf("\tvec2 offset = %s.z*Jdx;\n", textureSizeUni
Name); |
626 } | 643 } |
627 | 644 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3
(afwidth), distance), 1.0);\n"); | 699 fsBuilder->codeAppend("\tvec4 val = vec4(smoothstep(vec3(-afwidth), vec3
(afwidth), distance), 1.0);\n"); |
683 | 700 |
684 // adjust based on gamma | 701 // adjust based on gamma |
685 const char* textColorUniName = NULL; | 702 const char* textColorUniName = NULL; |
686 // width, height, 1/(3*width) | 703 // width, height, 1/(3*width) |
687 fTextColorUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visib
ility, | 704 fTextColorUni = args.fPB->addUniform(GrGLProgramBuilder::kFragment_Visib
ility, |
688 kVec3f_GrSLType, kDefault_GrSLPreci
sion, | 705 kVec3f_GrSLType, kDefault_GrSLPreci
sion, |
689 "TextColor", &textColorUniName); | 706 "TextColor", &textColorUniName); |
690 | 707 |
691 fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName); | 708 fsBuilder->codeAppendf("\tuv = vec2(val.x, %s.x);\n", textColorUniName); |
692 fsBuilder->codeAppend("\tvec4 gammaColor = "); | 709 fsBuilder->codeAppend("float gammaColor = "); |
693 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; | 710 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; |
694 fsBuilder->codeAppend(";\n"); | 711 fsBuilder->codeAppend(".r;\n"); |
695 fsBuilder->codeAppend("\tval.x = gammaColor.r;\n"); | 712 fsBuilder->codeAppend("\tval.x = gammaColor;\n"); |
696 | 713 |
697 fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName); | 714 fsBuilder->codeAppendf("\tuv = vec2(val.y, %s.y);\n", textColorUniName); |
698 fsBuilder->codeAppend("\tgammaColor = "); | 715 fsBuilder->codeAppend("\tgammaColor = "); |
699 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; | 716 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; |
700 fsBuilder->codeAppend(";\n"); | 717 fsBuilder->codeAppend(".r;\n"); |
701 fsBuilder->codeAppend("\tval.y = gammaColor.r;\n"); | 718 fsBuilder->codeAppend("\tval.y = gammaColor;\n"); |
702 | 719 |
703 fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName); | 720 fsBuilder->codeAppendf("\tuv = vec2(val.z, %s.z);\n", textColorUniName); |
704 fsBuilder->codeAppend("\tgammaColor = "); | 721 fsBuilder->codeAppend("\tgammaColor = "); |
705 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; | 722 fsBuilder->appendTextureLookup(args.fSamplers[1], "uv", kVec2f_GrSLType)
; |
706 fsBuilder->codeAppend(";\n"); | 723 fsBuilder->codeAppend(".r;\n"); |
707 fsBuilder->codeAppend("\tval.z = gammaColor.r;\n"); | 724 fsBuilder->codeAppend("\tval.z = gammaColor;\n"); |
708 | 725 |
709 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 726 fsBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
710 } | 727 } |
711 | 728 |
712 virtual void setData(const GrGLProgramDataManager& pdman, | 729 virtual void setData(const GrGLProgramDataManager& pdman, |
713 const GrPrimitiveProcessor& processor, | 730 const GrPrimitiveProcessor& processor, |
714 const GrBatchTracker& bt) SK_OVERRIDE { | 731 const GrBatchTracker& bt) SK_OVERRIDE { |
715 SkASSERT(fTextureSizeUni.isValid()); | 732 SkASSERT(fTextureSizeUni.isValid()); |
716 SkASSERT(fTextColorUni.isValid()); | 733 SkASSERT(fTextColorUni.isValid()); |
717 | 734 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; | 890 uint32_t flags = kUseLCD_DistanceFieldEffectFlag; |
874 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; | 891 flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; |
875 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 892 flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
876 return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random), | 893 return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random), |
877 GrProcessorUnitTest::TestMatr
ix(random), | 894 GrProcessorUnitTest::TestMatr
ix(random), |
878 textures[texIdx], params, | 895 textures[texIdx], params, |
879 textures[texIdx2], params2, | 896 textures[texIdx2], params2, |
880 textColor, | 897 textColor, |
881 flags); | 898 flags); |
882 } | 899 } |
OLD | NEW |