Make DashOp a non-legacy GrMeshDrawOp.

Change-Id: I84ee3c64a5af8889e9a122cbc08d70ed6b25fbab
Reviewed-on: https://skia-review.googlesource.com/22210
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/ops/GrDashLinePathRenderer.cpp b/src/gpu/ops/GrDashLinePathRenderer.cpp
index cafe247..a364d92 100644
--- a/src/gpu/ops/GrDashLinePathRenderer.cpp
+++ b/src/gpu/ops/GrDashLinePathRenderer.cpp
@@ -46,16 +46,12 @@
     }
     SkPoint pts[2];
     SkAssertResult(args.fShape->asLine(pts, nullptr));
-    std::unique_ptr<GrLegacyMeshDrawOp> op = GrDashOp::MakeDashLineOp(
-            args.fPaint.getColor(), *args.fViewMatrix, pts, aaMode, args.fShape->style());
+    std::unique_ptr<GrDrawOp> op =
+            GrDashOp::MakeDashLineOp(std::move(args.fPaint), *args.fViewMatrix, pts, aaMode,
+                                     args.fShape->style(), args.fUserStencilSettings);
     if (!op) {
         return false;
     }
-
-    GrPipelineBuilder pipelineBuilder(std::move(args.fPaint), args.fAAType);
-    pipelineBuilder.setUserStencil(args.fUserStencilSettings);
-
-    args.fRenderTargetContext->addLegacyMeshDrawOp(
-            std::move(pipelineBuilder), *args.fClip, std::move(op));
+    args.fRenderTargetContext->addDrawOp(*args.fClip, std::move(op));
     return true;
 }
diff --git a/src/gpu/ops/GrDashOp.cpp b/src/gpu/ops/GrDashOp.cpp
index 64ddc40..6454778 100644
--- a/src/gpu/ops/GrDashOp.cpp
+++ b/src/gpu/ops/GrDashOp.cpp
@@ -6,7 +6,7 @@
  */
 
 #include "GrDashOp.h"
-
+#include "GrAppliedClip.h"
 #include "GrCaps.h"
 #include "GrContext.h"
 #include "GrCoordTransform.h"
@@ -240,7 +240,7 @@
                                                const SkMatrix& localMatrix,
                                                bool usesLocalCoords);
 
-class DashOp final : public GrLegacyMeshDrawOp {
+class DashOp final : public GrMeshDrawOp {
 public:
     DEFINE_OP_CLASS_ID
     struct LineData {
@@ -254,11 +254,11 @@
         SkScalar fPerpendicularScale;
     };
 
-    static std::unique_ptr<GrLegacyMeshDrawOp> Make(const LineData& geometry, GrColor color,
-                                                    SkPaint::Cap cap, AAMode aaMode,
-                                                    bool fullDash) {
-        return std::unique_ptr<GrLegacyMeshDrawOp>(
-                new DashOp(geometry, color, cap, aaMode, fullDash));
+    static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const LineData& geometry,
+                                          SkPaint::Cap cap, AAMode aaMode, bool fullDash,
+                                          const GrUserStencilSettings* stencilSettings) {
+        return std::unique_ptr<GrDrawOp>(
+                new DashOp(std::move(paint), geometry, cap, aaMode, fullDash, stencilSettings));
     }
 
     const char* name() const override { return "DashOp"; }
@@ -275,14 +275,49 @@
                            geo.fIntervals[1],
                            geo.fPhase);
         }
-        string.append(DumpPipelineInfo(*this->pipeline()));
-        string.append(INHERITED::dumpInfo());
+        string += fProcessorSet.dumpProcessors();
+        string += INHERITED::dumpInfo();
         return string;
     }
 
+    FixedFunctionFlags fixedFunctionFlags() const override {
+        FixedFunctionFlags flags = FixedFunctionFlags::kNone;
+        if (AAMode::kCoverageWithMSAA == fAAMode) {
+            flags |= FixedFunctionFlags::kUsesHWAA;
+        }
+        if (fStencilSettings) {
+            flags |= FixedFunctionFlags::kUsesStencil;
+        }
+        return flags;
+    }
+
+    RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip) override {
+        GrProcessorAnalysisCoverage coverage;
+        if (AAMode::kNone == fAAMode && !clip->clipCoverageFragmentProcessor()) {
+            coverage = GrProcessorAnalysisCoverage::kNone;
+        } else {
+            coverage = GrProcessorAnalysisCoverage::kSingleChannel;
+        }
+        auto analysis = fProcessorSet.finalize(fColor, coverage, clip, false, caps, &fColor);
+        fDisallowCombineOnTouchOrOverlap = analysis.requiresDstTexture() ||
+                                           (fProcessorSet.xferProcessor() &&
+                                            fProcessorSet.xferProcessor()->xferBarrierType(caps));
+        fUsesLocalCoords = analysis.usesLocalCoords();
+        return analysis.requiresDstTexture() ? RequiresDstTexture::kYes : RequiresDstTexture::kNo;
+    }
+
 private:
