Bug 1255062 - allow Skia GrConvexPolyEffect to handle degenerate contours. r=mchang
authorLee Salzman <lsalzman@mozilla.com>
Thu, 26 May 2016 12:52:52 -0400
changeset 324432 4c907bc970305e4d976eb9de164c297fb050525f
parent 324431 8546d8cdf26fb61f221ada2d1ae02beea3412e30
child 324433 b3b8576fae4d81364479a2addd97cb0ff831a3db
push id9671
push userraliiev@mozilla.com
push dateMon, 06 Jun 2016 20:27:52 +0000
treeherdermozilla-aurora@cea65ca3d0bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmchang
bugs1255062
milestone49.0a1
Bug 1255062 - allow Skia GrConvexPolyEffect to handle degenerate contours. r=mchang
gfx/skia/skia/src/gpu/effects/GrConvexPolyEffect.cpp
--- a/gfx/skia/skia/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/gfx/skia/skia/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -242,23 +242,16 @@ GrFragmentProcessor* GrConvexPolyEffect:
     if (kHairlineAA_GrProcessorEdgeType == type) {
         return nullptr;
     }
     if (path.getSegmentMasks() != SkPath::kLine_SegmentMask ||
         !path.isConvex()) {
         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
     // skip the draw or omit the clip element.
     if (!SkPathPriv::CheapComputeFirstDirection(path, &dir)) {
         if (GrProcessorEdgeTypeIsInverseFill(type)) {
             return GrConstColorProcessor::Create(0xFFFFFFFF,
                                                  GrConstColorProcessor::kModulateRGBA_InputMode);
@@ -268,34 +261,49 @@ GrFragmentProcessor* GrConvexPolyEffect:
 
     SkVector t;
     if (nullptr == offset) {
         t.set(0, 0);
     } else {
         t = *offset;
     }
 
-    int count = path.getPoints(pts, kMaxEdges);
+    SkScalar        edges[3 * kMaxEdges];
+    SkPoint         pts[4];
+    SkPath::Verb    verb;
+    SkPath::Iter    iter(path, true);
+
     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;
-            }
-            SkPoint p = pts[i] + t;
-            edges[3 * n + 2] = -(edges[3 * n] * p.fX + edges[3 * n + 1] * p.fY);
-            ++n;
+    while ((verb = iter.next(pts, true, true)) != SkPath::kDone_Verb) {
+        switch (verb) {
+            case SkPath::kMove_Verb:
+            case SkPath::kClose_Verb:
+                continue;
+            case SkPath::kLine_Verb:
+                break;
+            default:
+                return nullptr;
+        }
+        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;
     }
+
     if (path.isInverseFillType()) {
         type = GrInvertProcessorEdgeType(type);
     }
     return Create(type, n, edges);
 }
 
 GrFragmentProcessor* GrConvexPolyEffect::Create(GrPrimitiveEdgeType edgeType, const SkRect& rect) {
     if (kHairlineAA_GrProcessorEdgeType == edgeType){