Revert "Revert "Converts remaining rect ops from GrLegacyMeshDrawOp to GrMeshDrawOp subclasses.""

This reverts commit a0485d94529905e76320b7aa941a0d94b5578ac2.

Bug: skia:
Change-Id: If50b2d1af285a6c3c943373bb7258b56e1af28d6
Reviewed-on: https://skia-review.googlesource.com/19961
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/ops/GrAAStrokeRectOp.cpp b/src/gpu/ops/GrAAStrokeRectOp.cpp
index 7af6c3e..82b4ec1 100644
--- a/src/gpu/ops/GrAAStrokeRectOp.cpp
+++ b/src/gpu/ops/GrAAStrokeRectOp.cpp
@@ -5,12 +5,12 @@
  * found in the LICENSE file.
  */
 
-#include "GrAAStrokeRectOp.h"
-
 #include "GrDefaultGeoProcFactory.h"
 #include "GrOpFlushState.h"
+#include "GrRectOpFactory.h"
 #include "GrResourceKey.h"
 #include "GrResourceProvider.h"
+#include "GrSimpleMeshDrawOpHelper.h"
 #include "SkStrokeRec.h"
 
 GR_DECLARE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey);
@@ -110,13 +110,26 @@
                               viewMatrix);
 }
 
-class AAStrokeRectOp final : public GrLegacyMeshDrawOp {
+namespace {
+
+class AAStrokeRectOp final : public GrMeshDrawOp {
+private:
+    using Helper = GrSimpleMeshDrawOpHelper;
+
 public:
     DEFINE_OP_CLASS_ID
 
-    AAStrokeRectOp(GrColor color, const SkMatrix& viewMatrix, const SkRect& devOutside,
-                   const SkRect& devInside)
-            : INHERITED(ClassID()), fViewMatrix(viewMatrix) {
+    static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
+                                          const SkRect& devOutside, const SkRect& devInside) {
+        return Helper::FactoryHelper<AAStrokeRectOp>(std::move(paint), viewMatrix, devOutside,
+                                                     devInside);
+    }
+
+    AAStrokeRectOp(const Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix,
+                   const SkRect& devOutside, const SkRect& devInside)
+            : INHERITED(ClassID())
+            , fHelper(helperArgs, GrAAType::kCoverage)
+            , fViewMatrix(viewMatrix) {
         SkASSERT(!devOutside.isEmpty());
         SkASSERT(!devInside.isEmpty());
 
@@ -125,30 +138,35 @@
         fMiterStroke = true;
     }
 
-    static std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, const SkMatrix& viewMatrix,
-                                                    const SkRect& rect, const SkStrokeRec& stroke) {
+    static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint, const SkMatrix& viewMatrix,
+                                          const SkRect& rect, const SkStrokeRec& stroke) {
         bool isMiter;
         if (!allowed_stroke(stroke, &isMiter)) {
             return nullptr;
         }
+        return Helper::FactoryHelper<AAStrokeRectOp>(std::move(paint), viewMatrix, rect, stroke,
+                                                     isMiter);
+    }
 
-        AAStrokeRectOp* op = new AAStrokeRectOp();
-        op->fMiterStroke = isMiter;
-        RectInfo& info = op->fRects.push_back();
+    AAStrokeRectOp(const Helper::MakeArgs& helperArgs, GrColor color, const SkMatrix& viewMatrix,
+                   const SkRect& rect, const SkStrokeRec& stroke, bool isMiter)
+            : INHERITED(ClassID())
+            , fHelper(helperArgs, GrAAType::kCoverage)
+            , fViewMatrix(viewMatrix) {
+        fMiterStroke = isMiter;
+        RectInfo& info = fRects.push_back();
         compute_rects(&info.fDevOutside, &info.fDevOutsideAssist, &info.fDevInside,
                       &info.fDegenerate, viewMatrix, rect, stroke.getWidth(), isMiter);
         info.fColor = color;
         if (isMiter) {
-            op->setBounds(info.fDevOutside, HasAABloat::kYes, IsZeroArea::kNo);
+            this->setBounds(info.fDevOutside, HasAABloat::kYes, IsZeroArea::kNo);
         } else {
             // The outer polygon of the bevel stroke is an octagon specified by the points of a
             // pair of overlapping rectangles where one is wide and the other is narrow.
             SkRect bounds = info.fDevOutside;
             bounds.joinPossiblyEmptyRect(info.fDevOutsideAssist);
-            op->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo);
+            this->setBounds(bounds, HasAABloat::kYes, IsZeroArea::kNo);
         }
-        op->fViewMatrix = viewMatrix;
-        return std::unique_ptr<GrLegacyMeshDrawOp>(op);
     }
 
     const char* name() const override { return "AAStrokeRect"; }
@@ -166,20 +184,18 @@
                     info.fDevOutsideAssist.fBottom, info.fDevInside.fLeft, info.fDevInside.fTop,
                     info.fDevInside.fRight, info.fDevInside.fBottom, info.fDegenerate);
         }
