Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: src/gpu/effects/GrDistanceFieldGeoProc.cpp

Issue 2163213004: Use dFdx in Vulkan to address distance field issues. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698