Chromium Code Reviews| 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 |