aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar brianosman <brianosman@google.com>2016-04-13 13:56:21 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-04-13 13:56:21 -0700
commit0e3c55431b463b5575983c0c875909e08a3562bf (patch)
tree4aa76104cefbbbf35f6ba57a90bb0824ce59ed5e /src
parentd3b63d3244add67b1d087123f36a418f7fd7ec0f (diff)
Tweak distance field path renderer behavior in gamma-correct mode to match
recent changes to text rendering. Uses linear coverage falloff. Produces results that are perceptually more similar to L32 (raster and gpu). Smoothstep + sRGB was too soft. Plumb the gamma-correctness via DrawPathArgs, which also paves the way for other path rendering implementations to easily make decisions about rendering technique based on that flag. Fix a few typos and formatting issues from my most recent change. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1889453002 Review URL: https://codereview.chromium.org/1889453002
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrClipMaskManager.cpp2
-rw-r--r--src/gpu/GrDrawContext.cpp2
-rw-r--r--src/gpu/GrPathRenderer.h3
-rw-r--r--src/gpu/batches/GrAADistanceFieldPathRenderer.cpp19
-rw-r--r--src/gpu/effects/GrDistanceFieldGeoProc.cpp12
5 files changed, 32 insertions, 6 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 2700f56986..7418e76449 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -856,6 +856,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
args.fPath = &clipPath;
args.fStroke = &stroke;
args.fAntiAlias = false;
+ args.fGammaCorrect = false;
pr->drawPath(args);
} else {
GrPathRenderer::StencilPathArgs args;
@@ -891,6 +892,7 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
args.fPath = &clipPath;
args.fStroke = &stroke;
args.fAntiAlias = false;
+ args.fGammaCorrect = false;
pr->drawPath(args);
}
} else {
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp
index 9110b34d6f..2e4b13f03e 100644
--- a/src/gpu/GrDrawContext.cpp
+++ b/src/gpu/GrDrawContext.cpp
@@ -922,6 +922,7 @@ bool GrDrawContextPriv::drawAndStencilPath(const SkIRect* scissorRect,
args.fPath = &path;
args.fStroke = &GrStrokeInfo::FillInfo();
args.fAntiAlias = useCoverageAA;
+ args.fGammaCorrect = fDrawContext->isGammaCorrect();
pr->drawPath(args);
return true;
}
@@ -1025,6 +1026,7 @@ void GrDrawContext::internalDrawPath(const GrClip& clip,
args.fPath = pathPtr;
args.fStroke = strokeInfoPtr;
args.fAntiAlias = useCoverageAA;
+ args.fGammaCorrect = this->isGammaCorrect();
pr->drawPath(args);
}
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index 85b3275e89..cc149061ed 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -119,6 +119,7 @@ public:
* fPath the path to draw.
* fStroke the stroke information (width, join, cap)
* fAntiAlias true if anti-aliasing is required.
+ * fGammaCorrect true if gamma-correct rendering is to be used.
*/
struct DrawPathArgs {
GrDrawTarget* fTarget;
@@ -129,6 +130,7 @@ public:
const SkPath* fPath;
const GrStrokeInfo* fStroke;
bool fAntiAlias;
+ bool fGammaCorrect;
void validate() const {
SkASSERT(fTarget);
@@ -281,6 +283,7 @@ private:
drawArgs.fPath = args.fPath;
drawArgs.fStroke = args.fStroke;
drawArgs.fAntiAlias = false;
+ drawArgs.fGammaCorrect = false;
this->drawPath(drawArgs);
}
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
index 35d1f61977..655a77127e 100644
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
@@ -148,8 +148,10 @@ public:
};
static GrDrawBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix,
- GrBatchAtlas* atlas, PathCache* pathCache, PathDataList* pathList) {
- return new AADistanceFieldPathBatch(geometry, viewMatrix, atlas, pathCache, pathList);
+ GrBatchAtlas* atlas, PathCache* pathCache, PathDataList* pathList,
+ bool gammaCorrect) {
+ return new AADistanceFieldPathBatch(geometry, viewMatrix, atlas, pathCache, pathList,
+ gammaCorrect);
}
const char* name() const override { return "AADistanceFieldPathBatch"; }
@@ -196,6 +198,7 @@ private:
uint32_t flags = 0;
flags |= ctm.isScaleTranslate() ? kScaleOnly_DistanceFieldEffectFlag : 0;
flags |= ctm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0;
+ flags |= fGammaCorrect ? kGammaCorrect_DistanceFieldEffectFlag : 0;
GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode);
@@ -296,7 +299,8 @@ private:
AADistanceFieldPathBatch(const Geometry& geometry,
const SkMatrix& viewMatrix,
GrBatchAtlas* atlas,
- PathCache* pathCache, PathDataList* pathList)
+ PathCache* pathCache, PathDataList* pathList,
+ bool gammaCorrect)
: INHERITED(ClassID()) {
fBatch.fViewMatrix = viewMatrix;
fGeoData.push_back(geometry);
@@ -304,6 +308,7 @@ private:
fAtlas = atlas;
fPathCache = pathCache;
fPathList = pathList;
+ fGammaCorrect = gammaCorrect;
// Compute bounds
fBounds = geometry.fPath.getBounds();
@@ -524,6 +529,7 @@ private:
GrBatchAtlas* fAtlas;
PathCache* fPathCache;
PathDataList* fPathList;
+ bool fGammaCorrect;
typedef GrVertexBatch INHERITED;
};
@@ -562,7 +568,8 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) {
SkAutoTUnref<GrDrawBatch> batch(AADistanceFieldPathBatch::Create(geometry,
*args.fViewMatrix, fAtlas,
- &fPathCache, &fPathList));
+ &fPathCache, &fPathList,
+ args.fGammaCorrect));
args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
return true;
@@ -630,6 +637,7 @@ DRAW_BATCH_TEST_DEFINE(AADistanceFieldPathBatch) {
SkMatrix viewMatrix = GrTest::TestMatrix(random);
GrColor color = GrRandomColor(random);
+ bool gammaCorrect = random->nextBool();
AADistanceFieldPathBatch::Geometry geometry(GrTest::TestStrokeRec(random));
geometry.fColor = color;
@@ -640,7 +648,8 @@ DRAW_BATCH_TEST_DEFINE(AADistanceFieldPathBatch) {
return AADistanceFieldPathBatch::Create(geometry, viewMatrix,
gTestStruct.fAtlas,
&gTestStruct.fPathCache,
- &gTestStruct.fPathList);
+ &gTestStruct.fPathList,
+ gammaCorrect);
}
#endif
diff --git a/src/gpu/effects/GrDistanceFieldGeoProc.cpp b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
index 5dd70cd0b8..e87021e978 100644
--- a/src/gpu/effects/GrDistanceFieldGeoProc.cpp
+++ b/src/gpu/effects/GrDistanceFieldGeoProc.cpp
@@ -362,6 +362,8 @@ public:
bool isUniformScale = (dfTexEffect.getFlags() & kUniformScale_DistanceFieldEffectMask) ==
kUniformScale_DistanceFieldEffectMask;
bool isSimilarity = SkToBool(dfTexEffect.getFlags() & kSimilarity_DistanceFieldEffectFlag);
+ bool isGammaCorrect =
+ SkToBool(dfTexEffect.getFlags() & kGammaCorrect_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.
@@ -402,7 +404,15 @@ public:
// this gives us a smooth step across approximately one fragment
fragBuilder->codeAppend("afwidth = " SK_DistanceFieldAAFactor "*length(grad);");
}
- fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
+ // The smoothstep falloff compensates for the non-linear sRGB response curve. If we are
+ // doing gamma-correct rendering (to an sRGB or F16 buffer), then we actually want distance
+ // mapped linearly to coverage, so use a linear step:
+ if (isGammaCorrect) {
+ fragBuilder->codeAppend(
+ "float val = clamp(distance + afwidth / (2.0 * afwidth), 0.0, 1.0);");
+ } else {
+ fragBuilder->codeAppend("float val = smoothstep(-afwidth, afwidth, distance);");
+ }
fragBuilder->codeAppendf("%s = vec4(val);", args.fOutputCoverage);
}