Use GrShape in GrPathRenderer.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2081383006

Review-Url: https://codereview.chromium.org/2081383006
diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp
index 390162e..bb097aa 100644
--- a/src/gpu/batches/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp
@@ -681,8 +681,8 @@
 
 bool GrAAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     return (args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
-            args.fStyle->isSimpleFill() && !args.fPath->isInverseFillType() &&
-            args.fPath->isConvex());
+            args.fShape->style().isSimpleFill() && !args.fShape->inverseFilled() &&
+            args.fShape->knownToBeConvex());
 }
 
 // extract the result vertices and indices from the GrAAConvexTessellator
@@ -998,15 +998,12 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrAAConvexPathRenderer::onDrawPath");
     SkASSERT(!args.fDrawContext->isUnifiedMultisampled());
-
-    if (args.fPath->isEmpty()) {
-        return true;
-    }
+    SkASSERT(!args.fShape->isEmpty());
 
     AAConvexPathBatch::Geometry geometry;
     geometry.fColor = args.fColor;
     geometry.fViewMatrix = *args.fViewMatrix;
-    geometry.fPath = *args.fPath;
+    args.fShape->asPath(&geometry.fPath);
 
     SkAutoTUnref<GrDrawBatch> batch(AAConvexPathBatch::Create(geometry));
 
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
index e6be590..6cf3e4b 100644
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
@@ -82,13 +82,13 @@
 ////////////////////////////////////////////////////////////////////////////////
 bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     // We don't currently apply the dash or factor it into the DF key. (skbug.com/5082)
-    if (args.fStyle->pathEffect()) {
+    if (args.fShape->style().pathEffect()) {
         return false;
     }
     // TODO: Support inverse fill
     if (!args.fShaderCaps->shaderDerivativeSupport() || !args.fAntiAlias ||
-        args.fStyle->isSimpleHairline() || args.fPath->isInverseFillType() ||
-        args.fPath->isVolatile()) {
+        args.fShape->style().isSimpleHairline() || args.fShape->mayBeInverseFilledAfterStyling() ||
+        !args.fShape->hasUnstyledKey()) {
         return false;
     }
 
@@ -102,7 +102,7 @@
     // the goal is to accelerate rendering of lots of small paths that may be scaling
     SkScalar maxScale = args.fViewMatrix->getMaxScale();
     SkRect bounds;
-    args.fStyle->adjustBounds(&bounds, args.fPath->getBounds());
+    args.fShape->styledBounds(&bounds);
     SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
 
     return maxDim <= kMediumMIP && maxDim * maxScale <= 2.0f*kLargeMIP;
@@ -532,9 +532,7 @@
     SkASSERT(!args.fDrawContext->isUnifiedMultisampled());
 
     // we've already bailed on inverse filled paths, so this is safe
-    if (args.fPath->isEmpty()) {
-        return true;
-    }
+    SkASSERT(!args.fShape->isEmpty());
 
     if (!fAtlas) {
         fAtlas = args.fResourceProvider->createAtlas(kAlpha_8_GrPixelConfig,
@@ -547,19 +545,19 @@
         }
     }
 
+    const GrStyle& style = args.fShape->style();
     // It's ok to ignore style's path effect because canDrawPath filtered out path effects.
-    AADistanceFieldPathBatch::Geometry geometry(args.fStyle->strokeRec());
-    if (args.fStyle->isSimpleFill()) {
-        geometry.fPath = *args.fPath;
-    } else {
-        args.fStyle->strokeRec().applyToPath(&geometry.fPath, *args.fPath);
-    }
-    geometry.fColor = args.fColor;
-    geometry.fAntiAlias = args.fAntiAlias;
+    AADistanceFieldPathBatch::Geometry geometry(style.strokeRec());
+    args.fShape->asPath(&geometry.fPath);
     // Note: this is the generation ID of the _original_ path. When a new path is
     // generated due to stroking it is important that the original path's id is used
     // for caching.
-    geometry.fGenID = args.fPath->getGenerationID();
+    geometry.fGenID = geometry.fPath.getGenerationID();
+    if (!style.isSimpleFill()) {
+        style.strokeRec().applyToPath(&geometry.fPath, geometry.fPath);
+    }
+    geometry.fColor = args.fColor;
+    geometry.fAntiAlias = args.fAntiAlias;
 
     SkAutoTUnref<GrDrawBatch> batch(AADistanceFieldPathBatch::Create(geometry,
                                                                      *args.fViewMatrix, fAtlas,
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.h b/src/gpu/batches/GrAADistanceFieldPathRenderer.h
index 099d0c7..e5c7dce 100755
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.h
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.h
@@ -23,7 +23,7 @@
     virtual ~GrAADistanceFieldPathRenderer();
 
 private:
-    StencilSupport onGetStencilSupport(const SkPath&) const override {
+    StencilSupport onGetStencilSupport(const GrShape&) const override {
         return GrPathRenderer::kNoSupport_StencilSupport;
     }
 
diff --git a/src/gpu/batches/GrAAHairLinePathRenderer.cpp b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
index f44c454..1f7407c 100644
--- a/src/gpu/batches/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
@@ -618,19 +618,20 @@
         return false;
     }
 
-    if (!IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr)) {
+    if (!IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr)) {
         return false;
     }
 
     // We don't currently handle dashing in this class though perhaps we should.
-    if (args.fStyle->pathEffect()) {
+    if (args.fShape->style().pathEffect()) {
         return false;
     }
 
-    if (SkPath::kLine_SegmentMask == args.fPath->getSegmentMasks() ||
+    if (SkPath::kLine_SegmentMask == args.fShape->segmentMask() ||
         args.fShaderCaps->shaderDerivativeSupport()) {
         return true;
     }
+
     return false;
 }
 
@@ -971,12 +972,13 @@
     args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawContext->height(),
                                       &devClipBounds);
 
-    SkAutoTUnref<GrDrawBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, *args.fPath,
-                                                          *args.fStyle, devClipBounds));
+    SkPath path;
+    args.fShape->asPath(&path);
+    SkAutoTUnref<GrDrawBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, path,
+                                                          args.fShape->style(), devClipBounds));
 
     GrPipelineBuilder pipelineBuilder(*args.fPaint);
     pipelineBuilder.setUserStencil(args.fUserStencilSettings);
