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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
75 dfTexEffect.inPosition()->fName, | 75 dfTexEffect.inPosition()->fName, |
76 args.fTransformsIn, | 76 args.fTransformsIn, |
77 args.fTransformsOut); | 77 args.fTransformsOut); |
78 | 78 |
79 // add varyings | 79 // add varyings |
80 GrGLSLVertToFrag recipScale(kFloat_GrSLType); | 80 GrGLSLVertToFrag recipScale(kFloat_GrSLType); |
81 GrGLSLVertToFrag uv(kVec2f_GrSLType); | 81 GrGLSLVertToFrag uv(kVec2f_GrSLType); |
82 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi eldEffectMask) == | 82 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi eldEffectMask) == |
83 kUniformScale_DistanceFieldEffectMask; | 83 kUniformScale_DistanceFieldEffectMask; |
84 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan ceFieldEffectFlag); | 84 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan ceFieldEffectFlag); |
85 bool srgbOutput = SkToBool(dfTexEffect.getFlags() & kSRGB_DistanceFieldE ffectFlag); | |
85 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); | 86 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
86 vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCo ords()->fName); | 87 vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCo ords()->fName); |
87 | 88 |
88 // compute numbers to be hardcoded to convert texture coordinates from f loat to int | 89 // compute numbers to be hardcoded to convert texture coordinates from f loat to int |
89 SkASSERT(dfTexEffect.numTextures() == 1); | 90 SkASSERT(dfTexEffect.numTextures() == 1); |
90 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); | 91 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); |
91 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ; | 92 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ; |
92 | 93 |
93 GrGLSLVertToFrag st(kVec2f_GrSLType); | 94 GrGLSLVertToFrag st(kVec2f_GrSLType); |
94 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision) ; | 95 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision) ; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
146 fragBuilder->codeAppend("}"); | 147 fragBuilder->codeAppend("}"); |
147 | 148 |
148 fragBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn()); | 149 fragBuilder->codeAppendf("vec2 Jdx = dFdx(%s);", st.fsIn()); |
149 fragBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn()); | 150 fragBuilder->codeAppendf("vec2 Jdy = dFdy(%s);", st.fsIn()); |
150 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g rad.y*Jdy.x,"); | 151 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g rad.y*Jdy.x,"); |
151 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g rad.y*Jdy.y);"); | 152 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g rad.y*Jdy.y);"); |
152 | 153 |
153 // this gives us a smooth step across approximately one fragment | 154 // this gives us a smooth step across approximately one fragment |
154 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng th(grad);"); | 155 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng th(grad);"); |
155 } | 156 } |
156 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, dista nce);"); | 157 |
158 // The smoothstep falloff compensates for the non-linear sRGB response c urve. If we are | |
159 // doing gamma-correct rendering (to an sRGB or F16 buffer), then we act ually want distance | |
160 // mapped linearly to coverage, so use a linear step: | |
161 if (srgbOutput) { | |
162 fragBuilder->codeAppend( | |
163 "float val = clamp(distance + afwidth / (2.0 * afwidth), 0.0, 1. 0);"); | |
164 } else { | |
165 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, d istance);"); | |
166 } | |
157 | 167 |
158 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 168 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
159 } | 169 } |
160 | 170 |
161 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess or& proc) override { | 171 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess or& proc) override { |
162 #ifdef SK_GAMMA_APPLY_TO_A8 | 172 #ifdef SK_GAMMA_APPLY_TO_A8 |
163 const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFi eldA8TextGeoProc>(); | 173 const GrDistanceFieldA8TextGeoProc& dfTexEffect = proc.cast<GrDistanceFi eldA8TextGeoProc>(); |
164 float distanceAdjust = dfTexEffect.getDistanceAdjust(); | 174 float distanceAdjust = dfTexEffect.getDistanceAdjust(); |
165 if (distanceAdjust != fDistanceAdjust) { | 175 if (distanceAdjust != fDistanceAdjust) { |
166 pdman.set1f(fDistanceAdjustUni, distanceAdjust); | 176 pdman.set1f(fDistanceAdjustUni, distanceAdjust); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
384 fragBuilder->codeAppend("}"); | 394 fragBuilder->codeAppend("}"); |
385 | 395 |
386 fragBuilder->codeAppend("vec2 Jdx = dFdx(st);"); | 396 fragBuilder->codeAppend("vec2 Jdx = dFdx(st);"); |
387 fragBuilder->codeAppend("vec2 Jdy = dFdy(st);"); | 397 fragBuilder->codeAppend("vec2 Jdy = dFdy(st);"); |
388 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g rad.y*Jdy.x,"); | 398 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g rad.y*Jdy.x,"); |
389 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g rad.y*Jdy.y);"); | 399 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g rad.y*Jdy.y);"); |
390 | 400 |
391 // this gives us a smooth step across approximately one fragment | 401 // this gives us a smooth step across approximately one fragment |
392 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng th(grad);"); | 402 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng th(grad);"); |
393 } | 403 } |
394 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, dista nce);"); | 404 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, dista nce);"); |
jvanverth1
2016/04/12 19:34:46
The SDF path renderer doesn't do any fake gamma, s
Brian Osman
2016/04/12 19:45:59
Yeah, I was planning to make that change after tes
| |
395 | 405 |
396 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 406 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
397 } | 407 } |
398 | 408 |
399 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess or& proc) override { | 409 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess or& proc) override { |
400 SkASSERT(fTextureSizeUni.isValid()); | 410 SkASSERT(fTextureSizeUni.isValid()); |
401 | 411 |
402 GrTexture* texture = proc.texture(0); | 412 GrTexture* texture = proc.texture(0); |
403 if (texture->width() != fTextureSize.width() || | 413 if (texture->width() != fTextureSize.width() || |
404 texture->height() != fTextureSize.height()) { | 414 texture->height() != fTextureSize.height()) { |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
546 uniformHandler, | 556 uniformHandler, |
547 gpArgs->fPositionVar, | 557 gpArgs->fPositionVar, |
548 dfTexEffect.inPosition()->fName, | 558 dfTexEffect.inPosition()->fName, |
549 args.fTransformsIn, | 559 args.fTransformsIn, |
550 args.fTransformsOut); | 560 args.fTransformsOut); |
551 | 561 |
552 // set up varyings | 562 // set up varyings |
553 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi eldEffectMask) == | 563 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi eldEffectMask) == |
554 kUniformScale_DistanceFieldEffectMask; | 564 kUniformScale_DistanceFieldEffectMask; |
555 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan ceFieldEffectFlag); | 565 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan ceFieldEffectFlag); |
566 bool srgbOutput = SkToBool(dfTexEffect.getFlags() & kSRGB_DistanceFieldE ffectFlag); | |
556 GrGLSLVertToFrag recipScale(kFloat_GrSLType); | 567 GrGLSLVertToFrag recipScale(kFloat_GrSLType); |
557 GrGLSLVertToFrag uv(kVec2f_GrSLType); | 568 GrGLSLVertToFrag uv(kVec2f_GrSLType); |
558 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); | 569 varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision); |
559 vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCo ords()->fName); | 570 vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCo ords()->fName); |
560 | 571 |
561 // compute numbers to be hardcoded to convert texture coordinates from f loat to int | 572 // compute numbers to be hardcoded to convert texture coordinates from f loat to int |
562 SkASSERT(dfTexEffect.numTextures() == 1); | 573 SkASSERT(dfTexEffect.numTextures() == 1); |
563 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); | 574 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); |
564 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ; | 575 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height())) ; |
565 | 576 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
660 fragBuilder->codeAppend("} else {"); | 671 fragBuilder->codeAppend("} else {"); |
661 fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2); "); | 672 fragBuilder->codeAppend("dist_grad = dist_grad*inversesqrt(dg_len2); "); |
662 fragBuilder->codeAppend("}"); | 673 fragBuilder->codeAppend("}"); |
663 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g rad.y*Jdy.x,"); | 674 fragBuilder->codeAppend("vec2 grad = vec2(dist_grad.x*Jdx.x + dist_g rad.y*Jdy.x,"); |
664 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g rad.y*Jdy.y);"); | 675 fragBuilder->codeAppend(" dist_grad.x*Jdx.y + dist_g rad.y*Jdy.y);"); |
665 | 676 |
666 // this gives us a smooth step across approximately one fragment | 677 // this gives us a smooth step across approximately one fragment |
667 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng th(grad);"); | 678 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*leng th(grad);"); |
668 } | 679 } |
669 | 680 |
670 fragBuilder->codeAppend( | 681 // The smoothstep falloff compensates for the non-linear sRGB response c urve. If we are |
671 "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), distance), 1.0);"); | 682 // doing gamma-correct rendering (to an sRGB or F16 buffer), then we act ually want distance |
683 // mapped linearly to coverage, so use a linear step: | |
684 if (srgbOutput) { | |
685 fragBuilder->codeAppend("vec4 val = " | |
686 "vec4(clamp(distance + vec3(afwidth) / vec3(2.0 * afwidth), 0.0, 1.0), 1.0f);"); | |
687 } else { | |
688 fragBuilder->codeAppend( | |
689 "vec4 val = vec4(smoothstep(vec3(-afwidth), vec3(afwidth), dista nce), 1.0);"); | |
690 } | |
691 | |
672 // set alpha to be max of rgb coverage | 692 // set alpha to be max of rgb coverage |
673 fragBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);"); | 693 fragBuilder->codeAppend("val.a = max(max(val.r, val.g), val.b);"); |
674 | 694 |
675 fragBuilder->codeAppendf("%s = val;", args.fOutputCoverage); | 695 fragBuilder->codeAppendf("%s = val;", args.fOutputCoverage); |
676 } | 696 } |
677 | 697 |
678 void setData(const GrGLSLProgramDataManager& pdman, | 698 void setData(const GrGLSLProgramDataManager& pdman, |
679 const GrPrimitiveProcessor& processor) override { | 699 const GrPrimitiveProcessor& processor) override { |
680 SkASSERT(fDistanceAdjustUni.isValid()); | 700 SkASSERT(fDistanceAdjustUni.isValid()); |
681 | 701 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
783 flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0 ; | 803 flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0 ; |
784 } | 804 } |
785 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 805 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
786 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), | 806 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), |
787 GrTest::TestMatrix(d->fRandom), | 807 GrTest::TestMatrix(d->fRandom), |
788 d->fTextures[texIdx], params, | 808 d->fTextures[texIdx], params, |
789 wa, | 809 wa, |
790 flags, | 810 flags, |
791 d->fRandom->nextBool()); | 811 d->fRandom->nextBool()); |
792 } | 812 } |
OLD | NEW |