Eliminate special case nvpr batch handling

Removes drawPathBatch methods from GrDrawTarget and GrDrawContext, and
integrates nvpr batches in with all the other batches.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1966763002

Review-Url: https://codereview.chromium.org/1966763002
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp
index 7f5cdc7..10b9b63 100644
--- a/src/gpu/GrDrawContext.cpp
+++ b/src/gpu/GrDrawContext.cpp
@@ -782,18 +782,6 @@
     this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
 }
 
-void GrDrawContext::drawPathBatch(const GrPipelineBuilder& pipelineBuilder,
-                                  GrDrawPathBatchBase* batch) {
-    ASSERT_SINGLE_OWNER
-    RETURN_IF_ABANDONED
-    SkDEBUGCODE(this->validate();)
-    GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawPathBatch");
-
-    AutoCheckFlush acf(fDrawingManager);
-
-    this->getDrawTarget()->drawPathBatch(pipelineBuilder, batch);
-}
-
 void GrDrawContext::drawPath(const GrClip& clip,
                              const GrPaint& paint,
                              const SkMatrix& viewMatrix,
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 7166fc7..26b271f 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -257,8 +257,51 @@
     }
 
     GrPipeline::CreateArgs args;
-    if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip.scissorState(),
-                                          clip.hasStencilClip(), batch)) {
+    args.fPipelineBuilder = &pipelineBuilder;
+    args.fCaps = this->caps();
+    args.fScissor = &clip.scissorState();
+    args.fHasStencilClip = clip.hasStencilClip();
+    if (pipelineBuilder.hasUserStencilSettings() || clip.hasStencilClip()) {
+        fResourceProvider->attachStencilAttachment(pipelineBuilder.getRenderTarget());
+    }
+    batch->getPipelineOptimizations(&args.fOpts);
+    GrScissorState finalScissor;
+    if (args.fOpts.fOverrides.fUsePLSDstRead) {
+        GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
+        GrGLIRect viewport;
+        viewport.fLeft = 0;
+        viewport.fBottom = 0;
+        viewport.fWidth = rt->width();
+        viewport.fHeight = rt->height();
+        SkIRect ibounds;
+        ibounds.fLeft = SkTPin(SkScalarFloorToInt(batch->bounds().fLeft), viewport.fLeft,
+                              viewport.fWidth);
+        ibounds.fTop = SkTPin(SkScalarFloorToInt(batch->bounds().fTop), viewport.fBottom,
+                             viewport.fHeight);
+        ibounds.fRight = SkTPin(SkScalarCeilToInt(batch->bounds().fRight), viewport.fLeft,
+                               viewport.fWidth);
+        ibounds.fBottom = SkTPin(SkScalarCeilToInt(batch->bounds().fBottom), viewport.fBottom,
+                                viewport.fHeight);
+        if (clip.scissorState().enabled()) {
+            const SkIRect& scissorRect = clip.scissorState().rect();
+            if (!ibounds.intersect(scissorRect)) {
+                ibounds = scissorRect;
+            }
+        }
+        finalScissor.set(ibounds);
+        args.fScissor = &finalScissor;
+    }
+    args.fOpts.fColorPOI.completeCalculations(pipelineBuilder.fColorFragmentProcessors.begin(),
+                                              pipelineBuilder.numColorFragmentProcessors());
+    args.fOpts.fCoveragePOI.completeCalculations(
+                                               pipelineBuilder.fCoverageFragmentProcessors.begin(),
+                                               pipelineBuilder.numCoverageFragmentProcessors());
+    if (!this->setupDstReadIfNecessary(pipelineBuilder, args.fOpts, &args.fDstTexture,
+                                       batch->bounds())) {
+        return;
+    }
+
+    if (!batch->installPipeline(args)) {
         return;
     }
 
@@ -270,38 +313,6 @@
     this->recordBatch(batch);
 }
 
