From 18fab30d7c4858ef2521e0380573aac5a21b2ed9 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Tue, 16 Feb 2016 08:00:05 -0800 Subject: [PATCH] Modify interface to GrPathUtils::convertCubicToQuads BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1694403003 Review URL: https://codereview.chromium.org/1694403003 --- src/gpu/GrPathUtils.cpp | 24 +++++++++++++++----- src/gpu/GrPathUtils.h | 21 +++++++++-------- src/gpu/batches/GrAAConvexPathRenderer.cpp | 2 +- src/gpu/batches/GrAAHairLinePathRenderer.cpp | 9 +++----- src/gpu/batches/GrPLSPathRenderer.cpp | 3 +-- 5 files changed, 34 insertions(+), 25 deletions(-) diff --git a/src/gpu/GrPathUtils.cpp b/src/gpu/GrPathUtils.cpp index f97a61e1f6..0fd8b0e882 100644 --- a/src/gpu/GrPathUtils.cpp +++ b/src/gpu/GrPathUtils.cpp @@ -545,21 +545,33 @@ void convert_noninflect_cubic_to_quads(const SkPoint p[4], void GrPathUtils::convertCubicToQuads(const SkPoint p[4], SkScalar tolScale, - bool constrainWithinTangents, - SkPathPriv::FirstDirection dir, SkTArray* quads) { SkPoint chopped[10]; int count = SkChopCubicAtInflections(p, chopped); - // base tolerance is 1 pixel. - static const SkScalar kTolerance = SK_Scalar1; - const SkScalar tolSqd = SkScalarSquare(SkScalarMul(tolScale, kTolerance)); + const SkScalar tolSqd = SkScalarSquare(tolScale); for (int i = 0; i < count; ++i) { SkPoint* cubic = chopped + 3*i; - convert_noninflect_cubic_to_quads(cubic, tolSqd, constrainWithinTangents, dir, quads); + // The direction param is ignored if the third param is false. + convert_noninflect_cubic_to_quads(cubic, tolSqd, false, + SkPathPriv::kCCW_FirstDirection, quads); } +} +void GrPathUtils::convertCubicToQuadsConstrainToTangents(const SkPoint p[4], + SkScalar tolScale, + SkPathPriv::FirstDirection dir, + SkTArray* quads) { + SkPoint chopped[10]; + int count = SkChopCubicAtInflections(p, chopped); + + const SkScalar tolSqd = SkScalarSquare(tolScale); + + for (int i = 0; i < count; ++i) { + SkPoint* cubic = chopped + 3*i; + convert_noninflect_cubic_to_quads(cubic, tolSqd, true, dir, quads); + } } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrPathUtils.h b/src/gpu/GrPathUtils.h index 4874fa2aef..cb2da30803 100644 --- a/src/gpu/GrPathUtils.h +++ b/src/gpu/GrPathUtils.h @@ -108,21 +108,22 @@ namespace GrPathUtils { // Converts a cubic into a sequence of quads. If working in device space // use tolScale = 1, otherwise set based on stretchiness of the matrix. The - // result is sets of 3 points in quads (TODO: share endpoints in returned - // array) + // result is sets of 3 points in quads. + void convertCubicToQuads(const SkPoint p[4], + SkScalar tolScale, + SkTArray* quads); + // When we approximate a cubic {a,b,c,d} with a quadratic we may have to // ensure that the new control point lies between the lines ab and cd. The // convex path renderer requires this. It starts with a path where all the // control points taken together form a convex polygon. It relies on this // property and the quadratic approximation of cubics step cannot alter it. - // Setting constrainWithinTangents to true enforces this property. When this - // is true the cubic must be simple and dir must specify the orientation of - // the cubic. Otherwise, dir is ignored. - void convertCubicToQuads(const SkPoint p[4], - SkScalar tolScale, - bool constrainWithinTangents, - SkPathPriv::FirstDirection dir, - SkTArray* quads); + // This variation enforces this constraint. The cubic must be simple and dir + // must specify the orientation of the contour containing the cubic. + void convertCubicToQuadsConstrainToTangents(const SkPoint p[4], + SkScalar tolScale, + SkPathPriv::FirstDirection dir, + SkTArray* quads); // Chops the cubic bezier passed in by src, at the double point (intersection point) // if the curve is a cubic loop. If it is a loop, there will be two parametric values for diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp index 4fd3c6fe00..f02ebfb2f5 100644 --- a/src/gpu/batches/GrAAConvexPathRenderer.cpp +++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp @@ -254,7 +254,7 @@ static inline void add_cubic_segments(const SkPoint pts[4], SkPathPriv::FirstDirection dir, SegmentArray* segments) { SkSTArray<15, SkPoint, true> quads; - GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, true, dir, &quads); + GrPathUtils::convertCubicToQuadsConstrainToTangents(pts, SK_Scalar1, dir, &quads); int count = quads.count(); for (int q = 0; q < count; q += 3) { add_quad_segment(&quads[q], segments); diff --git a/src/gpu/batches/GrAAHairLinePathRenderer.cpp b/src/gpu/batches/GrAAHairLinePathRenderer.cpp index 97a779ee3d..87e1940640 100644 --- a/src/gpu/batches/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/batches/GrAAHairLinePathRenderer.cpp @@ -345,17 +345,14 @@ static int gather_lines_and_quads(const SkPath& path, bounds.roundOut(&ibounds); if (SkIRect::Intersects(devClipBounds, ibounds)) { PREALLOC_PTARRAY(32) q; - // we don't need a direction if we aren't constraining the subdivision - const SkPathPriv::FirstDirection kDummyDir = SkPathPriv::kCCW_FirstDirection; // We convert cubics to quadratics (for now). // In perspective have to do conversion in src space. if (persp) { SkScalar tolScale = - GrPathUtils::scaleToleranceToSrc(SK_Scalar1, m, - path.getBounds()); - GrPathUtils::convertCubicToQuads(pathPts, tolScale, false, kDummyDir, &q); + GrPathUtils::scaleToleranceToSrc(SK_Scalar1, m, path.getBounds()); + GrPathUtils::convertCubicToQuads(pathPts, tolScale, &q); } else { - GrPathUtils::convertCubicToQuads(devPts, SK_Scalar1, false, kDummyDir, &q); + GrPathUtils::convertCubicToQuads(devPts, SK_Scalar1, &q); } for (int i = 0; i < q.count(); i += 3) { SkPoint* qInDevSpace; diff --git a/src/gpu/batches/GrPLSPathRenderer.cpp b/src/gpu/batches/GrPLSPathRenderer.cpp index faadd6d49b..6ca773d7b2 100644 --- a/src/gpu/batches/GrPLSPathRenderer.cpp +++ b/src/gpu/batches/GrPLSPathRenderer.cpp @@ -145,7 +145,6 @@ static bool get_geometry(const SkPath& path, const SkMatrix& m, PLSVertices& tri SkPath linesOnlyPath; linesOnlyPath.setFillType(path.getFillType()); SkSTArray<15, SkPoint, true> quadPoints; - SkPathPriv::FirstDirection dir = SkPathPriv::FirstDirection::kUnknown_FirstDirection; SkPath::Iter iter(path, true); bool done = false; while (!done) { @@ -175,7 +174,7 @@ static bool get_geometry(const SkPath& path, const SkMatrix& m, PLSVertices& tri case SkPath::kCubic_Verb: { m.mapPoints(pts, 4); SkSTArray<15, SkPoint, true> quads; - GrPathUtils::convertCubicToQuads(pts, kCubicTolerance, false, dir, &quads); + GrPathUtils::convertCubicToQuads(pts, kCubicTolerance, &quads); int count = quads.count(); for (int q = 0; q < count; q += 3) { linesOnlyPath.lineTo(quads[q + 2]);