-    DashOp(const LineData& geometry, GrColor color, SkPaint::Cap cap, AAMode aaMode, bool fullDash)
-            : INHERITED(ClassID()), fColor(color), fCap(cap), fAAMode(aaMode), fFullDash(fullDash) {
+    DashOp(GrPaint&& paint, const LineData& geometry, SkPaint::Cap cap, AAMode aaMode,
+           bool fullDash, const GrUserStencilSettings* stencilSettings)
+            : INHERITED(ClassID())
+            , fColor(paint.getColor())
+            , fAllowsSRGBInputs(paint.getAllowSRGBInputs())
+            , fDisableSRGBOutputConversion(paint.getDisableOutputConversionToSRGB())
+            , fCap(cap)
+            , fFullDash(fullDash)
+            , fAAMode(aaMode)
+            , fProcessorSet(std::move(paint))
+            , fStencilSettings(stencilSettings) {
         fLines.push_back(geometry);
 
         // compute bounds
@@ -301,18 +336,6 @@
         this->setTransformedBounds(bounds, combinedMatrix, aaBloat, zeroArea);
     }
 
-    void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color,
-                                    GrProcessorAnalysisCoverage* coverage) const override {
-        color->setToConstant(fColor);
-        *coverage = GrProcessorAnalysisCoverage::kSingleChannel;
-    }
-
-    void applyPipelineOptimizations(const PipelineOptimizations& optimizations) override {
-        optimizations.getOverrideColorIfSet(&fColor);
-
-        fUsesLocalCoords = optimizations.readsLocalCoords();
-    }
-
     struct DashDraw {
         DashDraw(const LineData& geo) {
             memcpy(fPtsRot, geo.fPtsRot, sizeof(geo.fPtsRot));
@@ -342,14 +365,13 @@
         sk_sp<GrGeometryProcessor> gp;
         if (this->fullDash()) {
             gp = make_dash_gp(this->color(), this->aaMode(), capType, this->viewMatrix(),
-                              this->usesLocalCoords());
+                              fUsesLocalCoords);
         } else {
             // Set up the vertex data for the line and start/end dashes
             using namespace GrDefaultGeoProcFactory;
             Color color(this->color());
-            LocalCoords::Type localCoordsType = this->usesLocalCoords()
-                                                        ? LocalCoords::kUsePosition_Type
-                                                        : LocalCoords::kUnused_Type;
+            LocalCoords::Type localCoordsType =
+                    fUsesLocalCoords ? LocalCoords::kUsePosition_Type : LocalCoords::kUnused_Type;
             gp = MakeForDeviceSpace(color, Coverage::kSolid_Type, localCoordsType,
                                     this->viewMatrix());
         }
@@ -630,13 +652,27 @@
             rectIndex++;
         }
         SkASSERT(0 == (curVIdx % 4) && (curVIdx / 4) == totalRectCount);
-        helper.recordDraw(target, gp.get(), this->pipeline());
+        uint32_t pipelineFlags = 0;
+        if (AAMode::kCoverageWithMSAA == fAAMode) {
+            pipelineFlags |= GrPipeline::kHWAntialias_Flag;
+        }
+        if (fDisableSRGBOutputConversion) {
+            pipelineFlags |= GrPipeline::kDisableOutputConversionToSRGB_Flag;
+        }
+        if (fAllowsSRGBInputs) {
+            pipelineFlags |= GrPipeline::kAllowSRGBInputs_Flag;
+        }
+        const GrPipeline* pipeline = target->makePipeline(pipelineFlags, &fProcessorSet);
+        helper.recordDraw(target, gp.get(), pipeline);
     }
 
     bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
         DashOp* that = t->cast<DashOp>();
-        if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
-                                    that->bounds(), caps)) {
+        if (fProcessorSet != that->fProcessorSet) {
+            return false;
+        }
+        if (fDisallowCombineOnTouchOrOverlap &&
+            GrRectsTouchOrOverlap(this->bounds(), that->bounds())) {
             return false;
         }
 
@@ -657,8 +693,7 @@
             return false;
         }
 
-        SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
-        if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
+        if (fUsesLocalCoords && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
             return false;
         }
 
@@ -668,7 +703,6 @@
     }
 
     GrColor color() const { return fColor; }
