never check for degenerates in path::iter

This does not appear to be used externally, and only internally in 3
sites in GPU, which we can handle explicitly.

For now you can still pass bools to Iter::next() but they are ignored.
After this lands, I will update the callers to remove those.

FWIW: none of our other tests or gms seem to notice this change...

Bug: skia:9339
Change-Id: If40077b1ebb3d47cfce0ec43996ff272318e4a62
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/235104
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/src/core/SkEdgeBuilder.cpp b/src/core/SkEdgeBuilder.cpp
index bc4b68c..6139a65 100644
--- a/src/core/SkEdgeBuilder.cpp
+++ b/src/core/SkEdgeBuilder.cpp
@@ -245,7 +245,7 @@
     if (iclip) {
         SkRect clip = this->recoverClip(*iclip);
 
-        while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
+        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
             switch (verb) {
                 case SkPath::kMove_Verb:
                 case SkPath::kClose_Verb:
@@ -272,7 +272,7 @@
             }
         }
     } else {
-        while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
+        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
             switch (verb) {
                 case SkPath::kMove_Verb:
                 case SkPath::kClose_Verb:
@@ -332,7 +332,7 @@
             }
         };
 
-        while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
+        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
             switch (verb) {
                 case SkPath::kMove_Verb:
                 case SkPath::kClose_Verb:
@@ -370,7 +370,7 @@
             }
         }
     } else {
-        while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
+        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
             auto handle_quad = [this](const SkPoint pts[3]) {
                 SkPoint monoX[5];
                 int n = SkChopQuadAtYExtrema(pts, monoX);
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 22b073d..c814fa4 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -311,7 +311,7 @@
     SkDEBUGCODE(int moveCnt = 0;)
     SkDEBUGCODE(int closeCount = 0;)
 
-    while ((verb = iter.next(pts, true, true)) != kDone_Verb) {
+    while ((verb = iter.next(pts)) != kDone_Verb) {
         int nextPt = -1;
         switch (verb) {
             case kMove_Verb:
@@ -320,20 +320,26 @@
                 firstPt = prevPt = pts[0];
                 break;
             case kLine_Verb:
-                nextPt = 1;
-                SkASSERT(moveCnt && !closeCount);
-                ++segmentCount;
+                if (!SkPathPriv::AllPointsEq(pts, 2)) {
+                    nextPt = 1;
+                    SkASSERT(moveCnt && !closeCount);
+                    ++segmentCount;
+                }
                 break;
             case kQuad_Verb:
             case kConic_Verb:
-                SkASSERT(moveCnt && !closeCount);
-                ++segmentCount;
-                nextPt = 2;
+                if (!SkPathPriv::AllPointsEq(pts, 3)) {
+                    SkASSERT(moveCnt && !closeCount);
+                    ++segmentCount;
+                    nextPt = 2;
+                }
                 break;
             case kCubic_Verb:
-                SkASSERT(moveCnt && !closeCount);
-                ++segmentCount;
-                nextPt = 3;
+                if (!SkPathPriv::AllPointsEq(pts, 4)) {
+                    SkASSERT(moveCnt && !closeCount);
+                    ++segmentCount;
+                    nextPt = 3;
+                }
                 break;
             case kClose_Verb:
                 SkDEBUGCODE(++closeCount;)
@@ -1837,7 +1843,7 @@
         SkPoint         pts[4];
         SkPath::Verb    verb;
 
-        while ((verb = iter.next(pts, false)) != kDone_Verb) {
+        while ((verb = iter.next(pts)) != kDone_Verb) {
             switch (verb) {
                 case kMove_Verb:
                     tmp.moveTo(pts[0]);
@@ -2015,90 +2021,7 @@
     return fPts[-1];
 }
 
-void SkPath::Iter::consumeDegenerateSegments(bool exact) {
-    // We need to step over anything that will not move the current draw point
-    // forward before the next move is seen
-    const uint8_t* lastMoveVerb = nullptr;
-    const SkPoint* lastMovePt = nullptr;
-    const SkScalar* lastMoveWeight = nullptr;
-    SkPoint lastPt = fLastPt;
-    while (fVerbs != fVerbStop) {
-        unsigned verb = *(fVerbs - 1); // fVerbs is one beyond the current verb
-        switch (verb) {
-            case kMove_Verb:
-                // Keep a record of this most recent move
-                lastMoveVerb = fVerbs;
-                lastMovePt = fPts;
-                lastMoveWeight = fConicWeights;
-                lastPt = fPts[0];
-                fVerbs--;
-                fPts++;
-                break;
-
-            case kClose_Verb:
-                // A close when we are in a segment is always valid except when it
-                // follows a move which follows a segment.
-                if (fSegmentState == kAfterPrimitive_SegmentState && !lastMoveVerb) {
-                    return;
-                }
-                // A close at any other time must be ignored
-                fVerbs--;
-                break;
-
-            case kLine_Verb:
-                if (!IsLineDegenerate(lastPt, fPts[0], exact)) {
-                    if (lastMoveVerb) {
-                        fVerbs = lastMoveVerb;
-                        fPts = lastMovePt;
-                        fConicWeights = lastMoveWeight;
-                        return;
-                    }
-                    return;
-                }
-                // Ignore this line and continue
-                fVerbs--;
-                fPts++;
-                break;
-
-            case kConic_Verb:
-            case kQuad_Verb:
-                if (!IsQuadDegenerate(lastPt, fPts[0], fPts[1], exact)) {
-                    if (lastMoveVerb) {
-                        fVerbs = lastMoveVerb;
-                        fPts = lastMovePt;
-                        fConicWeights = lastMoveWeight;
-                        return;
-                    }
-                    return;
-                }
-                // Ignore this line and continue
-                fVerbs--;
-                fPts += 2;
-                fConicWeights += (kConic_Verb == verb);
-                break;
-
-            case kCubic_Verb:
-                if (!IsCubicDegenerate(lastPt, fPts[0], fPts[1], fPts[2], exact)) {
-                    if (lastMoveVerb) {
-                        fVerbs = lastMoveVerb;
-                        fPts = lastMovePt;
-                        fConicWeights = lastMoveWeight;
-                        return;
-                    }
-                    return;
-                }
-                // Ignore this line and continue
-                fVerbs--;
-                fPts += 3;
-                break;
-
-            default:
-                SkDEBUGFAIL("Should never see kDone_Verb");
-        }
-    }
-}
-
-SkPath::Verb SkPath::Iter::doNext(SkPoint ptsParam[4]) {
+SkPath::Verb SkPath::Iter::next(SkPoint ptsParam[4]) {
     SkASSERT(ptsParam);
 
     if (fVerbs == fVerbStop) {
@@ -2231,7 +2154,7 @@
     };
     builder.printf("path.setFillType(SkPath::k%s_FillType);\n",
             gFillTypeStrs[(int) this->getFillType()]);
-    while ((verb = iter.next(pts, false)) != kDone_Verb) {
+    while ((verb = iter.next(pts)) != kDone_Verb) {
         switch (verb) {
             case kMove_Verb:
                 append_params(&builder, "path.moveTo", &pts[0], 1, asType);
@@ -2780,7 +2703,7 @@
         const SkPoint* points = fPathRef->points();
         const SkPoint* last = &points[pointCount];
         // only consider the last of the initial move tos
-        while (SkPath::kMove_Verb == iter.next(pts, false, false)) {
+        while (SkPath::kMove_Verb == iter.next(pts)) {
             ++points;
         }
         --points;
@@ -2805,7 +2728,7 @@
         return setComputedConvexity(SkPath::kConcave_Convexity);
     };
 
-    while ((verb = iter.next(pts, false, false)) != SkPath::kDone_Verb) {
+    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
         switch (verb) {
             case kMove_Verb:
                 if (++contourCount > 1) {
@@ -3556,7 +3479,7 @@
     int onCurveCount = 0;
     do {
         SkPoint pts[4];
-        switch (iter.next(pts, false)) {
+        switch (iter.next(pts)) {
             case SkPath::kMove_Verb:
             case SkPath::kClose_Verb:
                 break;
@@ -3599,7 +3522,7 @@
     do {
         SkPoint pts[4];
         int oldCount = tangents.count();
-        switch (iter.next(pts, false)) {
+        switch (iter.next(pts)) {
             case SkPath::kMove_Verb:
             case SkPath::kClose_Verb:
                 break;
diff --git a/src/core/SkPathPriv.h b/src/core/SkPathPriv.h
index d293a23..28f5a15 100644
--- a/src/core/SkPathPriv.h
+++ b/src/core/SkPathPriv.h
@@ -272,6 +272,15 @@
         SkRect tmp;
         return (path.fPathRef->fIsRRect | path.fPathRef->fIsOval) || path.isRect(&tmp);
     }
+
+    static bool AllPointsEq(const SkPoint pts[], int count) {
+        for (int i = 1; i < count; ++i) {
+            if (pts[0] != pts[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
 };
 
 #endif
diff --git a/src/core/SkRegion_path.cpp b/src/core/SkRegion_path.cpp
index e877c8c..022a84c 100644
--- a/src/core/SkRegion_path.cpp
+++ b/src/core/SkRegion_path.cpp
@@ -281,7 +281,7 @@
     SkScalar    top = SkIntToScalar(SK_MaxS16);
     SkScalar    bot = SkIntToScalar(SK_MinS16);
 
-    while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
+    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
         maxEdges += verb_to_max_edges(verb);
 
         int lastIndex = verb_to_initial_last_index(verb);
diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp
index e37c68c..ecfefdf 100644
--- a/src/core/SkStroke.cpp
+++ b/src/core/SkStroke.cpp
@@ -1415,7 +1415,7 @@
 
     for (;;) {
         SkPoint  pts[4];
-        switch (iter.next(pts, false)) {
+        switch (iter.next(pts)) {
             case SkPath::kMove_Verb:
                 stroker.moveTo(pts[0]);
                 break;
diff --git a/src/effects/SkCornerPathEffect.cpp b/src/effects/SkCornerPathEffect.cpp
index 3a5cfb4..16670e5 100644
--- a/src/effects/SkCornerPathEffect.cpp
+++ b/src/effects/SkCornerPathEffect.cpp
@@ -57,7 +57,7 @@
     lastCorner.set(0, 0);
 
     for (;;) {
-        switch (verb = iter.next(pts, false)) {
+        switch (verb = iter.next(pts)) {
             case SkPath::kMove_Verb:
                 // close out the previous (open) contour
                 if (SkPath::kLine_Verb == prevVerb) {
diff --git a/src/gpu/GrTessellator.cpp b/src/gpu/GrTessellator.cpp
index ef15483..ced0498 100644
--- a/src/gpu/GrTessellator.cpp
+++ b/src/gpu/GrTessellator.cpp
@@ -818,7 +818,7 @@
     }
     SkAutoConicToQuads converter;
     SkPath::Verb verb;
-    while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
+    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
         switch (verb) {
             case SkPath::kConic_Verb: {
                 SkScalar weight = iter.conicWeight();
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index c3bfd8f..64911cc 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -125,7 +125,7 @@
     // Iterate here to consume any degenerate contours and only process the points
     // on the actual convex contour.
     int n = 0;
-    while ((verb = iter.next(pts, true, true)) != SkPath::kDone_Verb) {
+    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
         switch (verb) {
             case SkPath::kMove_Verb:
                 SkASSERT(n == 0);
@@ -135,17 +135,19 @@
                 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;
+                if (pts[0] != pts[1]) {
+                    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;
+                    }
+                    edges[3 * n + 2] = -(edges[3 * n] * pts[1].fX + edges[3 * n + 1] * pts[1].fY);
+                    ++n;
                 }
-                edges[3 * n + 2] = -(edges[3 * n] * pts[1].fX + edges[3 * n + 1] * pts[1].fY);
-                ++n;
                 break;
             }
             default:
diff --git a/src/gpu/geometry/GrPathUtils.cpp b/src/gpu/geometry/GrPathUtils.cpp
index 3da6e13..0b3dd23 100644
--- a/src/gpu/geometry/GrPathUtils.cpp
+++ b/src/gpu/geometry/GrPathUtils.cpp
@@ -175,7 +175,7 @@
     SkPath::Verb verb;
 
     SkPoint pts[4];
-    while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
+    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
 
         switch (verb) {
             case SkPath::kLine_Verb:
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index 5944aef..5021aa7 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -289,42 +289,50 @@
 
     for (;;) {
         SkPoint pts[4];
-        SkPath::Verb verb = iter.next(pts, true, true);
+        SkPath::Verb verb = iter.next(pts);
         switch (verb) {
             case SkPath::kMove_Verb:
                 m.mapPoints(pts, 1);
                 update_degenerate_test(&degenerateData, pts[0]);
                 break;
             case SkPath::kLine_Verb: {
-                m.mapPoints(&pts[1], 1);
-                update_degenerate_test(&degenerateData, pts[1]);
-                add_line_to_segment(pts[1], segments);
+                if (!SkPathPriv::AllPointsEq(pts, 2)) {
+                    m.mapPoints(&pts[1], 1);
+                    update_degenerate_test(&degenerateData, pts[1]);
+                    add_line_to_segment(pts[1], segments);
+                }
                 break;
             }
             case SkPath::kQuad_Verb:
-                m.mapPoints(pts, 3);
-                update_degenerate_test(&degenerateData, pts[1]);
-                update_degenerate_test(&degenerateData, pts[2]);
-                add_quad_segment(pts, segments);
+                if (!SkPathPriv::AllPointsEq(pts, 3)) {
+                    m.mapPoints(pts, 3);
+                    update_degenerate_test(&degenerateData, pts[1]);
+                    update_degenerate_test(&degenerateData, pts[2]);
+                    add_quad_segment(pts, segments);
+                }
                 break;
             case SkPath::kConic_Verb: {
-                m.mapPoints(pts, 3);
-                SkScalar weight = iter.conicWeight();
-                SkAutoConicToQuads converter;
-                const SkPoint* quadPts = converter.computeQuads(pts, weight, 0.25f);
-                for (int i = 0; i < converter.countQuads(); ++i) {
-                    update_degenerate_test(&degenerateData, quadPts[2*i + 1]);
-                    update_degenerate_test(&degenerateData, quadPts[2*i + 2]);
-                    add_quad_segment(quadPts + 2*i, segments);
+                if (!SkPathPriv::AllPointsEq(pts, 3)) {
+                    m.mapPoints(pts, 3);
+                    SkScalar weight = iter.conicWeight();
+                    SkAutoConicToQuads converter;
+                    const SkPoint* quadPts = converter.computeQuads(pts, weight, 0.25f);
+                    for (int i = 0; i < converter.countQuads(); ++i) {
+                        update_degenerate_test(&degenerateData, quadPts[2*i + 1]);
+                        update_degenerate_test(&degenerateData, quadPts[2*i + 2]);
+                        add_quad_segment(quadPts + 2*i, segments);
+                    }
                 }
                 break;
             }
             case SkPath::kCubic_Verb: {
-                m.mapPoints(pts, 4);
-                update_degenerate_test(&degenerateData, pts[1]);
-                update_degenerate_test(&degenerateData, pts[2]);
-                update_degenerate_test(&degenerateData, pts[3]);
-                add_cubic_segments(pts, dir, segments);
+                if (!SkPathPriv::AllPointsEq(pts, 4)) {
+                    m.mapPoints(pts, 4);
+                    update_degenerate_test(&degenerateData, pts[1]);
+                    update_degenerate_test(&degenerateData, pts[2]);
+                    update_degenerate_test(&degenerateData, pts[3]);
+                    add_cubic_segments(pts, dir, segments);
+                }
                 break;
             }
             case SkPath::kDone_Verb:
diff --git a/src/gpu/ops/GrAAConvexTessellator.cpp b/src/gpu/ops/GrAAConvexTessellator.cpp
index 5e545d4..0e753a1 100644
--- a/src/gpu/ops/GrAAConvexTessellator.cpp
+++ b/src/gpu/ops/GrAAConvexTessellator.cpp
@@ -394,19 +394,27 @@
     SkPath::Iter iter(path, true);
     SkPoint pts[4];
     SkPath::Verb verb;
-    while ((verb = iter.next(pts, true, true)) != SkPath::kDone_Verb) {
+    while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
         switch (verb) {
             case SkPath::kLine_Verb:
-                this->lineTo(m, pts[1], kSharp_CurveState);
+                if (!SkPathPriv::AllPointsEq(pts, 2)) {
+                    this->lineTo(m, pts[1], kSharp_CurveState);
+                }
                 break;
             case SkPath::kQuad_Verb:
-                this->quadTo(m, pts);
+                if (!SkPathPriv::AllPointsEq(pts, 3)) {
+                    this->quadTo(m, pts);
+                }
                 break;
             case SkPath::kCubic_Verb:
-                this->cubicTo(m, pts);
+                if (!SkPathPriv::AllPointsEq(pts, 4)) {
+                    this->cubicTo(m, pts);
+                }
                 break;
             case SkPath::kConic_Verb:
-                this->conicTo(m, pts, iter.conicWeight());
+                if (!SkPathPriv::AllPointsEq(pts, 3)) {
+                    this->conicTo(m, pts, iter.conicWeight());
+                }
                 break;
             case SkPath::kMove_Verb:
             case SkPath::kClose_Verb:
diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
index 6b054f8..748946b 100644
--- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
@@ -312,7 +312,7 @@
 
     for (;;) {
         SkPoint pathPts[4];
-        SkPath::Verb verb = iter.next(pathPts, false);
+        SkPath::Verb verb = iter.next(pathPts);
         switch (verb) {
             case SkPath::kConic_Verb:
                 if (convertConicsToQuads) {
diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp
index 2c4db58..f31e7e9 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.cpp
+++ b/src/gpu/ops/GrDefaultPathRenderer.cpp
@@ -151,7 +151,7 @@
 
         bool done = false;
         while (!done) {
-            SkPath::Verb verb = iter.next(pts, false);
+            SkPath::Verb verb = iter.next(pts);
             switch (verb) {
                 case SkPath::kMove_Verb:
                     this->moveTo(pts[0]);
@@ -183,7 +183,7 @@
         SkPath::Verb verb;
 
         SkPoint pts[4];
-        while ((verb = iter.next(pts, false)) != SkPath::kDone_Verb) {
+        while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
             if (SkPath::kMove_Verb == verb && !first) {
                 return true;
             }
diff --git a/src/pdf/SkPDFUtils.cpp b/src/pdf/SkPDFUtils.cpp
index cc6db75..9beedfb 100644
--- a/src/pdf/SkPDFUtils.cpp
+++ b/src/pdf/SkPDFUtils.cpp
@@ -12,6 +12,7 @@
 #include "include/core/SkString.h"
 #include "include/private/SkFixed.h"
 #include "src/core/SkGeometry.h"
+#include "src/core/SkPathPriv.h"
 #include "src/image/SkImage_Base.h"
 #include "src/pdf/SkPDFResourceDict.h"
 #include "src/pdf/SkPDFTypes.h"
@@ -150,9 +151,9 @@
     SkDynamicMemoryWStream currentSegment;
     SkPoint args[4];
     SkPath::Iter iter(path, false);
-    for (SkPath::Verb verb = iter.next(args, doConsumeDegerates);
+    for (SkPath::Verb verb = iter.next(args);
          verb != SkPath::kDone_Verb;
-         verb = iter.next(args, doConsumeDegerates)) {
+         verb = iter.next(args)) {
         // args gets all the points, even the implicit first point.
         switch (verb) {
             case SkPath::kMove_Verb:
@@ -161,29 +162,37 @@
                 fillState = kEmpty_SkipFillState;
                 break;
             case SkPath::kLine_Verb:
-                AppendLine(args[1].fX, args[1].fY, &currentSegment);
-                if ((fillState == kEmpty_SkipFillState) && (args[0] != lastMovePt)) {
-                    fillState = kSingleLine_SkipFillState;
-                    break;
+                if (!doConsumeDegerates || !SkPathPriv::AllPointsEq(args, 2)) {
+                    AppendLine(args[1].fX, args[1].fY, &currentSegment);
+                    if ((fillState == kEmpty_SkipFillState) && (args[0] != lastMovePt)) {
+                        fillState = kSingleLine_SkipFillState;
+                        break;
+                    }
+                    fillState = kNonSingleLine_SkipFillState;
                 }
-                fillState = kNonSingleLine_SkipFillState;
                 break;
             case SkPath::kQuad_Verb:
-                append_quad(args, &currentSegment);
-                fillState = kNonSingleLine_SkipFillState;
-                break;
-            case SkPath::kConic_Verb: {
-                SkAutoConicToQuads converter;
-                const SkPoint* quads = converter.computeQuads(args, iter.conicWeight(), tolerance);
-                for (int i = 0; i < converter.countQuads(); ++i) {
-                    append_quad(&quads[i * 2], &currentSegment);
+                if (!doConsumeDegerates || !SkPathPriv::AllPointsEq(args, 3)) {
+                    append_quad(args, &currentSegment);
+                    fillState = kNonSingleLine_SkipFillState;
                 }
-                fillState = kNonSingleLine_SkipFillState;
-            } break;
+                break;
+            case SkPath::kConic_Verb:
+                if (!doConsumeDegerates || !SkPathPriv::AllPointsEq(args, 3)) {
+                    SkAutoConicToQuads converter;
+                    const SkPoint* quads = converter.computeQuads(args, iter.conicWeight(), tolerance);
+                    for (int i = 0; i < converter.countQuads(); ++i) {
+                        append_quad(&quads[i * 2], &currentSegment);
+                    }
+                    fillState = kNonSingleLine_SkipFillState;
+                }
+                break;
             case SkPath::kCubic_Verb:
-                append_cubic(args[1].fX, args[1].fY, args[2].fX, args[2].fY,
-                             args[3].fX, args[3].fY, &currentSegment);
-                fillState = kNonSingleLine_SkipFillState;
+                if (!doConsumeDegerates || !SkPathPriv::AllPointsEq(args, 4)) {
+                    append_cubic(args[1].fX, args[1].fY, args[2].fX, args[2].fY,
+                                 args[3].fX, args[3].fY, &currentSegment);
+                    fillState = kNonSingleLine_SkipFillState;
+                }
                 break;
             case SkPath::kClose_Verb:
                 ClosePath(&currentSegment);
diff --git a/src/utils/SkLua.cpp b/src/utils/SkLua.cpp
index 1b324be..b217563 100644
--- a/src/utils/SkLua.cpp
+++ b/src/utils/SkLua.cpp
@@ -1372,7 +1372,7 @@
     bool done = false;
     int i = 0;
     do {
-        switch (iter.next(pts, true)) {
+        switch (iter.next(pts)) {
             case SkPath::kMove_Verb:
                 setarray_string(L, ++i, "move");
                 break;
diff --git a/src/utils/SkParsePath.cpp b/src/utils/SkParsePath.cpp
index 6ad3aa0..8c9469b 100644
--- a/src/utils/SkParsePath.cpp
+++ b/src/utils/SkParsePath.cpp
@@ -236,7 +236,7 @@
     SkPoint         pts[4];
 
     for (;;) {
-        switch (iter.next(pts, false)) {
+        switch (iter.next(pts)) {
             case SkPath::kConic_Verb: {
                 const SkScalar tol = SK_Scalar1 / 1024; // how close to a quad
                 SkAutoConicToQuads quadder;