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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 #ifdef SK_GAMMA_APPLY_TO_A8 | 112 #ifdef SK_GAMMA_APPLY_TO_A8 |
113 // adjust width based on gamma | 113 // adjust width based on gamma |
114 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); | 114 fragBuilder->codeAppendf("distance -= %s;", distanceAdjustUniName); |
115 #endif | 115 #endif |
116 | 116 |
117 fragBuilder->codeAppend("float afwidth;"); | 117 fragBuilder->codeAppend("float afwidth;"); |
118 if (isUniformScale) { | 118 if (isUniformScale) { |
119 // For uniform scale, we adjust for the effect of the transformation
on the distance | 119 // For uniform scale, we adjust for the effect of the transformation
on the distance |
120 // by using the length of the gradient of the t coordinate in the y
direction. | 120 // by using the length of the gradient of the t coordinate in the y
direction. |
121 // We use st coordinates to ensure we're mapping 1:1 from texel spac
e to pixel space. | 121 // We use st coordinates to ensure we're mapping 1:1 from texel spac
e to pixel space. |
122 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. | |
123 | 122 |
124 // this gives us a smooth step across approximately one fragment | 123 // this gives us a smooth step across approximately one fragment |
| 124 #ifdef SK_VULKAN |
| 125 fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "
*dFdx(%s.x));", |
| 126 st.fsIn()); |
| 127 #else |
| 128 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. |
125 fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "
*dFdy(%s.y));", | 129 fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "
*dFdy(%s.y));", |
126 st.fsIn()); | 130 st.fsIn()); |
| 131 #endif |
127 } else if (isSimilarity) { | 132 } else if (isSimilarity) { |
128 // For similarity transform, we adjust the effect of the transformat
ion on the distance | 133 // For similarity transform, we adjust the effect of the transformat
ion on the distance |
129 // by using the length of the gradient of the texture coordinates. W
e use st coordinates | 134 // by using the length of the gradient of the texture coordinates. W
e use st coordinates |
130 // to ensure we're mapping 1:1 from texel space to pixel space. | 135 // to ensure we're mapping 1:1 from texel space to pixel space. |
131 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. | 136 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. |
132 | 137 |
133 // this gives us a smooth step across approximately one fragment | 138 // this gives us a smooth step across approximately one fragment |
| 139 #ifdef SK_VULKAN |
| 140 fragBuilder->codeAppendf("float st_grad_len = length(dFdx(%s));", st
.fsIn()); |
| 141 #else |
| 142 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. |
134 fragBuilder->codeAppendf("float st_grad_len = length(dFdy(%s));", st
.fsIn()); | 143 fragBuilder->codeAppendf("float st_grad_len = length(dFdy(%s));", st
.fsIn()); |
| 144 #endif |
135 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*
st_grad_len);"); | 145 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*
st_grad_len);"); |
136 } else { | 146 } else { |
137 // For general transforms, to determine the amount of correction we
multiply a unit | 147 // For general transforms, to determine the amount of correction we
multiply a unit |
138 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords | 148 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords |
139 // (which is the inverse transform for this fragment) and take the l
ength of the result. | 149 // (which is the inverse transform for this fragment) and take the l
ength of the result. |
140 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(
distance));"); | 150 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(
distance));"); |
141 // the length of the gradient may be 0, so we need to check for this | 151 // the length of the gradient may be 0, so we need to check for this |
142 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 | 152 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 |
143 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"
); | 153 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"
); |
144 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); | 154 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 fragBuilder->codeAppend("float afwidth;"); | 371 fragBuilder->codeAppend("float afwidth;"); |
362 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi
eldEffectMask) == | 372 bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFi
eldEffectMask) == |
363 kUniformScale_DistanceFieldEffectMask; | 373 kUniformScale_DistanceFieldEffectMask; |
364 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); | 374 bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_Distan
ceFieldEffectFlag); |
365 bool isGammaCorrect = | 375 bool isGammaCorrect = |
366 SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectF
lag); | 376 SkToBool(dfTexEffect.getFlags() & kGammaCorrect_DistanceFieldEffectF
lag); |
367 if (isUniformScale) { | 377 if (isUniformScale) { |
368 // For uniform scale, we adjust for the effect of the transformation
on the distance | 378 // For uniform scale, we adjust for the effect of the transformation
on the distance |
369 // by using the length of the gradient of the t coordinate in the y
direction. | 379 // by using the length of the gradient of the t coordinate in the y
direction. |
370 // We use st coordinates to ensure we're mapping 1:1 from texel spac
e to pixel space. | 380 // We use st coordinates to ensure we're mapping 1:1 from texel spac
e to pixel space. |
371 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. | |
372 | 381 |
373 // this gives us a smooth step across approximately one fragment | 382 // this gives us a smooth step across approximately one fragment |
| 383 #ifdef SK_VULKAN |
| 384 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*
dFdx(st.x));"); |
| 385 #else |
| 386 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. |
374 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*
dFdy(st.y));"); | 387 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*
dFdy(st.y));"); |
375 | 388 #endif |
376 } else if (isSimilarity) { | 389 } else if (isSimilarity) { |
377 // For similarity transform, we adjust the effect of the transformat
ion on the distance | 390 // For similarity transform, we adjust the effect of the transformat
ion on the distance |
378 // by using the length of the gradient of the texture coordinates. W
e use st coordinates | 391 // by using the length of the gradient of the texture coordinates. W
e use st coordinates |
379 // to ensure we're mapping 1:1 from texel space to pixel space. | 392 // to ensure we're mapping 1:1 from texel space to pixel space. |
380 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. | |
381 | 393 |
382 // this gives us a smooth step across approximately one fragment | 394 // this gives us a smooth step across approximately one fragment |
| 395 #ifdef SK_VULKAN |
| 396 fragBuilder->codeAppend("float st_grad_len = length(dFdx(st));"); |
| 397 #else |
| 398 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. |
383 fragBuilder->codeAppend("float st_grad_len = length(dFdy(st));"); | 399 fragBuilder->codeAppend("float st_grad_len = length(dFdy(st));"); |
| 400 #endif |
384 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*
st_grad_len);"); | 401 fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*
st_grad_len);"); |
385 } else { | 402 } else { |
386 // For general transforms, to determine the amount of correction we
multiply a unit | 403 // For general transforms, to determine the amount of correction we
multiply a unit |
387 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords | 404 // vector pointing along the SDF gradient direction by the Jacobian
of the st coords |
388 // (which is the inverse transform for this fragment) and take the l
ength of the result. | 405 // (which is the inverse transform for this fragment) and take the l
ength of the result. |
389 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(
distance));"); | 406 fragBuilder->codeAppend("vec2 dist_grad = vec2(dFdx(distance), dFdy(
distance));"); |
390 // the length of the gradient may be 0, so we need to check for this | 407 // the length of the gradient may be 0, so we need to check for this |
391 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 | 408 // this also compensates for the Adreno, which likes to drop tiles o
n division by 0 |
392 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"
); | 409 fragBuilder->codeAppend("float dg_len2 = dot(dist_grad, dist_grad);"
); |
393 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); | 410 fragBuilder->codeAppend("if (dg_len2 < 0.0001) {"); |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); | 620 fragBuilder->codeAppendf("vec2 uv = %s;\n", uv.fsIn()); |
604 fragBuilder->appendPrecisionModifier(kHigh_GrSLPrecision); | 621 fragBuilder->appendPrecisionModifier(kHigh_GrSLPrecision); |
605 | 622 |
606 SkScalar lcdDelta = 1.0f / (3.0f * atlas->width()); | 623 SkScalar lcdDelta = 1.0f / (3.0f * atlas->width()); |
607 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { | 624 if (dfTexEffect.getFlags() & kBGR_DistanceFieldEffectFlag) { |
608 fragBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DI
G, lcdDelta); | 625 fragBuilder->codeAppendf("float delta = -%.*f;\n", SK_FLT_DECIMAL_DI
G, lcdDelta); |
609 } else { | 626 } else { |
610 fragBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG
, lcdDelta); | 627 fragBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG
, lcdDelta); |
611 } | 628 } |
612 if (isUniformScale) { | 629 if (isUniformScale) { |
| 630 #ifdef SK_VULKAN |
| 631 fragBuilder->codeAppendf("float st_grad_len = abs(dFdx(%s.x));", st.
fsIn()); |
| 632 #else |
| 633 // We use the y gradient because there is a bug in the Mali 400 in t
he x direction. |
613 fragBuilder->codeAppendf("float st_grad_len = abs(dFdy(%s.y));", st.
fsIn()); | 634 fragBuilder->codeAppendf("float st_grad_len = abs(dFdy(%s.y));", st.
fsIn()); |
| 635 #endif |
614 fragBuilder->codeAppend("vec2 offset = vec2(st_grad_len*delta, 0.0);
"); | 636 fragBuilder->codeAppend("vec2 offset = vec2(st_grad_len*delta, 0.0);
"); |
615 } else if (isSimilarity) { | 637 } else if (isSimilarity) { |
616 // For a similarity matrix with rotation, the gradient will not be a
ligned | 638 // For a similarity matrix with rotation, the gradient will not be a
ligned |
617 // with the texel coordinate axes, so we need to calculate it. | 639 // with the texel coordinate axes, so we need to calculate it. |
| 640 #ifdef SK_VULKAN |
| 641 fragBuilder->codeAppendf("vec2 st_grad = dFdx(%s);", st.fsIn()); |
| 642 fragBuilder->codeAppend("vec2 offset = delta*st_grad;"); |
| 643 #else |
618 // We use dFdy because of a Mali 400 bug, and rotate -90 degrees to | 644 // We use dFdy because of a Mali 400 bug, and rotate -90 degrees to |
619 // get the gradient in the x direction. | 645 // get the gradient in the x direction. |
620 fragBuilder->codeAppendf("vec2 st_grad = dFdy(%s);", st.fsIn()); | 646 fragBuilder->codeAppendf("vec2 st_grad = dFdy(%s);", st.fsIn()); |
| 647 fragBuilder->codeAppend("vec2 offset = delta*vec2(st_grad.y, -st_gra
d.x);"); |
| 648 #endif |
621 fragBuilder->codeAppend("float st_grad_len = length(st_grad);"); | 649 fragBuilder->codeAppend("float st_grad_len = length(st_grad);"); |
622 fragBuilder->codeAppend("vec2 offset = delta*vec2(st_grad.y, -st_gra
d.x);"); | |
623 } else { | 650 } else { |
624 fragBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); | 651 fragBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn()); |
625 | 652 |
626 fragBuilder->codeAppend("vec2 Jdx = dFdx(st);"); | 653 fragBuilder->codeAppend("vec2 Jdx = dFdx(st);"); |
627 fragBuilder->codeAppend("vec2 Jdy = dFdy(st);"); | 654 fragBuilder->codeAppend("vec2 Jdy = dFdy(st);"); |
628 fragBuilder->codeAppend("vec2 offset = delta*Jdx;"); | 655 fragBuilder->codeAppend("vec2 offset = delta*Jdx;"); |
629 } | 656 } |
630 | 657 |
631 // green is distance to uv center | 658 // green is distance to uv center |
632 fragBuilder->codeAppend("\tvec4 texColor = "); | 659 fragBuilder->codeAppend("\tvec4 texColor = "); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0
; | 842 flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0
; |
816 } | 843 } |
817 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; | 844 flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; |
818 return GrDistanceFieldLCDTextGeoProc::Make(GrRandomColor(d->fRandom), | 845 return GrDistanceFieldLCDTextGeoProc::Make(GrRandomColor(d->fRandom), |
819 GrTest::TestMatrix(d->fRandom), | 846 GrTest::TestMatrix(d->fRandom), |
820 d->fTextures[texIdx], params, | 847 d->fTextures[texIdx], params, |
821 wa, | 848 wa, |
822 flags, | 849 flags, |
823 d->fRandom->nextBool()); | 850 d->fRandom->nextBool()); |
824 } | 851 } |
OLD | NEW |