Move more Ops to skgpu::v1 namespace (take 2)

GrClearOp
GrDashOp

Bug: skia:11837
Change-Id: I9ada76c061154e769e7f486e7c57a93fd1d74907
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/444636
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/ops/GrClearOp.cpp b/src/gpu/ops/ClearOp.cpp
similarity index 64%
rename from src/gpu/ops/GrClearOp.cpp
rename to src/gpu/ops/ClearOp.cpp
index 94ccff6..33fb97e 100644
--- a/src/gpu/ops/GrClearOp.cpp
+++ b/src/gpu/ops/ClearOp.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "src/gpu/ops/GrClearOp.h"
+#include "src/gpu/ops/ClearOp.h"
 
 #include "include/gpu/GrRecordingContext.h"
 #include "src/gpu/GrMemoryPool.h"
@@ -14,31 +14,37 @@
 #include "src/gpu/GrProxyProvider.h"
 #include "src/gpu/GrRecordingContextPriv.h"
 
-static bool contains_scissor(const GrScissorState& a, const GrScissorState& b) {
+namespace {
+
+bool contains_scissor(const GrScissorState& a, const GrScissorState& b) {
     return !a.enabled() || (b.enabled() && a.rect().contains(b.rect()));
 }
 
-GrOp::Owner GrClearOp::MakeColor(GrRecordingContext* context,
-                                 const GrScissorState& scissor,
-                                 std::array<float, 4> color) {
-    return GrOp::Make<GrClearOp>(context, Buffer::kColor, scissor, color, false);
+} // anonymous namespace
+
+namespace skgpu::v1 {
+
+GrOp::Owner ClearOp::MakeColor(GrRecordingContext* context,
+                               const GrScissorState& scissor,
+                               std::array<float, 4> color) {
+    return GrOp::Make<ClearOp>(context, Buffer::kColor, scissor, color, false);
 }
 
-GrOp::Owner GrClearOp::MakeStencilClip(GrRecordingContext* context,
-                                       const GrScissorState& scissor,
-                                       bool insideMask) {
-    return GrOp::Make<GrClearOp>(context,
-                                 Buffer::kStencilClip,
-                                 scissor,
-                                 std::array<float, 4>(),
-                                 insideMask);
+GrOp::Owner ClearOp::MakeStencilClip(GrRecordingContext* context,
+                                     const GrScissorState& scissor,
+                                     bool insideMask) {
+    return GrOp::Make<ClearOp>(context,
+                               Buffer::kStencilClip,
+                               scissor,
+                               std::array<float, 4>(),
+                               insideMask);
 }
 
-GrClearOp::GrClearOp(Buffer buffer,
-                     const GrScissorState& scissor,
-                     std::array<float, 4> color,
-                     bool insideMask)
-        : INHERITED(ClassID())
+ClearOp::ClearOp(Buffer buffer,
+                 const GrScissorState& scissor,
+                 std::array<float, 4> color,
+                 bool insideMask)
+        : GrOp(ClassID())
         , fScissor(scissor)
         , fColor(color)
         , fStencilInsideMask(insideMask)
@@ -46,8 +52,8 @@
     this->setBounds(SkRect::Make(scissor.rect()), HasAABloat::kNo, IsHairline::kNo);
 }
 
-GrOp::CombineResult GrClearOp::onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) {
-    GrClearOp* other = t->cast<GrClearOp>();
+GrOp::CombineResult ClearOp::onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) {
+    auto other = t->cast<ClearOp>();
 
     if (other->fBuffer == fBuffer) {
         // This could be much more complicated. Currently we look at cases where the new clear
@@ -77,7 +83,7 @@
     return CombineResult::kCannotCombine;
 }
 
-void GrClearOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
+void ClearOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
     SkASSERT(state->opsRenderPass());
     if (fBuffer & Buffer::kColor) {
         state->opsRenderPass()->clear(fScissor, fColor);
@@ -87,3 +93,6 @@
         state->opsRenderPass()->clearStencilClip(fScissor, fStencilInsideMask);
     }
 }
+
+} // namespace skgpu::v1
+
diff --git a/src/gpu/ops/GrClearOp.h b/src/gpu/ops/ClearOp.h
similarity index 87%
rename from src/gpu/ops/GrClearOp.h
rename to src/gpu/ops/ClearOp.h
index cf4281d..26854c6 100644
--- a/src/gpu/ops/GrClearOp.h
+++ b/src/gpu/ops/ClearOp.h
@@ -5,8 +5,8 @@
  * found in the LICENSE file.
  */
 
-#ifndef GrClearOp_DEFINED
-#define GrClearOp_DEFINED
+#ifndef ClearOp_DEFINED
+#define ClearOp_DEFINED
 
 #include "include/gpu/GrTypes.h"
 #include "src/gpu/GrScissorState.h"
@@ -15,7 +15,9 @@
 class GrOpFlushState;
 class GrRecordingContext;
 
-class GrClearOp final : public GrOp {
+namespace skgpu::v1 {
+
+class ClearOp final : public GrOp {
 public:
     DEFINE_OP_CLASS_ID
 
@@ -43,10 +45,10 @@
     };
     GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(Buffer);
 
-    GrClearOp(Buffer buffer,
-              const GrScissorState& scissor,
-              std::array<float, 4> color,
-              bool stencil);
+    ClearOp(Buffer buffer,
+            const GrScissorState& scissor,
+            std::array<float, 4> color,
+            bool stencil);
 
     CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override;
 
@@ -75,10 +77,10 @@
     std::array<float, 4> fColor;
     bool                 fStencilInsideMask;
     Buffer               fBuffer;
-
-    using INHERITED = GrOp;
 };
 
-GR_MAKE_BITFIELD_CLASS_OPS(GrClearOp::Buffer)
+GR_MAKE_BITFIELD_CLASS_OPS(ClearOp::Buffer)
 
-#endif
+} // namespace skgpu::v1
+
+#endif // ClearOp_DEFINED
diff --git a/src/gpu/ops/DashLinePathRenderer.cpp b/src/gpu/ops/DashLinePathRenderer.cpp
index d9e51125..ccfd5ba 100644
--- a/src/gpu/ops/DashLinePathRenderer.cpp
+++ b/src/gpu/ops/DashLinePathRenderer.cpp
@@ -10,7 +10,7 @@
 #include "src/gpu/GrAuditTrail.h"
 #include "src/gpu/GrGpu.h"
 #include "src/gpu/geometry/GrStyledShape.h"
-#include "src/gpu/ops/GrDashOp.h"
+#include "src/gpu/ops/DashOp.h"
 #include "src/gpu/ops/GrMeshDrawOp.h"
 #include "src/gpu/v1/SurfaceDrawContext_v1.h"
 
@@ -22,7 +22,7 @@
     if (args.fShape->style().isDashed() && args.fShape->asLine(pts, &inverted)) {
         // We should never have an inverse dashed case.
         SkASSERT(!inverted);
-        if (!GrDashOp::CanDrawDashLine(pts, args.fShape->style(), *args.fViewMatrix)) {
+        if (!DashOp::CanDrawDashLine(pts, args.fShape->style(), *args.fViewMatrix)) {
             return CanDrawPath::kNo;
         }
         return CanDrawPath::kYes;
@@ -33,25 +33,25 @@
 bool DashLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fContext->priv().auditTrail(),
                               "DashLinePathRenderer::onDrawPath");
-    GrDashOp::AAMode aaMode;
+    DashOp::AAMode aaMode;
     switch (args.fAAType) {
         case GrAAType::kNone:
-            aaMode = GrDashOp::AAMode::kNone;
+            aaMode = DashOp::AAMode::kNone;
             break;
         case GrAAType::kMSAA:
             // In this mode we will use aa between dashes but the outer border uses MSAA. Otherwise,
             // we can wind up with external edges antialiased and internal edges unantialiased.
-            aaMode = GrDashOp::AAMode::kCoverageWithMSAA;
+            aaMode = DashOp::AAMode::kCoverageWithMSAA;
             break;
         case GrAAType::kCoverage:
-            aaMode = GrDashOp::AAMode::kCoverage;
+            aaMode = DashOp::AAMode::kCoverage;
             break;
     }
     SkPoint pts[2];
     SkAssertResult(args.fShape->asLine(pts, nullptr));
-    GrOp::Owner op =
-            GrDashOp::MakeDashLineOp(args.fContext, std::move(args.fPaint), *args.fViewMatrix, pts,
-                                     aaMode, args.fShape->style(), args.fUserStencilSettings);
+    GrOp::Owner op = DashOp::MakeDashLineOp(args.fContext, std::move(args.fPaint),
+                                            *args.fViewMatrix, pts, aaMode, args.fShape->style(),
+                                            args.fUserStencilSettings);
     if (!op) {
         return false;
     }
diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/DashOp.cpp
similarity index 93%
rename from src/gpu/ops/GrDashOp.cpp
rename to src/gpu/ops/DashOp.cpp
index 35ffdb7..aaee912 100644
--- a/src/gpu/ops/GrDashOp.cpp
+++ b/src/gpu/ops/DashOp.cpp
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-#include "src/gpu/ops/GrDashOp.h"
+#include "src/gpu/ops/DashOp.h"
 
 #include "include/gpu/GrRecordingContext.h"
 #include "src/core/SkMatrixPriv.h"
@@ -13,7 +13,6 @@
 #include "src/gpu/GrAppliedClip.h"
 #include "src/gpu/GrCaps.h"
 #include "src/gpu/GrDefaultGeoProcFactory.h"
-#include "src/gpu/GrDrawOpTest.h"
 #include "src/gpu/GrGeometryProcessor.h"
 #include "src/gpu/GrMemoryPool.h"
 #include "src/gpu/GrOpFlushState.h"
@@ -32,51 +31,16 @@
 #include "src/gpu/ops/GrMeshDrawOp.h"
 #include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h"
 
-using AAMode = GrDashOp::AAMode;
+using AAMode = skgpu::v1::DashOp::AAMode;
 
-///////////////////////////////////////////////////////////////////////////////
+#if GR_TEST_UTILS
+static const int kAAModeCnt = static_cast<int>(skgpu::v1::DashOp::AAMode::kCoverageWithMSAA) + 1;
+#endif
 
-// Returns whether or not the gpu can fast path the dash line effect.
-bool GrDashOp::CanDrawDashLine(const SkPoint pts[2], const GrStyle& style,
-                               const SkMatrix& viewMatrix) {
-    // Pts must be either horizontal or vertical in src space
-    if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) {
-        return false;
-    }
+namespace {
 
-    // May be able to relax this to include skew. As of now cannot do perspective
-    // because of the non uniform scaling of bloating a rect
-    if (!viewMatrix.preservesRightAngles()) {
-        return false;
-    }
-
-    if (!style.isDashed() || 2 != style.dashIntervalCnt()) {
-        return false;
-    }
-
-    const SkScalar* intervals = style.dashIntervals();
-    if (0 == intervals[0] && 0 == intervals[1]) {
-        return false;
-    }
-
-    SkPaint::Cap cap = style.strokeRec().getCap();
-    if (SkPaint::kRound_Cap == cap) {
-        // Current we don't support round caps unless the on interval is zero
-        if (intervals[0] != 0.f) {
-            return false;
-        }
-        // If the width of the circle caps in greater than the off interval we will pick up unwanted
-        // segments of circles at the start and end of the dash line.
-        if (style.strokeRec().getWidth() > intervals[1]) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-static void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale,
-                            const SkMatrix& viewMatrix, const SkPoint pts[2]) {
+void calc_dash_scaling(SkScalar* parallelScale, SkScalar* perpScale,
+                       const SkMatrix& viewMatrix, const SkPoint pts[2]) {
     SkVector vecSrc = pts[1] - pts[0];
     if (pts[1] == pts[0]) {
         vecSrc.set(1.0, 0.0);
@@ -98,7 +62,7 @@
 
 // calculates the rotation needed to aligned pts to the x axis with pts[0] < pts[1]
 // Stores the rotation matrix in rotMatrix, and the mapped points in ptsRot
-static void align_to_x_axis(const SkPoint pts[2], SkMatrix* rotMatrix, SkPoint ptsRot[2] = nullptr) {
+void align_to_x_axis(const SkPoint pts[2], SkMatrix* rotMatrix, SkPoint ptsRot[2] = nullptr) {
     SkVector vec = pts[1] - pts[0];
     if (pts[1] == pts[0]) {
         vec.set(1.0, 0.0);
@@ -116,7 +80,7 @@
 }
 
 // Assumes phase < sum of all intervals
-static SkScalar calc_start_adjustment(const SkScalar intervals[2], SkScalar phase) {
+SkScalar calc_start_adjustment(const SkScalar intervals[2], SkScalar phase) {
     SkASSERT(phase < intervals[0] + intervals[1]);
     if (phase >= intervals[0] && phase != 0) {
         SkScalar srcIntervalLen = intervals[0] + intervals[1];
@@ -125,8 +89,8 @@
     return 0;
 }
 
-static SkScalar calc_end_adjustment(const SkScalar intervals[2], const SkPoint pts[2],
-                                    SkScalar phase, SkScalar* endingInt) {
+SkScalar calc_end_adjustment(const SkScalar intervals[2], const SkPoint pts[2],
+                             SkScalar phase, SkScalar* endingInt) {
     if (pts[1].fX <= pts[0].fX) {
         return 0;
     }
@@ -151,17 +115,17 @@
     kNonRound_DashCap,
 };
 
-static void setup_dashed_rect(const SkRect& rect,
-                              GrVertexWriter& vertices,
-                              const SkMatrix& matrix,
-                              SkScalar offset,
-                              SkScalar bloatX,
-                              SkScalar len,
-                              SkScalar startInterval,
-                              SkScalar endInterval,
-                              SkScalar strokeWidth,
-                              SkScalar perpScale,
-                              DashCap cap) {
+void setup_dashed_rect(const SkRect& rect,
+                       GrVertexWriter& vertices,
+                       const SkMatrix& matrix,
+                       SkScalar offset,
+                       SkScalar bloatX,
+                       SkScalar len,
+                       SkScalar startInterval,
+                       SkScalar endInterval,
+                       SkScalar strokeWidth,
+                       SkScalar perpScale,
+                       DashCap cap) {
     SkScalar intervalLength = startInterval + endInterval;
     // 'dashRect' gets interpolated over the rendered 'rect'. For y we want the perpendicular signed
     // distance from the stroke center line in device space. 'perpScale' is the scale factor applied
@@ -200,14 +164,14 @@
  * Bounding geometry is rendered and the effect computes coverage based on the fragment's
  * position relative to the dashed line.
  */
-static GrGeometryProcessor* make_dash_gp(SkArenaAlloc* arena,
-                                         const SkPMColor4f&,
-                                         AAMode aaMode,
-                                         DashCap cap,
-                                         const SkMatrix& localMatrix,
-                                         bool usesLocalCoords);
+GrGeometryProcessor* make_dash_gp(SkArenaAlloc* arena,
+                                  const SkPMColor4f&,
+                                  AAMode aaMode,
+                                  DashCap cap,
+                                  const SkMatrix& localMatrix,
+                                  bool usesLocalCoords);
 
-class DashOp final : public GrMeshDrawOp {
+class DashOpImpl final : public GrMeshDrawOp {
 public:
     DEFINE_OP_CLASS_ID
 
@@ -228,8 +192,8 @@
                             SkPaint::Cap cap,
                             AAMode aaMode, bool fullDash,
                             const GrUserStencilSettings* stencilSettings) {
-        return GrOp::Make<DashOp>(context, std::move(paint), geometry, cap,
-                                  aaMode, fullDash, stencilSettings);
+        return GrOp::Make<DashOpImpl>(context, std::move(paint), geometry, cap,
+                                      aaMode, fullDash, stencilSettings);
     }
 
     const char* name() const override { return "DashOp"; }
@@ -265,8 +229,8 @@
 private:
     friend class GrOp; // for ctor
 
-    DashOp(GrPaint&& paint, const LineData& geometry, SkPaint::Cap cap, AAMode aaMode,
-           bool fullDash, const GrUserStencilSettings* stencilSettings)
+    DashOpImpl(GrPaint&& paint, const LineData& geometry, SkPaint::Cap cap, AAMode aaMode,
+               bool fullDash, const GrUserStencilSettings* stencilSettings)
             : INHERITED(ClassID())
             , fColor(paint.getColor4f())
             , fFullDash(fullDash)
@@ -661,7 +625,7 @@
     }
 
     CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps& caps) override {
-        DashOp* that = t->cast<DashOp>();
+        auto that = t->cast<DashOpImpl>();
         if (fProcessorSet != that->fProcessorSet) {
             return CombineResult::kCannotCombine;
         }
@@ -715,9 +679,6 @@
     bool fullDash() const { return fFullDash; }
     SkPaint::Cap cap() const { return fCap; }
 
-    static const int kVertsPerDash = 4;
-    static const int kIndicesPerDash = 6;
-
     SkSTArray<1, LineData, true> fLines;
     SkPMColor4f fColor;
     bool fUsesLocalCoords : 1;
@@ -734,68 +695,6 @@
     using INHERITED = GrMeshDrawOp;
 };
 
-GrOp::Owner GrDashOp::MakeDashLineOp(GrRecordingContext* context,
-                                     GrPaint&& paint,
-                                     const SkMatrix& viewMatrix,
-                                     const SkPoint pts[2],
-                                     AAMode aaMode,
-                                     const GrStyle& style,
-                                     const GrUserStencilSettings* stencilSettings) {
-    SkASSERT(GrDashOp::CanDrawDashLine(pts, style, viewMatrix));
-    const SkScalar* intervals = style.dashIntervals();
-    SkScalar phase = style.dashPhase();
-
-    SkPaint::Cap cap = style.strokeRec().getCap();
-
-    DashOp::LineData lineData;
-    lineData.fSrcStrokeWidth = style.strokeRec().getWidth();
-
-    // the phase should be normalized to be [0, sum of all intervals)
-    SkASSERT(phase >= 0 && phase < intervals[0] + intervals[1]);
-
-    // Rotate the src pts so they are aligned horizontally with pts[0].fX < pts[1].fX
-    if (pts[0].fY != pts[1].fY || pts[0].fX > pts[1].fX) {
-        SkMatrix rotMatrix;
-        align_to_x_axis(pts, &rotMatrix, lineData.fPtsRot);
-        if (!rotMatrix.invert(&lineData.fSrcRotInv)) {
-            SkDebugf("Failed to create invertible rotation matrix!\n");
-            return nullptr;
-        }
-    } else {
-        lineData.fSrcRotInv.reset();
-        memcpy(lineData.fPtsRot, pts, 2 * sizeof(SkPoint));
-    }
-
-    // Scale corrections of intervals and stroke from view matrix
-    calc_dash_scaling(&lineData.fParallelScale, &lineData.fPerpendicularScale, viewMatrix, pts);
-    if (SkScalarNearlyZero(lineData.fParallelScale) ||
-        SkScalarNearlyZero(lineData.fPerpendicularScale)) {
-        return nullptr;
-    }
-
-    SkScalar offInterval = intervals[1] * lineData.fParallelScale;
-    SkScalar strokeWidth = lineData.fSrcStrokeWidth * lineData.fPerpendicularScale;
-
-    if (SkPaint::kSquare_Cap == cap && 0 != lineData.fSrcStrokeWidth) {
-        // add cap to on interval and remove from off interval
-        offInterval -= strokeWidth;
-    }
-
-    // TODO we can do a real rect call if not using fulldash(ie no off interval, not using AA)
-    bool fullDash = offInterval > 0.f || aaMode != AAMode::kNone;
-
-    lineData.fViewMatrix = viewMatrix;
-    lineData.fPhase = phase;
-    lineData.fIntervals[0] = intervals[0];
-    lineData.fIntervals[1] = intervals[1];
-
-    return DashOp::Make(context, std::move(paint), lineData, cap, aaMode, fullDash,
-                        stencilSettings);
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-namespace {
 /*
  * This effect will draw a dotted line (defined as a dashed lined with round caps and no on
  * interval). The radius of the dots is given by the strokeWidth and the spacing by the DashInfo.
@@ -840,7 +739,6 @@
 
     using INHERITED = GrGeometryProcessor;
 };
-}  // anonymous namespace
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -974,7 +872,7 @@
 
 #if GR_TEST_UTILS
 GrGeometryProcessor* DashingCircleEffect::TestCreate(GrProcessorTestData* d) {
-    AAMode aaMode = static_cast<AAMode>(d->fRandom->nextULessThan(GrDashOp::kAAModeCnt));
+    AAMode aaMode = static_cast<AAMode>(d->fRandom->nextULessThan(kAAModeCnt));
     GrColor color = GrTest::RandomColor(d->fRandom);
     SkMatrix matrix = GrTest::TestMatrix(d->fRandom);
     return DashingCircleEffect::Make(d->allocator(),
@@ -987,7 +885,6 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
-namespace {
 /*
  * This effect will draw a dashed line. The width of the dash is given by the strokeWidth and the
  * length and spacing by the DashInfo. Both of the previous two parameters are in device space.
@@ -1034,7 +931,6 @@
 
     using INHERITED = GrGeometryProcessor;
 };
-}  // anonymous namespace
 
 //////////////////////////////////////////////////////////////////////////////
 
@@ -1175,11 +1071,11 @@
                                      AAMode aaMode,
                                      const SkMatrix& localMatrix,
                                      bool usesLocalCoords)
-    : INHERITED(kDashingLineEffect_ClassID)
-    , fColor(color)
-    , fLocalMatrix(localMatrix)
-    , fUsesLocalCoords(usesLocalCoords)
-    , fAAMode(aaMode) {
+        : INHERITED(kDashingLineEffect_ClassID)
+        , fColor(color)
+        , fLocalMatrix(localMatrix)
+        , fUsesLocalCoords(usesLocalCoords)
+        , fAAMode(aaMode) {
     fInPosition = {"inPosition", kFloat2_GrVertexAttribType, kFloat2_GrSLType};
     fInDashParams = {"inDashParams", kFloat3_GrVertexAttribType, kHalf3_GrSLType};
     fInRect = {"inRect", kFloat4_GrVertexAttribType, kHalf4_GrSLType};
@@ -1190,7 +1086,7 @@
 
 #if GR_TEST_UTILS
 GrGeometryProcessor* DashingLineEffect::TestCreate(GrProcessorTestData* d) {
-    AAMode aaMode = static_cast<AAMode>(d->fRandom->nextULessThan(GrDashOp::kAAModeCnt));
+    AAMode aaMode = static_cast<AAMode>(d->fRandom->nextULessThan(kAAModeCnt));
     GrColor color = GrTest::RandomColor(d->fRandom);
     SkMatrix matrix = GrTest::TestMatrix(d->fRandom);
     return DashingLineEffect::Make(d->allocator(),
@@ -1203,12 +1099,12 @@
 #endif
 //////////////////////////////////////////////////////////////////////////////
 
-static GrGeometryProcessor* make_dash_gp(SkArenaAlloc* arena,
-                                         const SkPMColor4f& color,
-                                         AAMode aaMode,
-                                         DashCap cap,
-                                         const SkMatrix& viewMatrix,
-                                         bool usesLocalCoords) {
+GrGeometryProcessor* make_dash_gp(SkArenaAlloc* arena,
+                                  const SkPMColor4f& color,
+                                  AAMode aaMode,
+                                  DashCap cap,
+                                  const SkMatrix& viewMatrix,
+                                  bool usesLocalCoords) {
     SkMatrix invert;
     if (usesLocalCoords && !viewMatrix.invert(&invert)) {
         SkDebugf("Failed to invert\n");
@@ -1224,15 +1120,19 @@
     return nullptr;
 }
 
+} // anonymous namespace
+
 /////////////////////////////////////////////////////////////////////////////////////////////////
 
 #if GR_TEST_UTILS
 
-GR_DRAW_OP_TEST_DEFINE(DashOp) {
+#include "src/gpu/GrDrawOpTest.h"
+
+GR_DRAW_OP_TEST_DEFINE(DashOpImpl) {
     SkMatrix viewMatrix = GrTest::TestMatrixPreservesRightAngles(random);
     AAMode aaMode;
     do {
-        aaMode = static_cast<AAMode>(random->nextULessThan(GrDashOp::kAAModeCnt));
+        aaMode = static_cast<AAMode>(random->nextULessThan(kAAModeCnt));
     } while (AAMode::kCoverageWithMSAA == aaMode && numSamples <= 1);
 
     // We can only dash either horizontal or vertical lines
@@ -1298,8 +1198,111 @@
 
     GrStyle style(p);
 
-    return GrDashOp::MakeDashLineOp(context, std::move(paint), viewMatrix, pts, aaMode, style,
-                                    GrGetRandomStencil(random, context));
+    return skgpu::v1::DashOp::MakeDashLineOp(context, std::move(paint), viewMatrix, pts, aaMode,
+                                             style, GrGetRandomStencil(random, context));
 }
 
-#endif
+#endif // GR_TEST_UTILS
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace skgpu::v1::DashOp {
+
+GrOp::Owner MakeDashLineOp(GrRecordingContext* context,
+                           GrPaint&& paint,
+                           const SkMatrix& viewMatrix,
+                           const SkPoint pts[2],
+                           AAMode aaMode,
+                           const GrStyle& style,
+                           const GrUserStencilSettings* stencilSettings) {
+    SkASSERT(CanDrawDashLine(pts, style, viewMatrix));
+    const SkScalar* intervals = style.dashIntervals();
+    SkScalar phase = style.dashPhase();
+
+    SkPaint::Cap cap = style.strokeRec().getCap();
+
+    DashOpImpl::LineData lineData;
+    lineData.fSrcStrokeWidth = style.strokeRec().getWidth();
+
+    // the phase should be normalized to be [0, sum of all intervals)
+    SkASSERT(phase >= 0 && phase < intervals[0] + intervals[1]);
+
+    // Rotate the src pts so they are aligned horizontally with pts[0].fX < pts[1].fX
+    if (pts[0].fY != pts[1].fY || pts[0].fX > pts[1].fX) {
+        SkMatrix rotMatrix;
+        align_to_x_axis(pts, &rotMatrix, lineData.fPtsRot);
+        if (!rotMatrix.invert(&lineData.fSrcRotInv)) {
+            SkDebugf("Failed to create invertible rotation matrix!\n");
+            return nullptr;
+        }
+    } else {
+        lineData.fSrcRotInv.reset();
+        memcpy(lineData.fPtsRot, pts, 2 * sizeof(SkPoint));
+    }
+
+    // Scale corrections of intervals and stroke from view matrix
+    calc_dash_scaling(&lineData.fParallelScale, &lineData.fPerpendicularScale, viewMatrix, pts);
+    if (SkScalarNearlyZero(lineData.fParallelScale) ||
+        SkScalarNearlyZero(lineData.fPerpendicularScale)) {
+        return nullptr;
+    }
+
+    SkScalar offInterval = intervals[1] * lineData.fParallelScale;
+    SkScalar strokeWidth = lineData.fSrcStrokeWidth * lineData.fPerpendicularScale;
+
+    if (SkPaint::kSquare_Cap == cap && 0 != lineData.fSrcStrokeWidth) {
+        // add cap to on interval and remove from off interval
+        offInterval -= strokeWidth;
+    }
+
+    // TODO we can do a real rect call if not using fulldash(ie no off interval, not using AA)
+    bool fullDash = offInterval > 0.f || aaMode != AAMode::kNone;
+
+    lineData.fViewMatrix = viewMatrix;
+    lineData.fPhase = phase;
+    lineData.fIntervals[0] = intervals[0];
+    lineData.fIntervals[1] = intervals[1];
+
+    return DashOpImpl::Make(context, std::move(paint), lineData, cap, aaMode, fullDash,
+                            stencilSettings);
+}
+
+// Returns whether or not the gpu can fast path the dash line effect.
+bool CanDrawDashLine(const SkPoint pts[2], const GrStyle& style, const SkMatrix& viewMatrix) {
+    // Pts must be either horizontal or vertical in src space
+    if (pts[0].fX != pts[1].fX && pts[0].fY != pts[1].fY) {
+        return false;
+    }
+
+    // May be able to relax this to include skew. As of now cannot do perspective
+    // because of the non uniform scaling of bloating a rect
+    if (!viewMatrix.preservesRightAngles()) {
+        return false;
+    }
+
+    if (!style.isDashed() || 2 != style.dashIntervalCnt()) {
+        return false;
+    }
+
+    const SkScalar* intervals = style.dashIntervals();
+    if (0 == intervals[0] && 0 == intervals[1]) {
+        return false;
+    }
+
+    SkPaint::Cap cap = style.strokeRec().getCap();
+    if (SkPaint::kRound_Cap == cap) {
+        // Current we don't support round caps unless the on interval is zero
+        if (intervals[0] != 0.f) {
+            return false;
+        }
+        // If the width of the circle caps in greater than the off interval we will pick up unwanted
+        // segments of circles at the start and end of the dash line.
+        if (style.strokeRec().getWidth() > intervals[1]) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+} // namespace skgpu::v1::DashOp
diff --git a/src/gpu/ops/GrDashOp.h b/src/gpu/ops/DashOp.h
similarity index 77%
rename from src/gpu/ops/GrDashOp.h
rename to src/gpu/ops/DashOp.h
index addd9e1..18f9b9e 100644
--- a/src/gpu/ops/GrDashOp.h
+++ b/src/gpu/ops/DashOp.h
@@ -5,26 +5,24 @@
  * found in the LICENSE file.
  */
 
-#ifndef GrDashOp_DEFINED
-#define GrDashOp_DEFINED
+#ifndef DashOp_DEFINED
+#define DashOp_DEFINED
 
-#include "include/core/SkPathEffect.h"
 #include "include/gpu/GrTypes.h"
 #include "src/gpu/ops/GrOp.h"
 
-class GrDrawOp;
 class GrPaint;
 class GrRecordingContext;
 class GrStyle;
 struct GrUserStencilSettings;
 
-namespace GrDashOp {
+namespace skgpu::v1::DashOp {
+
 enum class AAMode {
     kNone,
     kCoverage,
     kCoverageWithMSAA,
 };
-static const int kAAModeCnt = static_cast<int>(AAMode::kCoverageWithMSAA) + 1;
 
 GrOp::Owner MakeDashLineOp(GrRecordingContext*,
                            GrPaint&&,
@@ -34,6 +32,7 @@
                            const GrStyle& style,
                            const GrUserStencilSettings*);
 bool CanDrawDashLine(const SkPoint pts[2], const GrStyle& style, const SkMatrix& viewMatrix);
-}  // namespace GrDashOp
 
-#endif
+}  // namespace skgpu::v1::DashOp
+
+#endif // DashOp_DEFINED
diff --git a/src/gpu/ops/OpsTask.cpp b/src/gpu/ops/OpsTask.cpp
index ab5c7cb..9c787e5 100644
--- a/src/gpu/ops/OpsTask.cpp
+++ b/src/gpu/ops/OpsTask.cpp
@@ -24,7 +24,6 @@
 #include "src/gpu/GrResourceProvider.h"
 #include "src/gpu/GrTexture.h"
 #include "src/gpu/geometry/GrRect.h"
-#include "src/gpu/ops/GrClearOp.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 
diff --git a/src/gpu/v1/SurfaceDrawContext.cpp b/src/gpu/v1/SurfaceDrawContext.cpp
index 6b278c2..15ca226 100644
--- a/src/gpu/v1/SurfaceDrawContext.cpp
+++ b/src/gpu/v1/SurfaceDrawContext.cpp
@@ -53,10 +53,10 @@
 #include "src/gpu/geometry/GrQuad.h"
 #include "src/gpu/geometry/GrQuadUtils.h"
 #include "src/gpu/geometry/GrStyledShape.h"
+#include "src/gpu/ops/ClearOp.h"
 #include "src/gpu/ops/DrawAtlasOp.h"
 #include "src/gpu/ops/DrawVerticesOp.h"
 #include "src/gpu/ops/DrawableOp.h"
-#include "src/gpu/ops/GrClearOp.h"
 #include "src/gpu/ops/GrDrawOp.h"
 #include "src/gpu/ops/GrFillRRectOp.h"
 #include "src/gpu/ops/GrFillRectOp.h"
@@ -905,7 +905,7 @@
                         GrFillRectOp::MakeNonAARect(fContext, std::move(paint), SkMatrix::I(),
                                                     SkRect::Make(scissorState.rect()), ss));
     } else {
-        this->addOp(GrClearOp::MakeStencilClip(fContext, scissorState, insideStencilMask));
+        this->addOp(ClearOp::MakeStencilClip(fContext, scissorState, insideStencilMask));
     }
 }
 
diff --git a/src/gpu/v1/SurfaceFillContext_v1.cpp b/src/gpu/v1/SurfaceFillContext_v1.cpp
index 8d11991..8f91023 100644
--- a/src/gpu/v1/SurfaceFillContext_v1.cpp
+++ b/src/gpu/v1/SurfaceFillContext_v1.cpp
@@ -13,7 +13,7 @@
 #include "src/gpu/GrProxyProvider.h"
 #include "src/gpu/effects/GrTextureEffect.h"
 #include "src/gpu/geometry/GrRect.h"
-#include "src/gpu/ops/GrClearOp.h"
+#include "src/gpu/ops/ClearOp.h"
 #include "src/gpu/ops/GrFillRectOp.h"
 #include "src/gpu/v1/SurfaceDrawContext_v1.h"
 
@@ -223,7 +223,7 @@
         this->addDrawOp(std::move(op));
     } else {
         color = this->writeSurfaceView().swizzle().applyTo(color);
-        this->addOp(GrClearOp::MakeColor(fContext, scissorState, color));
+        this->addOp(ClearOp::MakeColor(fContext, scissorState, color));
     }
 }