diff options
author | senorblanco <senorblanco@chromium.org> | 2015-04-22 13:45:18 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-22 13:45:18 -0700 |
commit | 2b4bb07492790d7d18dc046f05999915d4384c5d (patch) | |
tree | 3dc29e75e6535e372c1357dcc3bd5dc17b85754f /src/gpu | |
parent | b0e1be207f6b5a5346641b7b675bb9bd1993f9df (diff) |
Improve the curve tessellation subdivision of the path renderers.
The stencil-and-cover and tessellating path renderers currently
tessellate curves to linear segments to within one screen space pixel.
This is fairly poor accuracy, as can be seen from the strokecircle GM:
there are noticeable rotating bumps on the circles.
Improving the tolerance to 0.25 pixel eliminates the bumps, and
approximates the 16x supersampling of the raster path.
This does have a performance hit: 3-6% on desktop on
the IE chalkboard demo, ~1% on Nexus 7 2013.
Note: this will require rebaselining a number of GPU and MSAA images
in Skia, but nothing in Chrome (yet).
BUG=skia:3731
Review URL: https://codereview.chromium.org/1072273007
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/GrDefaultPathRenderer.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrPathUtils.h | 7 | ||||
-rw-r--r-- | src/gpu/GrTessellatingPathRenderer.cpp | 3 |
3 files changed, 10 insertions, 2 deletions
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp index 531b5e5f4a..65daa7ca89 100644 --- a/src/gpu/GrDefaultPathRenderer.cpp +++ b/src/gpu/GrDefaultPathRenderer.cpp @@ -658,7 +658,7 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target, } } - SkScalar tol = SK_Scalar1; + SkScalar tol = GrPathUtils::kDefaultTolerance; SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, path.getBounds()); SkRect devBounds; diff --git a/src/gpu/GrPathUtils.h b/src/gpu/GrPathUtils.h index c15fd7ae10..250b0a2324 100644 --- a/src/gpu/GrPathUtils.h +++ b/src/gpu/GrPathUtils.h @@ -168,5 +168,12 @@ namespace GrPathUtils { // If you transform the points the lines will also need to be transformed. This can be done // by mapping the lines with the inverse-transpose of the matrix used to map the points. void getCubicKLM(const SkPoint p[4], SkScalar klm[9]); + + // When tessellating curved paths into linear segments, this defines the maximum distance + // in screen space which a segment may deviate from the mathmatically correct value. + // Above this value, the segment will be subdivided. + // This value was chosen to approximate the supersampling accuracy of the raster path (16 + // samples, or one quarter pixel). + static const SkScalar kDefaultTolerance = SkDoubleToScalar(0.25); }; #endif diff --git a/src/gpu/GrTessellatingPathRenderer.cpp b/src/gpu/GrTessellatingPathRenderer.cpp index c80b693ef5..1c1663dbf3 100644 --- a/src/gpu/GrTessellatingPathRenderer.cpp +++ b/src/gpu/GrTessellatingPathRenderer.cpp @@ -1392,7 +1392,8 @@ public: c.sweep_lt = sweep_lt_vert; c.sweep_gt = sweep_gt_vert; } - SkScalar tol = GrPathUtils::scaleToleranceToSrc(SK_Scalar1, fViewMatrix, pathBounds); + SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance; + SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMatrix, pathBounds); int contourCnt; int maxPts = GrPathUtils::worstCasePointCount(fPath, &contourCnt, tol); if (maxPts <= 0) { |