-        string.append(DumpPipelineInfo(*this->pipeline()));
         string.append(INHERITED::dumpInfo());
         return string;
     }
 
-private:
-    AAStrokeRectOp() : INHERITED(ClassID()) {}
+    FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
 
-    void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color,
-                                    GrProcessorAnalysisCoverage* coverage) const override {
-        color->setToConstant(fRects[0].fColor);
-        *coverage = GrProcessorAnalysisCoverage::kSingleChannel;
+    bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override {
+        return fHelper.xpRequiresDstTexture(caps, clip, GrProcessorAnalysisCoverage::kSingleChannel,
+                                            &fRects.back().fColor);
     }
-    void applyPipelineOptimizations(const PipelineOptimizations&) override;
+
+private:
     void onPrepareDraws(Target*) const override;
 
     static const int kMiterIndexCnt = 3 * 24;
@@ -192,8 +208,6 @@
 
     static const GrBuffer* GetIndexBuffer(GrResourceProvider* resourceProvider, bool miterStroke);
 
-    bool usesLocalCoords() const { return fUsesLocalCoords; }
-    bool canTweakAlphaForCoverage() const { return fCanTweakAlphaForCoverage; }
     const SkMatrix& viewMatrix() const { return fViewMatrix; }
     bool miterStroke() const { return fMiterStroke; }
 
@@ -221,29 +235,20 @@
         bool fDegenerate;
     };
 
+    Helper fHelper;
     SkSTArray<1, RectInfo, true> fRects;
-    bool fUsesLocalCoords;
-    bool fCanTweakAlphaForCoverage;
     SkMatrix fViewMatrix;
     bool fMiterStroke;
 
-    typedef GrLegacyMeshDrawOp INHERITED;
+    typedef GrMeshDrawOp INHERITED;
 };
 
-void AAStrokeRectOp::applyPipelineOptimizations(const PipelineOptimizations& optimizations) {
-    optimizations.getOverrideColorIfSet(&fRects[0].fColor);
-
-    fUsesLocalCoords = optimizations.readsLocalCoords();
-    fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage();
-    fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage();
-}
+}  // anonymous namespace
 
 void AAStrokeRectOp::onPrepareDraws(Target* target) const {
-    bool canTweakAlphaForCoverage = this->canTweakAlphaForCoverage();
-
-    sk_sp<GrGeometryProcessor> gp(create_stroke_rect_gp(canTweakAlphaForCoverage,
+    sk_sp<GrGeometryProcessor> gp(create_stroke_rect_gp(fHelper.compatibleWithAlphaAsCoverage(),
                                                         this->viewMatrix(),
-                                                        this->usesLocalCoords()));
+                                                        fHelper.usesLocalCoords()));
     if (!gp) {
         SkDebugf("Couldn't create GrGeometryProcessor\n");
         return;
@@ -251,7 +256,7 @@
 
     size_t vertexStride = gp->getVertexStride();
 
-    SkASSERT(canTweakAlphaForCoverage
+    SkASSERT(fHelper.compatibleWithAlphaAsCoverage()
                      ? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)
                      : vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
     int innerVertexNum = 4;
@@ -284,9 +289,9 @@
                                            info.fDevInside,
                                            fMiterStroke,
                                            info.fDegenerate,
-                                           canTweakAlphaForCoverage);
+                                           fHelper.compatibleWithAlphaAsCoverage());
     }
