Move several more PathRenderers to skgpu::v1 namespace

Bug: skia:11837
Change-Id: Ifa1da88aafcaa96e0e885facaeb849cc9963bcfe
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/439938
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/gm/crbug_847759.cpp b/gm/crbug_847759.cpp
index 02f5e70..7190dd5 100644
--- a/gm/crbug_847759.cpp
+++ b/gm/crbug_847759.cpp
@@ -11,7 +11,7 @@
 #include "include/core/SkPathBuilder.h"
 
 DEF_SIMPLE_GM(crbug_847759, canvas, 500, 500) {
-    // This path exposed an issue in GrAAHairlinePathRenderer. When converting from cubics to quads
+    // This path exposed an issue in AAHairlinePathRenderer. When converting from cubics to quads
     // we produced quads where the previously vertical tangents at the left and right tips of the
     // squashed oval-like path became slightly non-vertical. This caused a missed pixel of AA just
     // outside each tip.
diff --git a/gn/gpu.gni b/gn/gpu.gni
index 300618b..3f299e9 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -513,12 +513,16 @@
   "$_src/gpu/GrStencilMaskHelper.h",
 
   # Ops
-  "$_src/gpu/ops/GrAAConvexPathRenderer.cpp",
-  "$_src/gpu/ops/GrAAConvexPathRenderer.h",
-  "$_src/gpu/ops/GrAAHairLinePathRenderer.cpp",
-  "$_src/gpu/ops/GrAAHairLinePathRenderer.h",
-  "$_src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp",
-  "$_src/gpu/ops/GrAALinearizingConvexPathRenderer.h",
+  "$_src/gpu/ops/AAConvexPathRenderer.cpp",
+  "$_src/gpu/ops/AAConvexPathRenderer.h",
+  "$_src/gpu/ops/AAHairLinePathRenderer.cpp",
+  "$_src/gpu/ops/AAHairLinePathRenderer.h",
+  "$_src/gpu/ops/AALinearizingConvexPathRenderer.cpp",
+  "$_src/gpu/ops/AALinearizingConvexPathRenderer.h",
+  "$_src/gpu/ops/DashLinePathRenderer.cpp",
+  "$_src/gpu/ops/DashLinePathRenderer.h",
+  "$_src/gpu/ops/DefaultPathRenderer.cpp",
+  "$_src/gpu/ops/DefaultPathRenderer.h",
   "$_src/gpu/ops/GrAtlasInstancedHelper.cpp",
   "$_src/gpu/ops/GrAtlasInstancedHelper.h",
   "$_src/gpu/ops/GrAtlasPathRenderer.cpp",
@@ -527,12 +531,8 @@
   "$_src/gpu/ops/GrAtlasTextOp.h",
   "$_src/gpu/ops/GrClearOp.cpp",
   "$_src/gpu/ops/GrClearOp.h",
-  "$_src/gpu/ops/GrDashLinePathRenderer.cpp",
-  "$_src/gpu/ops/GrDashLinePathRenderer.h",
   "$_src/gpu/ops/GrDashOp.cpp",
   "$_src/gpu/ops/GrDashOp.h",
-  "$_src/gpu/ops/GrDefaultPathRenderer.cpp",
-  "$_src/gpu/ops/GrDefaultPathRenderer.h",
   "$_src/gpu/ops/GrDrawAtlasOp.cpp",
   "$_src/gpu/ops/GrDrawAtlasOp.h",
   "$_src/gpu/ops/GrDrawAtlasPathOp.cpp",
diff --git a/include/private/GrTypesPriv.h b/include/private/GrTypesPriv.h
index 9c4d48d..6677836 100644
--- a/include/private/GrTypesPriv.h
+++ b/include/private/GrTypesPriv.h
@@ -854,7 +854,7 @@
  * Used to include or exclude specific GPU path renderers for testing purposes.
  */
 enum class GpuPathRenderers {
-    kNone              =   0,  // Always use software masks and/or GrDefaultPathRenderer.
+    kNone              =   0,  // Always use software masks and/or DefaultPathRenderer.
     kDashLine          =   1 << 0,
     kAtlas             =   1 << 1,
     kTessellation      =   1 << 2,
diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp
index 8190b97..b4be08a 100644
--- a/src/gpu/GrPathRendererChain.cpp
+++ b/src/gpu/GrPathRendererChain.cpp
@@ -16,12 +16,12 @@
 #include "src/gpu/GrRecordingContextPriv.h"
 #include "src/gpu/GrShaderCaps.h"
 #include "src/gpu/geometry/GrStyledShape.h"
-#include "src/gpu/ops/GrAAConvexPathRenderer.h"
-#include "src/gpu/ops/GrAAHairLinePathRenderer.h"
-#include "src/gpu/ops/GrAALinearizingConvexPathRenderer.h"
+#include "src/gpu/ops/AAConvexPathRenderer.h"
+#include "src/gpu/ops/AAHairLinePathRenderer.h"
+#include "src/gpu/ops/AALinearizingConvexPathRenderer.h"
+#include "src/gpu/ops/DashLinePathRenderer.h"
+#include "src/gpu/ops/DefaultPathRenderer.h"
 #include "src/gpu/ops/GrAtlasPathRenderer.h"
-#include "src/gpu/ops/GrDashLinePathRenderer.h"
-#include "src/gpu/ops/GrDefaultPathRenderer.h"
 #include "src/gpu/ops/GrTriangulatingPathRenderer.h"
 #include "src/gpu/ops/SmallPathRenderer.h"
 #include "src/gpu/tessellate/GrTessellationPathRenderer.h"
@@ -29,16 +29,16 @@
 GrPathRendererChain::GrPathRendererChain(GrRecordingContext* context, const Options& options) {
     const GrCaps& caps = *context->priv().caps();
     if (options.fGpuPathRenderers & GpuPathRenderers::kDashLine) {
-        fChain.push_back(sk_make_sp<GrDashLinePathRenderer>());
+        fChain.push_back(sk_make_sp<skgpu::v1::DashLinePathRenderer>());
     }
     if (options.fGpuPathRenderers & GpuPathRenderers::kAAConvex) {
-        fChain.push_back(sk_make_sp<GrAAConvexPathRenderer>());
+        fChain.push_back(sk_make_sp<skgpu::v1::AAConvexPathRenderer>());
     }
     if (options.fGpuPathRenderers & GpuPathRenderers::kAAHairline) {
-        fChain.push_back(sk_make_sp<GrAAHairLinePathRenderer>());
+        fChain.push_back(sk_make_sp<skgpu::v1::AAHairLinePathRenderer>());
     }
     if (options.fGpuPathRenderers & GpuPathRenderers::kAALinearizing) {
-        fChain.push_back(sk_make_sp<GrAALinearizingConvexPathRenderer>());
+        fChain.push_back(sk_make_sp<skgpu::v1::AALinearizingConvexPathRenderer>());
     }
     if (options.fGpuPathRenderers & GpuPathRenderers::kAtlas) {
         if (auto atlasPathRenderer = GrAtlasPathRenderer::Make(context)) {
@@ -62,7 +62,7 @@
     }
 
     // We always include the default path renderer (as well as SW), so we can draw any path
-    fChain.push_back(sk_make_sp<GrDefaultPathRenderer>());
+    fChain.push_back(sk_make_sp<skgpu::v1::DefaultPathRenderer>());
 }
 
 GrPathRenderer* GrPathRendererChain::getPathRenderer(
diff --git a/src/gpu/geometry/GrAAConvexTessellator.cpp b/src/gpu/geometry/GrAAConvexTessellator.cpp
index 6895df0..9f2e253 100644
--- a/src/gpu/geometry/GrAAConvexTessellator.cpp
+++ b/src/gpu/geometry/GrAAConvexTessellator.cpp
@@ -623,7 +623,7 @@
                         this->addTri(originalIdx, perp1Idx, perp2Idx);
                         break;
                     default:
-                        // kRound_Join is unsupported for now. GrAALinearizingConvexPathRenderer is
+                        // kRound_Join is unsupported for now. AALinearizingConvexPathRenderer is
                         // only willing to draw mitered or beveled, so we should never get here.
                         SkASSERT(false);
                 }
diff --git a/src/gpu/geometry/GrPathUtils.cpp b/src/gpu/geometry/GrPathUtils.cpp
index 69fe5ac..80ccd83 100644
--- a/src/gpu/geometry/GrPathUtils.cpp
+++ b/src/gpu/geometry/GrPathUtils.cpp
@@ -357,7 +357,7 @@
             // This introduced a large performance regression for tiny paths for no noticeable
             // quality improvement. However, we aren't quite fulfilling our contract of guaranteeing
             // the two tangent vectors and this could introduce a missed pixel in
-            // GrAAHairlinePathRenderer.
+            // AAHairlinePathRenderer.
             newC = (c0 + c1) * 0.5f;
         } else if (preserveFirstTangent) {
             newC = c0;
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/AAConvexPathRenderer.cpp
similarity index 94%
rename from src/gpu/ops/GrAAConvexPathRenderer.cpp
rename to src/gpu/ops/AAConvexPathRenderer.cpp
index f5b0ad7..a71beaa 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/AAConvexPathRenderer.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "src/gpu/ops/GrAAConvexPathRenderer.h"
+#include "src/gpu/ops/AAConvexPathRenderer.h"
 
 #include "include/core/SkString.h"
 #include "include/core/SkTypes.h"
@@ -31,8 +31,7 @@
 #include "src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h"
 #include "src/gpu/v1/SurfaceDrawContext_v1.h"
 
-GrAAConvexPathRenderer::GrAAConvexPathRenderer() {
-}
+namespace {
 
 struct Segment {
     enum {
@@ -65,7 +64,7 @@
 
 typedef SkTArray<Segment, true> SegmentArray;
 
-static bool center_of_mass(const SegmentArray& segments, SkPoint* c) {
+bool center_of_mass(const SegmentArray& segments, SkPoint* c) {
     SkScalar area = 0;
     SkPoint center = {0, 0};
     int count = segments.count();
@@ -115,11 +114,11 @@
     return !SkScalarIsNaN(c->fX) && !SkScalarIsNaN(c->fY) && c->isFinite();
 }
 
-static bool compute_vectors(SegmentArray* segments,
-                            SkPoint* fanPt,
-                            SkPathFirstDirection dir,
-                            int* vCount,
-                            int* iCount) {
+bool compute_vectors(SegmentArray* segments,
+                     SkPoint* fanPt,
+                     SkPathFirstDirection dir,
+                     int* vCount,
+                     int* iCount) {
     if (!center_of_mass(*segments, fanPt)) {
         return false;
     }
@@ -195,7 +194,7 @@
 static const SkScalar kClose = (SK_Scalar1 / 16);
 static const SkScalar kCloseSqd = kClose * kClose;
 
-static void update_degenerate_test(DegenerateTestData* data, const SkPoint& pt) {
+void update_degenerate_test(DegenerateTestData* data, const SkPoint& pt) {
     switch (data->fStage) {
         case DegenerateTestData::kInitial:
             data->fFirstPoint = pt;
@@ -222,8 +221,7 @@
     }
 }
 
-static inline bool get_direction(const SkPath& path, const SkMatrix& m,
-                                 SkPathFirstDirection* dir) {
+inline bool get_direction(const SkPath& path, const SkMatrix& m, SkPathFirstDirection* dir) {
     // At this point, we've already returned true from canDraw(), which checked that the path's
     // direction could be determined, so this should just be fetching the cached direction.
     // However, if perspective is involved, we're operating on a transformed path, which may no
@@ -244,15 +242,13 @@
     return true;
 }
 
-static inline void add_line_to_segment(const SkPoint& pt,
-                                       SegmentArray* segments) {
+inline void add_line_to_segment(const SkPoint& pt, SegmentArray* segments) {
     segments->push_back();
     segments->back().fType = Segment::kLine;
     segments->back().fPts[0] = pt;
 }
 
-static inline void add_quad_segment(const SkPoint pts[3],
-                                    SegmentArray* segments) {
+inline void add_quad_segment(const SkPoint pts[3], SegmentArray* segments) {
     if (SkPointPriv::DistanceToLineSegmentBetweenSqd(pts[1], pts[0], pts[2]) < kCloseSqd) {
         if (pts[0] != pts[2]) {
             add_line_to_segment(pts[2], segments);
@@ -265,9 +261,9 @@
     }
 }
 
-static inline void add_cubic_segments(const SkPoint pts[4],
-                                      SkPathFirstDirection dir,
-                                      SegmentArray* segments) {
+inline void add_cubic_segments(const SkPoint pts[4],
+                               SkPathFirstDirection dir,
+                               SegmentArray* segments) {
     SkSTArray<15, SkPoint, true> quads;
     GrPathUtils::convertCubicToQuadsConstrainToTangents(pts, SK_Scalar1, dir, &quads);
     int count = quads.count();
@@ -276,12 +272,12 @@
     }
 }
 
-static bool get_segments(const SkPath& path,
-                         const SkMatrix& m,
-                         SegmentArray* segments,
-                         SkPoint* fanPt,
-                         int* vCount,
-                         int* iCount) {
+bool get_segments(const SkPath& path,
+                  const SkMatrix& m,
+                  SegmentArray* segments,
+                  SkPoint* fanPt,
+                  int* vCount,
+                  int* iCount) {
     SkPath::Iter iter(path, true);
     // This renderer over-emphasizes very thin path regions. We use the distance
     // to the path from the sample to compute coverage. Every pixel intersected
@@ -364,13 +360,13 @@
 
 typedef SkTArray<Draw, true> DrawArray;
 
-static void create_vertices(const SegmentArray& segments,
-                            const SkPoint& fanPt,
-                            const GrVertexColor& color,
-                            DrawArray* draws,
-                            GrVertexWriter& verts,
-                            uint16_t* idxs,
-                            size_t vertexStride) {
+void create_vertices(const SegmentArray& segments,
+                     const SkPoint& fanPt,
+                     const GrVertexColor& color,
+                     DrawArray* draws,
+                     GrVertexWriter& verts,
+                     uint16_t* idxs,
+                     size_t vertexStride) {
     Draw* draw = &draws->push_back();
     // alias just to make vert/index assignments easier to read.
     int* v = &draw->fVertexCnt;
@@ -682,23 +678,6 @@
 }
 #endif
 
-///////////////////////////////////////////////////////////////////////////////
-
-GrPathRenderer::CanDrawPath
-GrAAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
-    // This check requires convexity and known direction, since the direction is used to build
-    // the geometry segments. Degenerate convex paths will fall through to some other path renderer.
-    if (args.fCaps->shaderCaps()->shaderDerivativeSupport() &&
-        (GrAAType::kCoverage == args.fAAType) && args.fShape->style().isSimpleFill() &&
-        !args.fShape->inverseFilled() && args.fShape->knownToBeConvex() &&
-        args.fShape->knownDirection()) {
-        return CanDrawPath::kYes;
-    }
-    return CanDrawPath::kNo;
-}
-
-namespace {
-
 class AAConvexPathOp final : public GrMeshDrawOp {
 private:
     using Helper = GrSimpleMeshDrawOpHelperWithStencil;
@@ -912,23 +891,7 @@
     using INHERITED = GrMeshDrawOp;
 };
 
-}  // anonymous namespace
-
-bool GrAAConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fContext->priv().auditTrail(),
-                              "GrAAConvexPathRenderer::onDrawPath");
-    SkASSERT(args.fSurfaceDrawContext->numSamples() <= 1);
-    SkASSERT(!args.fShape->isEmpty());
-
-    SkPath path;
-    args.fShape->asPath(&path);
-
-    GrOp::Owner op = AAConvexPathOp::Make(args.fContext, std::move(args.fPaint),
-                                          *args.fViewMatrix,
-                                          path, args.fUserStencilSettings);
-    args.fSurfaceDrawContext->addDrawOp(args.fClip, std::move(op));
-    return true;
-}
+} // anonymous namespace
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -942,3 +905,37 @@
 }
 
 #endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace skgpu::v1 {
+
+GrPathRenderer::CanDrawPath AAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
+    // This check requires convexity and known direction, since the direction is used to build
+    // the geometry segments. Degenerate convex paths will fall through to some other path renderer.
+    if (args.fCaps->shaderCaps()->shaderDerivativeSupport() &&
+        (GrAAType::kCoverage == args.fAAType) && args.fShape->style().isSimpleFill() &&
+        !args.fShape->inverseFilled() && args.fShape->knownToBeConvex() &&
+        args.fShape->knownDirection()) {
+        return CanDrawPath::kYes;
+    }
+    return CanDrawPath::kNo;
+}
+
+bool AAConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fContext->priv().auditTrail(),
+                              "AAConvexPathRenderer::onDrawPath");
+    SkASSERT(args.fSurfaceDrawContext->numSamples() <= 1);
+    SkASSERT(!args.fShape->isEmpty());
+
+    SkPath path;
+    args.fShape->asPath(&path);
+
+    GrOp::Owner op = AAConvexPathOp::Make(args.fContext, std::move(args.fPaint),
+                                          *args.fViewMatrix,
+                                          path, args.fUserStencilSettings);
+    args.fSurfaceDrawContext->addDrawOp(args.fClip, std::move(op));
+    return true;
+}
+
+} // namespace skgpu::v1
diff --git a/src/gpu/ops/AAConvexPathRenderer.h b/src/gpu/ops/AAConvexPathRenderer.h
new file mode 100644
index 0000000..6963fd6
--- /dev/null
+++ b/src/gpu/ops/AAConvexPathRenderer.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef AAConvexPathRenderer_DEFINED
+#define AAConvexPathRenderer_DEFINED
+
+#include "src/gpu/GrPathRenderer.h"
+
+namespace skgpu::v1 {
+
+class AAConvexPathRenderer final : public GrPathRenderer {
+public:
+    AAConvexPathRenderer() = default;
+
+    const char* name() const override { return "AAConvex"; }
+
+private:
+    CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override;
+
+    bool onDrawPath(const DrawPathArgs&) override;
+
+    using INHERITED = GrPathRenderer;
+};
+
+} // namespace skgpu::v1
+
+#endif // AAConvexPathRenderer_DEFINED
diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/AAHairLinePathRenderer.cpp
similarity index 90%
rename from src/gpu/ops/GrAAHairLinePathRenderer.cpp
rename to src/gpu/ops/AAHairLinePathRenderer.cpp
index 884eaef..1643b8e 100644
--- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/ops/AAHairLinePathRenderer.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "src/gpu/ops/GrAAHairLinePathRenderer.h"
+#include "src/gpu/ops/AAHairLinePathRenderer.h"
 
 #include "include/core/SkPoint3.h"
 #include "include/private/SkTemplates.h"
@@ -34,6 +34,12 @@
 
 #define PREALLOC_PTARRAY(N) SkSTArray<(N),SkPoint, true>
 
+using PtArray = SkTArray<SkPoint, true>;
+using IntArray = SkTArray<int, true>;
+using FloatArray = SkTArray<float, true>;
+
+namespace {
+
 // quadratics are rendered as 5-sided polys in order to bound the
 // AA stroke around the center-curve. See comments in push_quad_index_buffer and
 // bloat_quad. Quadratics and conics share an index buffer
@@ -71,7 +77,7 @@
 static const int kQuadsNumInIdxBuffer = 256;
 GR_DECLARE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey);
 
-static sk_sp<const GrBuffer> get_quads_index_buffer(GrResourceProvider* resourceProvider) {
+sk_sp<const GrBuffer> get_quads_index_buffer(GrResourceProvider* resourceProvider) {
     GR_DEFINE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey);
     return resourceProvider->findOrCreatePatternedIndexBuffer(
         kQuadIdxBufPattern, kIdxsPerQuad, kQuadsNumInIdxBuffer, kQuadNumVertices,
@@ -105,7 +111,7 @@
 
 GR_DECLARE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey);
 
-static sk_sp<const GrBuffer> get_lines_index_buffer(GrResourceProvider* resourceProvider) {
+sk_sp<const GrBuffer> get_lines_index_buffer(GrResourceProvider* resourceProvider) {
     GR_DEFINE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey);
     return resourceProvider->findOrCreatePatternedIndexBuffer(
         kLineSegIdxBufPattern, kIdxsPerLineSeg,  kLineSegsNumInIdxBuffer, kLineSegNumVertices,
@@ -113,7 +119,7 @@
 }
 
 // Takes 178th time of logf on Z600 / VC2010
-static int get_float_exp(float x) {
+int get_float_exp(float x) {
     static_assert(sizeof(int) == sizeof(float));
 #ifdef SK_DEBUG
     static bool tested;
@@ -141,7 +147,7 @@
 // found along the curve segment it will return 1 and
 // dst[0] is the original conic. If it returns 2 the dst[0]
 // and dst[1] are the two new conics.
-static int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
+int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
     SkScalar t = SkFindQuadMaxCurvature(src);
     if (t == 0 || t == 1) {
         if (dst) {
@@ -164,7 +170,7 @@
 // Calls split_conic on the entire conic and then once more on each subsection.
 // Most cases will result in either 1 conic (chop point is not within t range)
 // or 3 points (split once and then one subsection is split again).
-static int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) {
+int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) {
     SkConic dstTemp[2];
     int conicCnt = split_conic(src, dstTemp, weight);
     if (2 == conicCnt) {
@@ -179,7 +185,7 @@
 // returns 0 if quad/conic is degen or close to it
 // in this case approx the path with lines
 // otherwise returns 1
-static int is_degen_quad_or_conic(const SkPoint p[3], SkScalar* dsqd) {
+int is_degen_quad_or_conic(const SkPoint p[3], SkScalar* dsqd) {
     static const SkScalar gDegenerateToLineTol = GrPathUtils::kDefaultTolerance;
     static const SkScalar gDegenerateToLineTolSqd =
         gDegenerateToLineTol * gDegenerateToLineTol;
@@ -200,14 +206,14 @@
     return 0;
 }
 
-static int is_degen_quad_or_conic(const SkPoint p[3]) {
+int is_degen_quad_or_conic(const SkPoint p[3]) {
     SkScalar dsqd;
     return is_degen_quad_or_conic(p, &dsqd);
 }
 
 // we subdivide the quads to avoid huge overfill
 // if it returns -1 then should be drawn as lines
-static int num_quad_subdivs(const SkPoint p[3]) {
+int num_quad_subdivs(const SkPoint p[3]) {
     SkScalar dsqd;
     if (is_degen_quad_or_conic(p, &dsqd)) {
         return -1;
@@ -243,16 +249,16 @@
  * subdivide large quads to reduce over-fill. This subdivision has to be
  * performed before applying the perspective matrix.
  */
-static int gather_lines_and_quads(const SkPath& path,
-                                  const SkMatrix& m,
-                                  const SkIRect& devClipBounds,
-                                  SkScalar capLength,
-                                  bool convertConicsToQuads,
-                                  GrAAHairLinePathRenderer::PtArray* lines,
-                                  GrAAHairLinePathRenderer::PtArray* quads,
-                                  GrAAHairLinePathRenderer::PtArray* conics,
-                                  GrAAHairLinePathRenderer::IntArray* quadSubdivCnts,
-                                  GrAAHairLinePathRenderer::FloatArray* conicWeights) {
+int gather_lines_and_quads(const SkPath& path,
+                           const SkMatrix& m,
+                           const SkIRect& devClipBounds,
+                           SkScalar capLength,
+                           bool convertConicsToQuads,
+                           PtArray* lines,
+                           PtArray* quads,
+                           PtArray* conics,
+                           IntArray* quadSubdivCnts,
+                           FloatArray* conicWeights) {
     SkPath::Iter iter(path, false);
 
     int totalQuadCount = 0;
@@ -492,9 +498,9 @@
 
 static_assert(sizeof(BezierVertex) == 3 * sizeof(SkPoint));
 
-static void intersect_lines(const SkPoint& ptA, const SkVector& normA,
-                            const SkPoint& ptB, const SkVector& normB,
-                            SkPoint* result) {
+void intersect_lines(const SkPoint& ptA, const SkVector& normA,
+                     const SkPoint& ptB, const SkVector& normB,
+                     SkPoint* result) {
 
     SkScalar lineAW = -normA.dot(ptA);
     SkScalar lineBW = -normB.dot(ptB);
@@ -514,14 +520,16 @@
     }
 }
 
-static void set_uv_quad(const SkPoint qpts[3], BezierVertex verts[kQuadNumVertices]) {
+void set_uv_quad(const SkPoint qpts[3], BezierVertex verts[kQuadNumVertices]) {
     // this should be in the src space, not dev coords, when we have perspective
     GrPathUtils::QuadUVMatrix DevToUV(qpts);
     DevToUV.apply(verts, kQuadNumVertices, sizeof(BezierVertex), sizeof(SkPoint));
 }
 
-static void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice,
-                       const SkMatrix* toSrc, BezierVertex verts[kQuadNumVertices]) {
+void bloat_quad(const SkPoint qpts[3],
+                const SkMatrix* toDevice,
+                const SkMatrix* toSrc,
+                BezierVertex verts[kQuadNumVertices]) {
     SkASSERT(!toDevice == !toSrc);
     // original quad is specified by tri a,b,c
     SkPoint a = qpts[0];
@@ -610,8 +618,9 @@
 // f(x, y, w) = f(P) = K^2 - LM
 // K = dot(k, P), L = dot(l, P), M = dot(m, P)
 // k, l, m are calculated in function GrPathUtils::getConicKLM
-static void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kQuadNumVertices],
-                             const SkScalar weight) {
+void set_conic_coeffs(const SkPoint p[3],
+                      BezierVertex verts[kQuadNumVertices],
+                      const SkScalar weight) {
     SkMatrix klm;
 
     GrPathUtils::getConicKLM(p, weight, &klm);
@@ -622,21 +631,21 @@
     }
 }
 
-static void add_conics(const SkPoint p[3],
-                       const SkScalar weight,
-                       const SkMatrix* toDevice,
-                       const SkMatrix* toSrc,
-                       BezierVertex** vert) {
+void add_conics(const SkPoint p[3],
+                const SkScalar weight,
+                const SkMatrix* toDevice,
+                const SkMatrix* toSrc,
+                BezierVertex** vert) {
     bloat_quad(p, toDevice, toSrc, *vert);
     set_conic_coeffs(p, *vert, weight);
     *vert += kQuadNumVertices;
 }
 
-static void add_quads(const SkPoint p[3],
-                      int subdiv,
-                      const SkMatrix* toDevice,
-                      const SkMatrix* toSrc,
-                      BezierVertex** vert) {
+void add_quads(const SkPoint p[3],
+               int subdiv,
+               const SkMatrix* toDevice,
+               const SkMatrix* toSrc,
+               BezierVertex** vert) {
     SkASSERT(subdiv >= 0);
     // temporary vertex storage to avoid reading the vertex buffer
     BezierVertex outVerts[kQuadNumVertices] = {};
@@ -670,10 +679,10 @@
     *vert += kQuadNumVertices;
 }
 
-static void add_line(const SkPoint p[2],
-                     const SkMatrix* toSrc,
-                     uint8_t coverage,
-                     LineVertex** vert) {
+void add_line(const SkPoint p[2],
+              const SkMatrix* toSrc,
+              uint8_t coverage,
+              LineVertex** vert) {
     const SkPoint& a = p[0];
     const SkPoint& b = p[1];
 
@@ -736,66 +745,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrPathRenderer::CanDrawPath
-GrAAHairLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
-    if (GrAAType::kCoverage != args.fAAType) {
-        return CanDrawPath::kNo;
-    }
-
-    if (!GrIsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr)) {
-        return CanDrawPath::kNo;
-    }
-
-    // We don't currently handle dashing in this class though perhaps we should.
-    if (args.fShape->style().pathEffect()) {
-        return CanDrawPath::kNo;
-    }
-
-    if (SkPath::kLine_SegmentMask == args.fShape->segmentMask() ||
-        args.fCaps->shaderCaps()->shaderDerivativeSupport()) {
-        return CanDrawPath::kYes;
-    }
-
-    return CanDrawPath::kNo;
-}
-
-template <class VertexType>
-bool check_bounds(const SkMatrix& viewMatrix, const SkRect& devBounds, void* vertices, int vCount)
-{
-    SkRect tolDevBounds = devBounds;
-    // The bounds ought to be tight, but in perspective the below code runs the verts
-    // through the view matrix to get back to dev coords, which can introduce imprecision.
-    if (viewMatrix.hasPerspective()) {
-        tolDevBounds.outset(SK_Scalar1 / 1000, SK_Scalar1 / 1000);
-    } else {
-        // Non-persp matrices cause this path renderer to draw in device space.
-        SkASSERT(viewMatrix.isIdentity());
-    }
-    SkRect actualBounds;
-
-    VertexType* verts = reinterpret_cast<VertexType*>(vertices);
-    bool first = true;
-    for (int i = 0; i < vCount; ++i) {
-        SkPoint pos = verts[i].fPos;
-        // This is a hack to workaround the fact that we move some degenerate segments offscreen.
-        if (SK_ScalarMax == pos.fX) {
-            continue;
-        }
-        viewMatrix.mapPoints(&pos, 1);
-        if (first) {
-            actualBounds.setLTRB(pos.fX, pos.fY, pos.fX, pos.fY);
-            first = false;
-        } else {
-            SkRectPriv::GrowToInclude(&actualBounds, pos);
-        }
-    }
-    if (!first) {
-        return tolDevBounds.contains(actualBounds);
-    }
-
-    return true;
-}
-
 class AAHairlineOp final : public GrMeshDrawOp {
 private:
     using Helper = GrSimpleMeshDrawOpHelperWithStencil;
@@ -869,11 +818,11 @@
                                           nullptr);
     }
 
-    enum Program : uint8_t {
-        kNone_Program  = 0x0,
-        kLine_Program  = 0x1,
-        kQuad_Program  = 0x2,
-        kConic_Program = 0x4,
+    enum class Program : uint8_t {
+        kNone  = 0x0,
+        kLine  = 0x1,
+        kQuad  = 0x2,
+        kConic = 0x4,
     };
 
 private:
@@ -924,10 +873,6 @@
     void onPrepareDraws(GrMeshDrawTarget*) override;
     void onExecute(GrOpFlushState*, const SkRect& chainBounds) override;
 
-    typedef SkTArray<SkPoint, true> PtArray;
-    typedef SkTArray<int, true> IntArray;
-    typedef SkTArray<float, true> FloatArray;
-
     CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override {
         AAHairlineOp* that = t->cast<AAHairlineOp>();
 
@@ -989,14 +934,14 @@
     SkPMColor4f fColor;
     uint8_t fCoverage;
 
-    Program        fCharacterization = kNone_Program;       // holds a mask of required programs
+    Program        fCharacterization = Program::kNone;       // holds a mask of required programs
     GrSimpleMesh*  fMeshes[3] = { nullptr };
     GrProgramInfo* fProgramInfos[3] = { nullptr };
 
     using INHERITED = GrMeshDrawOp;
 };
 
-GR_MAKE_BITFIELD_OPS(AAHairlineOp::Program)
+GR_MAKE_BITFIELD_CLASS_OPS(AAHairlineOp::Program)
 
 void AAHairlineOp::makeLineProgramInfo(const GrCaps& caps, SkArenaAlloc* arena,
                                        const GrPipeline* pipeline,
@@ -1087,19 +1032,19 @@
     // When predicting the programs we always include the lineProgram bc it is used as a fallback
     // for quads and conics. In non-DDL mode there are cases where it sometimes isn't needed for a
     // given path.
-    Program neededPrograms = kLine_Program;
+    Program neededPrograms = Program::kLine;
 
     for (int i = 0; i < fPaths.count(); i++) {
         uint32_t mask = fPaths[i].fPath.getSegmentMasks();
 
         if (mask & (SkPath::kQuad_SegmentMask | SkPath::kCubic_SegmentMask)) {
-            neededPrograms |= kQuad_Program;
+            neededPrograms |= Program::kQuad;
         }
         if (mask & SkPath::kConic_SegmentMask) {
             if (convertConicsToQuads) {
-                neededPrograms |= kQuad_Program;
+                neededPrograms |= Program::kQuad;
             } else {
-                neededPrograms |= kConic_Program;
+                neededPrograms |= Program::kConic;
             }
         }
     }
@@ -1133,17 +1078,17 @@
     auto pipeline = fHelper.createPipeline(caps, arena, writeView.swizzle(),
                                            std::move(appliedClip), dstProxyView);
 
-    if (fCharacterization & kLine_Program) {
+    if (fCharacterization & Program::kLine) {
         this->makeLineProgramInfo(*caps, arena, pipeline, writeView,
                                   geometryProcessorViewM, geometryProcessorLocalM,
                                   renderPassXferBarriers, colorLoadOp);
     }
-    if (fCharacterization & kQuad_Program) {
+    if (fCharacterization & Program::kQuad) {
         this->makeQuadProgramInfo(*caps, arena, pipeline, writeView,
                                   geometryProcessorViewM, geometryProcessorLocalM,
                                   renderPassXferBarriers, colorLoadOp);
     }
-    if (fCharacterization & kConic_Program) {
+    if (fCharacterization & Program::kConic) {
         this->makeConicProgramInfo(*caps, arena, pipeline, writeView,
                                    geometryProcessorViewM, geometryProcessorLocalM,
                                    renderPassXferBarriers, colorLoadOp);
@@ -1193,7 +1138,7 @@
     }
 
     SkDEBUGCODE(Program predictedPrograms = this->predictPrograms(&target->caps()));
-    Program actualPrograms = kNone_Program;
+    Program actualPrograms = Program::kNone;
 
     // This is hand inlined for maximum performance.
     PREALLOC_PTARRAY(128) lines;
@@ -1224,8 +1169,8 @@
 
     // do lines first
     if (lineCount) {
-        SkASSERT(predictedPrograms & kLine_Program);
-        actualPrograms |= kLine_Program;
+        SkASSERT(predictedPrograms & Program::kLine);
+        actualPrograms |= Program::kLine;
 
         sk_sp<const GrBuffer> linesIndexBuffer = get_lines_index_buffer(target->resourceProvider());
 
@@ -1279,8 +1224,8 @@
         }
 
         if (quadCount > 0) {
-            SkASSERT(predictedPrograms & kQuad_Program);
-            actualPrograms |= kQuad_Program;
+            SkASSERT(predictedPrograms & Program::kQuad);
+            actualPrograms |= Program::kQuad;
 
             fMeshes[1] = target->allocMesh();
             fMeshes[1]->setIndexedPatterned(quadsIndexBuffer, kIdxsPerQuad, quadCount,
@@ -1290,8 +1235,8 @@
         }
 
         if (conicCount > 0) {
-            SkASSERT(predictedPrograms & kConic_Program);
-            actualPrograms |= kConic_Program;
+            SkASSERT(predictedPrograms & Program::kConic);
+            actualPrograms |= Program::kConic;
 
             fMeshes[2] = target->allocMesh();
             fMeshes[2]->setIndexedPatterned(std::move(quadsIndexBuffer), kIdxsPerQuad, conicCount,
@@ -1318,20 +1263,7 @@
     }
 }
 
-bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fContext->priv().auditTrail(),
-                              "GrAAHairlinePathRenderer::onDrawPath");
-    SkASSERT(args.fSurfaceDrawContext->numSamples() <= 1);
-
-    SkPath path;
-    args.fShape->asPath(&path);
-    GrOp::Owner op =
-            AAHairlineOp::Make(args.fContext, std::move(args.fPaint), *args.fViewMatrix, path,
-                               args.fShape->style(), *args.fClipConservativeBounds,
-                               args.fUserStencilSettings);
-    args.fSurfaceDrawContext->addDrawOp(args.fClip, std::move(op));
-    return true;
-}
+} // anonymous namespace
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -1348,3 +1280,49 @@
 }
 
 #endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace skgpu::v1 {
+
+GrPathRenderer::CanDrawPath
+AAHairLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
+    if (GrAAType::kCoverage != args.fAAType) {
+        return CanDrawPath::kNo;
+    }
+
+    if (!GrIsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr)) {
+        return CanDrawPath::kNo;
+    }
+
+    // We don't currently handle dashing in this class though perhaps we should.
+    if (args.fShape->style().pathEffect()) {
+        return CanDrawPath::kNo;
+    }
+
+    if (SkPath::kLine_SegmentMask == args.fShape->segmentMask() ||
+        args.fCaps->shaderCaps()->shaderDerivativeSupport()) {
+        return CanDrawPath::kYes;
+    }
+
+    return CanDrawPath::kNo;
+}
+
+
+bool AAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fContext->priv().auditTrail(),
+                              "AAHairlinePathRenderer::onDrawPath");
+    SkASSERT(args.fSurfaceDrawContext->numSamples() <= 1);
+
+    SkPath path;
+    args.fShape->asPath(&path);
+    GrOp::Owner op =
+            AAHairlineOp::Make(args.fContext, std::move(args.fPaint), *args.fViewMatrix, path,
+                               args.fShape->style(), *args.fClipConservativeBounds,
+                               args.fUserStencilSettings);
+    args.fSurfaceDrawContext->addDrawOp(args.fClip, std::move(op));
+    return true;
+}
+
+} // namespace skgpu::v1
+
diff --git a/src/gpu/ops/AAHairLinePathRenderer.h b/src/gpu/ops/AAHairLinePathRenderer.h
new file mode 100644
index 0000000..39c5646
--- /dev/null
+++ b/src/gpu/ops/AAHairLinePathRenderer.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef AAHairLinePathRenderer_DEFINED
+#define AAHairLinePathRenderer_DEFINED
+
+#include "src/gpu/GrPathRenderer.h"
+
+namespace skgpu::v1 {
+
+class AAHairLinePathRenderer final : public GrPathRenderer {
+public:
+    AAHairLinePathRenderer() = default;
+
+    const char* name() const override { return "AAHairline"; }
+
+private:
+    CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override;
+
+    bool onDrawPath(const DrawPathArgs&) override;
+
+    using INHERITED = GrPathRenderer;
+};
+
+} // namespace skgpu::v1
+
+#endif // AAHairLinePathRenderer_DEFINED
diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/AALinearizingConvexPathRenderer.cpp
similarity index 94%
rename from src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
rename to src/gpu/ops/AALinearizingConvexPathRenderer.cpp
index 2c51330..19e7c4e 100644
--- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/ops/AALinearizingConvexPathRenderer.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "src/gpu/ops/GrAALinearizingConvexPathRenderer.h"
+#include "src/gpu/ops/AALinearizingConvexPathRenderer.h"
 
 #include "include/core/SkString.h"
 #include "src/core/SkGeometry.h"
@@ -28,71 +28,22 @@
 #include "src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h"
 #include "src/gpu/v1/SurfaceDrawContext_v1.h"
 
+///////////////////////////////////////////////////////////////////////////////
+namespace {
+
 static const int DEFAULT_BUFFER_SIZE = 100;
 
 // The thicker the stroke, the harder it is to produce high-quality results using tessellation. For
 // the time being, we simply drop back to software rendering above this stroke width.
 static const SkScalar kMaxStrokeWidth = 20.0;
 
-GrAALinearizingConvexPathRenderer::GrAALinearizingConvexPathRenderer() = default;
-
-///////////////////////////////////////////////////////////////////////////////
-
-GrPathRenderer::CanDrawPath
-GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
-    if (GrAAType::kCoverage != args.fAAType) {
-        return CanDrawPath::kNo;
-    }
-    if (!args.fShape->knownToBeConvex()) {
-        return CanDrawPath::kNo;
-    }
-    if (args.fShape->style().pathEffect()) {
-        return CanDrawPath::kNo;
-    }
-    if (args.fShape->inverseFilled()) {
-        return CanDrawPath::kNo;
-    }
-    if (args.fShape->bounds().width() <= 0 && args.fShape->bounds().height() <= 0) {
-        // Stroked zero length lines should draw, but this PR doesn't handle that case
-        return CanDrawPath::kNo;
-    }
-    const SkStrokeRec& stroke = args.fShape->style().strokeRec();
-
-    if (stroke.getStyle() == SkStrokeRec::kStroke_Style ||
-        stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style) {
-        if (!args.fViewMatrix->isSimilarity()) {
-            return CanDrawPath::kNo;
-        }
-        SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * stroke.getWidth();
-        if (strokeWidth < 1.0f && stroke.getStyle() == SkStrokeRec::kStroke_Style) {
-            return CanDrawPath::kNo;
-        }
-        if (strokeWidth > kMaxStrokeWidth ||
-            !args.fShape->knownToBeClosed() ||
-            stroke.getJoin() == SkPaint::Join::kRound_Join) {
-            return CanDrawPath::kNo;
-        }
-        return CanDrawPath::kYes;
-    }
-    if (stroke.getStyle() != SkStrokeRec::kFill_Style) {
-        return CanDrawPath::kNo;
-    }
-    // This can almost handle perspective. It would need to use 3 component explicit local coords
-    // when there are FPs that require them. This is difficult to test because AAConvexPathRenderer
-    // takes almost all filled paths that could get here. So just avoid perspective fills.
-    if (args.fViewMatrix->hasPerspective()) {
-        return CanDrawPath::kNo;
-    }
-    return CanDrawPath::kYes;
-}
-
 // extract the result vertices and indices from the GrAAConvexTessellator
-static void extract_verts(const GrAAConvexTessellator& tess,
-                          const SkMatrix* localCoordsMatrix,
-                          void* vertData,
-                          const GrVertexColor& color,
-                          uint16_t firstIndex,
-                          uint16_t* idxs) {
+void extract_verts(const GrAAConvexTessellator& tess,
+                   const SkMatrix* localCoordsMatrix,
+                   void* vertData,
+                   const GrVertexColor& color,
+                   uint16_t firstIndex,
+                   uint16_t* idxs) {
     GrVertexWriter verts{vertData};
     for (int i = 0; i < tess.numPts(); ++i) {
         SkPoint lc;
@@ -108,10 +59,10 @@
     }
 }
 
-static GrGeometryProcessor* create_lines_only_gp(SkArenaAlloc* arena,
-                                                 bool tweakAlphaForCoverage,
-                                                 bool usesLocalCoords,
-                                                 bool wideColor) {
+GrGeometryProcessor* create_lines_only_gp(SkArenaAlloc* arena,
+                                          bool tweakAlphaForCoverage,
+                                          bool usesLocalCoords,
+                                          bool wideColor) {
     using namespace GrDefaultGeoProcFactory;
 
     Coverage::Type coverageType =
@@ -124,8 +75,6 @@
     return Make(arena, colorType, coverageType, localCoordsType, SkMatrix::I());
 }
 
-namespace {
-
 class AAFlatteningConvexPathOp final : public GrMeshDrawOp {
 private:
     using Helper = GrSimpleMeshDrawOpHelperWithStencil;
@@ -388,28 +337,6 @@
 
 }  // anonymous namespace
 
-bool GrAALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fContext->priv().auditTrail(),
-                              "GrAALinearizingConvexPathRenderer::onDrawPath");
-    SkASSERT(args.fSurfaceDrawContext->numSamples() <= 1);
-    SkASSERT(!args.fShape->isEmpty());
-    SkASSERT(!args.fShape->style().pathEffect());
-
-    SkPath path;
-    args.fShape->asPath(&path);
-    bool fill = args.fShape->style().isSimpleFill();
-    const SkStrokeRec& stroke = args.fShape->style().strokeRec();
-    SkScalar strokeWidth = fill ? -1.0f : stroke.getWidth();
-    SkPaint::Join join = fill ? SkPaint::Join::kMiter_Join : stroke.getJoin();
-    SkScalar miterLimit = stroke.getMiter();
-
-    GrOp::Owner op = AAFlatteningConvexPathOp::Make(
-            args.fContext, std::move(args.fPaint), *args.fViewMatrix, path, strokeWidth,
-            stroke.getStyle(), join, miterLimit, args.fUserStencilSettings);
-    args.fSurfaceDrawContext->addDrawOp(args.fClip, std::move(op));
-    return true;
-}
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 #if GR_TEST_UTILS
@@ -443,3 +370,79 @@
 }
 
 #endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace skgpu::v1 {
+
+GrPathRenderer::CanDrawPath
+AALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
+    if (GrAAType::kCoverage != args.fAAType) {
+        return CanDrawPath::kNo;
+    }
+    if (!args.fShape->knownToBeConvex()) {
+        return CanDrawPath::kNo;
+    }
+    if (args.fShape->style().pathEffect()) {
+        return CanDrawPath::kNo;
+    }
+    if (args.fShape->inverseFilled()) {
+        return CanDrawPath::kNo;
+    }
+    if (args.fShape->bounds().width() <= 0 && args.fShape->bounds().height() <= 0) {
+        // Stroked zero length lines should draw, but this PR doesn't handle that case
+        return CanDrawPath::kNo;
+    }
+    const SkStrokeRec& stroke = args.fShape->style().strokeRec();
+
+    if (stroke.getStyle() == SkStrokeRec::kStroke_Style ||
+        stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style) {
+        if (!args.fViewMatrix->isSimilarity()) {
+            return CanDrawPath::kNo;
+        }
+        SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * stroke.getWidth();
+        if (strokeWidth < 1.0f && stroke.getStyle() == SkStrokeRec::kStroke_Style) {
+            return CanDrawPath::kNo;
+        }
+        if (strokeWidth > kMaxStrokeWidth ||
+            !args.fShape->knownToBeClosed() ||
+            stroke.getJoin() == SkPaint::Join::kRound_Join) {
+            return CanDrawPath::kNo;
+        }
+        return CanDrawPath::kYes;
+    }
+    if (stroke.getStyle() != SkStrokeRec::kFill_Style) {
+        return CanDrawPath::kNo;
+    }
+    // This can almost handle perspective. It would need to use 3 component explicit local coords
+    // when there are FPs that require them. This is difficult to test because AAConvexPathRenderer
+    // takes almost all filled paths that could get here. So just avoid perspective fills.
+    if (args.fViewMatrix->hasPerspective()) {
+        return CanDrawPath::kNo;
+    }
+    return CanDrawPath::kYes;
+}
+
+bool AALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fContext->priv().auditTrail(),
+                              "AALinearizingConvexPathRenderer::onDrawPath");
+    SkASSERT(args.fSurfaceDrawContext->numSamples() <= 1);
+    SkASSERT(!args.fShape->isEmpty());
+    SkASSERT(!args.fShape->style().pathEffect());
+
+    SkPath path;
+    args.fShape->asPath(&path);
+    bool fill = args.fShape->style().isSimpleFill();
+    const SkStrokeRec& stroke = args.fShape->style().strokeRec();
+    SkScalar strokeWidth = fill ? -1.0f : stroke.getWidth();
+    SkPaint::Join join = fill ? SkPaint::Join::kMiter_Join : stroke.getJoin();
+    SkScalar miterLimit = stroke.getMiter();
+
+    GrOp::Owner op = AAFlatteningConvexPathOp::Make(
+            args.fContext, std::move(args.fPaint), *args.fViewMatrix, path, strokeWidth,
+            stroke.getStyle(), join, miterLimit, args.fUserStencilSettings);
+    args.fSurfaceDrawContext->addDrawOp(args.fClip, std::move(op));
+    return true;
+}
+
+} // namespace skgpu::v1
diff --git a/src/gpu/ops/AALinearizingConvexPathRenderer.h b/src/gpu/ops/AALinearizingConvexPathRenderer.h
new file mode 100644
index 0000000..b047087
--- /dev/null
+++ b/src/gpu/ops/AALinearizingConvexPathRenderer.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef AALinearizingConvexPathRenderer_DEFINED
+#define AALinearizingConvexPathRenderer_DEFINED
+
+#include "src/gpu/GrPathRenderer.h"
+
+namespace skgpu::v1 {
+
+class AALinearizingConvexPathRenderer final : public GrPathRenderer {
+public:
+    AALinearizingConvexPathRenderer() = default;
+
+    const char* name() const override { return "AALinear"; }
+
+private:
+    CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override;
+
+    bool onDrawPath(const DrawPathArgs&) override;
+
+    using INHERITED = GrPathRenderer;
+};
+
+} // namespace skgpu::v1
+
+#endif // AALinearizingConvexPathRenderer_DEFINED
diff --git a/src/gpu/ops/GrDashLinePathRenderer.cpp b/src/gpu/ops/DashLinePathRenderer.cpp
similarity index 84%
rename from src/gpu/ops/GrDashLinePathRenderer.cpp
rename to src/gpu/ops/DashLinePathRenderer.cpp
index 9f7932a..27992aa 100644
--- a/src/gpu/ops/GrDashLinePathRenderer.cpp
+++ b/src/gpu/ops/DashLinePathRenderer.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "src/gpu/ops/GrDashLinePathRenderer.h"
+#include "src/gpu/ops/DashLinePathRenderer.h"
 
 #include "src/gpu/GrAuditTrail.h"
 #include "src/gpu/GrGpu.h"
@@ -14,8 +14,9 @@
 #include "src/gpu/ops/GrMeshDrawOp.h"
 #include "src/gpu/v1/SurfaceDrawContext_v1.h"
 
-GrPathRenderer::CanDrawPath
-GrDashLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
+namespace skgpu::v1 {
+
+GrPathRenderer::CanDrawPath DashLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     SkPoint pts[2];
     bool inverted;
     if (args.fShape->style().isDashed() && args.fShape->asLine(pts, &inverted)) {
@@ -29,9 +30,9 @@
     return CanDrawPath::kNo;
 }
 
-bool GrDashLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
+bool DashLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fContext->priv().auditTrail(),
-                              "GrDashLinePathRenderer::onDrawPath");
+                              "DashLinePathRenderer::onDrawPath");
     GrDashOp::AAMode aaMode;
     switch (args.fAAType) {
         case GrAAType::kNone:
@@ -57,3 +58,5 @@
     args.fSurfaceDrawContext->addDrawOp(args.fClip, std::move(op));
     return true;
 }
+
+} // namespace skgpu::v1
diff --git a/src/gpu/ops/GrDashLinePathRenderer.h b/src/gpu/ops/DashLinePathRenderer.h
similarity index 61%
rename from src/gpu/ops/GrDashLinePathRenderer.h
rename to src/gpu/ops/DashLinePathRenderer.h
index 0bc172e..ef4a885 100644
--- a/src/gpu/ops/GrDashLinePathRenderer.h
+++ b/src/gpu/ops/DashLinePathRenderer.h
@@ -5,17 +5,22 @@
  * found in the LICENSE file.
  */
 
-#ifndef GrDashLinePathRenderer_DEFINED
-#define GrDashLinePathRenderer_DEFINED
+#ifndef DashLinePathRenderer_DEFINED
+#define DashLinePathRenderer_DEFINED
 
 #include "src/gpu/GrPathRenderer.h"
 
 class GrGpu;
 
-class GrDashLinePathRenderer : public GrPathRenderer {
-private:
-    const char* name() const final { return "DashLine"; }
+namespace skgpu::v1 {
 
+class DashLinePathRenderer final : public GrPathRenderer {
+public:
+    DashLinePathRenderer() = default;
+
+    const char* name() const override { return "DashLine"; }
+
+private:
     CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override;
 
     StencilSupport onGetStencilSupport(const GrStyledShape&) const override {
@@ -25,8 +30,10 @@
     bool onDrawPath(const DrawPathArgs&) override;
 
     sk_sp<GrGpu> fGpu;
+
     using INHERITED = GrPathRenderer;
 };
 
+} // namespace skgpu::v1
 
-#endif
+#endif // DashLinePathRenderer_DEFINED
diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/DefaultPathRenderer.cpp
similarity index 95%
rename from src/gpu/ops/GrDefaultPathRenderer.cpp
rename to src/gpu/ops/DefaultPathRenderer.cpp
index 53f33f5..6b07cac 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.cpp
+++ b/src/gpu/ops/DefaultPathRenderer.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "src/gpu/ops/GrDefaultPathRenderer.h"
+#include "src/gpu/ops/DefaultPathRenderer.h"
 
 #include "include/core/SkString.h"
 #include "include/core/SkStrokeRec.h"
@@ -30,15 +30,14 @@
 #include "src/gpu/ops/GrSimpleMeshDrawOpHelperWithStencil.h"
 #include "src/gpu/v1/SurfaceDrawContext_v1.h"
 
-GrDefaultPathRenderer::GrDefaultPathRenderer() {
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // Helpers for drawPath
 
+namespace {
+
 #define STENCIL_OFF     0   // Always disable stencil (even when needed)
 
-static inline bool single_pass_shape(const GrStyledShape& shape) {
+inline bool single_pass_shape(const GrStyledShape& shape) {
 #if STENCIL_OFF
     return true;
 #else
@@ -56,17 +55,6 @@
 #endif
 }
 
-GrPathRenderer::StencilSupport
-GrDefaultPathRenderer::onGetStencilSupport(const GrStyledShape& shape) const {
-    if (single_pass_shape(shape)) {
-        return GrPathRenderer::kNoRestriction_StencilSupport;
-    } else {
-        return GrPathRenderer::kStencilOnly_StencilSupport;
-    }
-}
-
-namespace {
-
 class PathGeoBuilder {
 public:
     PathGeoBuilder(GrPrimitiveType primitiveType,
@@ -253,7 +241,7 @@
                                                                           &fFirstVertex,
                                                                           &fVerticesInChunk));
         if (!fVertices) {
-            SkDebugf("WARNING: Failed to allocate vertex buffer for GrDefaultPathRenderer.\n");
+            SkDebugf("WARNING: Failed to allocate vertex buffer for DefaultPathRenderer.\n");
             fCurVert = nullptr;
             fCurIdx = fIndices = nullptr;
             fSubpathIndexStart = 0;
@@ -272,7 +260,7 @@
                                                       &fIndexBuffer, &fFirstIndex,
                                                       &fIndicesInChunk);
             if (!fIndices) {
-                SkDebugf("WARNING: Failed to allocate index buffer for GrDefaultPathRenderer.\n");
+                SkDebugf("WARNING: Failed to allocate index buffer for DefaultPathRenderer.\n");
                 fVertices = nullptr;
                 fValid = false;
             }
@@ -592,14 +580,47 @@
 
 }  // anonymous namespace
 
-bool GrDefaultPathRenderer::internalDrawPath(skgpu::v1::SurfaceDrawContext* sdc,
-                                             GrPaint&& paint,
-                                             GrAAType aaType,
-                                             const GrUserStencilSettings& userStencilSettings,
-                                             const GrClip* clip,
-                                             const SkMatrix& viewMatrix,
-                                             const GrStyledShape& shape,
-                                             bool stencilOnly) {
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#if GR_TEST_UTILS
+
+GR_DRAW_OP_TEST_DEFINE(DefaultPathOp) {
+    SkMatrix viewMatrix = GrTest::TestMatrix(random);
+
+    // For now just hairlines because the other types of draws require two ops.
+    // TODO we should figure out a way to combine the stencil and cover steps into one op.
+    GrStyle style(SkStrokeRec::kHairline_InitStyle);
+    const SkPath& path = GrTest::TestPath(random);
+
+    // Compute srcSpaceTol
+    SkRect bounds = path.getBounds();
+    SkScalar tol = GrPathUtils::kDefaultTolerance;
+    SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, bounds);
+
+    viewMatrix.mapRect(&bounds);
+    uint8_t coverage = GrRandomCoverage(random);
+    GrAAType aaType = GrAAType::kNone;
+    if (numSamples > 1 && random->nextBool()) {
+        aaType = GrAAType::kMSAA;
+    }
+    return DefaultPathOp::Make(context, std::move(paint), path, srcSpaceTol, coverage, viewMatrix,
+                               true, aaType, bounds, GrGetRandomStencil(random, context));
+}
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace skgpu::v1 {
+
+bool DefaultPathRenderer::internalDrawPath(skgpu::v1::SurfaceDrawContext* sdc,
+                                           GrPaint&& paint,
+                                           GrAAType aaType,
+                                           const GrUserStencilSettings& userStencilSettings,
+                                           const GrClip* clip,
+                                           const SkMatrix& viewMatrix,
+                                           const GrStyledShape& shape,
+                                           bool stencilOnly) {
     auto context = sdc->recordingContext();
 
     SkASSERT(GrAAType::kCoverage != aaType);
@@ -737,8 +758,17 @@
     return true;
 }
 
-GrPathRenderer::CanDrawPath
-GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
+
+GrPathRenderer::StencilSupport
+DefaultPathRenderer::onGetStencilSupport(const GrStyledShape& shape) const {
+    if (single_pass_shape(shape)) {
+        return GrPathRenderer::kNoRestriction_StencilSupport;
+    } else {
+        return GrPathRenderer::kStencilOnly_StencilSupport;
+    }
+}
+
+GrPathRenderer::CanDrawPath DefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     bool isHairline = GrIsStrokeHairlineOrEquivalent(
             args.fShape->style(), *args.fViewMatrix, nullptr);
     // If we aren't a single_pass_shape or hairline, we require stencil buffers.
@@ -758,9 +788,9 @@
     return CanDrawPath::kAsBackup;
 }
 
-bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
+bool DefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fContext->priv().auditTrail(),
-                              "GrDefaultPathRenderer::onDrawPath");
+                              "DefaultPathRenderer::onDrawPath");
     GrAAType aaType = (GrAAType::kNone != args.fAAType) ? GrAAType::kMSAA : GrAAType::kNone;
 
     return this->internalDrawPath(
@@ -768,9 +798,9 @@
             args.fClip, *args.fViewMatrix, *args.fShape, false);
 }
 
-void GrDefaultPathRenderer::onStencilPath(const StencilPathArgs& args) {
+void DefaultPathRenderer::onStencilPath(const StencilPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fContext->priv().auditTrail(),
-                              "GrDefaultPathRenderer::onStencilPath");
+                              "DefaultPathRenderer::onStencilPath");
     SkASSERT(!args.fShape->inverseFilled());
 
     GrPaint paint;
@@ -783,31 +813,4 @@
             args.fClip, *args.fViewMatrix, *args.fShape, true);
 }
 
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-#if GR_TEST_UTILS
-
-GR_DRAW_OP_TEST_DEFINE(DefaultPathOp) {
-    SkMatrix viewMatrix = GrTest::TestMatrix(random);
-
-    // For now just hairlines because the other types of draws require two ops.
-    // TODO we should figure out a way to combine the stencil and cover steps into one op.
-    GrStyle style(SkStrokeRec::kHairline_InitStyle);
-    const SkPath& path = GrTest::TestPath(random);
-
-    // Compute srcSpaceTol
-    SkRect bounds = path.getBounds();
-    SkScalar tol = GrPathUtils::kDefaultTolerance;
-    SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, bounds);
-
-    viewMatrix.mapRect(&bounds);
-    uint8_t coverage = GrRandomCoverage(random);
-    GrAAType aaType = GrAAType::kNone;
-    if (numSamples > 1 && random->nextBool()) {
-        aaType = GrAAType::kMSAA;
-    }
-    return DefaultPathOp::Make(context, std::move(paint), path, srcSpaceTol, coverage, viewMatrix,
-                               true, aaType, bounds, GrGetRandomStencil(random, context));
-}
-
-#endif
+} // namespace skgpu::v1
diff --git a/src/gpu/ops/GrDefaultPathRenderer.h b/src/gpu/ops/DefaultPathRenderer.h
similarity index 77%
rename from src/gpu/ops/GrDefaultPathRenderer.h
rename to src/gpu/ops/DefaultPathRenderer.h
index d9106a0..974c3dd 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.h
+++ b/src/gpu/ops/DefaultPathRenderer.h
@@ -5,22 +5,24 @@
  * found in the LICENSE file.
  */
 
-#ifndef GrDefaultPathRenderer_DEFINED
-#define GrDefaultPathRenderer_DEFINED
+#ifndef DefaultPathRenderer_DEFINED
+#define DefaultPathRenderer_DEFINED
 
 #include "include/core/SkTypes.h"
 #include "src/gpu/GrPathRenderer.h"
 #include "src/gpu/ops/GrPathStencilSettings.h"
 
+namespace skgpu::v1 {
+
 /**
  *  Subclass that renders the path using the stencil buffer to resolve fill rules
  * (e.g. winding, even-odd)
  */
-class GrDefaultPathRenderer : public GrPathRenderer {
+class DefaultPathRenderer final : public GrPathRenderer {
 public:
-    GrDefaultPathRenderer();
+    DefaultPathRenderer() = default;
 
-    const char* name() const final { return "Default"; }
+    const char* name() const override { return "Default"; }
 
 private:
     StencilSupport onGetStencilSupport(const GrStyledShape&) const override;
@@ -43,4 +45,6 @@
     using INHERITED = GrPathRenderer;
 };
 
-#endif
+} // namespace skgpu::v1
+
+#endif // DefaultPathRenderer_DEFINED
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.h b/src/gpu/ops/GrAAConvexPathRenderer.h
deleted file mode 100644
index bb69745..0000000
--- a/src/gpu/ops/GrAAConvexPathRenderer.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrAAConvexPathRenderer_DEFINED
-#define GrAAConvexPathRenderer_DEFINED
-
-#include "src/gpu/GrPathRenderer.h"
-
-class GrAAConvexPathRenderer : public GrPathRenderer {
-public:
-    const char* name() const final { return "AAConvex"; }
-
-    GrAAConvexPathRenderer();
-
-private:
-    CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override;
-
-    bool onDrawPath(const DrawPathArgs&) override;
-};
-
-#endif
diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.h b/src/gpu/ops/GrAAHairLinePathRenderer.h
deleted file mode 100644
index bac3041..0000000
--- a/src/gpu/ops/GrAAHairLinePathRenderer.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrAAHairLinePathRenderer_DEFINED
-#define GrAAHairLinePathRenderer_DEFINED
-
-#include "src/gpu/GrPathRenderer.h"
-
-class GrAAHairLinePathRenderer : public GrPathRenderer {
-public:
-    GrAAHairLinePathRenderer() {}
-
-    const char* name() const final { return "AAHairline"; }
-
-    typedef SkTArray<SkPoint, true> PtArray;
-    typedef SkTArray<int, true> IntArray;
-    typedef SkTArray<float, true> FloatArray;
-
-private:
-    CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override;
-
-    bool onDrawPath(const DrawPathArgs&) override;
-
-    using INHERITED = GrPathRenderer;
-};
-
-
-#endif
diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.h b/src/gpu/ops/GrAALinearizingConvexPathRenderer.h
deleted file mode 100644
index c9c895d..0000000
--- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef GrAALinearizingConvexPathRenderer_DEFINED
-#define GrAALinearizingConvexPathRenderer_DEFINED
-
-#include "src/gpu/GrPathRenderer.h"
-
-class GrAALinearizingConvexPathRenderer : public GrPathRenderer {
-public:
-    const char* name() const final { return "AALinear"; }
-
-    GrAALinearizingConvexPathRenderer();
-
-private:
-    CanDrawPath onCanDrawPath(const CanDrawPathArgs&) const override;
-
-    bool onDrawPath(const DrawPathArgs&) override;
-};
-
-#endif
diff --git a/tests/DefaultPathRendererTest.cpp b/tests/DefaultPathRendererTest.cpp
index 9134bcd..1e9598e 100644
--- a/tests/DefaultPathRendererTest.cpp
+++ b/tests/DefaultPathRendererTest.cpp
@@ -72,7 +72,7 @@
 //   create a new render target context that will reuse the prior GrSurface
 //   draw a normally wound concave path that touches outside of the approx fit RTC's content rect
 //
-// When the bug manifests the GrDefaultPathRenderer/GrMSAAPathRenderer is/was leaving the stencil
+// When the bug manifests the DefaultPathRenderer/GrMSAAPathRenderer is/was leaving the stencil
 // buffer outside of the first content rect in a bad state and the second draw would be incorrect.
 
 static void run_test(GrDirectContext* dContext, skiatest::Reporter* reporter) {
@@ -130,7 +130,7 @@
     }
 }
 
-DEF_GPUTEST_FOR_CONTEXTS(GrDefaultPathRendererTest,
+DEF_GPUTEST_FOR_CONTEXTS(DefaultPathRendererTest,
                          sk_gpu_test::GrContextFactory::IsRenderingContext,
                          reporter, ctxInfo, only_allow_default) {
     auto ctx = ctxInfo.directContext();
diff --git a/tests/GpuDrawPathTest.cpp b/tests/GpuDrawPathTest.cpp
index d71ea2f..6f4976a 100644
--- a/tests/GpuDrawPathTest.cpp
+++ b/tests/GpuDrawPathTest.cpp
@@ -114,7 +114,7 @@
 }
 
 DEF_GPUTEST_FOR_ALL_CONTEXTS(PathTest_CrBug1232834, reporter, ctxInfo) {
-    // GrAAHairlinePathRenderer chops this path to quads that include infinities (and then NaNs).
+    // AAHairlinePathRenderer chops this path to quads that include infinities (and then NaNs).
     // It used to trigger asserts, now the degenerate quad segments should cause it to be rejected.
     SkImageInfo info = SkImageInfo::MakeN32Premul(256, 256);
     auto surface(SkSurface::MakeRenderTarget(ctxInfo.directContext(), SkBudgeted::kNo, info));