-    bool usesLocalCoords() const { return fUsesLocalCoords; }
     const SkMatrix& viewMatrix() const { return fLines[0].fViewMatrix; }
     AAMode aaMode() const { return fAAMode; }
     bool fullDash() const { return fFullDash; }
@@ -677,21 +711,27 @@
     static const int kVertsPerDash = 4;
     static const int kIndicesPerDash = 6;
 
-    GrColor fColor;
-    bool fUsesLocalCoords;
-    SkPaint::Cap fCap;
-    AAMode fAAMode;
-    bool fFullDash;
     SkSTArray<1, LineData, true> fLines;
+    GrColor fColor;
+    bool fAllowsSRGBInputs : 1;
+    bool fDisableSRGBOutputConversion : 1;
+    bool fDisallowCombineOnTouchOrOverlap : 1;
+    bool fUsesLocalCoords : 1;
+    SkPaint::Cap fCap : 2;
+    bool fFullDash : 1;
+    AAMode fAAMode;
+    GrProcessorSet fProcessorSet;
+    const GrUserStencilSettings* fStencilSettings;
 
-    typedef GrLegacyMeshDrawOp INHERITED;
+    typedef GrMeshDrawOp INHERITED;
 };
 
-std::unique_ptr<GrLegacyMeshDrawOp> GrDashOp::MakeDashLineOp(GrColor color,
-                                                             const SkMatrix& viewMatrix,
-                                                             const SkPoint pts[2],
-                                                             AAMode aaMode,
-                                                             const GrStyle& style) {
+std::unique_ptr<GrDrawOp> GrDashOp::MakeDashLineOp(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();
@@ -737,7 +777,7 @@
     lineData.fIntervals[0] = intervals[0];
     lineData.fIntervals[1] = intervals[1];
 
-    return DashOp::Make(lineData, color, cap, aaMode, fullDash);
+    return DashOp::Make(std::move(paint), lineData, cap, aaMode, fullDash, stencilSettings);
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1198,10 +1238,12 @@
 
 #if GR_TEST_UTILS
 
-GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(DashOp) {
-    GrColor color = GrRandomColor(random);
+GR_DRAW_OP_TEST_DEFINE(DashOp) {
     SkMatrix viewMatrix = GrTest::TestMatrixPreservesRightAngles(random);
-    AAMode aaMode = static_cast<AAMode>(random->nextULessThan(GrDashOp::kAAModeCnt));
+    AAMode aaMode;
+    do {
+        aaMode = static_cast<AAMode>(random->nextULessThan(GrDashOp::kAAModeCnt));
+    } while (AAMode::kCoverageWithMSAA == aaMode && GrFSAAType::kUnifiedMSAA != fsaaType);
 
     // We can only dash either horizontal or vertical lines
     SkPoint pts[2];
@@ -1266,7 +1308,8 @@
 
     GrStyle style(p);
 
-    return GrDashOp::MakeDashLineOp(color, viewMatrix, pts, aaMode, style);
+    return GrDashOp::MakeDashLineOp(std::move(paint), viewMatrix, pts, aaMode, style,
+                                    GrGetRandomStencil(random, context));
 }
 
 #endif
diff --git a/src/gpu/ops/GrDashOp.h b/src/gpu/ops/GrDashOp.h
index d3e0b6f..86ab619 100644
--- a/src/gpu/ops/GrDashOp.h
+++ b/src/gpu/ops/GrDashOp.h
@@ -8,12 +8,13 @@
 #ifndef GrDashOp_DEFINED
 #define GrDashOp_DEFINED
 
-#include "GrColor.h"
-#include "GrTypesPriv.h"
+#include "GrTypes.h"
 #include "SkPathEffect.h"
 
-class GrLegacyMeshDrawOp;
+class GrDrawOp;
+class GrPaint;
 class GrStyle;
+struct GrUserStencilSettings;
 
 namespace GrDashOp {
 enum class AAMode {
@@ -23,9 +24,9 @@
 };
 static const int kAAModeCnt = static_cast<int>(AAMode::kCoverageWithMSAA) + 1;
 
-std::unique_ptr<GrLegacyMeshDrawOp> MakeDashLineOp(GrColor, const SkMatrix& viewMatrix,
-                                                   const SkPoint pts[2], AAMode,
-                                                   const GrStyle& style);
+std::unique_ptr<GrDrawOp> MakeDashLineOp(GrPaint&&, const SkMatrix& viewMatrix,
+                                         const SkPoint pts[2], AAMode, const GrStyle& style,
+                                         const GrUserStencilSettings*);
 bool CanDrawDashLine(const SkPoint pts[2], const GrStyle& style, const SkMatrix& viewMatrix);
 }