-    helper.recordDraw(target, gp.get(), this->pipeline());
+    helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
 }
 
 const GrBuffer* AAStrokeRectOp::GetIndexBuffer(GrResourceProvider* resourceProvider,
@@ -386,8 +391,7 @@
 bool AAStrokeRectOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
     AAStrokeRectOp* that = t->cast<AAStrokeRectOp>();
 
-    if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
-                                that->bounds(), caps)) {
+    if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
         return false;
     }
 
@@ -397,18 +401,11 @@
     }
 
     // We apply the viewmatrix to the rect points on the cpu.  However, if the pipeline uses
-    // local coords then we won't be able to combine.  We could actually upload the viewmatrix
-    // using vertex attributes in these cases, but haven't investigated that
-    if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
+    // local coords then we won't be able to combine. TODO: Upload local coords as an attribute.
+    if (fHelper.usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
         return false;
     }
 
-    // In the event of two ops, one who can tweak, one who cannot, we just fall back to not
-    // tweaking.
-    if (this->canTweakAlphaForCoverage() != that->canTweakAlphaForCoverage()) {
-        fCanTweakAlphaForCoverage = false;
-    }
-
     fRects.push_back_n(that->fRects.count(), that->fRects.begin());
     this->joinBounds(*that);
     return true;
@@ -569,23 +566,35 @@
     }
 }
 
-namespace GrAAStrokeRectOp {
+namespace GrRectOpFactory {
 
-std::unique_ptr<GrLegacyMeshDrawOp> MakeFillBetweenRects(GrColor color,
-                                                         const SkMatrix& viewMatrix,
-                                                         const SkRect& devOutside,
-                                                         const SkRect& devInside) {
-    return std::unique_ptr<GrLegacyMeshDrawOp>(
-            new AAStrokeRectOp(color, viewMatrix, devOutside, devInside));
+std::unique_ptr<GrDrawOp> MakeAAFillNestedRects(GrPaint&& paint,
+                                                const SkMatrix& viewMatrix,
+                                                const SkRect rects[2]) {
+    SkASSERT(viewMatrix.rectStaysRect());
+    SkASSERT(!rects[0].isEmpty() && !rects[1].isEmpty());
+
+    SkRect devOutside, devInside;
+    viewMatrix.mapRect(&devOutside, rects[0]);
+    viewMatrix.mapRect(&devInside, rects[1]);
+    if (devInside.isEmpty()) {
+        if (devOutside.isEmpty()) {
+            return nullptr;
+        }
+        return MakeAAFillWithDevRect(std::move(paint), viewMatrix, rects[0], devOutside);
+    }
+
+    return AAStrokeRectOp::Make(std::move(paint), viewMatrix, devOutside, devInside);
 }
 
-std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color,
-                                         const SkMatrix& viewMatrix,
-                                         const SkRect& rect,
-                                         const SkStrokeRec& stroke) {
-    return AAStrokeRectOp::Make(color, viewMatrix, rect, stroke);
+std::unique_ptr<GrDrawOp> MakeAAStroke(GrPaint&& paint,
+                                       const SkMatrix& viewMatrix,
+                                       const SkRect& rect,
+                                       const SkStrokeRec& stroke) {
+    return AAStrokeRectOp::Make(std::move(paint), viewMatrix, rect, stroke);
 }
-}
+
+}  // namespace GrRectOpFactory
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -593,7 +602,7 @@
 
 #include "GrDrawOpTest.h"
 
-GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) {
+GR_DRAW_OP_TEST_DEFINE(AAStrokeRectOp) {
     bool miterStroke = random->nextBool();
 
     // Create either a empty rect or a non-empty rect.
@@ -602,14 +611,12 @@
     SkScalar minDim = SkMinScalar(rect.width(), rect.height());
     SkScalar strokeWidth = random->nextUScalar1() * minDim;
 
-    GrColor color = GrRandomColor(random);
-
     SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
     rec.setStrokeStyle(strokeWidth);
     rec.setStrokeParams(SkPaint::kButt_Cap,
                         miterStroke ? SkPaint::kMiter_Join : SkPaint::kBevel_Join, 1.f);
     SkMatrix matrix = GrTest::TestMatrixRectStaysRect(random);
-    return GrAAStrokeRectOp::Make(color, matrix, rect, rec);
+    return GrRectOpFactory::MakeAAStroke(std::move(paint), matrix, rect, rec);
 }
 
 #endif