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/GrAAFillRectOp.cpp b/src/gpu/ops/GrAAFillRectOp.cpp
index af5885c..ec190c7 100644
--- a/src/gpu/ops/GrAAFillRectOp.cpp
+++ b/src/gpu/ops/GrAAFillRectOp.cpp
@@ -5,21 +5,26 @@
  * found in the LICENSE file.
  */
 
-#include "GrAAFillRectOp.h"
-
 #include "GrColor.h"
 #include "GrDefaultGeoProcFactory.h"
 #include "GrMeshDrawOp.h"
 #include "GrOpFlushState.h"
+#include "GrRectOpFactory.h"
 #include "GrResourceKey.h"
 #include "GrResourceProvider.h"
 #include "GrTypes.h"
 #include "SkMatrix.h"
 #include "SkRect.h"
+#include "ops/GrSimpleMeshDrawOpHelper.h"
 
 GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
 
-static void set_inset_fan(SkPoint* pts, size_t stride, const SkRect& r, SkScalar dx, SkScalar dy) {
+static inline bool view_matrix_ok_for_aa_fill_rect(const SkMatrix& viewMatrix) {
+    return viewMatrix.preservesRightAngles();
+}
+
+static inline void set_inset_fan(SkPoint* pts, size_t stride, const SkRect& r, SkScalar dx,
+                                 SkScalar dy) {
     pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride);
 }
 
@@ -153,16 +158,34 @@
     }
 }
 