-inline static const GrUserStencilSettings& get_path_stencil_settings_for_fill(
-        GrPathRendering::FillType fill) {
-    static constexpr GrUserStencilSettings kWindingStencilSettings(
-        GrUserStencilSettings::StaticInit<
-            0xffff,
-            GrUserStencilTest::kAlwaysIfInClip,
-            0xffff,
-            GrUserStencilOp::kIncMaybeClamp, // TODO: Use wrap ops for NVPR.
-            GrUserStencilOp::kIncMaybeClamp,
-            0xffff>()
-    );
-
-    static constexpr GrUserStencilSettings kEvenOddStencilSettings(
-        GrUserStencilSettings::StaticInit<
-            0xffff,
-            GrUserStencilTest::kAlwaysIfInClip,
-            0xffff,
-            GrUserStencilOp::kInvert,
-            GrUserStencilOp::kInvert,
-            0xffff>()
-    );
-
-    switch (fill) {
-        default:
-            SkFAIL("Unexpected path fill.");
-        case GrPathRendering::kWinding_FillType:
-            return kWindingStencilSettings;
-        case GrPathRendering::kEvenOdd_FillType:
-            return kEvenOddStencilSettings;
-    }
-}
-
 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
                                const SkMatrix& viewMatrix,
                                const GrPath* path,
@@ -327,7 +338,7 @@
 
     GrBatch* batch = GrStencilPathBatch::Create(viewMatrix,
                                                 pipelineBuilder.isHWAntialias(),
-                                                get_path_stencil_settings_for_fill(fill),
+                                                fill,
                                                 clip.hasStencilClip(),
                                                 stencilAttachment->bits(),
                                                 clip.scissorState(),
@@ -337,42 +348,6 @@
     batch->unref();
 }
 
