| 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 // compute numbers to be hardcoded to convert texture coordinates from f
loat to int | 88 // compute numbers to be hardcoded to convert texture coordinates from f
loat to int |
| 89 SkASSERT(dfTexEffect.numTextures() == 1); | 89 SkASSERT(dfTexEffect.numTextures() == 1); |
| 90 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); | 90 GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture(); |
| 91 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()))
; | 91 SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()))
; |
| 92 | 92 |
| 93 GrGLSLVertToFrag st(kVec2f_GrSLType); | 93 GrGLSLVertToFrag st(kVec2f_GrSLType); |
| 94 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision)
; | 94 varyingHandler->addVarying("IntTextureCoords", &st, kHigh_GrSLPrecision)
; |
| 95 vertBuilder->codeAppendf("%s = vec2(%d, %d) * %s;", st.vsOut(), | 95 vertBuilder->codeAppendf("%s = vec2(%d, %d) * %s;", st.vsOut(), |
| 96 atlas->width(), atlas->height(), | 96 atlas->width(), atlas->height(), |
| 97 dfTexEffect.inTextureCoords()->fName); | 97 dfTexEffect.inTextureCoords()->fName); |
| 98 | 98 |
| 99 // Use highp to work around aliasing issues | 99 // Use highp to work around aliasing issues |
| 100 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps, | 100 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps, |
| 101 kHigh_GrSLPreci
sion)); | 101 kHigh_GrSLPreci
sion)); |
| 102 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); | 102 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); |
| 103 | 103 |
| 104 fragBuilder->codeAppend("\tfloat texColor = "); | 104 fragBuilder->codeAppend("\tfloat texColor = "); |
| 105 fragBuilder->appendTextureLookup(args.fSamplers[0], | 105 fragBuilder->appendTextureLookup(args.fSamplers[0], |
| 106 "uv", | 106 "uv", |
| 107 kVec2f_GrSLType); | 107 kVec2f_GrSLType); |
| 108 fragBuilder->codeAppend(".r;\n"); | 108 fragBuilder->codeAppend(".r;\n"); |
| 109 fragBuilder->codeAppend("\tfloat distance = " | 109 fragBuilder->codeAppend("\tfloat distance = " |
| 110 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie
ldThreshold ");"); | 110 SK_DistanceFieldMultiplier "*(texColor - " SK_DistanceFie
ldThreshold ");"); |
| 111 #ifdef SK_GAMMA_APPLY_TO_A8 | 111 #ifdef SK_GAMMA_APPLY_TO_A8 |
| 112 // adjust width based on gamma | 112 // adjust width based on gamma |
| 113 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); | 113 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); |
| 114 #endif | 114 #endif |
| 115 | 115 |
| 116 fragBuilder->codeAppend("float afwidth;"); | 116 fragBuilder->codeAppend("float afwidth;"); |
| 117 if (isUniformScale) { | 117 if (isUniformScale) { |
| 118 // For uniform scale, we adjust for the effect of the transformation
on the distance | 118 // For uniform scale, we adjust for the effect of the transformation
on the distance |
| 119 // by using the length of the gradient of the t coordinate in the y
direction. | 119 // by using the length of the gradient of the t coordinate in the y
direction. |
| 120 // We use st coordinates to ensure we're mapping 1:1 from texel spac
e to pixel space. | 120 // We use st coordinates to ensure we're mapping 1:1 from texel spac
e to pixel space. |
| 121 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. | 121 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. |
| 122 | 122 |
| 123 // this gives us a smooth step across approximately one fragment | 123 // this gives us a smooth step across approximately one fragment |
| 124 fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "
*dFdy(%s.y));", | 124 fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "
*dFdy(%s.y));", |
| 125 st.fsIn()); | 125 st.fsIn()); |
| 126 } else if (isSimilarity) { | 126 } else if (isSimilarity) { |
| 127 // For similarity transform, we adjust the effect of the transformat
ion on the distance | 127 // For similarity transform, we adjust the effect of the transformat
ion on the distance |
| 128 // by using the length of the gradient of the texture coordinates. W
e use st coordinates | 128 // by using the length of the gradient of the texture coordinates. W
e use st coordinates |
| 129 // to ensure we're mapping 1:1 from texel space to pixel space. | 129 // to ensure we're mapping 1:1 from texel space to pixel space. |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 | 349 |
| 350 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps, | 350 fragBuilder->codeAppend(GrGLSLShaderVar::PrecisionString(args.fGLSLCaps, |
| 351 kHigh_GrSLPreci
sion)); | 351 kHigh_GrSLPreci
sion)); |
| 352 fragBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); | 352 fragBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName); |
| 353 fragBuilder->codeAppend("float afwidth;"); | 353 fragBuilder->codeAppend("float afwidth;"); |
| 354 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi
eldEffectMask) == | 354 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi
eldEffectMask) == |
| 355 kUniformScale_DistanceFieldEffectMask; | 355 kUniformScale_DistanceFieldEffectMask; |
| 356 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); | 356 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); |
| 357 if (isUniformScale) { | 357 if (isUniformScale) { |
| 358 // For uniform scale, we adjust for the effect of the transformation
on the distance | 358 // For uniform scale, we adjust for the effect of the transformation
on the distance |
| 359 // by using the length of the gradient of the t coordinate in the y
direction. | 359 // by using the length of the gradient of the t coordinate in the y
direction. |
| 360 // We use st coordinates to ensure we're mapping 1:1 from texel spac
e to pixel space. | 360 // We use st coordinates to ensure we're mapping 1:1 from texel spac
e to pixel space. |
| 361 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. | 361 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. |
| 362 | 362 |
| 363 // this gives us a smooth step across approximately one fragment | 363 // this gives us a smooth step across approximately one fragment |
| 364 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*
dFdy(st.y));"); | 364 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*
dFdy(st.y));"); |
| 365 | 365 |
| 366 } else if (isSimilarity) { | 366 } else if (isSimilarity) { |
| 367 // For similarity transform, we adjust the effect of the transformat
ion on the distance | 367 // For similarity transform, we adjust the effect of the transformat
ion on the distance |
| 368 // by using the length of the gradient of the texture coordinates. W
e use st coordinates | 368 // by using the length of the gradient of the texture coordinates. W
e use st coordinates |
| 369 // to ensure we're mapping 1:1 from texel space to pixel space. | 369 // to ensure we're mapping 1:1 from texel space to pixel space. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 396 } | 396 } |
| 397 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, dista
nce);"); | 397 fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, dista
nce);"); |
| 398 | 398 |
| 399 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); | 399 fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage); |
| 400 } | 400 } |
| 401 | 401 |
| 402 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess
or& proc) override { | 402 void setData(const GrGLSLProgramDataManager& pdman, const GrPrimitiveProcess
or& proc) override { |
| 403 SkASSERT(fTextureSizeUni.isValid()); | 403 SkASSERT(fTextureSizeUni.isValid()); |
| 404 | 404 |
| 405 GrTexture* texture = proc.texture(0); | 405 GrTexture* texture = proc.texture(0); |
| 406 if (texture->width() != fTextureSize.width() || | 406 if (texture->width() != fTextureSize.width() || |
| 407 texture->height() != fTextureSize.height()) { | 407 texture->height() != fTextureSize.height()) { |
| 408 fTextureSize = SkISize::Make(texture->width(), texture->height()); | 408 fTextureSize = SkISize::Make(texture->width(), texture->height()); |
| 409 pdman.set2f(fTextureSizeUni, | 409 pdman.set2f(fTextureSizeUni, |
| 410 SkIntToScalar(fTextureSize.width()), | 410 SkIntToScalar(fTextureSize.width()), |
| 411 SkIntToScalar(fTextureSize.height())); | 411 SkIntToScalar(fTextureSize.height())); |
| 412 } | 412 } |
| 413 | 413 |
| 414 const GrDistanceFieldPathGeoProc& dfpgp = proc.cast<GrDistanceFieldPathG
eoProc>(); | 414 const GrDistanceFieldPathGeoProc& dfpgp = proc.cast<GrDistanceFieldPathG
eoProc>(); |
| 415 | 415 |
| 416 if (!dfpgp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dfpgp.
viewMatrix())) { | 416 if (!dfpgp.viewMatrix().isIdentity() && !fViewMatrix.cheapEqualTo(dfpgp.
viewMatrix())) { |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 kVec3f_GrSLType, kDefaul
t_GrSLPrecision, | 638 kVec3f_GrSLType, kDefaul
t_GrSLPrecision, |
| 639 "DistanceAdjust", &dista
nceAdjustUniName); | 639 "DistanceAdjust", &dista
nceAdjustUniName); |
| 640 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); | 640 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); |
| 641 | 641 |
| 642 // To be strictly correct, we should compute the anti-aliasing factor se
parately | 642 // To be strictly correct, we should compute the anti-aliasing factor se
parately |
| 643 // for each color component. However, this is only important when using
perspective | 643 // for each color component. However, this is only important when using
perspective |
| 644 // transformations, and even then using a single factor seems like a rea
sonable | 644 // transformations, and even then using a single factor seems like a rea
sonable |
| 645 // trade-off between quality and speed. | 645 // trade-off between quality and speed. |
| 646 fragBuilder->codeAppend("float afwidth;"); | 646 fragBuilder->codeAppend("float afwidth;"); |
| 647 if (isSimilarity) { | 647 if (isSimilarity) { |
| 648 // For similarity transform (uniform scale-only is a subset of this)
, we adjust for the | 648 // For similarity transform (uniform scale-only is a subset of this)
, we adjust for the |
| 649 // effect of the transformation on the distance by using the length
of the gradient of | 649 // effect of the transformation on the distance by using the length
of the gradient of |
| 650 // the texture coordinates. We use st coordinates to ensure we're ma
pping 1:1 from texel | 650 // the texture coordinates. We use st coordinates to ensure we're ma
pping 1:1 from texel |
| 651 // space to pixel space. | 651 // space to pixel space. |
| 652 | 652 |
| 653 // this gives us a smooth step across approximately one fragment | 653 // this gives us a smooth step across approximately one fragment |
| 654 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*st_g
rad_len;"); | 654 fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*st_g
rad_len;"); |
| 655 } else { | 655 } else { |
| 656 // For general transforms, to determine the amount of correction we
multiply a unit | 656 // For general transforms, to determine the amount of correction we
multiply a unit |
| 657 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords | 657 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords |
| 658 // (which is the inverse transform for this fragment) and take the l
ength of the result. | 658 // (which is the inverse transform for this fragment) and take the l
ength of the result. |
| 659 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFd
y(distance.r));"); | 659 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance.r), dFd
y(distance.r));"); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0
; | 788 flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0
; |
| 789 } | 789 } |
| 790 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 790 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
| 791 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), | 791 return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom), |
| 792 GrTest::TestMatrix(d->fRandom), | 792 GrTest::TestMatrix(d->fRandom), |
| 793 d->fTextures[texIdx], params, | 793 d->fTextures[texIdx], params, |
| 794 wa, | 794 wa, |
| 795 flags, | 795 flags, |
| 796 d->fRandom->nextBool()); | 796 d->fRandom->nextBool()); |
| 797 } | 797 } |
| OLD | NEW |