Reland "Fix tessellation checks for "usesVaryingCoords""

This is a reland of bd727d0620c4bd85663d6d7c57beb6d40605fb3e

TBR=jvanverth@google.com

Original change's description:
> Fix tessellation checks for "usesVaryingCoords"
>
> We can't use our hardware tessellation back door if any FPs in the
> program have varyings. Before this CL, we were forgetting to check the
> clip FP for strokes, and weren't checking any FPs yet for fills.
>
> Bug: skia:10419
> Change-Id: Ica631ab3cf0407fb359c02c6d53f88f5f301cddc
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/417237
> Reviewed-by: Greg Daniel <egdaniel@google.com>
> Commit-Queue: Chris Dalton <csmartdalton@google.com>

Bug: skia:10419
Change-Id: If8c1e18efc663641b2d565314110f66a6840f8bb
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/417317
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/bench/TessellateBench.cpp b/bench/TessellateBench.cpp
index 2694a75..6a96581 100644
--- a/bench/TessellateBench.cpp
+++ b/bench/TessellateBench.cpp
@@ -113,18 +113,22 @@
 
 DEF_PATH_TESS_BENCH(GrPathOuterCurveTessellator, make_cubic_path(8), SkMatrix::I()) {
     SkArenaAlloc arena(1024);
+    GrPipeline noVaryingsPipeline(GrScissorTest::kDisabled, SkBlendMode::kSrcOver,
+                                  GrSwizzle::RGBA());
     auto tess = GrPathCurveTessellator::Make(&arena, fMatrix, SK_PMColor4fTRANSPARENT,
                                              GrPathCurveTessellator::DrawInnerFan::kNo,
                                              fTarget->caps().minPathVerbsForHwTessellation(),
-                                             fTarget->caps());
+                                             noVaryingsPipeline, fTarget->caps());
     tess->prepare(fTarget.get(), SkRectPriv::MakeLargest(), fPath, nullptr);
 }
 
 DEF_PATH_TESS_BENCH(GrPathWedgeTessellator, make_cubic_path(8), SkMatrix::I()) {
     SkArenaAlloc arena(1024);
+    GrPipeline noVaryingsPipeline(GrScissorTest::kDisabled, SkBlendMode::kSrcOver,
+                                  GrSwizzle::RGBA());
     auto tess = GrPathWedgeTessellator::Make(&arena, fMatrix, SK_PMColor4fTRANSPARENT,
                                              fTarget->caps().minPathVerbsForHwTessellation(),
-                                             fTarget->caps());
+                                             noVaryingsPipeline, fTarget->caps());
     tess->prepare(fTarget.get(), SkRectPriv::MakeLargest(), fPath, nullptr);
 }
 
diff --git a/samplecode/SamplePathTessellators.cpp b/samplecode/SamplePathTessellators.cpp
index 18e8f2f..e154694 100644
--- a/samplecode/SamplePathTessellators.cpp
+++ b/samplecode/SamplePathTessellators.cpp
@@ -74,30 +74,34 @@
         const GrCaps& caps = flushState->caps();
         int numVerbsToGetMiddleOut = 0;
         int numVerbsToGetTessellation = caps.minPathVerbsForHwTessellation();
+        auto pipeline = GrSimpleMeshDrawOpHelper::CreatePipeline(flushState, std::move(fProcessors),
+                                                                 fPipelineFlags);
         switch (fMode) {
             using DrawInnerFan = GrPathCurveTessellator::DrawInnerFan;
             case Mode::kWedgeMiddleOut:
                 fTessellator = GrPathWedgeTessellator::Make(alloc, fMatrix, kCyan,
-                                                            numVerbsToGetMiddleOut, caps);
+                                                            numVerbsToGetMiddleOut, *pipeline,
+                                                            caps);
                 break;
             case Mode::kCurveMiddleOut:
                 fTessellator = GrPathCurveTessellator::Make(alloc, fMatrix, kCyan,
                                                             DrawInnerFan::kYes,
-                                                            numVerbsToGetMiddleOut, caps);
+                                                            numVerbsToGetMiddleOut, *pipeline,
+                                                            caps);
                 break;
             case Mode::kWedgeTessellate:
                 fTessellator = GrPathWedgeTessellator::Make(alloc, fMatrix, kCyan,
-                                                            numVerbsToGetTessellation, caps);
+                                                            numVerbsToGetTessellation, *pipeline,
+                                                            caps);
                 break;
             case Mode::kCurveTessellate:
                 fTessellator = GrPathCurveTessellator::Make(alloc, fMatrix, kCyan,
                                                             DrawInnerFan::kYes,
-                                                            numVerbsToGetTessellation, caps);
+                                                            numVerbsToGetTessellation, *pipeline,
+                                                            caps);
                 break;
         }
         fTessellator->prepare(flushState, this->bounds(), fPath);