-void GrDrawTarget::drawPathBatch(const GrPipelineBuilder& pipelineBuilder,
-                                 GrDrawPathBatchBase* batch) {
-    // This looks like drawBatch() but there is an added wrinkle that stencil settings get inserted
-    // after setting up clipping but before onDrawBatch(). TODO: Figure out a better model for
-    // handling stencil settings WRT interactions between pipeline(builder), clipmaskmanager, and
-    // batches.
-    SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport());
-
-    GrAppliedClip clip;
-    if (!fClipMaskManager->setupClipping(pipelineBuilder, &batch->bounds(), &clip)) {
-        return;
-    }
-
-    GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
-    if (clip.clipCoverageFragmentProcessor()) {
-        arfps.set(&pipelineBuilder);
-        arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor());
-    }
-
-    // Ensure the render target has a stencil buffer and get the stencil settings.
-    GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
-    GrStencilAttachment* sb = fResourceProvider->attachStencilAttachment(rt);
-    // TODO: Move this step into GrDrawPathPath::onPrepare().
-    batch->setStencilSettings(get_path_stencil_settings_for_fill(batch->fillType()),
-                              clip.hasStencilClip(),
-                              sb->bits());
-
-    GrPipeline::CreateArgs args;
-    if (!this->installPipelineInDrawBatch(&pipelineBuilder, &clip.scissorState(),
-                                          clip.hasStencilClip(), batch)) {
-        return;
-    }
-
-    this->recordBatch(batch);
-}
-
 void GrDrawTarget::clear(const SkIRect* rect,
                          GrColor color,
                          bool canIgnoreRect,
@@ -548,65 +523,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-bool GrDrawTarget::installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder,
-                                              const GrScissorState* scissor,
-                                              bool hasStencilClip,
-                                              GrDrawBatch* batch) {
-    GrPipeline::CreateArgs args;
-    args.fPipelineBuilder = pipelineBuilder;
-    args.fCaps = this->caps();
-    args.fScissor = scissor;
-    if (pipelineBuilder->hasUserStencilSettings() || hasStencilClip) {
-        GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
-        GrStencilAttachment* sb = fResourceProvider->attachStencilAttachment(rt);
-        args.fNumStencilBits = sb->bits();
-    } else {
-        args.fNumStencilBits = 0;
-    }
-    args.fHasStencilClip = hasStencilClip;
-    batch->getPipelineOptimizations(&args.fOpts);
-    GrScissorState finalScissor;
-    if (args.fOpts.fOverrides.fUsePLSDstRead) {
-        GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
-        GrGLIRect viewport;
-        viewport.fLeft = 0;
-        viewport.fBottom = 0;
-        viewport.fWidth = rt->width();
-        viewport.fHeight = rt->height();
-        SkIRect ibounds;
-        ibounds.fLeft = SkTPin(SkScalarFloorToInt(batch->bounds().fLeft), viewport.fLeft,
-                              viewport.fWidth);
-        ibounds.fTop = SkTPin(SkScalarFloorToInt(batch->bounds().fTop), viewport.fBottom,
-                             viewport.fHeight);
-        ibounds.fRight = SkTPin(SkScalarCeilToInt(batch->bounds().fRight), viewport.fLeft,
-                               viewport.fWidth);
-        ibounds.fBottom = SkTPin(SkScalarCeilToInt(batch->bounds().fBottom), viewport.fBottom,
-                                viewport.fHeight);
-        if (scissor != nullptr && scissor->enabled()) {
-            if (!ibounds.intersect(scissor->rect())) {
-                ibounds = scissor->rect();
-            }
-        }
-        finalScissor.set(ibounds);
-        args.fScissor = &finalScissor;
-    }
-    args.fOpts.fColorPOI.completeCalculations(pipelineBuilder->fColorFragmentProcessors.begin(),
-                                              pipelineBuilder->numColorFragmentProcessors());
-    args.fOpts.fCoveragePOI.completeCalculations(
-                                               pipelineBuilder->fCoverageFragmentProcessors.begin(),
-                                               pipelineBuilder->numCoverageFragmentProcessors());
-    if (!this->setupDstReadIfNecessary(*pipelineBuilder, args.fOpts, &args.fDstTexture,
-                                       batch->bounds())) {
-        return false;
-    }
-
-    if (!batch->installPipeline(args)) {
-        return false;
-    }
-
-    return true;
-}
-
 void GrDrawTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) {
     GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt);
     this->recordBatch(batch);
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 907fc1f..9deacc2 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -117,15 +117,6 @@
                      GrPathRendering::FillType);
 
     /**
-     * Draws a path batch. Fill must not be a hairline. It will respect the HW antialias flag on
-     * the GrPipelineBuilder (if possible in the 3D API). This needs to be separate from drawBatch
-     * because we install path stencil settings late.
-     *
-     * TODO: Figure out a better model that allows us to roll this method into drawBatch.
-     */
-    void drawPathBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawPathBatchBase* batch);
-
-    /**
      * Clear the passed in render target. Ignores the GrPipelineBuilder and clip. Clears the whole
      * thing if rect is nullptr, otherwise just the rect. If canIgnoreRect is set then the entire
      * render target can be optionally cleared.
@@ -221,10 +212,6 @@
 
     void recordBatch(GrBatch*);
     void forwardCombine();
-    bool installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder,
-                                    const GrScissorState* scissor,
-                                    bool hasStencilClip,
-                                    GrDrawBatch* batch);
 
     // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
     // but couldn't be made. Otherwise, returns true.  This method needs to be protected because it
diff --git a/src/gpu/GrPathRendering.cpp b/src/gpu/GrPathRendering.cpp
index d1345c9..652f2ce 100644
--- a/src/gpu/GrPathRendering.cpp
+++ b/src/gpu/GrPathRendering.cpp
@@ -12,6 +12,37 @@
 #include "SkTypeface.h"
 #include "GrPathRange.h"
 
+const GrUserStencilSettings& GrPathRendering::GetStencilPassSettings(FillType fill) {
+    switch (fill) {
+        default:
+            SkFAIL("Unexpected path fill.");
+        case GrPathRendering::kWinding_FillType: {
+            constexpr static GrUserStencilSettings kWindingStencilPass(
+                GrUserStencilSettings::StaticInit<
+                    0xffff,
+                    GrUserStencilTest::kAlwaysIfInClip,
+                    0xffff,
+                    GrUserStencilOp::kIncWrap,
+                    GrUserStencilOp::kIncWrap,
+                    0xffff>()
+            );
+            return kWindingStencilPass;
+        }
+        case GrPathRendering::kEvenOdd_FillType: {
+            constexpr static GrUserStencilSettings kEvenOddStencilPass(
+                GrUserStencilSettings::StaticInit<
+                    0xffff,
+                    GrUserStencilTest::kAlwaysIfInClip,
+                    0xffff,
+                    GrUserStencilOp::kInvert,
+                    GrUserStencilOp::kInvert,
+                    0xffff>()
+            );
+            return kEvenOddStencilPass;
+        }
+    }
+}
+
 class GlyphGenerator : public GrPathRange::PathGenerator {
 public:
     GlyphGenerator(const SkTypeface& typeface, const SkScalerContextEffects& effects,
diff --git a/src/gpu/GrPathRendering.h b/src/gpu/GrPathRendering.h
index 8eea321..f2c02d9 100644
--- a/src/gpu/GrPathRendering.h
+++ b/src/gpu/GrPathRendering.h
@@ -77,6 +77,8 @@
         kEvenOdd_FillType,
     };
 
+    static const GrUserStencilSettings& GetStencilPassSettings(FillType);
+
     /**
      * Creates a new gpu path, based on the specified path and stroke and returns it.
      * The caller owns a ref on the returned path which must be balanced by a call to unref.
@@ -157,18 +159,18 @@
 
     void drawPath(const GrPipeline& pipeline,
                   const GrPrimitiveProcessor& primProc,
-                  const GrStencilSettings& stencil,
+                  const GrStencilSettings& stencilPassSettings, // Cover pass settings in pipeline.
                   const GrPath* path) {
         fGpu->handleDirtyContext();
         if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*fGpu->caps())) {
             fGpu->xferBarrier(pipeline.getRenderTarget(), barrierType);
         }
-        this->onDrawPath(pipeline, primProc, stencil, path);
+        this->onDrawPath(pipeline, primProc, stencilPassSettings, path);
     }
 
     void drawPaths(const GrPipeline& pipeline,
                    const GrPrimitiveProcessor& primProc,
-                   const GrStencilSettings& stencil,
+                   const GrStencilSettings& stencilPassSettings, // Cover pass settings in pipeline.
                    const GrPathRange* pathRange,
                    const void* indices,
                    PathIndexType indexType,
@@ -182,7 +184,7 @@
 #ifdef SK_DEBUG
         pathRange->assertPathsLoaded(indices, indexType, count);
 #endif
-        this->onDrawPaths(pipeline, primProc, stencil, pathRange, indices, indexType,
+        this->onDrawPaths(pipeline, primProc, stencilPassSettings, pathRange, indices, indexType,
                           transformValues, transformType, count);
     }
 
diff --git a/src/gpu/GrPipeline.cpp b/src/gpu/GrPipeline.cpp
index 761a876..d52e811 100644
--- a/src/gpu/GrPipeline.cpp
+++ b/src/gpu/GrPipeline.cpp
@@ -12,6 +12,7 @@
 #include "GrGpu.h"
 #include "GrPipelineBuilder.h"
 #include "GrProcOptInfo.h"
+#include "GrRenderTargetPriv.h"
 #include "GrXferProcessor.h"
 
 #include "batches/GrBatch.h"
@@ -25,9 +26,9 @@
     SkASSERT(pipeline->fRenderTarget);
     pipeline->fScissorState = *args.fScissor;
     if (builder.hasUserStencilSettings() || args.fHasStencilClip) {
-        SkASSERT(args.fNumStencilBits);
+        const GrRenderTargetPriv& rtPriv = builder.getRenderTarget()->renderTargetPriv();
         pipeline->fStencilSettings.reset(*builder.getUserStencil(), args.fHasStencilClip,
-                                         args.fNumStencilBits);
+                                         rtPriv.numStencilBits());
         SkASSERT(!pipeline->fStencilSettings.usesWrapOp() || args.fCaps->stencilWrapOpsSupport());
     }
     pipeline->fDrawFace = builder.getDrawFace();
@@ -45,6 +46,9 @@
     if (builder.getAllowSRGBInputs()) {
         pipeline->fFlags |= kAllowSRGBInputs_Flag;
     }
+    if (args.fHasStencilClip) {
+        pipeline->fFlags |= kHasStencilClip_Flag;
+    }
 
     // Create XferProcessor from DS's XPFactory
     bool hasMixedSamples = builder.getRenderTarget()->hasMixedSamples() &&
diff --git a/src/gpu/GrPipeline.h b/src/gpu/GrPipeline.h
index ff1905b..60e1631 100644
--- a/src/gpu/GrPipeline.h
+++ b/src/gpu/GrPipeline.h
@@ -51,7 +51,6 @@
         const GrCaps*               fCaps;
         GrPipelineOptimizations     fOpts;
         const GrScissorState*       fScissor;
-        int                         fNumStencilBits;
         bool                        fHasStencilClip;
         GrXferProcessor::DstTexture fDstTexture;
     };
@@ -153,6 +152,9 @@
     bool getAllowSRGBInputs() const {
         return SkToBool(fFlags & kAllowSRGBInputs_Flag);
     }
+    bool hasStencilClip() const {
+        return SkToBool(fFlags & kHasStencilClip_Flag);
+    }
 
     GrXferBarrierType xferBarrierType(const GrCaps& caps) const {
         return this->getXferProcessor().xferBarrierType(fRenderTarget.get(), caps);
@@ -196,6 +198,7 @@
         kSnapVertices_Flag                  = 0x2,
         kDisableOutputConversionToSRGB_Flag = 0x4,
         kAllowSRGBInputs_Flag               = 0x8,
+        kHasStencilClip_Flag                = 0x10
     };
 
     typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp
index ebbfae9..6a9d489 100644
--- a/src/gpu/GrRenderTarget.cpp
+++ b/src/gpu/GrRenderTarget.cpp
@@ -105,6 +105,10 @@
     return true;
 }
 
+int GrRenderTargetPriv::numStencilBits() const {
+    return fRenderTarget->fStencilAttachment ? fRenderTarget->fStencilAttachment->bits() : 0;
+}
+
 const GrGpu::MultisampleSpecs&
 GrRenderTargetPriv::getMultisampleSpecs(const GrStencilSettings& stencil) const {
     return fRenderTarget->getGpu()->getMultisampleSpecs(fRenderTarget, stencil);
diff --git a/src/gpu/GrRenderTargetPriv.h b/src/gpu/GrRenderTargetPriv.h
index 24b7e88..52eed69 100644
--- a/src/gpu/GrRenderTargetPriv.h
+++ b/src/gpu/GrRenderTargetPriv.h
@@ -30,6 +30,8 @@
      */
     bool attachStencilAttachment(GrStencilAttachment* stencil);
 