-
     args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
 
     return true;
diff --git a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
index 1847a67..9748829 100644
--- a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
@@ -40,23 +40,23 @@
     if (!args.fAntiAlias) {
         return false;
     }
-    if (args.fPath->isInverseFillType()) {
+    if (!args.fShape->knownToBeConvex()) {
         return false;
     }
-    if (!args.fPath->isConvex()) {
+    if (args.fShape->style().pathEffect()) {
         return false;
     }
-    if (args.fStyle->pathEffect()) {
+    if (args.fShape->inverseFilled()) {
         return false;
     }
-    const SkStrokeRec& stroke = args.fStyle->strokeRec();
+    const SkStrokeRec& stroke = args.fShape->style().strokeRec();
     if (stroke.getStyle() == SkStrokeRec::kStroke_Style) {
         if (!args.fViewMatrix->isSimilarity()) {
             return false;
         }
         SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * stroke.getWidth();
         return strokeWidth >= 1.0f && strokeWidth <= kMaxStrokeWidth &&
-               SkPathPriv::IsClosedSingleContour(*args.fPath) &&
+               args.fShape->knownToBeClosed() &&
                stroke.getJoin() != SkPaint::Join::kRound_Join;
     }
     return stroke.getStyle() == SkStrokeRec::kFill_Style;
@@ -324,18 +324,17 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrAALinearizingConvexPathRenderer::onDrawPath");
     SkASSERT(!args.fDrawContext->isUnifiedMultisampled());
+    SkASSERT(!args.fShape->isEmpty());
 
-    if (args.fPath->isEmpty()) {
-        return true;
-    }
     AAFlatteningConvexPathBatch::Geometry geometry;
     geometry.fColor = args.fColor;
     geometry.fViewMatrix = *args.fViewMatrix;
-    geometry.fPath = *args.fPath;
-    bool fill = args.fStyle->isSimpleFill();
-    geometry.fStrokeWidth = fill ? -1.0f : args.fStyle->strokeRec().getWidth();
-    geometry.fJoin = fill ? SkPaint::Join::kMiter_Join : args.fStyle->strokeRec().getJoin();
-    geometry.fMiterLimit = args.fStyle->strokeRec().getMiter();
+    args.fShape->asPath(&geometry.fPath);
+    bool fill = args.fShape->style().isSimpleFill();
+    const SkStrokeRec& stroke = args.fShape->style().strokeRec();
+    geometry.fStrokeWidth = fill ? -1.0f : stroke.getWidth();
+    geometry.fJoin = fill ? SkPaint::Join::kMiter_Join : stroke.getJoin();
+    geometry.fMiterLimit = stroke.getMiter();
 
     SkAutoTUnref<GrDrawBatch> batch(AAFlatteningConvexPathBatch::Create(geometry));
 
diff --git a/src/gpu/batches/GrDashLinePathRenderer.cpp b/src/gpu/batches/GrDashLinePathRenderer.cpp
index a442b66..8dba7b9 100644
--- a/src/gpu/batches/GrDashLinePathRenderer.cpp
+++ b/src/gpu/batches/GrDashLinePathRenderer.cpp
@@ -13,8 +13,8 @@
 
 bool GrDashLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     SkPoint pts[2];
-    if (args.fStyle->isDashed() && args.fPath->isLine(pts)) {
-        return GrDashingEffect::CanDrawDashLine(pts, *args.fStyle, *args.fViewMatrix);
+    if (args.fShape->style().isDashed() && args.fShape->asLine(pts)) {
+        return GrDashingEffect::CanDrawDashLine(pts, args.fShape->style(), *args.fViewMatrix);
     }
     return false;
 }
@@ -34,12 +34,12 @@
         aaMode = GrDashingEffect::AAMode::kNone;
     }
     SkPoint pts[2];
-    SkAssertResult(args.fPath->isLine(pts));
+    SkAssertResult(args.fShape->asLine(pts));
     SkAutoTUnref<GrDrawBatch> batch(GrDashingEffect::CreateDashLineBatch(args.fColor,
                                                                          *args.fViewMatrix,
                                                                          pts,
                                                                          aaMode,
-                                                                         *args.fStyle));
+                                                                         args.fShape->style()));
     if (!batch) {
         return false;
     }