-class AAFillRectOp final : public GrLegacyMeshDrawOp {
+namespace {
+
+class AAFillRectOp final : public GrMeshDrawOp {
+private:
+    using Helper = GrSimpleMeshDrawOpHelperWithStencil;
+
 public:
     DEFINE_OP_CLASS_ID
 
-    AAFillRectOp(GrColor color,
+    static std::unique_ptr<GrDrawOp> Make(GrPaint&& paint,
+                                          const SkMatrix& viewMatrix,
+                                          const SkRect& rect,
+                                          const SkRect& devRect,
+                                          const SkMatrix* localMatrix,
+                                          const GrUserStencilSettings* stencil) {
+        SkASSERT(view_matrix_ok_for_aa_fill_rect(viewMatrix));
+        return Helper::FactoryHelper<AAFillRectOp>(std::move(paint), viewMatrix, rect, devRect,
+                                                   localMatrix, stencil);
+    }
+
+    AAFillRectOp(const Helper::MakeArgs& helperArgs,
+                 GrColor color,
                  const SkMatrix& viewMatrix,
                  const SkRect& rect,
                  const SkRect& devRect,
-                 const SkMatrix* localMatrix)
-            : INHERITED(ClassID()) {
+                 const SkMatrix* localMatrix,
+                 const GrUserStencilSettings* stencil)
+            : INHERITED(ClassID()), fHelper(helperArgs, GrAAType::kCoverage, stencil) {
         if (localMatrix) {
             void* mem = fRectData.push_back_n(sizeof(RectWithLocalMatrixInfo));
             new (mem) RectWithLocalMatrixInfo(color, viewMatrix, rect, devRect, *localMatrix);
@@ -189,38 +212,29 @@
                         info->color(), rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
             info = this->next(info);
         }
-        str.append(DumpPipelineInfo(*this->pipeline()));
         return str;
     }
 
-    void applyPipelineOptimizations(const PipelineOptimizations& optimizations) override {
-        GrColor color;
-        if (optimizations.getOverrideColorIfSet(&color)) {
-            this->first()->setColor(color);
-        }
-        fCanTweakAlphaForCoverage = optimizations.canTweakAlphaForCoverage();
-        fNeedsLocalCoords = optimizations.readsLocalCoords();
+    FixedFunctionFlags fixedFunctionFlags() const override { return fHelper.fixedFunctionFlags(); }
+
+    bool xpRequiresDstTexture(const GrCaps& caps, const GrAppliedClip* clip) override {
+        GrColor color = this->first()->color();
+        bool result = fHelper.xpRequiresDstTexture(
+                caps, clip, GrProcessorAnalysisCoverage::kSingleChannel, &color);
+        this->first()->setColor(color);
+        return result;
     }
 
 private:
-    void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color,
-                                    GrProcessorAnalysisCoverage* coverage) const override {
-        color->setToConstant(this->first()->color());
-        *coverage = GrProcessorAnalysisCoverage::kSingleChannel;
-    }
-
     void onPrepareDraws(Target* target) const override {
         using namespace GrDefaultGeoProcFactory;
 
         Color color(Color::kPremulGrColorAttribute_Type);
-        Coverage::Type coverageType;
-        if (fCanTweakAlphaForCoverage) {
-            coverageType = Coverage::kSolid_Type;
-        } else {
-            coverageType = Coverage::kAttribute_Type;
-        }
-        LocalCoords lc =
-                fNeedsLocalCoords ? LocalCoords::kHasExplicit_Type : LocalCoords::kUnused_Type;
+        Coverage::Type coverageType = fHelper.compatibleWithAlphaAsCoverage()
+                                              ? Coverage::kSolid_Type
+                                              : Coverage::kAttribute_Type;
+        LocalCoords lc = fHelper.usesLocalCoords() ? LocalCoords::kHasExplicit_Type
+                                                   : LocalCoords::kUnused_Type;
         sk_sp<GrGeometryProcessor> gp =
                 GrDefaultGeoProcFactory::Make(color, coverageType, lc, SkMatrix::I());
         if (!gp) {
@@ -245,7 +259,7 @@
         for (int i = 0; i < fRectCnt; i++) {
             intptr_t verts =
                     reinterpret_cast<intptr_t>(vertices) + i * kVertsPerAAFillRect * vertexStride;
-            if (fNeedsLocalCoords) {
+            if (fHelper.usesLocalCoords()) {
                 if (info->hasLocalMatrix()) {
                     localMatrix = &static_cast<const RectWithLocalMatrixInfo*>(info)->localMatrix();
                 } else {
@@ -253,28 +267,19 @@
                 }
             }
             generate_aa_fill_rect_geometry(verts, vertexStride, info->color(), info->viewMatrix(),
-                                           info->rect(), info->devRect(), fCanTweakAlphaForCoverage,
-                                           localMatrix);
+                                           info->rect(), info->devRect(),
+                                           fHelper.compatibleWithAlphaAsCoverage(), localMatrix);
             info = this->next(info);
         }
-        helper.recordDraw(target, gp.get(), this->pipeline());
+        helper.recordDraw(target, gp.get(), fHelper.makePipeline(target));
     }
 
     bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
         AAFillRectOp* that = t->cast<AAFillRectOp>();
-        if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeline(),
-                                    that->bounds(), caps)) {
+        if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
             return false;
         }
 
-        SkASSERT(fNeedsLocalCoords == that->fNeedsLocalCoords);
-
-        // In the event of two ops, one who can tweak, one who cannot, we just fall back to not
-        // tweaking.
-        if (fCanTweakAlphaForCoverage && !that->fCanTweakAlphaForCoverage) {
-            fCanTweakAlphaForCoverage = false;
-        }
-
         fRectData.push_back_n(that->fRectData.count(), that->fRectData.begin());
         fRectCnt += that->fRectCnt;
         this->joinBounds(*that);
@@ -333,55 +338,61 @@
         return reinterpret_cast<const RectInfo*>(next);
     }
 
-    bool fNeedsLocalCoords;
-    bool fCanTweakAlphaForCoverage;
     SkSTArray<4 * sizeof(RectWithLocalMatrixInfo), uint8_t, true> fRectData;
+    Helper fHelper;
     int fRectCnt;
 
-    typedef GrLegacyMeshDrawOp INHERITED;
+    typedef GrMeshDrawOp INHERITED;
 };
 
-namespace GrAAFillRectOp {
+}  // anonymous namespace
 
-std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color,
-                                         const SkMatrix& viewMatrix,
-                                         const SkRect& rect,
-                                         const SkRect& devRect) {
-    return std::unique_ptr<GrLegacyMeshDrawOp>(
-            new AAFillRectOp(color, viewMatrix, rect, devRect, nullptr));
-}
+namespace GrRectOpFactory {
 
-std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color,
-                                         const SkMatrix& viewMatrix,
-                                         const SkMatrix& localMatrix,
-                                         const SkRect& rect,
-                                         const SkRect& devRect) {
-    return std::unique_ptr<GrLegacyMeshDrawOp>(
-            new AAFillRectOp(color, viewMatrix, rect, devRect, &localMatrix));
-}
-
-std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color,
-                                         const SkMatrix& viewMatrix,
-                                         const SkMatrix& localMatrix,
-                                         const SkRect& rect) {
+std::unique_ptr<GrDrawOp> MakeAAFill(GrPaint&& paint, const SkMatrix& viewMatrix,
+                                     const SkRect& rect, const GrUserStencilSettings* stencil) {
+    if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
+        return nullptr;
+    }
     SkRect devRect;
     viewMatrix.mapRect(&devRect, rect);
-    return Make(color, viewMatrix, localMatrix, rect, devRect);
+    return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, nullptr, stencil);
 }
 
