| Index: src/gpu/effects/GrConvexPolyEffect.cpp
|
| diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
|
| index 7b78305bb1e014d8a8d5ca2597ff00c942ac884a..caf86c2804bca2069e509ba5d13b4adba8eeeb6e 100644
|
| --- a/src/gpu/effects/GrConvexPolyEffect.cpp
|
| +++ b/src/gpu/effects/GrConvexPolyEffect.cpp
|
| @@ -247,13 +247,6 @@ GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType type, const
|
| return nullptr;
|
| }
|
|
|
| - if (path.countPoints() > kMaxEdges) {
|
| - return nullptr;
|
| - }
|
| -
|
| - SkPoint pts[kMaxEdges];
|
| - SkScalar edges[3 * kMaxEdges];
|
| -
|
| SkPathPriv::FirstDirection dir;
|
| // The only way this should fail is if the clip is effectively a infinitely thin line. In that
|
| // case nothing is inside the clip. It'd be nice to detect this at a higher level and either
|
| @@ -273,24 +266,45 @@ GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType type, const
|
| t = *offset;
|
| }
|
|
|
| - int count = path.getPoints(pts, kMaxEdges);
|
| + SkScalar edges[3 * kMaxEdges];
|
| + SkPoint pts[4];
|
| + SkPath::Verb verb;
|
| + SkPath::Iter iter(path, true);
|
| +
|
| + // SkPath considers itself convex so long as there is a convex contour within it,
|
| + // regardless of any degenerate contours such as a string of moveTos before it.
|
| + // Iterate here to consume any degenerate contours and only process the points
|
| + // on the actual convex contour.
|
| int n = 0;
|
| - for (int lastPt = count - 1, i = 0; i < count; lastPt = i++) {
|
| - if (pts[lastPt] != pts[i]) {
|
| - SkVector v = pts[i] - pts[lastPt];
|
| - v.normalize();
|
| - if (SkPathPriv::kCCW_FirstDirection == dir) {
|
| - edges[3 * n] = v.fY;
|
| - edges[3 * n + 1] = -v.fX;
|
| - } else {
|
| - edges[3 * n] = -v.fY;
|
| - edges[3 * n + 1] = v.fX;
|
| + while ((verb = iter.next(pts, true, true)) != SkPath::kDone_Verb) {
|
| + switch (verb) {
|
| + case SkPath::kMove_Verb:
|
| + SkASSERT(n == 0);
|
| + case SkPath::kClose_Verb:
|
| + break;
|
| + case SkPath::kLine_Verb: {
|
| + if (n >= kMaxEdges) {
|
| + return nullptr;
|
| + }
|
| + SkVector v = pts[1] - pts[0];
|
| + v.normalize();
|
| + if (SkPathPriv::kCCW_FirstDirection == dir) {
|
| + edges[3 * n] = v.fY;
|
| + edges[3 * n + 1] = -v.fX;
|
| + } else {
|
| + edges[3 * n] = -v.fY;
|
| + edges[3 * n + 1] = v.fX;
|
| + }
|
| + SkPoint p = pts[1] + t;
|
| + edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY);
|
| + ++n;
|
| + break;
|
| }
|
| - SkPoint p = pts[i] + t;
|
| - edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY);
|
| - ++n;
|
| + default:
|
| + return nullptr;
|
| }
|
| }
|
| +
|
| if (path.isInverseFillType()) {
|
| type = GrInvertProcessorEdgeType(type);
|
| }
|
|
|