+    int numStencilBits() const;
+
     const GrGpu::MultisampleSpecs& getMultisampleSpecs(const GrStencilSettings& stencil) const;
 
     GrRenderTarget::SampleConfig sampleConfig() const { return fRenderTarget->fSampleConfig; }
diff --git a/src/gpu/GrStencilSettings.cpp b/src/gpu/GrStencilSettings.cpp
index ae8b03b..d3216db 100644
--- a/src/gpu/GrStencilSettings.cpp
+++ b/src/gpu/GrStencilSettings.cpp
@@ -170,7 +170,7 @@
     SkASSERT(user.fTest < (GrUserStencilTest)kGrUserStencilTestCount);
     SkASSERT(user.fPassOp < (GrUserStencilOp)kGrUserStencilOpCount);
     SkASSERT(user.fFailOp < (GrUserStencilOp)kGrUserStencilOpCount);
-    SkASSERT(numStencilBits <= 16);
+    SkASSERT(numStencilBits > 0 && numStencilBits <= 16);
     int clipBit = 1 << (numStencilBits - 1);
     int userMask = clipBit - 1;
 
diff --git a/src/gpu/batches/GrDrawPathBatch.cpp b/src/gpu/batches/GrDrawPathBatch.cpp
index 1395d08..751ddda 100644
--- a/src/gpu/batches/GrDrawPathBatch.cpp
+++ b/src/gpu/batches/GrDrawPathBatch.cpp
@@ -7,10 +7,18 @@
 
 #include "GrDrawPathBatch.h"
 