-std::unique_ptr<GrLegacyMeshDrawOp> MakeWithLocalRect(GrColor color,
-                                                      const SkMatrix& viewMatrix,
-                                                      const SkRect& rect,
-                                                      const SkRect& localRect) {
+std::unique_ptr<GrDrawOp> MakeAAFillWithDevRect(GrPaint&& paint, const SkMatrix& viewMatrix,
+                                                const SkRect& rect, const SkRect& devRect) {
+    if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
+        return nullptr;
+    }
+    return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, nullptr, nullptr);
+}
+
+std::unique_ptr<GrDrawOp> MakeAAFillWithLocalMatrix(GrPaint&& paint, const SkMatrix& viewMatrix,
+                                                    const SkMatrix& localMatrix,
+                                                    const SkRect& rect) {
+    if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
+        return nullptr;
+    }
+    SkRect devRect;
+    viewMatrix.mapRect(&devRect, rect);
+    return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, &localMatrix, nullptr);
+}
+
+std::unique_ptr<GrDrawOp> MakeAAFillWithLocalRect(GrPaint&& paint, const SkMatrix& viewMatrix,
+                                                  const SkRect& rect, const SkRect& localRect) {
+    if (!view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
+        return nullptr;
+    }
     SkRect devRect;
     viewMatrix.mapRect(&devRect, rect);
     SkMatrix localMatrix;
     if (!localMatrix.setRectToRect(rect, localRect, SkMatrix::kFill_ScaleToFit)) {
         return nullptr;
     }
-    return Make(color, viewMatrix, localMatrix, rect, devRect);
+    return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, &localMatrix, nullptr);
 }
-};
+
+}  // namespace GrRectOpFactory
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -389,21 +400,22 @@
 
 #include "GrDrawOpTest.h"
 
-GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAFillRectOp) {
-    GrColor color = GrRandomColor(random);
-    SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
+GR_DRAW_OP_TEST_DEFINE(AAFillRectOp) {
+    SkMatrix viewMatrix;
+    do {
+        viewMatrix = GrTest::TestMatrixInvertible(random);
+    } while (!view_matrix_ok_for_aa_fill_rect(viewMatrix));
     SkRect rect = GrTest::TestRect(random);
-    SkRect devRect = GrTest::TestRect(random);
-    return GrAAFillRectOp::Make(color, viewMatrix, rect, devRect);
-}
-
-GR_LEGACY_MESH_DRAW_OP_TEST_DEFINE(AAFillRectOpLocalMatrix) {
-    GrColor color = GrRandomColor(random);
-    SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
-    SkMatrix localMatrix = GrTest::TestMatrix(random);
-    SkRect rect = GrTest::TestRect(random);
-    SkRect devRect = GrTest::TestRect(random);
-    return GrAAFillRectOp::Make(color, viewMatrix, localMatrix, rect, devRect);
+    SkRect devRect;
+    viewMatrix.mapRect(&devRect, rect);
+    const SkMatrix* localMatrix = nullptr;
+    SkMatrix m;
+    if (random->nextBool()) {
+        m = GrTest::TestMatrix(random);
+    }
+    const GrUserStencilSettings* stencil =
+            random->nextBool() ? nullptr : GrGetRandomStencil(random, context);
+    return AAFillRectOp::Make(std::move(paint), viewMatrix, rect, devRect, localMatrix, stencil);
 }
 
 #endif