aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrPathUtils.cpp
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-05-09 16:36:41 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-09 20:58:41 +0000
commit25294d76b1c5ca34ba6cc7033ee42af6484b046b (patch)
tree61ba4d5a8b44f8cb1221703281b0f633e2544c92 /src/gpu/GrPathUtils.cpp
parentfdf31035a9639c2d377bdf2ddb404d269f8ca42a (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.cpp31
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;