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

Unified Diff: src/gpu/effects/GrDistanceFieldGeoProc.cpp

Issue 1776383002: Use correct gradient calculation for rotated distance fields. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix android error Created 4 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/effects/GrDistanceFieldGeoProc.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/effects/GrDistanceFieldGeoProc.cpp
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
index b77a1f5a5d21fce5660895dee26070a8c8b12254..2182a1175828be3ae2e35a8a172c88afb21b4e46 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
@@ -79,11 +79,13 @@ public:
// add varyings
GrGLSLVertToFrag recipScale(kFloat_GrSLType);
GrGLSLVertToFrag uv(kVec2f_GrSLType);
+ bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
+ kUniformScale_DistanceFieldEffectMask;
bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCoords()->fName);
- // compute numbers to be hardcoded to convert texture coordinates from int to float
+ // compute numbers to be hardcoded to convert texture coordinates from float to int
SkASSERT(dfTexEffect.numTextures() == 1);
GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
@@ -112,15 +114,24 @@ public:
#endif
fragBuilder->codeAppend("float afwidth;");
- if (isSimilarity) {
+ if (isUniformScale) {
// For uniform scale, we adjust for the effect of the transformation on the distance
- // by using the length of the gradient of the texture coordinates. We use st coordinates
- // to ensure we're mapping 1:1 from texel space to pixel space.
+ // by using the length of the gradient of the t coordinate in the y direction.
+ // We use st coordinates to ensure we're mapping 1:1 from texel space to pixel space.
+ // We use the y gradient because there is a bug in the Mali 400 in the x direction.
// this gives us a smooth step across approximately one fragment
- // we use y to work around a Mali400 bug in the x direction
fragBuilder->codeAppendf("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(%s.y));",
st.fsIn());
+ } else if (isSimilarity) {
+ // For similarity transform, we adjust the effect of the transformation on the distance
+ // by using the length of the gradient of the texture coordinates. We use st coordinates
+ // to ensure we're mapping 1:1 from texel space to pixel space.
+ // We use the y gradient because there is a bug in the Mali 400 in the x direction.
+
+ // this gives us a smooth step across approximately one fragment
+ fragBuilder->codeAppendf("float st_grad_len = length(dFdy(%s));", st.fsIn());
+ fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*st_grad_len);");
} else {
// For general transforms, to determine the amount of correction we multiply a unit
// vector pointing along the SDF gradient direction by the Jacobian of the st coords
@@ -254,15 +265,20 @@ const GrGeometryProcessor* GrDistanceFieldA8TextGeoProc::TestCreate(GrProcessorT
GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams::kBilerp_FilterMode :
GrTextureParams::kNone_FilterMode);
+ uint32_t flags = 0;
+ flags |= d->fRandom->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0;
+ if (flags & kSimilarity_DistanceFieldEffectFlag) {
+ flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0;
+ }
+
return GrDistanceFieldA8TextGeoProc::Create(GrRandomColor(d->fRandom),
GrTest::TestMatrix(d->fRandom),
d->fTextures[texIdx], params,
#ifdef SK_GAMMA_APPLY_TO_A8
d->fRandom->nextF(),
#endif
- d->fRandom->nextBool() ?
- kSimilarity_DistanceFieldEffectFlag : 0,
- d->fRandom->nextBool());
+ flags,
+ d->fRandom->nextBool());
}
///////////////////////////////////////////////////////////////////////////////
@@ -335,13 +351,27 @@ public:
kHigh_GrSLPrecision));
fragBuilder->codeAppendf("vec2 st = uv*%s;", textureSizeUniName);
fragBuilder->codeAppend("float afwidth;");
- if (dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag) {
+ bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
+ kUniformScale_DistanceFieldEffectMask;
+ bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
+ if (isUniformScale) {
// For uniform scale, we adjust for the effect of the transformation on the distance
+ // by using the length of the gradient of the t coordinate in the y direction.
+ // We use st coordinates to ensure we're mapping 1:1 from texel space to pixel space.
+ // We use the y gradient because there is a bug in the Mali 400 in the x direction.
+
+ // this gives us a smooth step across approximately one fragment
+ fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(st.y));");
+
+ } else if (isSimilarity) {
+ // For similarity transform, we adjust the effect of the transformation on the distance
// by using the length of the gradient of the texture coordinates. We use st coordinates
// to ensure we're mapping 1:1 from texel space to pixel space.
+ // We use the y gradient because there is a bug in the Mali 400 in the x direction.
// this gives us a smooth step across approximately one fragment
- fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*dFdy(st.y));");
+ fragBuilder->codeAppend("float st_grad_len = length(dFdy(st));");
+ fragBuilder->codeAppend("afwidth = abs(" SK_DistanceFieldAAFactor "*st_grad_len);");
} else {
// For general transforms, to determine the amount of correction we multiply a unit
// vector pointing along the SDF gradient direction by the Jacobian of the st coords
@@ -464,13 +494,18 @@ const GrGeometryProcessor* GrDistanceFieldPathGeoProc::TestCreate(GrProcessorTes
GrTextureParams params(tileModes, d->fRandom->nextBool() ? GrTextureParams::kBilerp_FilterMode
: GrTextureParams::kNone_FilterMode);
+ uint32_t flags = 0;
+ flags |= d->fRandom->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0;
+ if (flags & kSimilarity_DistanceFieldEffectFlag) {
+ flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0;
+ }
+
return GrDistanceFieldPathGeoProc::Create(GrRandomColor(d->fRandom),
GrTest::TestMatrix(d->fRandom),
d->fTextures[texIdx],
params,
- d->fRandom->nextBool() ?
- kSimilarity_DistanceFieldEffectFlag : 0,
- d->fRandom->nextBool());
+ flags,
+ d->fRandom->nextBool());
}
///////////////////////////////////////////////////////////////////////////////
@@ -518,13 +553,15 @@ public:
args.fTransformsOut);
// set up varyings
- bool isUniformScale = SkToBool(dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask);
+ bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
+ kUniformScale_DistanceFieldEffectMask;
+ bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
GrGLSLVertToFrag recipScale(kFloat_GrSLType);
GrGLSLVertToFrag uv(kVec2f_GrSLType);
varyingHandler->addVarying("TextureCoords", &uv, kHigh_GrSLPrecision);
vertBuilder->codeAppendf("%s = %s;", uv.vsOut(), dfTexEffect.inTextureCoords()->fName);
- // compute numbers to be hardcoded to convert texture coordinates from int to float
+ // compute numbers to be hardcoded to convert texture coordinates from float to int
SkASSERT(dfTexEffect.numTextures() == 1);
GrTexture* atlas = dfTexEffect.textureAccess(0).getTexture();
SkASSERT(atlas && SkIsPow2(atlas->width()) && SkIsPow2(atlas->height()));
@@ -555,8 +592,16 @@ public:
fragBuilder->codeAppendf("float delta = %.*f;\n", SK_FLT_DECIMAL_DIG, lcdDelta);
}
if (isUniformScale) {
- fragBuilder->codeAppendf("float dy = abs(dFdy(%s.y));", st.fsIn());
- fragBuilder->codeAppend("vec2 offset = vec2(dy*delta, 0.0);");
+ fragBuilder->codeAppendf("float st_grad_len = abs(dFdy(%s.y));", st.fsIn());
+ fragBuilder->codeAppend("vec2 offset = vec2(st_grad_len*delta, 0.0);");
+ } else if (isSimilarity) {
+ // For a similarity matrix with rotation, the gradient will not be aligned
+ // with the texel coordinate axes, so we need to calculate it.
+ // We use dFdy because of a Mali 400 bug, and rotate -90 degrees to
+ // get the gradient in the x direction.
+ fragBuilder->codeAppendf("vec2 st_grad = dFdy(%s);", st.fsIn());
+ fragBuilder->codeAppend("float st_grad_len = length(st_grad);");
+ fragBuilder->codeAppend("vec2 offset = delta*vec2(st_grad.y, -st_grad.x);");
} else {
fragBuilder->codeAppendf("vec2 st = %s;\n", st.fsIn());
@@ -599,13 +644,14 @@ public:
// transformations, and even then using a single factor seems like a reasonable
// trade-off between quality and speed.
fragBuilder->codeAppend("float afwidth;");
- if (isUniformScale) {
- // For uniform scale, we adjust for the effect of the transformation on the distance
- // by using the length of the gradient of the texture coordinates. We use st coordinates
- // to ensure we're mapping 1:1 from texel space to pixel space.
+ if (isSimilarity) {
+ // For similarity transform (uniform scale-only is a subset of this), we adjust for the
+ // effect of the transformation on the distance by using the length of the gradient of
+ // the texture coordinates. We use st coordinates to ensure we're mapping 1:1 from texel
+ // space to pixel space.
// this gives us a smooth step across approximately one fragment
- fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*dy;");
+ fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*st_grad_len;");
} else {
// For general transforms, to determine the amount of correction we multiply a unit
// vector pointing along the SDF gradient direction by the Jacobian of the st coords
@@ -737,7 +783,10 @@ const GrGeometryProcessor* GrDistanceFieldLCDTextGeoProc::TestCreate(GrProcessor
GrTextureParams::kNone_FilterMode);
DistanceAdjust wa = { 0.0f, 0.1f, -0.1f };
uint32_t flags = kUseLCD_DistanceFieldEffectFlag;
- flags |= d->fRandom->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0;
+ flags |= d->fRandom->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0;
+ if (flags & kSimilarity_DistanceFieldEffectFlag) {
+ flags |= d->fRandom->nextBool() ? kScaleOnly_DistanceFieldEffectFlag : 0;
+ }
flags |= d->fRandom->nextBool() ? kBGR_DistanceFieldEffectFlag : 0;
return GrDistanceFieldLCDTextGeoProc::Create(GrRandomColor(d->fRandom),
GrTest::TestMatrix(d->fRandom),
« no previous file with comments | « src/gpu/effects/GrDistanceFieldGeoProc.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698