Move some v1-only gpu/tessellate files to gpu/ops

This CL just moves the files and renames them. It doesn't move them into the skgpu::v1 namespace.

Bug: skia:11837
Change-Id: Iab322d0dc5b5d1cfd32436785081539dc85c18d3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/440776
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/ops/TessellationPathRenderer.cpp b/src/gpu/ops/TessellationPathRenderer.cpp
new file mode 100644
index 0000000..28ed003
--- /dev/null
+++ b/src/gpu/ops/TessellationPathRenderer.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2019 Google LLC.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "src/gpu/ops/TessellationPathRenderer.h"
+
+#include "include/private/SkVx.h"
+#include "src/core/SkPathPriv.h"
+#include "src/gpu/GrClip.h"
+#include "src/gpu/GrMemoryPool.h"
+#include "src/gpu/GrRecordingContextPriv.h"
+#include "src/gpu/GrVx.h"
+#include "src/gpu/effects/GrDisableColorXP.h"
+#include "src/gpu/geometry/GrStyledShape.h"
+#include "src/gpu/ops/PathInnerTriangulateOp.h"
+#include "src/gpu/ops/PathStencilCoverOp.h"
+#include "src/gpu/ops/PathTessellateOp.h"
+#include "src/gpu/ops/StrokeTessellateOp.h"
+#include "src/gpu/v1/SurfaceDrawContext_v1.h"
+
+bool GrTessellationPathRenderer::IsSupported(const GrCaps& caps) {
+    return !caps.avoidStencilBuffers() &&
+           caps.drawInstancedSupport() &&
+           !caps.disableTessellationPathRenderer();
+}
+
+skgpu::v1::PathRenderer::StencilSupport GrTessellationPathRenderer::onGetStencilSupport(
+        const GrStyledShape& shape) const {
+    if (!shape.style().isSimpleFill() || shape.inverseFilled()) {
+        // Don't bother with stroke stencilling or inverse fills yet. The Skia API doesn't support
+        // clipping by a stroke, and the stencilling code already knows how to invert a fill.
+        return kNoSupport_StencilSupport;
+    }
+    return shape.knownToBeConvex() ? kNoRestriction_StencilSupport : kStencilOnly_StencilSupport;
+}
+
+skgpu::v1::PathRenderer::CanDrawPath GrTessellationPathRenderer::onCanDrawPath(
+        const CanDrawPathArgs& args) const {
+    const GrStyledShape& shape = *args.fShape;
+    if (args.fAAType == GrAAType::kCoverage ||
+        shape.style().hasPathEffect() ||
+        args.fViewMatrix->hasPerspective() ||
+        shape.style().strokeRec().getStyle() == SkStrokeRec::kStrokeAndFill_Style ||
+        !args.fProxy->canUseStencil(*args.fCaps)) {
+        return CanDrawPath::kNo;
+    }
+    if (!shape.style().isSimpleFill()) {
+        if (shape.inverseFilled()) {
+            return CanDrawPath::kNo;
+        }
+    }
+    if (args.fHasUserStencilSettings) {
+        // Non-convex paths and strokes use the stencil buffer internally, so they can't support
+        // draws with stencil settings.
+        if (!shape.style().isSimpleFill() || !shape.knownToBeConvex() || shape.inverseFilled()) {
+            return CanDrawPath::kNo;
+        }
+    }
+    return CanDrawPath::kYes;
+}
+
+static GrOp::Owner make_non_convex_fill_op(GrRecordingContext* rContext,
+                                           SkArenaAlloc* arena,
+                                           GrTessellationPathFlags pathFlags,
+                                           GrAAType aaType,
+                                           const SkRect& drawBounds,
+                                           const SkMatrix& viewMatrix,
+                                           const SkPath& path,
+                                           GrPaint&& paint) {
+    SkASSERT(!path.isConvex() || path.isInverseFillType());
+    int numVerbs = path.countVerbs();
+    if (numVerbs > 0 && !path.isInverseFillType()) {
+        // Check if the path is large and/or simple enough that we can triangulate the inner fan
+        // on the CPU. This is our fastest approach. It allows us to stencil only the curves,
+        // and then fill the inner fan directly to the final render target, thus drawing the
+        // majority of pixels in a single render pass.
+        float gpuFragmentWork = drawBounds.height() * drawBounds.width();
+        float cpuTessellationWork = numVerbs * SkNextLog2(numVerbs);  // N log N.
+        constexpr static float kCpuWeight = 512;
+        constexpr static float kMinNumPixelsToTriangulate = 256 * 256;
+        if (cpuTessellationWork * kCpuWeight + kMinNumPixelsToTriangulate < gpuFragmentWork) {
+            return GrOp::Make<GrPathInnerTriangulateOp>(rContext,
+                                                        viewMatrix,
+                                                        path,
+                                                        std::move(paint),
+                                                        aaType,
+                                                        pathFlags,
+                                                        drawBounds);
+        }
+    }
+    return GrOp::Make<GrPathStencilCoverOp>(rContext,
+                                            arena,
+                                            viewMatrix,
+                                            path,
+                                            std::move(paint),
+                                            aaType,
+                                            pathFlags,
+                                            drawBounds);
+}
+
+bool GrTessellationPathRenderer::onDrawPath(const DrawPathArgs& args) {
+    auto sdc = args.fSurfaceDrawContext;
+
+    SkPath path;
+    args.fShape->asPath(&path);
+
+    // Handle strokes first.
+    if (!args.fShape->style().isSimpleFill()) {
+        SkASSERT(!path.isInverseFillType());  // See onGetStencilSupport().
+        SkASSERT(args.fUserStencilSettings->isUnused());
+        const SkStrokeRec& stroke = args.fShape->style().strokeRec();
+        SkASSERT(stroke.getStyle() != SkStrokeRec::kStrokeAndFill_Style);
+        auto op = GrOp::Make<GrStrokeTessellateOp>(args.fContext, args.fAAType, *args.fViewMatrix,
+                                                   path, stroke, std::move(args.fPaint));
+        sdc->addDrawOp(args.fClip, std::move(op));
+        return true;
+    }
+
+    // Handle empty paths.
+    const SkRect pathDevBounds = args.fViewMatrix->mapRect(args.fShape->bounds());
+    if (pathDevBounds.isEmpty()) {
+        if (path.isInverseFillType()) {
+            args.fSurfaceDrawContext->drawPaint(args.fClip, std::move(args.fPaint),
+                                                *args.fViewMatrix);
+        }
+        return true;
+    }
+
+    // Handle convex paths.
+    if (args.fShape->knownToBeConvex() && !path.isInverseFillType()) {
+        auto op = GrOp::Make<GrPathTessellateOp>(args.fContext, *args.fViewMatrix, path,
+                                                 std::move(args.fPaint), args.fAAType,
+                                                 args.fUserStencilSettings, pathDevBounds);
+        sdc->addDrawOp(args.fClip, std::move(op));
+        return true;
+    }
+
+    SkASSERT(args.fUserStencilSettings->isUnused());  // See onGetStencilSupport().
+    const SkRect& drawBounds = path.isInverseFillType()
+            ? args.fSurfaceDrawContext->asSurfaceProxy()->backingStoreBoundsRect()
+            : pathDevBounds;
+    auto op = make_non_convex_fill_op(args.fContext,
+                                      args.fSurfaceDrawContext->arenaAlloc(),
+                                      GrTessellationPathFlags::kNone,
+                                      args.fAAType,
+                                      drawBounds,
+                                      *args.fViewMatrix,
+                                      path,
+                                      std::move(args.fPaint));
+    sdc->addDrawOp(args.fClip, std::move(op));
+    return true;
+}
+
+void GrTessellationPathRenderer::onStencilPath(const StencilPathArgs& args) {
+    SkASSERT(args.fShape->style().isSimpleFill());  // See onGetStencilSupport().
+    SkASSERT(!args.fShape->inverseFilled());  // See onGetStencilSupport().
+
+    auto sdc = args.fSurfaceDrawContext;
+    GrAAType aaType = (GrAA::kYes == args.fDoStencilMSAA) ? GrAAType::kMSAA : GrAAType::kNone;
+
+    SkRect pathDevBounds;
+    args.fViewMatrix->mapRect(&pathDevBounds, args.fShape->bounds());
+
+    SkPath path;
+    args.fShape->asPath(&path);
+
+    if (args.fShape->knownToBeConvex()) {
+        constexpr static GrUserStencilSettings kMarkStencil(
+            GrUserStencilSettings::StaticInit<
+                0x0001,
+                GrUserStencilTest::kAlways,
+                0xffff,
+                GrUserStencilOp::kReplace,
+                GrUserStencilOp::kKeep,
+                0xffff>());
+
+        GrPaint stencilPaint;
+        stencilPaint.setXPFactory(GrDisableColorXPFactory::Get());
+        auto op = GrOp::Make<GrPathTessellateOp>(args.fContext, *args.fViewMatrix, path,
+                                                 std::move(stencilPaint), aaType, &kMarkStencil,
+                                                 pathDevBounds);
+        sdc->addDrawOp(args.fClip, std::move(op));
+        return;
+    }
+
+    auto op = make_non_convex_fill_op(args.fContext,
+                                      args.fSurfaceDrawContext->arenaAlloc(),
+                                      GrTessellationPathFlags::kStencilOnly,
+                                      aaType,
+                                      pathDevBounds,
+                                      *args.fViewMatrix,
+                                      path,
+                                      GrPaint());
+    sdc->addDrawOp(args.fClip, std::move(op));
+}