-        auto pipeline = GrSimpleMeshDrawOpHelper::CreatePipeline(flushState, std::move(fProcessors),
-                                                                 fPipelineFlags);
         fProgram = GrTessellationShader::MakeProgram({alloc, flushState->writeView(),
                                                      &flushState->dstProxyView(),
                                                      flushState->renderPassBarriers(),
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index aaf68dc..c7172da 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -110,6 +110,15 @@
     bool isColorFragmentProcessor(int idx) const { return idx < fNumColorProcessors; }
     bool isCoverageFragmentProcessor(int idx) const { return idx >= fNumColorProcessors; }
 
+    bool usesVaryingCoords() const {
+        for (const auto& fp : fFragmentProcessors) {
+            if (fp->usesVaryingCoords()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     void visitTextureEffects(const std::function<void(const GrTextureEffect&)>&) const;
 
     const GrXferProcessor& getXferProcessor() const {
diff --git a/src/gpu/GrProcessorSet.h b/src/gpu/GrProcessorSet.h
index ab1e28b..7dbf695 100644
--- a/src/gpu/GrProcessorSet.h
+++ b/src/gpu/GrProcessorSet.h
@@ -43,11 +43,6 @@
         return fCoverageFragmentProcessor.get();
     }
 
-    bool usesVaryingCoords() const {
-        return (fColorFragmentProcessor && fColorFragmentProcessor->usesVaryingCoords()) ||
-               (fCoverageFragmentProcessor && fCoverageFragmentProcessor->usesVaryingCoords());
-    }
-
     const GrXferProcessor* xferProcessor() const {
         SkASSERT(this->isFinalized());
         return fXP.fProcessor;
diff --git a/src/gpu/tessellate/GrPathCurveTessellator.cpp b/src/gpu/tessellate/GrPathCurveTessellator.cpp
index de4894a..cf3adf3 100644
--- a/src/gpu/tessellate/GrPathCurveTessellator.cpp
+++ b/src/gpu/tessellate/GrPathCurveTessellator.cpp
@@ -137,10 +137,12 @@
 
 GrPathTessellator* GrPathCurveTessellator::Make(SkArenaAlloc* arena, const SkMatrix& viewMatrix,
                                                 const SkPMColor4f& color, DrawInnerFan drawInnerFan,
-                                                int numPathVerbs, const GrCaps& caps) {
+                                                int numPathVerbs, const GrPipeline& pipeline,
+                                                const GrCaps& caps) {
     using PatchType = GrPathTessellationShader::PatchType;
     GrPathTessellationShader* shader;
     if (caps.shaderCaps()->tessellationSupport() &&
+        !pipeline.usesVaryingCoords() &&  // Our tessellation back door doesn't handle varyings.
         numPathVerbs >= caps.minPathVerbsForHwTessellation()) {
         shader = GrPathTessellationShader::MakeHardwareTessellationShader(arena, viewMatrix, color,
                                                                           PatchType::kCurves);
diff --git a/src/gpu/tessellate/GrPathCurveTessellator.h b/src/gpu/tessellate/GrPathCurveTessellator.h
index ac9da97..1132fa7 100644
--- a/src/gpu/tessellate/GrPathCurveTessellator.h
+++ b/src/gpu/tessellate/GrPathCurveTessellator.h
@@ -25,7 +25,8 @@
 
     // Creates a curve tessellator with the shader type best suited for the given path description.
     static GrPathTessellator* Make(SkArenaAlloc*, const SkMatrix& viewMatrix, const SkPMColor4f&,
-                                   DrawInnerFan, int numPathVerbs, const GrCaps&);
+                                   DrawInnerFan, int numPathVerbs, const GrPipeline&,
+                                   const GrCaps&);
 
     void prepare(GrMeshDrawOp::Target*, const SkRect& cullBounds, const SkPath&,
                  const BreadcrumbTriangleList*) override;
diff --git a/src/gpu/tessellate/GrPathInnerTriangulateOp.cpp b/src/gpu/tessellate/GrPathInnerTriangulateOp.cpp
index cbeffc1..41054fe 100644
--- a/src/gpu/tessellate/GrPathInnerTriangulateOp.cpp
+++ b/src/gpu/tessellate/GrPathInnerTriangulateOp.cpp
@@ -192,7 +192,8 @@
         fTessellator = GrPathCurveTessellator::Make(args.fArena, fViewMatrix,
                                                     SK_PMColor4fTRANSPARENT,
                                                     GrPathCurveTessellator::DrawInnerFan::kNo,
-                                                    fPath.countVerbs(), *args.fCaps);
+                                                    fPath.countVerbs(), *pipelineForStencils,
+                                                    *args.fCaps);
         const GrUserStencilSettings* stencilPathSettings =
                 GrPathTessellationShader::StencilPathSettings(fPath.getFillType());
         fStencilCurvesProgram = GrTessellationShader::MakeProgram(args, fTessellator->shader(),
diff --git a/src/gpu/tessellate/GrPathStencilCoverOp.cpp b/src/gpu/tessellate/GrPathStencilCoverOp.cpp
index aff707a..525092c 100644
--- a/src/gpu/tessellate/GrPathStencilCoverOp.cpp
+++ b/src/gpu/tessellate/GrPathStencilCoverOp.cpp
@@ -113,11 +113,12 @@
         fTessellator = GrPathCurveTessellator::Make(args.fArena, fViewMatrix,
                                                     SK_PMColor4fTRANSPARENT,
                                                     GrPathCurveTessellator::DrawInnerFan::kNo,
-                                                    fPath.countVerbs(), *args.fCaps);
+                                                    fPath.countVerbs(), *stencilPipeline,
+                                                    *args.fCaps);
     } else {
         fTessellator = GrPathWedgeTessellator::Make(args.fArena, fViewMatrix,
                                                     SK_PMColor4fTRANSPARENT, fPath.countVerbs(),
-                                                    *args.fCaps);
+                                                    *stencilPipeline, *args.fCaps);
     }
     fStencilPathProgram = GrTessellationShader::MakeProgram(args, fTessellator->shader(),
                                                             stencilPipeline, stencilPathSettings);
diff --git a/src/gpu/tessellate/GrPathWedgeTessellator.cpp b/src/gpu/tessellate/GrPathWedgeTessellator.cpp
index b380fb7..d00e866 100644
--- a/src/gpu/tessellate/GrPathWedgeTessellator.cpp
+++ b/src/gpu/tessellate/GrPathWedgeTessellator.cpp
@@ -227,10 +227,11 @@
 
 GrPathTessellator* GrPathWedgeTessellator::Make(SkArenaAlloc* arena, const SkMatrix& viewMatrix,
                                                 const SkPMColor4f& color, int numPathVerbs,
-                                                const GrCaps& caps) {
+                                                const GrPipeline& pipeline, const GrCaps& caps) {
     using PatchType = GrPathTessellationShader::PatchType;
     GrPathTessellationShader* shader;
     if (caps.shaderCaps()->tessellationSupport() &&
+        !pipeline.usesVaryingCoords() &&  // Our tessellation back door doesn't handle varyings.
         numPathVerbs >= caps.minPathVerbsForHwTessellation()) {
         shader = GrPathTessellationShader::MakeHardwareTessellationShader(arena, viewMatrix, color,
                                                                           PatchType::kWedges);
diff --git a/src/gpu/tessellate/GrPathWedgeTessellator.h b/src/gpu/tessellate/GrPathWedgeTessellator.h
index da3c6c0..660be63 100644
--- a/src/gpu/tessellate/GrPathWedgeTessellator.h
+++ b/src/gpu/tessellate/GrPathWedgeTessellator.h
@@ -19,7 +19,7 @@
 public:
     // Creates a wedge tessellator with the shader type best suited for the given path description.
     static GrPathTessellator* Make(SkArenaAlloc*, const SkMatrix& viewMatrix, const SkPMColor4f&,
-                                   int numPathVerbs, const GrCaps&);
+                                   int numPathVerbs, const GrPipeline&, const GrCaps&);
 
     void prepare(GrMeshDrawOp::Target*, const SkRect& cullBounds, const SkPath&,
                  const BreadcrumbTriangleList*) override;
diff --git a/src/gpu/tessellate/GrStrokeTessellateOp.cpp b/src/gpu/tessellate/GrStrokeTessellateOp.cpp
index bd4d8fd..fb2526e 100644
--- a/src/gpu/tessellate/GrStrokeTessellateOp.cpp
+++ b/src/gpu/tessellate/GrStrokeTessellateOp.cpp
@@ -146,12 +146,11 @@
         GrUserStencilOp::kReplace,
         0xffff>());
 
-bool GrStrokeTessellateOp::canUseHardwareTessellation(int numVerbs, const GrCaps& caps) {
-    SkASSERT(!fStencilProgram && !fFillProgram);  // Ensure we haven't std::moved fProcessors.
+bool can_use_hardware_tessellation(int numVerbs, const GrPipeline& pipeline, const GrCaps& caps) {
     if (!caps.shaderCaps()->tessellationSupport()) {
         return false;
     }
-    if (fProcessors.usesVaryingCoords()) {
+    if (pipeline.usesVaryingCoords()) {
         // Our back door for HW tessellation shaders isn't currently capable of passing varyings to
         // the fragment shader, so if the processors have varyings, we need to use instanced draws
         // instead.
@@ -185,7 +184,10 @@
     }
     SkRect strokeCullBounds = this->bounds().makeOutset(devInflationRadius, devInflationRadius);
 
-    if (this->canUseHardwareTessellation(fTotalCombinedVerbCnt, caps)) {
+    auto* pipeline = GrTessellationShader::MakePipeline(args, fAAType, std::move(clip),
+                                                        std::move(fProcessors));
+
+    if (can_use_hardware_tessellation(fTotalCombinedVerbCnt, *pipeline, caps)) {
         // Only use hardware tessellation if we're drawing a somewhat large number of verbs.
         // Otherwise we seem to be better off using instanced draws.
         fTessellator = arena->make<GrStrokeHardwareTessellator>(fShaderFlags, *caps.shaderCaps(),
@@ -199,8 +201,6 @@
                                                                   strokeCullBounds);
     }
 
-    auto* pipeline = GrTessellationShader::MakePipeline(args, fAAType, std::move(clip),
-                                                        std::move(fProcessors));
     auto fillStencil = &GrUserStencilSettings::kUnused;
     if (fNeedsStencil) {
         fStencilProgram = GrTessellationShader::MakeProgram(args, fTessellator->shader(), pipeline,
diff --git a/src/gpu/tessellate/GrStrokeTessellateOp.h b/src/gpu/tessellate/GrStrokeTessellateOp.h
index e3890cb..e8f61e1 100644
--- a/src/gpu/tessellate/GrStrokeTessellateOp.h
+++ b/src/gpu/tessellate/GrStrokeTessellateOp.h
@@ -41,8 +41,6 @@
         return allStatesEnabled || (fTotalCombinedVerbCnt <= kMaxVerbsToEnableDynamicState);
     }
 
-    bool canUseHardwareTessellation(int numVerbs, const GrCaps& caps);
-
     const char* name() const override { return "GrStrokeTessellateOp"; }
     void visitProxies(const VisitProxyFunc& fn) const override;
     bool usesMSAA() const override { return fAAType == GrAAType::kMSAA; }