use pathbuilder

Change-Id: I2bca419a3273a9cc8a984b0f4159f518968c6652
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/313077
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/bench/BigPathBench.cpp b/bench/BigPathBench.cpp
index 02f4203..f3c5948 100644
--- a/bench/BigPathBench.cpp
+++ b/bench/BigPathBench.cpp
@@ -42,7 +42,7 @@
         return SkIPoint::Make(640, 100);
     }
 
-    void onDelayedSetup() override { ToolUtils::make_big_path(fPath); }
+    void onDelayedSetup() override { fPath = ToolUtils::make_big_path(); }
 
     void onDraw(int loops, SkCanvas* canvas) override {
         SkPaint paint;
diff --git a/gm/aaa.cpp b/gm/aaa.cpp
index b6d869f..edb77e9 100644
--- a/gm/aaa.cpp
+++ b/gm/aaa.cpp
@@ -121,16 +121,14 @@
     // column where the left rect and the right rect abut.
     p.setStyle(SkPaint::kFill_Style);
     canvas->translate(0, 300);
-    path.reset();
-    path.addRect({20, 20, 100.4999f, 100});
-    path.addRect({100.5001f, 20, 200, 100});
-    canvas->drawPath(path, p);
+    canvas->drawPath(SkPathBuilder().addRect({20, 20, 100.4999f, 100})
+                                    .addRect({100.5001f, 20, 200, 100})
+                                    .detach(), p);
 
     canvas->translate(300, 0);
-    path.reset();
-    path.addRect({20, 20, 100.1f, 100});
-    path.addRect({100.9f, 20, 200, 100});
-    canvas->drawPath(path, p);
+    canvas->drawPath(SkPathBuilder().addRect({20, 20, 100.1f, 100})
+                                    .addRect({100.9f, 20, 200, 100})
+                                    .detach(), p);
 }
 
 DEF_SIMPLE_GM(analytic_antialias_inverse, canvas, W, H) {
diff --git a/gm/addarc.cpp b/gm/addarc.cpp
index 3f4d578..b04bf21 100644
--- a/gm/addarc.cpp
+++ b/gm/addarc.cpp
@@ -9,7 +9,6 @@
 #include "include/core/SkCanvas.h"
 #include "include/core/SkColor.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
 #include "include/core/SkPathBuilder.h"
 #include "include/core/SkPathMeasure.h"
 #include "include/core/SkPoint.h"
@@ -54,9 +53,9 @@
             SkScalar speed = SkScalarSqrt(16 / r.width()) * 0.5f;
             startAngle += fRotate * 360 * speed * sign;
 
-            SkPath path;
+            SkPathBuilder path;
             path.addArc(r, startAngle, sweepAngle);
-            canvas->drawPath(path, paint);
+            canvas->drawPath(path.detach(), paint);
 
             r.inset(inset, inset);
             sign = -sign;
@@ -99,9 +98,7 @@
 
             canvas->drawLine(0, 0, rx, ry, paint);
 
-            SkPath path;
-            path.addArc(oval, 0, deg);
-            SkPathMeasure meas(path, false);
+            SkPathMeasure meas(SkPathBuilder().addArc(oval, 0, deg).detach(), false);
             SkScalar arcLen = rad * R;
             SkPoint pos;
             if (meas.getPosTan(arcLen, &pos, nullptr)) {
diff --git a/gm/bigblurs.cpp b/gm/bigblurs.cpp
index 95f97ff..09e94dc 100644
--- a/gm/bigblurs.cpp
+++ b/gm/bigblurs.cpp
@@ -11,7 +11,7 @@
 #include "include/core/SkColor.h"
 #include "include/core/SkMaskFilter.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/core/SkPoint.h"
 #include "include/core/SkRect.h"
 #include "include/core/SkScalar.h"
@@ -49,10 +49,9 @@
         SkRect insetRect = bigRect;
         insetRect.inset(20, 20);
 
-        SkPath rectori;
-
-        rectori.addRect(bigRect);
-        rectori.addRect(insetRect, SkPathDirection::kCCW);
+        SkPath rectori = SkPathBuilder().addRect(bigRect)
+                                        .addRect(insetRect, SkPathDirection::kCCW)
+                                        .detach();
 
         // The blur extends 3*kSigma out from the big rect.
         // Offset the close-up windows so we get the entire blur
diff --git a/gm/bigmatrix.cpp b/gm/bigmatrix.cpp
index 37b092e..d19b049 100644
--- a/gm/bigmatrix.cpp
+++ b/gm/bigmatrix.cpp
@@ -38,14 +38,11 @@
     SkASSERT(success);
     (void)success;  // silence compiler :(
 
-    SkPath path;
-
     SkPoint  pt    = {10 * SK_Scalar1, 10 * SK_Scalar1};
     SkScalar small = 1 / (500 * SK_Scalar1);
 
     m.mapPoints(&pt, 1);
-    path.addCircle(pt.fX, pt.fY, small);
-    canvas->drawPath(path, paint);
+    canvas->drawCircle(pt.fX, pt.fY, small, paint);
 
     pt.set(30 * SK_Scalar1, 10 * SK_Scalar1);
     m.mapPoints(&pt, 1);
diff --git a/gm/bug5252.cpp b/gm/bug5252.cpp
index b323c07..7b3a223 100644
--- a/gm/bug5252.cpp
+++ b/gm/bug5252.cpp
@@ -15,13 +15,9 @@
 DEF_SIMPLE_GM(bug5252, canvas, 500, 500) {
 	canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
 
-	SkPath clip1;
-	clip1.addOval(SkRect::MakeWH(225, 200));
-	canvas->clipPath(clip1); // bug
+	canvas->clipPath(SkPath::Oval(SkRect::MakeWH(225, 200))); // bug
 
-	SkPath clip2;
-	clip2.addRect(SkRect::MakeWH(220, 200));
-	//canvas->clipPath(clip2); // ok
+	//canvas->clipPath(SkPath::Oval(SkRect::MakeWH(220, 200))); // ok
 
 	SkPaint pa;
 	pa.setStyle(SkPaint::kStroke_Style);
diff --git a/gm/bug530095.cpp b/gm/bug530095.cpp
index 8d882fd..1a2a7dc 100644
--- a/gm/bug530095.cpp
+++ b/gm/bug530095.cpp
@@ -16,9 +16,8 @@
 #include "include/effects/SkDashPathEffect.h"
 
 DEF_SIMPLE_GM(bug530095, canvas, 900, 1200) {
-    SkPath path1, path2;
-    path1.addCircle(200, 200, 124);
-    path2.addCircle(2, 2, 1.24f);
+    SkPath path1 = SkPath::Circle(200, 200, 124),
+           path2 = SkPath::Circle(2, 2, 1.24f);
 
     SkPaint paint;
     paint.setAntiAlias(true);
diff --git a/gm/convexpaths.cpp b/gm/convexpaths.cpp
index 0edfc45..18f1cd2 100644
--- a/gm/convexpaths.cpp
+++ b/gm/convexpaths.cpp
@@ -224,7 +224,7 @@
 
         // small circle. This is listed last so that it has device coords far
         // from the origin (small area relative to x,y values).
-        fPaths.push_back().addCircle(0, 0, 1.2f);
+        fPaths.push_back(SkPath::Circle(0, 0, 1.2f));
     }
 
     void onDraw(SkCanvas* canvas) override {
diff --git a/gm/convexpolyclip.cpp b/gm/convexpolyclip.cpp
index f2ea645..8d53b50 100644
--- a/gm/convexpolyclip.cpp
+++ b/gm/convexpolyclip.cpp
@@ -14,7 +14,7 @@
 #include "include/core/SkFontTypes.h"
 #include "include/core/SkMatrix.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/core/SkPoint.h"
 #include "include/core/SkRect.h"
 #include "include/core/SkScalar.h"
@@ -114,14 +114,13 @@
     }
 
     void onOnceBeforeDraw() override {
-        SkPath tri;
-        tri.moveTo(5.f, 5.f);
-        tri.lineTo(100.f, 20.f);
-        tri.lineTo(15.f, 100.f);
+        fClips.addToTail()->setPath(SkPath::Polygon({
+            {  5.f,   5.f},
+            {100.f,  20.f},
+            { 15.f, 100.f},
+        }, false));
 
-        fClips.addToTail()->setPath(tri);
-
-        SkPath hexagon;
+        SkPathBuilder hexagon;
         constexpr SkScalar kRadius = 45.f;
         const SkPoint center = { kRadius, kRadius };
         for (int i = 0; i < 6; ++i) {
@@ -135,22 +134,18 @@
                 hexagon.lineTo(point);
             }
         }
-        fClips.addToTail()->setPath(hexagon);
+        fClips.addToTail()->setPath(hexagon.snapshot());
 
         SkMatrix scaleM;
         scaleM.setScale(1.1f, 0.4f, kRadius, kRadius);
-        hexagon.transform(scaleM);
-        fClips.addToTail()->setPath(hexagon);
+        fClips.addToTail()->setPath(hexagon.detach().makeTransform(scaleM));
 
         fClips.addToTail()->setRect(SkRect::MakeXYWH(8.3f, 11.6f, 78.2f, 72.6f));
 
-        SkPath rotRect;
         SkRect rect = SkRect::MakeLTRB(10.f, 12.f, 80.f, 86.f);
-        rotRect.addRect(rect);
         SkMatrix rotM;
         rotM.setRotate(23.f, rect.centerX(), rect.centerY());
-        rotRect.transform(rotM);
-        fClips.addToTail()->setPath(rotRect);
+        fClips.addToTail()->setPath(SkPath::Rect(rect).makeTransform(rotM));
 
         fBmp = make_bmp(100, 100);
     }
diff --git a/gm/croppedrects.cpp b/gm/croppedrects.cpp
index 94835ee..3a16e27 100644
--- a/gm/croppedrects.cpp
+++ b/gm/croppedrects.cpp
@@ -89,9 +89,9 @@
         {
             // GrRenderTargetContext::fillRectWithLocalMatrix.
             SkAutoCanvasRestore acr(canvas, true);
-            SkPath path;
-            path.moveTo(kSrcImageClip.fLeft - kSrcImageClip.width(), kSrcImageClip.centerY());
-            path.lineTo(kSrcImageClip.fRight + 3 * kSrcImageClip.width(), kSrcImageClip.centerY());
+            SkPath path = SkPath::Line(
+                   {kSrcImageClip.fLeft - kSrcImageClip.width(), kSrcImageClip.centerY()},
+                   {kSrcImageClip.fRight + 3 * kSrcImageClip.width(), kSrcImageClip.centerY()});
             SkPaint paint;
             paint.setStyle(SkPaint::kStroke_Style);
             paint.setStrokeWidth(2 * kSrcImageClip.height());
diff --git a/gm/daa.cpp b/gm/daa.cpp
index 37af912..c914889 100644
--- a/gm/daa.cpp
+++ b/gm/daa.cpp
@@ -10,7 +10,7 @@
 #include "include/core/SkColor.h"
 #include "include/core/SkFont.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/core/SkPoint.h"
 #include "include/core/SkTypes.h"
 
@@ -31,11 +31,11 @@
         paint.setColor(SK_ColorRED);
         canvas->drawRect({0,0,K,K}, paint);
 
-        SkPath path;
         SkPoint tri1[] = {{0,0},{K,K},{0,K},{0,0}};
         SkPoint tri2[] = {{0,0},{K,K},{K,0},{0,0}};
-        path.addPoly(tri1, SK_ARRAY_COUNT(tri1), false);
-        path.addPoly(tri2, SK_ARRAY_COUNT(tri2), false);
+        SkPath path = SkPathBuilder().addPolygon(tri1, SK_ARRAY_COUNT(tri1), false)
+                                     .addPolygon(tri2, SK_ARRAY_COUNT(tri2), false)
+                                     .detach();
 
         paint.setColor(SK_ColorGREEN);
         canvas->drawPath(path, paint);
@@ -51,19 +51,13 @@
         canvas->drawRect({0,0,K,K}, paint);
 
         {
-            SkPath path;
-            SkPoint rect1[] = {{0,0},{0,K},{K*0.5f,K},{K*0.5f,0}};
-            path.addPoly(rect1, SK_ARRAY_COUNT(rect1), false);
-
+            SkPath path = SkPath::Polygon({{0,0},{0,K},{K*0.5f,K},{K*0.5f,0}}, false);
             paint.setColor(SK_ColorBLUE);
             canvas->drawPath(path, paint);
         }
 
         {
-            SkPath path;
-            SkPoint rect2[] = {{K*0.5f,0},{K*0.5f,K},{K,K},{K,0}};
-            path.addPoly(rect2, SK_ARRAY_COUNT(rect2), false);
-
+            SkPath path = SkPath::Polygon({{K*0.5f,0},{K*0.5f,K},{K,K},{K,0}}, false);
             paint.setColor(SK_ColorGREEN);
             canvas->drawPath(path, paint);
         }
@@ -79,12 +73,9 @@
         canvas->drawRect({0,0,K,K}, paint);
 
         {
-            SkPath path;
-            SkPoint rect1[] = {{0,0},{0,K},{K*0.5f,K},{K*0.5f,0}};
-            SkPoint rect2[] = {{K*0.5f,0},{K*0.5f,K},{K,K},{K,0}};
-
-            path.addPoly(rect1, SK_ARRAY_COUNT(rect1), false);
-            path.addPoly(rect2, SK_ARRAY_COUNT(rect2), false);
+            SkPath path = SkPathBuilder().addPolygon({{0,0},{0,K},{K*0.5f,K},{K*0.5f,0}}, false)
+                                         .addPolygon({{K*0.5f,0},{K*0.5f,K},{K,K},{K,0}}, false)
+                                         .detach();
 
             paint.setColor(SK_ColorGREEN);
             canvas->drawPath(path, paint);
@@ -101,12 +92,9 @@
         canvas->drawRect({0,0,K,K}, paint);
 
         {
-            SkPath path;
-            SkPoint rect1[] = {{0,0},{0,K},{K*0.5f,K},{K*0.5f,0}};
-            SkPoint rect2[] = {{K*0.5f,0},{K,0},{K,K},{K*0.5f,K}};
-
-            path.addPoly(rect1, SK_ARRAY_COUNT(rect1), false);
-            path.addPoly(rect2, SK_ARRAY_COUNT(rect2), false);
+            SkPath path = SkPathBuilder().addPolygon({{0,0},{0,K},{K*0.5f,K},{K*0.5f,0}}, false)
+                                         .addPolygon({{K*0.5f,0},{K,0},{K,K},{K*0.5f,K}}, false)
+                                         .detach();
 
             paint.setColor(SK_ColorGREEN);
             canvas->drawPath(path, paint);
@@ -122,14 +110,11 @@
         paint.setColor(SK_ColorRED);
         canvas->drawRect({0,0,K,K}, paint);
 
-        {
-            SkPath path;
-            SkPoint poly[] = {{K*0.5f,0},{0,0},{0,K},{K*0.5f,K},{K*0.5f,0},{K,0},{K,K},{K*0.5f,K}};
+        SkPath path = SkPath::Polygon({{K*0.5f,0},{0,0},{0,K},{K*0.5f,K},
+                                       {K*0.5f,0},{K,0},{K,K},{K*0.5f,K}},
+                                      false);
 
-            path.addPoly(poly, SK_ARRAY_COUNT(poly), false);
-
-            paint.setColor(SK_ColorGREEN);
-            canvas->drawPath(path, paint);
-        }
+        paint.setColor(SK_ColorGREEN);
+        canvas->drawPath(path, paint);
     }
 }
diff --git a/gm/dashcircle.cpp b/gm/dashcircle.cpp
index c6392c1..19a275d 100644
--- a/gm/dashcircle.cpp
+++ b/gm/dashcircle.cpp
@@ -54,8 +54,7 @@
         refPaint.setStrokeWidth(1);
         const SkScalar radius = 125;
         SkRect oval = SkRect::MakeLTRB(-radius - 20, -radius - 20, radius + 20, radius + 20);
-        SkPath circle;
-        circle.addCircle(0, 0, radius);
+        SkPath circle = SkPath::Circle(0, 0, radius);
         SkScalar circumference = radius * SK_ScalarPI * 2;
         int wedges[] = { 6, 12, 36 };
         canvas->translate(radius+20, radius+20);
@@ -250,7 +249,7 @@
 
     canvas->drawCircle(400, 400, 200, p);
 
-    SkPath path;
+    SkPathBuilder path;
     path.moveTo(800, 400);
     path.quadTo(1000, 400, 1000, 600);
     path.quadTo(1000, 800, 800, 800);
@@ -259,9 +258,8 @@
     path.close();
     canvas->translate(350, 150);
     p.setStrokeWidth(320);
-    canvas->drawPath(path, p);
+    canvas->drawPath(path.detach(), p);
 
-    path.reset();
     path.moveTo(800, 400);
     path.cubicTo(900, 400, 1000, 500, 1000, 600);
     path.cubicTo(1000, 700, 900, 800, 800, 800);
@@ -270,5 +268,5 @@
     path.close();
     canvas->translate(-550, 500);
     p.setStrokeWidth(300);
-    canvas->drawPath(path, p);
+    canvas->drawPath(path.detach(), p);
 }
diff --git a/gm/degeneratesegments.cpp b/gm/degeneratesegments.cpp
index 3644138..029ac24 100644
--- a/gm/degeneratesegments.cpp
+++ b/gm/degeneratesegments.cpp
@@ -10,7 +10,7 @@
 #include "include/core/SkColor.h"
 #include "include/core/SkFont.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/core/SkPoint.h"
 #include "include/core/SkRect.h"
 #include "include/core/SkScalar.h"
@@ -34,37 +34,37 @@
 
     SkISize onISize() override { return {896, 930}; }
 
-    typedef SkPoint (*AddSegmentFunc)(SkPath&, SkPoint&);
+    typedef SkPoint (*AddSegmentFunc)(SkPathBuilder&, SkPoint&);
 
     // We need to use explicit commands here, instead of addPath, because we
     // do not want the moveTo that is added at the beginning of a path to
     // appear in the appended path.
-    static SkPoint AddMove(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMove(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         path.moveTo(moveToPt);
         return moveToPt;
     }
 
-    static SkPoint AddMoveClose(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveClose(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         path.moveTo(moveToPt);
         path.close();
         return moveToPt;
     }
 
-    static SkPoint AddDegenLine(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddDegenLine(SkPathBuilder& path, SkPoint& startPt) {
         path.lineTo(startPt);
         return startPt;
     }
 
-    static SkPoint AddMoveDegenLine(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveDegenLine(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         path.moveTo(moveToPt);
         path.lineTo(moveToPt);
         return moveToPt;
     }
 
-    static SkPoint AddMoveDegenLineClose(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveDegenLineClose(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         path.moveTo(moveToPt);
         path.lineTo(moveToPt);
@@ -72,19 +72,19 @@
         return moveToPt;
     }
 
-    static SkPoint AddDegenQuad(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddDegenQuad(SkPathBuilder& path, SkPoint& startPt) {
         path.quadTo(startPt, startPt);
         return startPt;
     }
 
-    static SkPoint AddMoveDegenQuad(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveDegenQuad(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         path.moveTo(moveToPt);
         path.quadTo(moveToPt, moveToPt);
         return moveToPt;
     }
 
-    static SkPoint AddMoveDegenQuadClose(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveDegenQuadClose(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         path.moveTo(moveToPt);
         path.quadTo(moveToPt, moveToPt);
@@ -92,19 +92,19 @@
         return moveToPt;
     }
 
-    static SkPoint AddDegenCubic(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddDegenCubic(SkPathBuilder& path, SkPoint& startPt) {
         path.cubicTo(startPt, startPt, startPt);
         return startPt;
     }
 
-    static SkPoint AddMoveDegenCubic(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveDegenCubic(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         path.moveTo(moveToPt);
         path.cubicTo(moveToPt, moveToPt, moveToPt);
         return moveToPt;
     }
 
-    static SkPoint AddMoveDegenCubicClose(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveDegenCubicClose(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         path.moveTo(moveToPt);
         path.cubicTo(moveToPt, moveToPt, moveToPt);
@@ -112,18 +112,18 @@
         return moveToPt;
     }
 
-    static SkPoint AddClose(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddClose(SkPathBuilder& path, SkPoint& startPt) {
         path.close();
         return startPt;
     }
 
-    static SkPoint AddLine(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddLine(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
         path.lineTo(endPt);
         return endPt;
     }
 
-    static SkPoint AddMoveLine(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveLine(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
         path.moveTo(moveToPt);
@@ -131,7 +131,7 @@
         return endPt;
     }
 
-    static SkPoint AddMoveLineClose(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveLineClose(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
         path.moveTo(moveToPt);
@@ -140,14 +140,14 @@
         return endPt;
     }
 
-    static SkPoint AddQuad(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddQuad(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint midPt = startPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
         SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
         path.quadTo(midPt, endPt);
         return endPt;
     }
 
-    static SkPoint AddMoveQuad(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveQuad(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         SkPoint midPt = moveToPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
         SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
@@ -156,7 +156,7 @@
         return endPt;
     }
 
-    static SkPoint AddMoveQuadClose(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveQuadClose(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         SkPoint midPt = moveToPt + SkPoint::Make(20*SK_Scalar1, 5*SK_Scalar1);
         SkPoint endPt = moveToPt + SkPoint::Make(40*SK_Scalar1, 0);
@@ -166,7 +166,7 @@
         return endPt;
     }
 
-    static SkPoint AddCubic(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddCubic(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint t1Pt = startPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
         SkPoint t2Pt = startPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
         SkPoint endPt = startPt + SkPoint::Make(40*SK_Scalar1, 0);
@@ -174,7 +174,7 @@
         return endPt;
     }
 
-    static SkPoint AddMoveCubic(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveCubic(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         SkPoint t1Pt = moveToPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
         SkPoint t2Pt = moveToPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
@@ -184,7 +184,7 @@
         return endPt;
     }
 
-    static SkPoint AddMoveCubicClose(SkPath& path, SkPoint& startPt) {
+    static SkPoint AddMoveCubicClose(SkPathBuilder& path, SkPoint& startPt) {
         SkPoint moveToPt = startPt + SkPoint::Make(0, 10*SK_Scalar1);
         SkPoint t1Pt = moveToPt + SkPoint::Make(15*SK_Scalar1, 5*SK_Scalar1);
         SkPoint t2Pt = moveToPt + SkPoint::Make(25*SK_Scalar1, 5*SK_Scalar1);
@@ -195,7 +195,7 @@
         return endPt;
     }
 
-    void drawPath(SkPath& path, SkCanvas* canvas, SkColor color,
+    void drawPath(SkPath path, SkCanvas* canvas, SkColor color,
                   const SkRect& clip, SkPaint::Cap cap, SkPaint::Join join,
                   SkPaint::Style style, SkPathFillType fill,
                   SkScalar strokeWidth) {
@@ -322,20 +322,20 @@
                 StyleAndName style = gStyles[(rand.nextU() >> 16) % numStyles];
                 CapAndName cap = gCaps[(rand.nextU() >> 16) % numCaps];
                 FillAndName fill = gFills[(rand.nextU() >> 16) % numFills];
-                SkPath path;
                 unsigned s1 = (rand.nextU() >> 16) % numSegments;
                 unsigned s2 = (rand.nextU() >> 16) % numSegments;
                 unsigned s3 = (rand.nextU() >> 16) % numSegments;
                 unsigned s4 = (rand.nextU() >> 16) % numSegments;
                 unsigned s5 = (rand.nextU() >> 16) % numSegments;
                 SkPoint pt = SkPoint::Make(10*SK_Scalar1, 0);
+                SkPathBuilder path;
                 pt = gSegmentFunctions[s1](path, pt);
                 pt = gSegmentFunctions[s2](path, pt);
                 pt = gSegmentFunctions[s3](path, pt);
                 pt = gSegmentFunctions[s4](path, pt);
                 pt = gSegmentFunctions[s5](path, pt);
 
-                this->drawPath(path, canvas, color, rect,
+                this->drawPath(path.detach(), canvas, color, rect,
                                cap.fCap, cap.fJoin, style.fStyle,
                                fill.fFill, SK_Scalar1*6);
 
diff --git a/gm/distantclip.cpp b/gm/distantclip.cpp
index 3c84653..a21567e 100644
--- a/gm/distantclip.cpp
+++ b/gm/distantclip.cpp
@@ -37,9 +37,7 @@
         rec->drawColor(SK_ColorRED);
         rec->save();
         SkRect r = SkRect::MakeXYWH(-kExtents, kOffset - kExtents, 2 * kExtents, 2 * kExtents);
-        SkPath p;
-        p.addRoundRect(r, 5, 5);
-        rec->clipPath(p, true);
+        rec->clipPath(SkPath::RRect(r, 5, 5), true);
         rec->drawColor(SK_ColorGREEN);
         rec->restore();
         sk_sp<SkPicture> pict(recorder.finishRecordingAsPicture());
diff --git a/gm/filltypes.cpp b/gm/filltypes.cpp
index 5aaa50e..5f547b9 100644
--- a/gm/filltypes.cpp
+++ b/gm/filltypes.cpp
@@ -9,7 +9,7 @@
 #include "include/core/SkCanvas.h"
 #include "include/core/SkColor.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/core/SkRect.h"
 #include "include/core/SkScalar.h"
 #include "include/core/SkSize.h"
@@ -27,8 +27,9 @@
     void makePath() {
         if (fPath.isEmpty()) {
             const SkScalar radius = SkIntToScalar(45);
-            fPath.addCircle(SkIntToScalar(50), SkIntToScalar(50), radius);
-            fPath.addCircle(SkIntToScalar(100), SkIntToScalar(100), radius);
+            fPath = SkPathBuilder().addCircle(SkIntToScalar(50), SkIntToScalar(50), radius)
+                                   .addCircle(SkIntToScalar(100), SkIntToScalar(100), radius)
+                                   .detach();
         }
     }
 
diff --git a/gm/filltypespersp.cpp b/gm/filltypespersp.cpp
index c396fb8..6ea8ec0 100644
--- a/gm/filltypespersp.cpp
+++ b/gm/filltypespersp.cpp
@@ -10,7 +10,7 @@
 #include "include/core/SkColor.h"
 #include "include/core/SkMatrix.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/core/SkPoint.h"
 #include "include/core/SkRect.h"
 #include "include/core/SkScalar.h"
@@ -31,8 +31,9 @@
     void makePath() {
         if (fPath.isEmpty()) {
             const SkScalar radius = SkIntToScalar(45);
-            fPath.addCircle(SkIntToScalar(50), SkIntToScalar(50), radius);
-            fPath.addCircle(SkIntToScalar(100), SkIntToScalar(100), radius);
+            fPath = SkPathBuilder().addCircle(SkIntToScalar(50), SkIntToScalar(50), radius)
+                                   .addCircle(SkIntToScalar(100), SkIntToScalar(100), radius)
+                                   .detach();
         }
     }
 
diff --git a/gm/nested.cpp b/gm/nested.cpp
index 81b92f2..67390ad 100644
--- a/gm/nested.cpp
+++ b/gm/nested.cpp
@@ -9,7 +9,7 @@
 #include "include/core/SkCanvas.h"
 #include "include/core/SkColor.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/core/SkRRect.h"
 #include "include/core/SkRect.h"
 #include "include/core/SkScalar.h"
@@ -53,19 +53,19 @@
         kShapeCount
     };
 
-    static void AddShape(SkPath* path, const SkRect& rect, Shapes shape, SkPathDirection dir) {
+    static void AddShape(SkPathBuilder* b, const SkRect& rect, Shapes shape, SkPathDirection dir) {
         switch (shape) {
             case kRect_Shape:
-                path->addRect(rect, dir);
+                b->addRect(rect, dir);
                 break;
             case kRRect_Shape: {
                 SkRRect rr;
                 rr.setRectXY(rect, 5, 5);
-                path->addRRect(rr, dir);
+                b->addRRect(rr, dir);
                 break;
                 }
             case kOval_Shape:
-                path->addOval(rect, dir);
+                b->addOval(rect, dir);
                 break;
             default:
                 break;
@@ -103,10 +103,10 @@
         for (int outerShape = 0; outerShape < kShapeCount; ++outerShape) {
             for (int innerShape = 0; innerShape < kShapeCount; ++innerShape) {
                 for (size_t innerRect = 0; innerRect < SK_ARRAY_COUNT(innerRects); ++innerRect) {
-                    SkPath path;
+                    SkPathBuilder builder;
 
-                    AddShape(&path, outerRect, (Shapes) outerShape, SkPathDirection::kCW);
-                    AddShape(&path, innerRects[innerRect], (Shapes) innerShape,
+                    AddShape(&builder, outerRect, (Shapes) outerShape, SkPathDirection::kCW);
+                    AddShape(&builder, innerRects[innerRect], (Shapes) innerShape,
                              SkPathDirection::kCCW);
 
                     canvas->save();
@@ -117,7 +117,7 @@
                         canvas->translate(xOff, yOff);
                     }
 
-                    canvas->drawPath(path, shapePaint);
+                    canvas->drawPath(builder.detach(), shapePaint);
                     canvas->restore();
 
                     xOff += 45;
diff --git a/gm/nonclosedpaths.cpp b/gm/nonclosedpaths.cpp
index 168b2fc..67d94c6 100644
--- a/gm/nonclosedpaths.cpp
+++ b/gm/nonclosedpaths.cpp
@@ -8,7 +8,7 @@
 #include "gm/gm.h"
 #include "include/core/SkCanvas.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/core/SkScalar.h"
 #include "include/core/SkSize.h"
 #include "include/core/SkString.h"
@@ -49,20 +49,22 @@
 
     // Use rect-like geometry for non-closed path, for right angles make it
     // easier to show the visual difference of lineCap and lineJoin.
-    static void MakePath(SkPath* path, ClosureType type) {
+    static SkPath MakePath(ClosureType type) {
+        SkPathBuilder path;
         if (FakeCloseMiddle == type) {
-            path->moveTo(30, 50);
-            path->lineTo(30, 30);
+            path.moveTo(30, 50);
+            path.lineTo(30, 30);
         } else {
-            path->moveTo(30, 30);
+            path.moveTo(30, 30);
         }
-        path->lineTo(70, 30);
-        path->lineTo(70, 70);
-        path->lineTo(30, 70);
-        path->lineTo(30, 50);
+        path.lineTo(70, 30);
+        path.lineTo(70, 70);
+        path.lineTo(30, 70);
+        path.lineTo(30, 50);
         if (FakeCloseCorner == type) {
-            path->lineTo(30, 30);
+            path.lineTo(30, 30);
         }
+        return path.detach();
     }
 
     // Set the location for the current test on the canvas
@@ -108,8 +110,7 @@
                             canvas->save();
                             SetLocation(canvas, counter, SkPaint::kJoinCount * numWidths);
 
-                            SkPath path;
-                            MakePath(&path, kType[type]);
+                            SkPath path = MakePath(kType[type]);
 
                             paint.setStyle(kStyle[style]);
                             paint.setStrokeCap(kCap[cap]);
@@ -131,8 +132,7 @@
             canvas->save();
             SetLocation(canvas, counter, SkPaint::kJoinCount * numWidths);
 
-            SkPath path;
-            MakePath(&path, kType[type]);
+            SkPath path = MakePath(kType[type]);
 
             canvas->drawPath(path, paint);
             canvas->restore();
diff --git a/gm/pathcontourstart.cpp b/gm/pathcontourstart.cpp
index 7d3ff48..1a7d3b3 100644
--- a/gm/pathcontourstart.cpp
+++ b/gm/pathcontourstart.cpp
@@ -56,9 +56,7 @@
     void onDraw(SkCanvas* canvas) override {
 
         drawDirs(canvas, [](const SkRect& rect, SkPathDirection dir, unsigned startIndex) {
-            SkPath path;
-            path.addRect(rect, dir, startIndex);
-            return path;
+            return SkPath::Rect(rect, dir, startIndex);
         });
 
         drawDirs(canvas, [](const SkRect& rect, SkPathDirection dir, unsigned startIndex) {
diff --git a/gm/pathfill.cpp b/gm/pathfill.cpp
index 246332a..578edad 100644
--- a/gm/pathfill.cpp
+++ b/gm/pathfill.cpp
@@ -167,136 +167,118 @@
     };
 }
 
-static void make_info(SkPath* path) {
-    path->moveTo(24, 4);
-    path->cubicTo(12.94999980926514f,
-                  4,
-                  4,
-                  12.94999980926514f,
-                  4,
-                  24);
-    path->cubicTo(4,
-                  35.04999923706055f,
-                  12.94999980926514f,
-                  44,
-                  24,
-                  44);
-    path->cubicTo(35.04999923706055f,
-                  44,
-                  44,
-                  35.04999923706055f,
-                  44,
-                  24);
-    path->cubicTo(44,
-                  12.95000076293945f,
-                  35.04999923706055f,
-                  4,
-                  24,
-                  4);
-    path->close();
-    path->moveTo(26, 34);
-    path->lineTo(22, 34);
-    path->lineTo(22, 22);
-    path->lineTo(26, 22);
-    path->lineTo(26, 34);
-    path->close();
-    path->moveTo(26, 18);
-    path->lineTo(22, 18);
-    path->lineTo(22, 14);
-    path->lineTo(26, 14);
-    path->lineTo(26, 18);
-    path->close();
+static SkPath make_info() {
+    SkPathBuilder path;
+    path.moveTo(24, 4);
+    path.cubicTo(12.94999980926514f, 4,
+                 4, 12.94999980926514f,
+                 4, 24);
+    path.cubicTo(4, 35.04999923706055f,
+                 12.94999980926514f, 44,
+                 24, 44);
+    path.cubicTo(35.04999923706055f, 44,
+                 44, 35.04999923706055f,
+                 44, 24);
+    path.cubicTo(44, 12.95000076293945f,
+                 35.04999923706055f, 4,
+                 24, 4);
+    path.close();
+    path.moveTo(26, 34);
+    path.lineTo(22, 34);
+    path.lineTo(22, 22);
+    path.lineTo(26, 22);
+    path.lineTo(26, 34);
+    path.close();
+    path.moveTo(26, 18);
+    path.lineTo(22, 18);
+    path.lineTo(22, 14);
+    path.lineTo(26, 14);
+    path.lineTo(26, 18);
+    path.close();
+    return path.detach();
 }
 
-static void make_accessibility(SkPath* path) {
-    path->moveTo(12, 2);
-    path->cubicTo(13.10000038146973f,
-                  2,
-                  14,
-                  2.900000095367432f,
-                  14,
-                  4);
-    path->cubicTo(14,
-                  5.099999904632568f,
-                  13.10000038146973f,
-                  6,
-                  12,
-                  6);
-    path->cubicTo(10.89999961853027f,
-                  6,
-                  10,
-                  5.099999904632568f,
-                  10,
-                  4);
-    path->cubicTo(10,
-                  2.900000095367432f,
-                  10.89999961853027f,
-                  2,
-                  12,
-                  2);
-    path->close();
-    path->moveTo(21, 9);
-    path->lineTo(15, 9);
-    path->lineTo(15, 22);
-    path->lineTo(13, 22);
-    path->lineTo(13, 16);
-    path->lineTo(11, 16);
-    path->lineTo(11, 22);
-    path->lineTo(9, 22);
-    path->lineTo(9, 9);
-    path->lineTo(3, 9);
-    path->lineTo(3, 7);
-    path->lineTo(21, 7);
-    path->lineTo(21, 9);
-    path->close();
+static SkPath make_accessibility() {
+    SkPathBuilder path;
+    path.moveTo(12, 2);
+    path.cubicTo(13.10000038146973f, 2,
+                 14, 2.900000095367432f,
+                 14, 4);
+    path.cubicTo(14, 5.099999904632568f,
+                 13.10000038146973f, 6,
+                 12, 6);
+    path.cubicTo(10.89999961853027f, 6,
+                 10, 5.099999904632568f,
+                 10, 4);
+    path.cubicTo(10, 2.900000095367432f,
+                 10.89999961853027f, 2,
+                 12, 2);
+    path.close();
+    path.moveTo(21, 9);
+    path.lineTo(15, 9);
+    path.lineTo(15, 22);
+    path.lineTo(13, 22);
+    path.lineTo(13, 16);
+    path.lineTo(11, 16);
+    path.lineTo(11, 22);
+    path.lineTo(9, 22);
+    path.lineTo(9, 9);
+    path.lineTo(3, 9);
+    path.lineTo(3, 7);
+    path.lineTo(21, 7);
+    path.lineTo(21, 9);
+    path.close();
+    return path.detach();
 }
 
 // test case for http://crbug.com/695196
-static void make_visualizer(SkPath* path) {
-    path->moveTo(1.9520f, 2.0000f);
-    path->conicTo(1.5573f, 1.9992f, 1.2782f, 2.2782f, 0.9235f);
-    path->conicTo(0.9992f, 2.5573f, 1.0000f, 2.9520f, 0.9235f);
-    path->lineTo(1.0000f, 5.4300f);
-    path->lineTo(17.0000f, 5.4300f);
-    path->lineTo(17.0000f, 2.9520f);
-    path->conicTo(17.0008f, 2.5573f, 16.7218f, 2.2782f, 0.9235f);
-    path->conicTo(16.4427f, 1.9992f, 16.0480f, 2.0000f, 0.9235f);
-    path->lineTo(1.9520f, 2.0000f);
-    path->close();
-    path->moveTo(2.7140f, 3.1430f);
-    path->conicTo(3.0547f, 3.1287f, 3.2292f, 3.4216f, 0.8590f);
-    path->conicTo(3.4038f, 3.7145f, 3.2292f, 4.0074f, 0.8590f);
-    path->conicTo(3.0547f, 4.3003f, 2.7140f, 4.2860f, 0.8590f);
-    path->conicTo(2.1659f, 4.2631f, 2.1659f, 3.7145f, 0.7217f);
-    path->conicTo(2.1659f, 3.1659f, 2.7140f, 3.1430f, 0.7217f);
-    path->lineTo(2.7140f, 3.1430f);
-    path->close();
-    path->moveTo(5.0000f, 3.1430f);
-    path->conicTo(5.3407f, 3.1287f, 5.5152f, 3.4216f, 0.8590f);
-    path->conicTo(5.6898f, 3.7145f, 5.5152f, 4.0074f, 0.8590f);
-    path->conicTo(5.3407f, 4.3003f, 5.0000f, 4.2860f, 0.8590f);
-    path->conicTo(4.4519f, 4.2631f, 4.4519f, 3.7145f, 0.7217f);
-    path->conicTo(4.4519f, 3.1659f, 5.0000f, 3.1430f, 0.7217f);
-    path->lineTo(5.0000f, 3.1430f);
-    path->close();
-    path->moveTo(7.2860f, 3.1430f);
-    path->conicTo(7.6267f, 3.1287f, 7.8012f, 3.4216f, 0.8590f);
-    path->conicTo(7.9758f, 3.7145f, 7.8012f, 4.0074f, 0.8590f);
-    path->conicTo(7.6267f, 4.3003f, 7.2860f, 4.2860f, 0.8590f);
-    path->conicTo(6.7379f, 4.2631f, 6.7379f, 3.7145f, 0.7217f);
-    path->conicTo(6.7379f, 3.1659f, 7.2860f, 3.1430f, 0.7217f);
-    path->close();
-    path->moveTo(1.0000f, 6.1900f);
-    path->lineTo(1.0000f, 14.3810f);
-    path->conicTo(0.9992f, 14.7757f, 1.2782f, 15.0548f, 0.9235f);
-    path->conicTo(1.5573f, 15.3338f, 1.9520f, 15.3330f, 0.9235f);
-    path->lineTo(16.0480f, 15.3330f);
-    path->conicTo(16.4427f, 15.3338f, 16.7218f, 15.0548f, 0.9235f);
-    path->conicTo(17.0008f, 14.7757f, 17.0000f, 14.3810f, 0.9235f);
-    path->lineTo(17.0000f, 6.1910f);
-    path->lineTo(1.0000f, 6.1910f);
-    path->lineTo(1.0000f, 6.1900f);
-    path->close();
+static SkPath make_visualizer() {
+    SkPathBuilder path;
+    path.moveTo(1.9520f, 2.0000f);
+    path.conicTo(1.5573f, 1.9992f, 1.2782f, 2.2782f, 0.9235f);
+    path.conicTo(0.9992f, 2.5573f, 1.0000f, 2.9520f, 0.9235f);
+    path.lineTo(1.0000f, 5.4300f);
+    path.lineTo(17.0000f, 5.4300f);
+    path.lineTo(17.0000f, 2.9520f);
+    path.conicTo(17.0008f, 2.5573f, 16.7218f, 2.2782f, 0.9235f);
+    path.conicTo(16.4427f, 1.9992f, 16.0480f, 2.0000f, 0.9235f);
+    path.lineTo(1.9520f, 2.0000f);
+    path.close();
+    path.moveTo(2.7140f, 3.1430f);
+    path.conicTo(3.0547f, 3.1287f, 3.2292f, 3.4216f, 0.8590f);
+    path.conicTo(3.4038f, 3.7145f, 3.2292f, 4.0074f, 0.8590f);
+    path.conicTo(3.0547f, 4.3003f, 2.7140f, 4.2860f, 0.8590f);
+    path.conicTo(2.1659f, 4.2631f, 2.1659f, 3.7145f, 0.7217f);
+    path.conicTo(2.1659f, 3.1659f, 2.7140f, 3.1430f, 0.7217f);
+    path.lineTo(2.7140f, 3.1430f);
+    path.close();
+    path.moveTo(5.0000f, 3.1430f);
+    path.conicTo(5.3407f, 3.1287f, 5.5152f, 3.4216f, 0.8590f);
+    path.conicTo(5.6898f, 3.7145f, 5.5152f, 4.0074f, 0.8590f);
+    path.conicTo(5.3407f, 4.3003f, 5.0000f, 4.2860f, 0.8590f);
+    path.conicTo(4.4519f, 4.2631f, 4.4519f, 3.7145f, 0.7217f);
+    path.conicTo(4.4519f, 3.1659f, 5.0000f, 3.1430f, 0.7217f);
+    path.lineTo(5.0000f, 3.1430f);
+    path.close();
+    path.moveTo(7.2860f, 3.1430f);
+    path.conicTo(7.6267f, 3.1287f, 7.8012f, 3.4216f, 0.8590f);
+    path.conicTo(7.9758f, 3.7145f, 7.8012f, 4.0074f, 0.8590f);
+    path.conicTo(7.6267f, 4.3003f, 7.2860f, 4.2860f, 0.8590f);
+    path.conicTo(6.7379f, 4.2631f, 6.7379f, 3.7145f, 0.7217f);
+    path.conicTo(6.7379f, 3.1659f, 7.2860f, 3.1430f, 0.7217f);
+    path.close();
+    path.moveTo(1.0000f, 6.1900f);
+    path.lineTo(1.0000f, 14.3810f);
+    path.conicTo(0.9992f, 14.7757f, 1.2782f, 15.0548f, 0.9235f);
+    path.conicTo(1.5573f, 15.3338f, 1.9520f, 15.3330f, 0.9235f);
+    path.lineTo(16.0480f, 15.3330f);
+    path.conicTo(16.4427f, 15.3338f, 16.7218f, 15.0548f, 0.9235f);
+    path.conicTo(17.0008f, 14.7757f, 17.0000f, 14.3810f, 0.9235f);
+    path.lineTo(17.0000f, 6.1910f);
+    path.lineTo(1.0000f, 6.1910f);
+    path.lineTo(1.0000f, 6.1900f);
+    path.close();
+    return path.detach();
 }
 
 constexpr MakePathProc gProcs[] = {
@@ -328,9 +310,9 @@
             fDY[i] = dy;
         }
 
-        make_info(&fInfoPath);
-        make_accessibility(&fAccessibilityPath);
-        make_visualizer(&fVisualizerPath);
+        fInfoPath = make_info();
+        fAccessibilityPath = make_accessibility();
+        fVisualizerPath = make_visualizer();
     }
 
 
@@ -405,14 +387,13 @@
     }
 
     void onDraw(SkCanvas* canvas) override {
-        SkPath path;
+        SkPath path = SkPathBuilder().addCircle(50, 50, 40)
+                                     .toggleInverseFillType()
+                                     .detach();
 
-        path.addCircle(SkIntToScalar(50), SkIntToScalar(50), SkIntToScalar(40));
-        path.toggleInverseFillType();
+        SkRect clipR = {0, 0, 100, 200};
 
-        SkRect clipR = { 0, 0, SkIntToScalar(100), SkIntToScalar(200) };
-
-        canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
+        canvas->translate(10, 10);
 
         for (int doclip = 0; doclip <= 1; ++doclip) {
             for (int aa = 0; aa <= 1; ++aa) {
diff --git a/gm/pathmeasure.cpp b/gm/pathmeasure.cpp
index cd79cfb..25b3611 100644
--- a/gm/pathmeasure.cpp
+++ b/gm/pathmeasure.cpp
@@ -7,7 +7,7 @@
 
 #include "include/core/SkCanvas.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/core/SkPathEffect.h"
 #include "include/core/SkTypes.h"
 #include "include/effects/SkDashPathEffect.h"
@@ -29,7 +29,7 @@
     };
     int next_quadratic_at = 0;
 
-    SkPath path;
+    SkPathBuilder path;
     path.moveTo(0, 0);
 
     int i = 1;
@@ -51,7 +51,7 @@
             i = 1;
         }
     }
-    canvas->drawPath(path, p);
+    canvas->drawPath(path.detach(), p);
 }
 
 #if 0
diff --git a/gm/pathreverse.cpp b/gm/pathreverse.cpp
index b8b3547..e272d8d 100644
--- a/gm/pathreverse.cpp
+++ b/gm/pathreverse.cpp
@@ -9,7 +9,7 @@
 #include "include/core/SkCanvas.h"
 #include "include/core/SkColor.h"
 #include "include/core/SkPaint.h"
-#include "include/core/SkPath.h"
+#include "include/core/SkPathBuilder.h"
 #include "include/core/SkRect.h"
 #include "include/core/SkString.h"
 
@@ -24,7 +24,7 @@
  * should future Macs edit or delete the font.
  */
 static SkPath hiragino_maru_goth_pro_e() {
-    SkPath path;
+    SkPathBuilder path;
     path.moveTo(98.6f, 24.7f);
     path.cubicTo(101.7f, 24.7f, 103.6f, 22.8f, 103.6f, 19.2f);
     path.cubicTo(103.6f, 18.9f, 103.6f, 18.7f, 103.6f, 18.4f);
@@ -47,7 +47,7 @@
     path.cubicTo(94.5f, 17, 94.1f, 17.4f, 93, 17.4f);
     path.lineTo(63.7f, 17.4f);
     path.close();
-    return path;
+    return path.detach();
 }
 
 static void test_path(SkCanvas* canvas, const SkPath& path) {
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index c481376..7a82e34 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -68,11 +68,13 @@
                        const SkScalar[], int conicWeightCount,
                        SkPathFillType, bool isVolatile = false);
 
-    static SkPath Rect(const SkRect&,   SkPathDirection dir = SkPathDirection::kCW);
-    static SkPath Oval(const SkRect&,   SkPathDirection dir = SkPathDirection::kCW);
+    static SkPath Rect(const SkRect&, SkPathDirection = SkPathDirection::kCW,
+                       unsigned startIndex = 0);
+    static SkPath Oval(const SkRect&, SkPathDirection = SkPathDirection::kCW);
     static SkPath Circle(SkScalar center_x, SkScalar center_y, SkScalar radius,
                          SkPathDirection dir = SkPathDirection::kCW);
     static SkPath RRect(const SkRRect&, SkPathDirection dir = SkPathDirection::kCW);
+    static SkPath RRect(const SkRRect&, SkPathDirection, unsigned startIndex);
     static SkPath RRect(const SkRect& bounds, SkScalar rx, SkScalar ry,
                         SkPathDirection dir = SkPathDirection::kCW);
 
diff --git a/include/core/SkPathBuilder.h b/include/core/SkPathBuilder.h
index 6446c64..04e0d46 100644
--- a/include/core/SkPathBuilder.h
+++ b/include/core/SkPathBuilder.h
@@ -202,6 +202,11 @@
 
     SkPathBuilder& offset(SkScalar dx, SkScalar dy);
 
+    SkPathBuilder& toggleInverseFillType() {
+        fFillType = (SkPathFillType)((unsigned)fFillType ^ 2);
+        return *this;
+    }
+
 private:
     SkTDArray<SkPoint>  fPts;
     SkTDArray<uint8_t>  fVerbs;
diff --git a/modules/skparagraph/src/Decorations.cpp b/modules/skparagraph/src/Decorations.cpp
index fb59ef8..5994349 100644
--- a/modules/skparagraph/src/Decorations.cpp
+++ b/modules/skparagraph/src/Decorations.cpp
@@ -1,4 +1,5 @@
 // Copyright 2020 Google LLC.
+#include "include/core/SkPathBuilder.h"
 #include "include/effects/SkDashPathEffect.h"
 #include "include/effects/SkDiscretePathEffect.h"
 #include "modules/skparagraph/src/Decorations.h"
@@ -91,39 +92,39 @@
     }
 }
 
-void Decorations::calculateGaps(const TextLine::ClipContext& context, const SkRect& rect, SkScalar baseline, SkScalar halo) {
+void Decorations::calculateGaps(const TextLine::ClipContext& context, const SkRect& rect,
+                                SkScalar baseline, SkScalar halo) {
+    // Create a special textblob for decorations
+    SkTextBlobBuilder builder;
+    context.run->copyTo(builder,
+                      SkToU32(context.pos),
+                      context.size);
+    auto blob = builder.make();
 
-      fPath.reset();
+    // Since we do not shift down the text by {baseline}
+    // (it now happens on drawTextBlob but we do not draw text here)
+    // we have to shift up the bounds to compensate
+    // This baseline thing ends with getIntercepts
+    const SkScalar bounds[2] = {rect.fTop - baseline, rect.fBottom - baseline};
+    auto count = blob->getIntercepts(bounds, nullptr, &fPaint);
+    SkTArray<SkScalar> intersections(count);
+    intersections.resize(count);
+    blob->getIntercepts(bounds, intersections.data(), &fPaint);
 
-      // Create a special textblob for decorations
-      SkTextBlobBuilder builder;
-      context.run->copyTo(builder,
-                          SkToU32(context.pos),
-                          context.size);
-      auto blob = builder.make();
-
-      // Since we do not shift down the text by {baseline}
-      // (it now happens on drawTextBlob but we do not draw text here)
-      // we have to shift up the bounds to compensate
-      // This baseline thing ends with getIntercepts
-      const SkScalar bounds[2] = {rect.fTop - baseline, rect.fBottom - baseline};
-      auto count = blob->getIntercepts(bounds, nullptr, &fPaint);
-      SkTArray<SkScalar> intersections(count);
-      intersections.resize(count);
-      blob->getIntercepts(bounds, intersections.data(), &fPaint);
-
-      auto start = rect.fLeft;
-      fPath.moveTo(rect.fLeft, rect.fTop);
-      for (int i = 0; i < intersections.count(); i += 2) {
-          auto end = intersections[i] - halo;
-          if (end - start >= halo) {
-              start = intersections[i + 1] + halo;
-              fPath.lineTo(end, rect.fTop).moveTo(start, rect.fTop);
-          }
-      }
-      if (!intersections.empty() && (rect.fRight - start > halo)) {
-          fPath.lineTo(rect.fRight, rect.fTop);
-      }
+    SkPathBuilder path;
+    auto start = rect.fLeft;
+    path.moveTo(rect.fLeft, rect.fTop);
+    for (int i = 0; i < intersections.count(); i += 2) {
+        auto end = intersections[i] - halo;
+        if (end - start >= halo) {
+            start = intersections[i + 1] + halo;
+            path.lineTo(end, rect.fTop).moveTo(start, rect.fTop);
+        }
+    }
+    if (!intersections.empty() && (rect.fRight - start > halo)) {
+        path.lineTo(rect.fRight, rect.fTop);
+    }
+    fPath = path.detach();
 }
 
 // This is how flutter calculates the thickness
diff --git a/modules/sksg/src/SkSGRect.cpp b/modules/sksg/src/SkSGRect.cpp
index e5acd65..ece6331 100644
--- a/modules/sksg/src/SkSGRect.cpp
+++ b/modules/sksg/src/SkSGRect.cpp
@@ -34,9 +34,7 @@
 }
 
 SkPath Rect::onAsPath() const {
-    SkPath path;
-    path.addRect(fRect, this->getDirection(), this->getInitialPointIndex());
-    return path;
+    return SkPath::Rect(fRect, this->getDirection(), this->getInitialPointIndex());
 }
 
 RRect::RRect(const SkRRect& rr) : fRRect(rr) {}
@@ -72,9 +70,7 @@
 }
 
 SkPath RRect::onAsPath() const {
-    SkPath path;
-    path.addRRect(fRRect, this->getDirection(), this->getInitialPointIndex());
-    return path;
+    return SkPath::RRect(fRRect, this->getDirection(), this->getInitialPointIndex());
 }
 
 } // namespace sksg
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 53a76de..b83c739 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -3405,8 +3405,8 @@
                   ft, isVolatile, SkPathConvexityType::kUnknown);
 }
 
-SkPath SkPath::Rect(const SkRect& r, SkPathDirection dir) {
-    return SkPathBuilder().addRect(r, dir).detach();
+SkPath SkPath::Rect(const SkRect& r, SkPathDirection dir, unsigned startIndex) {
+    return SkPathBuilder().addRect(r, dir, startIndex).detach();
 }
 
 SkPath SkPath::Oval(const SkRect& r, SkPathDirection dir) {
@@ -3421,6 +3421,10 @@
     return SkPathBuilder().addRRect(rr, dir).detach();
 }
 
+SkPath SkPath::RRect(const SkRRect& rr, SkPathDirection dir, unsigned startIndex) {
+    return SkPathBuilder().addRRect(rr, dir, startIndex).detach();
+}
+
 SkPath SkPath::RRect(const SkRect& r, SkScalar rx, SkScalar ry, SkPathDirection dir) {
     return SkPathBuilder().addRRect(SkRRect::MakeRectXY(r, rx, ry), dir).detach();
 }
diff --git a/tests/ClipCubicTest.cpp b/tests/ClipCubicTest.cpp
index 5da7e6a..24cc85e 100644
--- a/tests/ClipCubicTest.cpp
+++ b/tests/ClipCubicTest.cpp
@@ -29,11 +29,9 @@
     SkCanvas canvas(bm);
     canvas.clear(SK_ColorTRANSPARENT);
 
-    SkPath path;
-    path.moveTo(0, 0); path.lineTo(1, 0); path.lineTo(33, 1);
     SkPaint paint;
     paint.setAntiAlias(true);
-    canvas.drawPath(path, paint);
+    canvas.drawPath(SkPath::Polygon({{0,0}, {1,0}, {33,1}}, false), paint);
 }
 
 static void PrintCurve(const char *name, const SkPoint crv[4]) {
diff --git a/tests/GrCCPRTest.cpp b/tests/GrCCPRTest.cpp
index a4a8d36..974931d 100644
--- a/tests/GrCCPRTest.cpp
+++ b/tests/GrCCPRTest.cpp
@@ -266,10 +266,11 @@
 
         // Make a path large enough that ccpr chooses to crop it by the RT bounds, and ends up with
         // an empty path.
-        SkPath largeOutsidePath;
-        largeOutsidePath.moveTo(-1e30f, -1e30f);
-        largeOutsidePath.lineTo(-1e30f, +1e30f);
-        largeOutsidePath.lineTo(-1e10f, +1e30f);
+        SkPath largeOutsidePath = SkPath::Polygon({
+            {-1e30f, -1e30f},
+            {-1e30f, +1e30f},
+            {-1e10f, +1e30f},
+        }, false);
         ccpr.drawPath(largeOutsidePath);
 
         // Normally an empty path is culled before reaching ccpr, however we use a back door for
diff --git a/tools/ToolUtils.cpp b/tools/ToolUtils.cpp
index 392820d..7060271 100644
--- a/tools/ToolUtils.cpp
+++ b/tools/ToolUtils.cpp
@@ -363,8 +363,10 @@
 // We don't really care to wait that long for this function.
 #pragma optimize("", off)
 #endif
-void make_big_path(SkPath& path) {
+SkPath make_big_path() {
+    SkPathBuilder path;
 #include "BigPathBench.inc"  // IWYU pragma: keep
+    return path.detach();
 }
 
 bool copy_to(SkBitmap* dst, SkColorType dstColorType, const SkBitmap& src) {
diff --git a/tools/ToolUtils.h b/tools/ToolUtils.h
index d193f3f..0a5ecc6 100644
--- a/tools/ToolUtils.h
+++ b/tools/ToolUtils.h
@@ -145,7 +145,7 @@
 
 void create_tetra_normal_map(SkBitmap* bm, const SkIRect& dst);
 
-void make_big_path(SkPath& path);
+SkPath make_big_path();
 
 // A helper object to test the topological sorting code (TopoSortBench.cpp & TopoSortTest.cpp)
 class TopoTestNode : public SkRefCnt {
diff --git a/tools/fonts/ToolUtilsFont.cpp b/tools/fonts/ToolUtilsFont.cpp
index 64d7023..7a673da 100644
--- a/tools/fonts/ToolUtilsFont.cpp
+++ b/tools/fonts/ToolUtilsFont.cpp
@@ -94,10 +94,8 @@
     for (SkGlyphID index = 0; index <= 67; ++index) {
         SkScalar width;
         width = 100;
-        SkPath path;
-        path.addCircle(50, -50, 75);
 
-        builder.setGlyph(index, width/upem, path.makeTransform(scale));
+        builder.setGlyph(index, width/upem, SkPath::Circle(50, -50, 75).makeTransform(scale));
     }
 
     return builder.detach();
diff --git a/tools/skpbench/skpbench.cpp b/tools/skpbench/skpbench.cpp
index 87047e3..85e98f6 100644
--- a/tools/skpbench/skpbench.cpp
+++ b/tools/skpbench/skpbench.cpp
@@ -679,8 +679,7 @@
     stroke.setStrokeWidth(2);
 
     // Use a big path to (theoretically) warmup the CPU.
-    SkPath bigPath;
-    ToolUtils::make_big_path(bigPath);
+    SkPath bigPath = ToolUtils::make_big_path();
     recording->drawPath(bigPath, stroke);
 
     // Use a perlin shader to warmup the GPU.