diff --git a/src/gpu/batches/GrDashLinePathRenderer.h b/src/gpu/batches/GrDashLinePathRenderer.h
index e25f882..d959421 100644
--- a/src/gpu/batches/GrDashLinePathRenderer.h
+++ b/src/gpu/batches/GrDashLinePathRenderer.h
@@ -14,7 +14,7 @@
 private:
     bool onCanDrawPath(const CanDrawPathArgs&) const override;
 
-    StencilSupport onGetStencilSupport(const SkPath&) const override {
+    StencilSupport onGetStencilSupport(const GrShape&) const override {
         return kNoSupport_StencilSupport;
     }
 
diff --git a/src/gpu/batches/GrDefaultPathRenderer.cpp b/src/gpu/batches/GrDefaultPathRenderer.cpp
index 7fd7913..1e807f8 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.cpp
+++ b/src/gpu/batches/GrDefaultPathRenderer.cpp
@@ -34,20 +34,20 @@
 
 #define STENCIL_OFF     0   // Always disable stencil (even when needed)
 
-static inline bool single_pass_path(const SkPath& path, const SkStrokeRec& stroke) {
+static inline bool single_pass_shape(const GrShape& shape) {
 #if STENCIL_OFF
     return true;
 #else
-    if (!stroke.isHairlineStyle() && !path.isInverseFillType()) {
-        return path.isConvex();
+    if (!shape.style().couldBeHairline() && !shape.inverseFilled()) {
+        return shape.knownToBeConvex();
     }
     return false;
 #endif
 }
 
 GrPathRenderer::StencilSupport
-GrDefaultPathRenderer::onGetStencilSupport(const SkPath& path) const {
-    if (single_pass_path(path, SkStrokeRec(SkStrokeRec::kFill_InitStyle))) {
+GrDefaultPathRenderer::onGetStencilSupport(const GrShape& shape) const {
+    if (single_pass_shape(shape)) {
         return GrPathRenderer::kNoRestriction_StencilSupport;
     } else {
         return GrPathRenderer::kStencilOnly_StencilSupport;
@@ -422,20 +422,19 @@
                                              const GrClip& clip,
                                              GrColor color,
                                              const SkMatrix& viewMatrix,
-                                             const SkPath& path,
-                                             const GrStyle& origStyle,
+                                             const GrShape& shape,
                                              bool stencilOnly) {
-    const GrStyle* style = &origStyle;
+    SkPath path;
+    shape.asPath(&path);
 
     SkScalar hairlineCoverage;
     uint8_t newCoverage = 0xff;
     bool isHairline = false;
-    if (IsStrokeHairlineOrEquivalent(*style, viewMatrix, &hairlineCoverage)) {
+    if (IsStrokeHairlineOrEquivalent(shape.style(), viewMatrix, &hairlineCoverage)) {
         newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
-        style = &GrStyle::SimpleHairline();
         isHairline = true;
     } else {
-        SkASSERT(style->isSimpleFill());
+        SkASSERT(shape.style().isSimpleFill());
     }
 
     int                          passCount = 0;
@@ -454,7 +453,7 @@
         lastPassIsBounds = false;
         drawFace[0] = GrPipelineBuilder::kBoth_DrawFace;
     } else {
-        if (single_pass_path(path, style->strokeRec())) {
+        if (single_pass_shape(shape)) {
             passCount = 1;
             if (stencilOnly) {
                 passes[0] = &gDirectToStencil;
@@ -600,9 +599,8 @@
 bool GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     // this class can draw any path with any simple fill style but doesn't do any anti-aliasing.
     return !args.fAntiAlias &&
-           (args.fStyle->isSimpleFill() || IsStrokeHairlineOrEquivalent(*args.fStyle,
-                                                                        *args.fViewMatrix,
-                                                                        nullptr));
+           (args.fShape->style().isSimpleFill() ||
+            IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr));
 }
 
 bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
@@ -614,30 +612,21 @@
                                   *args.fClip,
                                   args.fColor,
                                   *args.fViewMatrix,
-                                  *args.fPath,
-                                  *args.fStyle,
+                                  *args.fShape,
                                   false);
 }
 
 void GrDefaultPathRenderer::onStencilPath(const StencilPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrDefaultPathRenderer::onStencilPath");
-    SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
-    SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
+    SkASSERT(!args.fShape->inverseFilled());
 
     GrPaint paint;
     paint.setXPFactory(GrDisableColorXPFactory::Make());
     paint.setAntiAlias(args.fIsAA);
 
-    this->internalDrawPath(args.fDrawContext,
-                           paint,
-                           &GrUserStencilSettings::kUnused,
-                           *args.fClip,
-                           GrColor_WHITE,
-                           *args.fViewMatrix,
-                           *args.fPath,
-                           GrStyle::SimpleFill(),
-                           true);
+    this->internalDrawPath(args.fDrawContext, paint, &GrUserStencilSettings::kUnused, *args.fClip,
+                           GrColor_WHITE, *args.fViewMatrix, *args.fShape, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/batches/GrDefaultPathRenderer.h b/src/gpu/batches/GrDefaultPathRenderer.h
index 277d7a8..04e1013 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.h
+++ b/src/gpu/batches/GrDefaultPathRenderer.h
@@ -22,7 +22,7 @@
 
 private:
 
-    StencilSupport onGetStencilSupport(const SkPath&) const override;
+    StencilSupport onGetStencilSupport(const GrShape&) const override;
 
     bool onCanDrawPath(const CanDrawPathArgs&) const override;
 
@@ -36,8 +36,7 @@
                           const GrClip&,
                           GrColor,
                           const SkMatrix& viewMatrix,
-                          const SkPath&,
-                          const GrStyle&,
+                          const GrShape&,
                           bool stencilOnly);
 
     bool    fSeparateStencil;
diff --git a/src/gpu/batches/GrMSAAPathRenderer.cpp b/src/gpu/batches/GrMSAAPathRenderer.cpp
index edc285e..31b9ebf 100644
--- a/src/gpu/batches/GrMSAAPathRenderer.cpp
+++ b/src/gpu/batches/GrMSAAPathRenderer.cpp
@@ -31,16 +31,15 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Helpers for drawPath
 
-static inline bool single_pass_path(const SkPath& path) {
-    if (!path.isInverseFillType()) {
-        return path.isConvex();
+static inline bool single_pass_shape(const GrShape& shape) {
+    if (!shape.inverseFilled()) {
+        return shape.knownToBeConvex();
     }
     return false;
 }
 
-GrPathRenderer::StencilSupport
-GrMSAAPathRenderer::onGetStencilSupport(const SkPath& path) const {
-    if (single_pass_path(path)) {
+GrPathRenderer::StencilSupport GrMSAAPathRenderer::onGetStencilSupport(const GrShape& shape) const {
+    if (single_pass_shape(shape)) {
         return GrPathRenderer::kNoRestriction_StencilSupport;
     } else {
         return GrPathRenderer::kStencilOnly_StencilSupport;
@@ -574,15 +573,19 @@
                                           const GrClip& clip,
                                           GrColor color,
                                           const SkMatrix& viewMatrix,
-                                          const SkPath& path,
+                                          const GrShape& shape,
                                           bool stencilOnly) {
+    SkASSERT(shape.style().isSimpleFill());
+    SkPath path;
+    shape.asPath(&path);
+
     int                          passCount = 0;
     const GrUserStencilSettings* passes[3];
     GrPipelineBuilder::DrawFace  drawFace[3];
     bool                         reverse = false;
     bool                         lastPassIsBounds;
 
-    if (single_pass_path(path)) {
+    if (single_pass_shape(shape)) {
         passCount = 1;
         if (stencilOnly) {
             passes[0] = &gDirectToStencil;
@@ -709,28 +712,19 @@
     // This path renderer does not support hairlines. We defer on anything that could be handled
     // as a hairline by another path renderer. Also, arbitrary path effects could produce
     // a hairline result.
-    return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr) &&
-           !args.fStyle->strokeRec().isHairlineStyle() &&
-           !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias;
+    return !IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr) &&
+           !args.fShape->style().couldBeHairline() && !args.fAntiAlias;
 }
 
 bool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrMSAAPathRenderer::onDrawPath");
-    SkPath tmpPath;
-    const SkPath* path;
-    if (args.fStyle->applies()) {
-        SkStrokeRec::InitStyle fill;
+    SkTLazy<GrShape> tmpShape;
+    const GrShape* shape = args.fShape;
+    if (shape->style().applies()) {
         SkScalar styleScale = GrStyle::MatrixToScaleFactor(*args.fViewMatrix);
-        if (!args.fStyle->applyToPath(&tmpPath, &fill, *args.fPath, styleScale)) {
-            return false;
-        }
-        // We don't accept styles that are hairlines or have path effects that could produce
-        // hairlines.
-        SkASSERT(SkStrokeRec::kFill_InitStyle == fill);
-        path = &tmpPath;
-    } else {
-        path = args.fPath;
+        tmpShape.init(args.fShape->applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, styleScale));
+        shape = tmpShape.get();
     }
     return this->internalDrawPath(args.fDrawContext,
                                   *args.fPaint,
@@ -738,28 +732,22 @@
                                   *args.fClip,
                                   args.fColor,
                                   *args.fViewMatrix,
-                                  *path,
+                                  *shape,
                                   false);
 }
 
 void GrMSAAPathRenderer::onStencilPath(const StencilPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrMSAAPathRenderer::onStencilPath");
-    SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
-    SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
+    SkASSERT(args.fShape->style().isSimpleFill());
+    SkASSERT(!args.fShape->mayBeInverseFilledAfterStyling());
 
     GrPaint paint;
     paint.setXPFactory(GrDisableColorXPFactory::Make());
     paint.setAntiAlias(args.fIsAA);
 
-    this->internalDrawPath(args.fDrawContext,
-                           paint,
-                           &GrUserStencilSettings::kUnused,
-                           *args.fClip,
-                           GrColor_WHITE,
-                           *args.fViewMatrix,
-                           *args.fPath,
-                           true);
+    this->internalDrawPath(args.fDrawContext, paint, &GrUserStencilSettings::kUnused, *args.fClip,
+                           GrColor_WHITE, *args.fViewMatrix, *args.fShape, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/batches/GrMSAAPathRenderer.h b/src/gpu/batches/GrMSAAPathRenderer.h
index 0c27e8c..e1cf4a3 100644
--- a/src/gpu/batches/GrMSAAPathRenderer.h
+++ b/src/gpu/batches/GrMSAAPathRenderer.h
@@ -13,7 +13,7 @@
 
 class SK_API GrMSAAPathRenderer : public GrPathRenderer {
 private:
-    StencilSupport onGetStencilSupport(const SkPath&) const override;
+    StencilSupport onGetStencilSupport(const GrShape&) const override;
 
     bool onCanDrawPath(const CanDrawPathArgs&) const override;
 
@@ -27,7 +27,7 @@
                           const GrClip&,
                           GrColor,
                           const SkMatrix& viewMatrix,
-                          const SkPath&,
+                          const GrShape&,
                           bool stencilOnly);
 
     typedef GrPathRenderer INHERITED;
diff --git a/src/gpu/batches/GrPLSPathRenderer.cpp b/src/gpu/batches/GrPLSPathRenderer.cpp
index a81b883..ba84d73 100644
--- a/src/gpu/batches/GrPLSPathRenderer.cpp
+++ b/src/gpu/batches/GrPLSPathRenderer.cpp
@@ -777,9 +777,11 @@
 bool GrPLSPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     // We have support for even-odd rendering, but are having some troublesome
     // seams. Disable in the presence of even-odd for now.
+    SkPath path;
+    args.fShape->asPath(&path);
     return args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
-            args.fStyle->isSimpleFill() && !args.fPath->isInverseFillType() &&
-            args.fPath->getFillType() == SkPath::FillType::kWinding_FillType;
+            args.fShape->style().isSimpleFill() && !path.isInverseFillType() &&
+            path.getFillType() == SkPath::FillType::kWinding_FillType;
 }
 
 class PLSPathBatch : public GrVertexBatch {
@@ -974,15 +976,13 @@
 
 SkDEBUGCODE(bool inPLSDraw = false;)
 bool GrPLSPathRenderer::onDrawPath(const DrawPathArgs& args) {
-    if (args.fPath->isEmpty()) {
-        return true;
-    }
+    SkASSERT(!args.fShape->isEmpty())
     SkASSERT(!inPLSDraw);
     SkDEBUGCODE(inPLSDraw = true;)
     PLSPathBatch::Geometry geometry;
     geometry.fColor = args.fColor;
     geometry.fViewMatrix = *args.fViewMatrix;
-    geometry.fPath = *args.fPath;
+    args.fShape->asPath(&geometry.fPath);
 
     SkAutoTUnref<GrDrawBatch> batch(PLSPathBatch::Create(geometry));
 
diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
index 2a48018..0995310 100644
--- a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
@@ -33,9 +33,8 @@
 }
 
 bool GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
-    // GrPath doesn't support hairline paths. Also, an arbitrary path effect could change
-    // the style type to hairline.
-    if (args.fStyle->hasNonDashPathEffect() || args.fStyle->strokeRec().isHairlineStyle()) {
+    // GrPath doesn't support hairline paths.
+    if (args.fShape->style().couldBeHairline()) {
         return false;
     }
     if (args.fHasUserStencilSettings) {
@@ -70,6 +69,8 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrStencilAndCoverPathRenderer::onStencilPath");
     SkASSERT(!args.fIsAA || args.fDrawContext->isStencilBufferMultisampled());
+    SkPath path;
+    args.fShape->asPath(&path);
 
     GrPaint paint;
     paint.setXPFactory(GrDisableColorXPFactory::Make());
@@ -77,24 +78,23 @@
 
     const GrPipelineBuilder pipelineBuilder(paint, args.fIsAA);
 
-    SkASSERT(!args.fPath->isInverseFillType());
-    SkAutoTUnref<GrPath> path(get_gr_path(fResourceProvider, *args.fPath, GrStyle::SimpleFill()));
-    args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder,
-                                                     *args.fClip,
-                                                     *args.fViewMatrix,
-                                                     path,
-                                                     path->getFillType());
+    SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, GrStyle::SimpleFill()));
+    args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder, *args.fClip,
+                                                     *args.fViewMatrix, p, p->getFillType());
 }
 
 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrStencilAndCoverPathRenderer::onDrawPath");
     SkASSERT(!args.fPaint->isAntiAlias() || args.fDrawContext->isStencilBufferMultisampled());
-    SkASSERT(!args.fStyle->strokeRec().isHairlineStyle());
-    const SkPath& path = *args.fPath;
+    SkASSERT(!args.fShape->style().strokeRec().isHairlineStyle());
+
     const SkMatrix& viewMatrix = *args.fViewMatrix;
 
-    SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, *args.fStyle));
+    SkPath path;
+    args.fShape->asPath(&path);
+
+    SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, args.fShape->style()));
 
     if (path.isInverseFillType()) {
         static constexpr GrUserStencilSettings kInvertedCoverPass(
diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.h b/src/gpu/batches/GrStencilAndCoverPathRenderer.h
index cec8126..c896e61 100644
--- a/src/gpu/batches/GrStencilAndCoverPathRenderer.h
+++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.h
@@ -24,7 +24,7 @@
 
 
 private:
-    StencilSupport onGetStencilSupport(const SkPath&) const override {
+    StencilSupport onGetStencilSupport(const GrShape&) const override {
         return GrPathRenderer::kStencilOnly_StencilSupport;
     }
 
diff --git a/src/gpu/batches/GrTessellatingPathRenderer.cpp b/src/gpu/batches/GrTessellatingPathRenderer.cpp
index 6bc8549..060e3f0 100644
--- a/src/gpu/batches/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/batches/GrTessellatingPathRenderer.cpp
@@ -109,9 +109,10 @@
     // not do antialiasing. It can do convex and concave paths, but we'll leave the convex ones to
     // simpler algorithms. Similary, we skip the non-hairlines that can be treated as hairline.
     // An arbitrary path effect could produce a hairline result so we pass on those.
-    return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr) &&
-           !args.fStyle->strokeRec().isHairlineStyle() &&
-           !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias && !args.fPath->isConvex();
+    return !IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr) &&
+           !args.fShape->style().strokeRec().isHairlineStyle() &&
+           !args.fShape->style().hasNonDashPathEffect() && !args.fAntiAlias &&
+           !args.fShape->knownToBeConvex();
 }
 
 class TessellatingPathBatch : public GrVertexBatch {
@@ -292,8 +293,11 @@
         return false;
     }
     vmi.mapRect(&clipBounds);
-    SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, *args.fPath,
-                                                                  *args.fStyle, *args.fViewMatrix,
+    SkPath path;
+    args.fShape->asPath(&path);
+    SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, path,
+                                                                  args.fShape->style(),
+                                                                  *args.fViewMatrix,
                                                                   clipBounds));
 
     GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHWAA(*args.fPaint));
diff --git a/src/gpu/batches/GrTessellatingPathRenderer.h b/src/gpu/batches/GrTessellatingPathRenderer.h
index f1faa60..d5f2c7a 100644
--- a/src/gpu/batches/GrTessellatingPathRenderer.h
+++ b/src/gpu/batches/GrTessellatingPathRenderer.h
@@ -21,7 +21,7 @@
 private:
     bool onCanDrawPath(const CanDrawPathArgs& ) const override;
 
-    StencilSupport onGetStencilSupport(const SkPath&) const override {
+    StencilSupport onGetStencilSupport(const GrShape&) const override {
         return GrPathRenderer::kNoSupport_StencilSupport;
     }