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 |