diff options
author | Brian Osman <brianosman@google.com> | 2017-05-09 16:36:41 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-05-09 20:58:41 +0000 |
commit | 25294d76b1c5ca34ba6cc7033ee42af6484b046b (patch) | |
tree | 61ba4d5a8b44f8cb1221703281b0f633e2544c92 /src/gpu/GrPathUtils.cpp | |
parent | fdf31035a9639c2d377bdf2ddb404d269f8ca42a (diff) |
Pre-clamp path tolerance
GrDefaultPathRenderer was using GrPathUtils::worstCasePointCount, which
clamped the tolerance. Then it built geometry with the unclamped value,
leading to vertex overflow (found by canvas fuzzer). The new rule is if
you use GrPathUtils, your tolerance must come from scaleToleranceToSrc.
Bug: skia:6569
Change-Id: I851519db8e569e570c717033d697f3d4d3d787fb
Reviewed-on: https://skia-review.googlesource.com/16234
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/gpu/GrPathUtils.cpp')
-rw-r--r-- | src/gpu/GrPathUtils.cpp | 31 |
1 files changed, 14 insertions, 17 deletions
diff --git a/src/gpu/GrPathUtils.cpp b/src/gpu/GrPathUtils.cpp index 8e0a9fc0cc..8991500834 100644 --- a/src/gpu/GrPathUtils.cpp +++ b/src/gpu/GrPathUtils.cpp @@ -11,13 +11,15 @@ #include "SkGeometry.h" #include "SkMathPriv.h" +static const int MAX_POINTS_PER_CURVE = 1 << 10; +static const SkScalar gMinCurveTol = 0.0001f; + SkScalar GrPathUtils::scaleToleranceToSrc(SkScalar devTol, const SkMatrix& viewM, const SkRect& pathBounds) { // In order to tesselate the path we get a bound on how much the matrix can // scale when mapping to screen coordinates. SkScalar stretch = viewM.getMaxScale(); - SkScalar srcTol = devTol; if (stretch < 0) { // take worst case mapRadius amoung four corners. @@ -30,17 +32,16 @@ SkScalar GrPathUtils::scaleToleranceToSrc(SkScalar devTol, stretch = SkMaxScalar(stretch, mat.mapRadius(SK_Scalar1)); } } - return srcTol / stretch; + SkScalar srcTol = devTol / stretch; + if (srcTol < gMinCurveTol) { + srcTol = gMinCurveTol; + } + return srcTol; } -static const int MAX_POINTS_PER_CURVE = 1 << 10; -static const SkScalar gMinCurveTol = 0.0001f; - uint32_t GrPathUtils::quadraticPointCount(const SkPoint points[], SkScalar tol) { - if (tol < gMinCurveTol) { - tol = gMinCurveTol; - } - SkASSERT(tol > 0); + // You should have called scaleToleranceToSrc, which guarantees this + SkASSERT(tol >= gMinCurveTol); SkScalar d = points[1].distanceToLineSegmentBetween(points[0], points[2]); if (!SkScalarIsFinite(d)) { @@ -96,10 +97,8 @@ uint32_t GrPathUtils::generateQuadraticPoints(const SkPoint& p0, uint32_t GrPathUtils::cubicPointCount(const SkPoint points[], SkScalar tol) { - if (tol < gMinCurveTol) { - tol = gMinCurveTol; - } - SkASSERT(tol > 0); + // You should have called scaleToleranceToSrc, which guarantees this + SkASSERT(tol >= gMinCurveTol); SkScalar d = SkTMax( points[1].distanceToLineSegmentBetweenSqd(points[0], points[3]), @@ -158,10 +157,8 @@ uint32_t GrPathUtils::generateCubicPoints(const SkPoint& p0, } int GrPathUtils::worstCasePointCount(const SkPath& path, int* subpaths, SkScalar tol) { - if (tol < gMinCurveTol) { - tol = gMinCurveTol; - } - SkASSERT(tol > 0); + // You should have called scaleToleranceToSrc, which guarantees this + SkASSERT(tol >= gMinCurveTol); int pointCount = 0; *subpaths = 1; |