diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/effects/GrConvexPolyEffect.cpp | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp index 7b78305bb1..caf86c2804 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); } |