+#include "GrRenderTargetPriv.h"
+
 static void pre_translate_transform_values(const float* xforms,
                                            GrPathRendering::PathTransformType type, int count,
                                            SkScalar x, SkScalar y, float* dst);
 
+void GrDrawPathBatchBase::onPrepare(GrBatchFlushState*) {
+    const GrRenderTargetPriv& rtPriv = this->pipeline()->getRenderTarget()->renderTargetPriv();
+    fStencilPassSettings.reset(GrPathRendering::GetStencilPassSettings(fFillType),
+                               this->pipeline()->hasStencilClip(), rtPriv.numStencilBits());
+}
+
 SkString GrDrawPathBatch::dumpInfo() const {
     SkString string;
     string.printf("PATH: 0x%p", fPath.get());
@@ -23,8 +31,8 @@
     SkAutoTUnref<GrPathProcessor> pathProc(GrPathProcessor::Create(this->color(),
                                                                    this->overrides(),
                                                                    this->viewMatrix()));
-    state->gpu()->pathRendering()->drawPath(*this->pipeline(), *pathProc, this->stencilSettings(),
-                                            fPath.get());
+    state->gpu()->pathRendering()->drawPath(*this->pipeline(), *pathProc,
+                                            this->stencilPassSettings(), fPath.get());
 }
 
 SkString GrDrawPathRangeBatch::dumpInfo() const {
@@ -89,7 +97,7 @@
     // numbers, and we only partially account for this by not allowing even/odd paths to be
     // combined. (Glyphs in the same font tend to wind the same direction so it works out OK.)
     if (GrPathRendering::kWinding_FillType != this->fillType() ||
-        this->stencilSettings() != that->stencilSettings() ||
+        GrPathRendering::kWinding_FillType != that->fillType() ||
         this->overrides().willColorBlendWithDst()) {
         return false;
     }
@@ -126,7 +134,7 @@
         const InstanceData& instances = *head.fInstanceData;
         state->gpu()->pathRendering()->drawPaths(*this->pipeline(),
                                                  *pathProc,
-                                                 this->stencilSettings(),
+                                                 this->stencilPassSettings(),
                                                  fPathRange.get(),
                                                  instances.indices(),
                                                  GrPathRange::kU16_PathIndexType,
@@ -155,7 +163,7 @@
 
         state->gpu()->pathRendering()->drawPaths(*this->pipeline(),
                                                  *pathProc,
-                                                 this->stencilSettings(),
+                                                 this->stencilPassSettings(),
                                                  fPathRange.get(),
                                                  indexStorage,
                                                  GrPathRange::kU16_PathIndexType,
diff --git a/src/gpu/batches/GrDrawPathBatch.h b/src/gpu/batches/GrDrawPathBatch.h
index 55fe31a..7e695d8 100644
--- a/src/gpu/batches/GrDrawPathBatch.h
+++ b/src/gpu/batches/GrDrawPathBatch.h
@@ -26,13 +26,6 @@
         coverage->setKnownSingleComponent(0xff);
     }
 
-    GrPathRendering::FillType fillType() const { return fFillType; }
-
-    void setStencilSettings(const GrUserStencilSettings& stencil, bool hasStencilClip,
-                            int numStencilBits) {
-        fStencilSettings.reset(stencil, hasStencilClip, numStencilBits);
-    }
-
 protected:
     GrDrawPathBatchBase(uint32_t classID, const SkMatrix& viewMatrix, GrColor initialColor,
                         GrPathRendering::FillType fill)
@@ -41,10 +34,14 @@
         , fColor(initialColor)
         , fFillType(fill) {}
 
-    const GrStencilSettings& stencilSettings() const { return fStencilSettings; }
+    const GrStencilSettings& stencilPassSettings() const {
+        SkASSERT(!fStencilPassSettings.isDisabled()); // This shouldn't be called before onPrepare.
+        return fStencilPassSettings;
+    }
     const GrXPOverridesForBatch& overrides() const { return fOverrides; }
     const SkMatrix& viewMatrix() const { return fViewMatrix; }
     GrColor color() const { return fColor; }
+    GrPathRendering::FillType fillType() const { return fFillType; }
 
 private:
     void initBatchTracker(const GrXPOverridesForBatch& overrides) override {
@@ -52,10 +49,12 @@
         fOverrides = overrides;
     }
 
+    void onPrepare(GrBatchFlushState*) override; // Initializes fStencilPassSettings.
+
     SkMatrix                                                fViewMatrix;
     GrColor                                                 fColor;
     GrPathRendering::FillType                               fFillType;
-    GrStencilSettings                                       fStencilSettings;
+    GrStencilSettings                                       fStencilPassSettings;
     GrXPOverridesForBatch                                   fOverrides;
 
     typedef GrDrawBatch INHERITED;
@@ -65,9 +64,8 @@
 public:
     DEFINE_BATCH_CLASS_ID
 
-    // This can't return a more abstract type because we install the stencil settings late :(
-    static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, GrColor color,
-                                       GrPathRendering::FillType fill, const GrPath* path) {
+    static GrDrawBatch* Create(const SkMatrix& viewMatrix, GrColor color,
+                               GrPathRendering::FillType fill, const GrPath* path) {
         return new GrDrawPathBatch(viewMatrix, color, fill, path);
     }
 
@@ -86,8 +84,6 @@
 
     bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { return false; }
 
-    void onPrepare(GrBatchFlushState*) override {}
-
     void onDraw(GrBatchFlushState* state) override;
 
     GrPendingIOResource<const GrPath, kRead_GrIOType> fPath;
@@ -161,11 +157,9 @@
         SkDEBUGCODE(int fReserveCnt;)
     };
 
-    // This can't return a more abstract type because we install the stencil settings late :(
-    static GrDrawPathBatchBase* Create(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x,
-                                       SkScalar y, GrColor color, GrPathRendering::FillType fill,
-                                       GrPathRange* range, const InstanceData* instanceData,
-                                       const SkRect& bounds) {
+    static GrDrawBatch* Create(const SkMatrix& viewMatrix, SkScalar scale, SkScalar x, SkScalar y,
+                               GrColor color, GrPathRendering::FillType fill, GrPathRange* range,
+                               const InstanceData* instanceData, const SkRect& bounds) {
         return new GrDrawPathRangeBatch(viewMatrix, scale, x, y, color, fill, range, instanceData,
                                         bounds);
     }
@@ -183,8 +177,6 @@
 
     bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override;
 
-    void onPrepare(GrBatchFlushState*) override {}
-
     void onDraw(GrBatchFlushState* state) override;
 
     struct Draw {
diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
index 1309ded..af0c397 100644
--- a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
@@ -147,9 +147,9 @@
         );
 
         pipelineBuilder->setUserStencil(&kCoverPass);
-        SkAutoTUnref<GrDrawPathBatchBase> batch(
+        SkAutoTUnref<GrDrawBatch> batch(
                 GrDrawPathBatch::Create(viewMatrix, args.fColor, p->getFillType(), p));
-        args.fTarget->drawPathBatch(*pipelineBuilder, batch);
+        args.fTarget->drawBatch(*pipelineBuilder, batch);
     }
 
     pipelineBuilder->disableUserStencil();
diff --git a/src/gpu/batches/GrStencilPathBatch.h b/src/gpu/batches/GrStencilPathBatch.h
index 8477822..05b55ef 100644
--- a/src/gpu/batches/GrStencilPathBatch.h
+++ b/src/gpu/batches/GrStencilPathBatch.h
@@ -21,13 +21,13 @@
 
     static GrBatch* Create(const SkMatrix& viewMatrix,
                            bool useHWAA,
-                           const GrUserStencilSettings& userStencil,
+                           GrPathRendering::FillType fillType,
                            bool hasStencilClip,
                            int numStencilBits,
                            const GrScissorState& scissor,
                            GrRenderTarget* renderTarget,
                            const GrPath* path) {
-        return new GrStencilPathBatch(viewMatrix, useHWAA, userStencil, hasStencilClip,
+        return new GrStencilPathBatch(viewMatrix, useHWAA, fillType, hasStencilClip,
                                       numStencilBits, scissor, renderTarget, path);
     }
 
@@ -45,7 +45,7 @@
 private:
     GrStencilPathBatch(const SkMatrix& viewMatrix,
                        bool useHWAA,
-                       const GrUserStencilSettings& userStencil,
+                       GrPathRendering::FillType fillType,
                        bool hasStencilClip,
                        int numStencilBits,
                        const GrScissorState& scissor,
@@ -54,7 +54,7 @@
     : INHERITED(ClassID())
     , fViewMatrix(viewMatrix)
     , fUseHWAA(useHWAA)
-    , fStencil(userStencil, hasStencilClip, numStencilBits)
+    , fStencil(GrPathRendering::GetStencilPassSettings(fillType), hasStencilClip, numStencilBits)
     , fScissor(scissor)
     , fRenderTarget(renderTarget)
     , fPath(path) {
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index 66648d8..35b5e9a 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -70,7 +70,7 @@
         default:
             SkFAIL("Unexpected path fill.");
             /* fallthrough */;
-        case GrStencilOp::kIncClamp:
+        case GrStencilOp::kIncWrap:
             return GR_GL_COUNT_UP;
         case GrStencilOp::kInvert:
             return GR_GL_INVERT;
@@ -147,14 +147,14 @@
 
 void GrGLPathRendering::onDrawPath(const GrPipeline& pipeline,
                                    const GrPrimitiveProcessor& primProc,
-                                   const GrStencilSettings& stencil,
+                                   const GrStencilSettings& stencilPassSettings,
                                    const GrPath* path) {
     if (!this->gpu()->flushGLState(pipeline, primProc)) {
         return;
     }
     const GrGLPath* glPath = static_cast<const GrGLPath*>(path);
 
-    this->flushPathStencilSettings(stencil);
+    this->flushPathStencilSettings(stencilPassSettings);
     SkASSERT(!fHWPathStencilSettings.isTwoSided());
 
     GrGLenum fillMode =
@@ -175,16 +175,16 @@
 
 void GrGLPathRendering::onDrawPaths(const GrPipeline& pipeline,
                                     const GrPrimitiveProcessor& primProc,
-                                    const GrStencilSettings& stencil, const GrPathRange* pathRange,
-                                    const void* indices, PathIndexType indexType,
-                                    const float transformValues[], PathTransformType transformType,
-                                    int count) {
+                                    const GrStencilSettings& stencilPassSettings,
+                                    const GrPathRange* pathRange, const void* indices,
+                                    PathIndexType indexType, const float transformValues[],
+                                    PathTransformType transformType, int count) {
     SkDEBUGCODE(verify_floats(transformValues, gXformType2ComponentCount[transformType] * count));
 
     if (!this->gpu()->flushGLState(pipeline, primProc)) {
         return;
     }
-    this->flushPathStencilSettings(stencil);
+    this->flushPathStencilSettings(stencilPassSettings);
     SkASSERT(!fHWPathStencilSettings.isTwoSided());
 
 
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.cpp b/src/gpu/text/GrStencilAndCoverTextContext.cpp
index bce0716..8600582 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/text/GrStencilAndCoverTextContext.cpp
@@ -637,13 +637,13 @@
         SkRect bounds = SkRect::MakeIWH(pipelineBuilder->getRenderTarget()->width(),
                                         pipelineBuilder->getRenderTarget()->height());
 
-        SkAutoTUnref<GrDrawPathBatchBase> batch(
+        SkAutoTUnref<GrDrawBatch> batch(
             GrDrawPathRangeBatch::Create(viewMatrix, fTextRatio, fTextInverseRatio * x,
                                          fTextInverseRatio * y, color,
                                          GrPathRendering::kWinding_FillType, glyphs, fInstanceData,
                                          bounds));
 
-        dc->drawPathBatch(*pipelineBuilder, batch);
+        dc->drawBatch(pipelineBuilder, batch);
     }
 
     if (fFallbackTextBlob) {