Make GrClipMaskManager stateless and push GrPipelineBuilder construction downstack

This will be followed up with a CL to remove the GrRenderTarget from the GrPipelineBuilder.

Split out of:
https://codereview.chromium.org/1988923002/ (Declassify GrClipMaskManager and Remove GrRenderTarget and GrDrawTarget from GrPipelineBuilder)

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2035823002

Review-Url: https://codereview.chromium.org/2035823002
diff --git a/include/gpu/GrClip.h b/include/gpu/GrClip.h
index 751db4d..e684dfa 100644
--- a/include/gpu/GrClip.h
+++ b/include/gpu/GrClip.h
@@ -12,7 +12,7 @@
 #include "GrTypesPriv.h"
 #include "SkClipStack.h"
 
-class GrClipMaskManager;
+class GrDrawContext;
 class GrPipelineBuilder;
 
 /**
@@ -69,8 +69,8 @@
     virtual bool quickContains(const SkRect&) const = 0;
     virtual void getConservativeBounds(int width, int height, SkIRect* devResult,
                                        bool* isIntersectionOfRects = nullptr) const = 0;
-    virtual bool apply(GrClipMaskManager*, const GrPipelineBuilder&, const SkRect* devBounds,
-                       GrAppliedClip*) const = 0;
+    virtual bool apply(GrContext*, const GrPipelineBuilder&, GrDrawContext*,
+                       const SkRect* devBounds, GrAppliedClip*) const = 0;
 
     virtual ~GrClip() {}
 };
@@ -83,7 +83,7 @@
     bool quickContains(const SkRect&) const final { return true; }
     void getConservativeBounds(int width, int height, SkIRect* devResult,
                                bool* isIntersectionOfRects) const final;
-    bool apply(GrClipMaskManager*, const GrPipelineBuilder&,
+    bool apply(GrContext*, const GrPipelineBuilder&, GrDrawContext*,
                const SkRect*, GrAppliedClip*) const final { return true; }
 };
 
@@ -116,7 +116,7 @@
                                bool* isIntersectionOfRects) const final;
 
 private:
-    bool apply(GrClipMaskManager*, const GrPipelineBuilder&,
+    bool apply(GrContext*, const GrPipelineBuilder&, GrDrawContext*,
                const SkRect* devBounds, GrAppliedClip* out) const final;
 
     GrScissorState   fScissorState;
@@ -144,7 +144,7 @@
     bool quickContains(const SkRect&) const final;
     void getConservativeBounds(int width, int height, SkIRect* devResult,
                                bool* isIntersectionOfRects) const final;
-    bool apply(GrClipMaskManager*, const GrPipelineBuilder&,
+    bool apply(GrContext*, const GrPipelineBuilder&, GrDrawContext*,
                const SkRect* devBounds, GrAppliedClip*) const final;
 
 private:
diff --git a/include/gpu/GrDrawContext.h b/include/gpu/GrDrawContext.h
index 3778b72..4dd331e 100644
--- a/include/gpu/GrDrawContext.h
+++ b/include/gpu/GrDrawContext.h
@@ -258,6 +258,9 @@
      */
     void drawBatch(const GrClip&, const GrPaint&, GrDrawBatch*);
 
+    bool isStencilBufferMultisampled() const {
+        return fRenderTarget->isStencilBufferMultisampled();
+    }
     bool hasMixedSamples() const { return fRenderTarget->hasMixedSamples(); }
 
     const GrSurfaceDesc& desc() const { return fRenderTarget->desc(); }
@@ -281,12 +284,13 @@
     GrDrawContextPriv drawContextPriv();
     const GrDrawContextPriv drawContextPriv() const;
 
+    GrAuditTrail* auditTrail() { return fAuditTrail; }
+
 protected:
     GrDrawContext(GrContext*, GrDrawingManager*, sk_sp<GrRenderTarget>,
                   const SkSurfaceProps* surfaceProps, GrAuditTrail*, GrSingleOwner*);
 
     GrDrawingManager* drawingManager() { return fDrawingManager; }
-    GrAuditTrail* auditTrail() { return fAuditTrail; }
 
     SkDEBUGCODE(GrSingleOwner* singleOwner() { return fSingleOwner; })
     SkDEBUGCODE(void validate() const;)
@@ -297,6 +301,21 @@
     friend class GrDrawingManager; // for ctor
     friend class GrDrawContextPriv;
     friend class GrTestTarget;  // for access to getDrawTarget
+    friend class GrSWMaskHelper;                 // for access to drawBatch
+    friend class GrClipMaskManager;              // for access to drawBatch
+
+    // All the path renderers currently make their own batches
+    friend class GrSoftwarePathRenderer;         // for access to drawBatch
+    friend class GrAAConvexPathRenderer;         // for access to drawBatch
+    friend class GrDashLinePathRenderer;         // for access to drawBatch
+    friend class GrAAHairLinePathRenderer;       // for access to drawBatch
+    friend class GrAALinearizingConvexPathRenderer;  // for access to drawBatch
+    friend class GrAADistanceFieldPathRenderer;  // for access to drawBatch
+    friend class GrDefaultPathRenderer;          // for access to drawBatch
+    friend class GrPLSPathRenderer;              // for access to drawBatch
+    friend class GrMSAAPathRenderer;             // for access to drawBatch
+    friend class GrStencilAndCoverPathRenderer;  // for access to drawBatch
+    friend class GrTessellatingPathRenderer;     // for access to drawBatch
 
     bool drawFilledDRRect(const GrClip& clip,
                           const GrPaint& paint,
@@ -316,7 +335,7 @@
 
     // This entry point allows the GrTextContext-derived classes to add their batches to
     // the drawTarget.
-    void drawBatch(GrPipelineBuilder* pipelineBuilder, const GrClip&, GrDrawBatch* batch);
+    void drawBatch(const GrPipelineBuilder& pipelineBuilder, const GrClip&, GrDrawBatch* batch);
 
     GrDrawTarget* getDrawTarget();
 
diff --git a/src/gpu/GrClip.cpp b/src/gpu/GrClip.cpp
index eeb105e..d74d935 100644
--- a/src/gpu/GrClip.cpp
+++ b/src/gpu/GrClip.cpp
@@ -8,6 +8,7 @@
 #include "GrClip.h"
 
 #include "GrClipMaskManager.h"
+#include "GrDrawContext.h"
 
 void GrNoClip::getConservativeBounds(int width, int height, SkIRect* devResult,
                                      bool* isIntersectionOfRects) const {
@@ -40,13 +41,13 @@
     }
 }
 
-bool GrFixedClip::apply(GrClipMaskManager*, const GrPipelineBuilder& pipelineBuilder,
+bool GrFixedClip::apply(GrContext*, const GrPipelineBuilder& pipelineBuilder,
+                        GrDrawContext* drawContext,
                         const SkRect* devBounds, GrAppliedClip* out) const {
     if (fScissorState.enabled()) {
-        const GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
         SkIRect tightScissor;
         if (!tightScissor.intersect(fScissorState.rect(),
-                                    SkIRect::MakeWH(rt->width(), rt->height()))) {
+                                    SkIRect::MakeWH(drawContext->width(), drawContext->height()))) {
             return false;
         }
         if (devBounds && !devBounds->intersects(SkRect::Make(tightScissor))) {
@@ -83,9 +84,9 @@
     devBounds.roundOut(devResult);
 }
 
-bool GrClipStackClip::apply(GrClipMaskManager* clipMaskManager,
-                            const GrPipelineBuilder& pipelineBuilder, const SkRect* devBounds,
-                            GrAppliedClip* out) const {
-    // TODO: Collapse ClipMaskManager into this class.(?)
-    return clipMaskManager->setupClipping(pipelineBuilder, *this, devBounds, out);
+bool GrClipStackClip::apply(GrContext* context,
+                            const GrPipelineBuilder& pipelineBuilder, GrDrawContext* drawContext,
+                            const SkRect* devBounds, GrAppliedClip* out) const {
+    return GrClipMaskManager::SetupClipping(context, pipelineBuilder, drawContext,
+                                            *this, devBounds, out);
 }
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index df58a92..ff95eea 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -9,7 +9,6 @@
 #include "GrCaps.h"
 #include "GrDrawingManager.h"
 #include "GrDrawContextPriv.h"
-#include "GrDrawTarget.h"
 #include "GrGpuResourcePriv.h"
 #include "GrPaint.h"
 #include "GrPathRenderer.h"
@@ -28,6 +27,8 @@
 
 typedef SkClipStack::Element Element;
 
+static const int kMaxAnalyticElements = 4;
+
 ////////////////////////////////////////////////////////////////////////////////
 // set up the draw state to enable the aa clipping mask. Besides setting up the
 // stage matrix this also alters the vertex layout
@@ -50,15 +51,13 @@
                                          kDevice_GrCoordSet));
 }
 
-static void draw_non_aa_rect(GrDrawTarget* drawTarget,
-                             const GrPipelineBuilder& pipelineBuilder,
-                             const GrClip& clip,
-                             GrColor color,
-                             const SkMatrix& viewMatrix,
-                             const SkRect& rect) {
-    SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
-                                                                        nullptr, nullptr));
-    drawTarget->drawBatch(pipelineBuilder, clip, batch);
+void GrClipMaskManager::DrawNonAARect(GrDrawContext* drawContext,
+                                      const GrFixedClip& clip,
+                                      const SkMatrix& viewMatrix,
+                                      const SkRect& rect,
+                                      bool doAA,
+                                      const GrUserStencilSettings* stencilSettings) {
+    drawContext->drawContextPriv().stencilRect(clip, stencilSettings, doAA, viewMatrix, rect);
 }
 
 // Does the path in 'element' require SW rendering? If so, return true (and,
@@ -66,7 +65,7 @@
 // 'prOut' to the non-SW path renderer that will do the job).
 bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context,
                                             bool hasUserStencilSettings,
-                                            const GrRenderTarget* rt,
+                                            const GrDrawContext* drawContext,
                                             const SkMatrix& viewMatrix,
                                             const Element* element,
                                             GrPathRenderer** prOut,
@@ -108,7 +107,7 @@
         canDrawArgs.fStyle = &GrStyle::SimpleFill();
         canDrawArgs.fAntiAlias = element->isAA();
         canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
-        canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
+        canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferMultisampled();
 
         // the 'false' parameter disallows use of the SW path renderer
         GrPathRenderer* pr = context->drawingManager()->getPathRenderer(canDrawArgs, false, type);
@@ -119,37 +118,6 @@
     }
 }
 
-// Determines whether it is possible to draw the element to both the stencil buffer and the
-// alpha mask simultaneously. If so and the element is a path a compatible path renderer is
-// also returned.
-GrPathRenderer* GrClipMaskManager::GetPathRenderer(GrContext* context,
-                                                   GrTexture* texture,
-                                                   const SkMatrix& viewMatrix,
-                                                   const SkClipStack::Element* element) {
-    GrPathRenderer* pr;
-    constexpr bool kNeedsStencil = true;
-    constexpr bool kHasUserStencilSettings = false;
-    PathNeedsSWRenderer(context,
-                        kHasUserStencilSettings,
-                        texture->asRenderTarget(),
-                        viewMatrix,
-                        element,
-                        &pr,
-                        kNeedsStencil);
-    return pr;
-}
-
-GrContext* GrClipMaskManager::getContext() {
-    return fDrawTarget->cmmAccess().context();
-}
-
-const GrCaps* GrClipMaskManager::caps() const {
-    return fDrawTarget->caps();
-}
-
-GrResourceProvider* GrClipMaskManager::resourceProvider() {
-    return fDrawTarget->cmmAccess().resourceProvider();
-}
 /*
  * This method traverses the clip stack to see if the GrSoftwarePathRenderer
  * will be used on any element. If so, it returns true to indicate that the
@@ -157,7 +125,7 @@
  */
 bool GrClipMaskManager::UseSWOnlyPath(GrContext* context,
                                       const GrPipelineBuilder& pipelineBuilder,
-                                      const GrRenderTarget* rt,
+                                      const GrDrawContext* drawContext,
                                       const SkVector& clipToMaskOffset,
                                       const GrReducedClip::ElementList& elements) {
     // TODO: generalize this function so that when
@@ -177,18 +145,18 @@
                             SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op;
 
         if (PathNeedsSWRenderer(context, pipelineBuilder.hasUserStencilSettings(),
-                                rt, translate, element, nullptr, needsStencil)) {
+                                drawContext, translate, element, nullptr, needsStencil)) {
             return true;
         }
     }
     return false;
 }
 
-bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementList& elements,
-                                                 bool abortIfAA,
-                                                 SkVector& clipToRTOffset,
-                                                 const SkRect* drawBounds,
-                                                 sk_sp<const GrFragmentProcessor>* resultFP) {
+static bool get_analytic_clip_processor(const GrReducedClip::ElementList& elements,
+                                        bool abortIfAA,
+                                        SkVector& clipToRTOffset,
+                                        const SkRect* drawBounds,
+                                        sk_sp<const GrFragmentProcessor>* resultFP) {
     SkRect boundsInClipSpace;
     if (drawBounds) {
         boundsInClipSpace = *drawBounds;
@@ -284,7 +252,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 // sort out what kind of clip mask needs to be created: alpha, stencil,
 // scissor, or entirely software
-bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
+bool GrClipMaskManager::SetupClipping(GrContext* context,
+                                      const GrPipelineBuilder& pipelineBuilder,
+                                      GrDrawContext* drawContext,
                                       const GrClipStackClip& clip,
                                       const SkRect* devBounds,
                                       GrAppliedClip* out) {
@@ -297,12 +267,8 @@
     GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialState;
     SkIRect clipSpaceIBounds;
     bool requiresAA = false;
-    GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
 
-    // GrDrawTarget should have filtered this for us
-    SkASSERT(rt);
-
-    SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
+    SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(drawContext->width(), drawContext->height());
     clipSpaceRTIBounds.offset(clip.origin());
 
     SkIRect clipSpaceReduceQueryBounds;
@@ -346,8 +312,8 @@
                                     SkIntToScalar(-clip.origin().fY) };
         // When there are multiple samples we want to do per-sample clipping, not compute a
         // fractional pixel coverage.
-        bool disallowAnalyticAA = rt->isStencilBufferMultisampled();
-        if (disallowAnalyticAA && !rt->numColorSamples()) {
+        bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled();
+        if (disallowAnalyticAA && !drawContext->numColorSamples()) {
             // With a single color sample, any coverage info is lost from color once it hits the
             // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe
             // is multisampled.
@@ -357,12 +323,11 @@
         sk_sp<const GrFragmentProcessor> clipFP;
         if (elements.isEmpty() ||
             (requiresAA &&
-             this->getAnalyticClipProcessor(elements, disallowAnalyticAA, clipToRTOffset, devBounds,
-                                            &clipFP))) {
+             get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTOffset, devBounds,
+                                         &clipFP))) {
             SkIRect scissorSpaceIBounds(clipSpaceIBounds);
             scissorSpaceIBounds.offset(-clip.origin());
-            if (nullptr == devBounds ||
-                !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
+            if (!devBounds || !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
                 out->makeScissoredFPBased(clipFP, scissorSpaceIBounds);
                 return true;
             }
@@ -372,7 +337,7 @@
     }
 
     // If the stencil buffer is multisampled we can use it to do everything.
-    if (!rt->isStencilBufferMultisampled() && requiresAA) {
+    if (!drawContext->isStencilBufferMultisampled() && requiresAA) {
         sk_sp<GrTexture> result;
 
         // The top-left of the mask corresponds to the top-left corner of the bounds.
@@ -381,17 +346,18 @@
             SkIntToScalar(-clipSpaceIBounds.fTop)
         };
 
-        if (UseSWOnlyPath(this->getContext(), pipelineBuilder, rt, clipToMaskOffset, elements)) {
+        if (UseSWOnlyPath(context, pipelineBuilder, drawContext,
+                          clipToMaskOffset, elements)) {
             // The clip geometry is complex enough that it will be more efficient to create it
             // entirely in software
-            result = CreateSoftwareClipMask(this->getContext()->textureProvider(),
+            result = CreateSoftwareClipMask(context->textureProvider(),
                                             genID,
                                             initialState,
                                             elements,
                                             clipToMaskOffset,
                                             clipSpaceIBounds);
         } else {
-            result = CreateAlphaClipMask(this->getContext(),
+            result = CreateAlphaClipMask(context,
                                          genID,
                                          initialState,
                                          elements,
@@ -414,12 +380,13 @@
 
     // use the stencil clip if we can't represent the clip as a rectangle.
     SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin();
-    this->createStencilClipMask(rt,
-                                genID,
-                                initialState,
-                                elements,
-                                clipSpaceIBounds,
-                                clipSpaceToStencilSpaceOffset);
+    CreateStencilClipMask(context,
+                          drawContext,
+                          genID,
+                          initialState,
+                          elements,
+                          clipSpaceIBounds,
+                          clipSpaceToStencilSpaceOffset);
 
     // This must occur after createStencilClipMask. That function may change the scissor. Also, it
     // only guarantees that the stencil mask is correct within the bounds it was passed, so we must
@@ -609,19 +576,22 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
 // (as opposed to canvas) coordinates
-bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
+bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
+                                              GrDrawContext* drawContext,
                                               int32_t elementsGenID,
                                               GrReducedClip::InitialState initialState,
                                               const GrReducedClip::ElementList& elements,
                                               const SkIRect& clipSpaceIBounds,
                                               const SkIPoint& clipSpaceToStencilOffset) {
-    SkASSERT(rt);
+    SkASSERT(drawContext);
 
-    GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachStencilAttachment(rt);
+    GrStencilAttachment* stencilAttachment = context->resourceProvider()->attachStencilAttachment(
+                                                    drawContext->accessRenderTarget());
     if (nullptr == stencilAttachment) {
         return false;
     }
 
+    // TODO: these need to be swapped over to using a StencilAttachmentProxy
     if (stencilAttachment->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset)) {
         stencilAttachment->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset);
         // Set the matrix so that rendered clip elements are transformed from clip to stencil space.
@@ -637,24 +607,15 @@
         stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
         GrFixedClip clip(stencilSpaceIBounds);
 
-        fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds,
-            GrReducedClip::kAllIn_InitialState == initialState, rt);
+        drawContext->drawContextPriv().clearStencilClip(
+                                            stencilSpaceIBounds,
+                                            GrReducedClip::kAllIn_InitialState == initialState);
 
         // walk through each clip element and perform its set op
         // with the existing clip.
         for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
             const Element* element = iter.get();
 
-            GrPipelineBuilder pipelineBuilder;
-            pipelineBuilder.setRenderTarget(rt);
-
-            pipelineBuilder.setDisableColorXPFactory();
-
-            // if the target is MSAA then we want MSAA enabled when the clip is soft
-            if (rt->isStencilBufferMultisampled()) {
-                pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, element->isAA());
-            }
-
             bool fillInverted = false;
             // enabled at bottom of loop
             clip.enableStencilClip(false);
@@ -677,21 +638,19 @@
                     clipPath.toggleInverseFillType();
                 }
 
-                SkASSERT(!pipelineBuilder.hasUserStencilSettings());
-
                 GrPathRenderer::CanDrawPathArgs canDrawArgs;
-                canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps();
+                canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
                 canDrawArgs.fViewMatrix = &viewMatrix;
                 canDrawArgs.fPath = &clipPath;
                 canDrawArgs.fStyle = &GrStyle::SimpleFill();
                 canDrawArgs.fAntiAlias = false;
-                canDrawArgs.fHasUserStencilSettings = pipelineBuilder.hasUserStencilSettings();
-                canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
+                canDrawArgs.fHasUserStencilSettings = false;
+                canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferMultisampled();
 
-                pr = this->getContext()->drawingManager()->getPathRenderer(canDrawArgs, false,
-                                                                           GrPathRendererChain::kStencilOnly_DrawType,
-                                                                           &stencilSupport);
-                if (nullptr == pr) {
+                pr = context->drawingManager()->getPathRenderer(canDrawArgs, false,
+                                                                GrPathRendererChain::kStencilOnly_DrawType,
+                                                                &stencilSupport);
+                if (!pr) {
                     return false;
                 }
             }
@@ -718,19 +677,20 @@
                          0xffff>()
                 );
                 if (Element::kRect_Type == element->getType()) {
-                    pipelineBuilder.setUserStencil(&kDrawToStencil);
-
-                    draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE, viewMatrix,
-                                     element->getRect());
+                    DrawNonAARect(drawContext, clip, viewMatrix,
+                                  element->getRect(), element->isAA(), &kDrawToStencil);
                 } else {
                     if (!clipPath.isEmpty()) {
                         if (canRenderDirectToStencil) {
-                            pipelineBuilder.setUserStencil(&kDrawToStencil);
+                            GrPaint paint;
+                            paint.setXPFactory(GrDisableColorXPFactory::Create());
+                            paint.setAntiAlias(element->isAA());
 
                             GrPathRenderer::DrawPathArgs args;
-                            args.fTarget = fDrawTarget;
-                            args.fResourceProvider = this->getContext()->resourceProvider();
-                            args.fPipelineBuilder = &pipelineBuilder;
+                            args.fResourceProvider = context->resourceProvider();
+                            args.fPaint = &paint;
+                            args.fUserStencilSettings = &kDrawToStencil;
+                            args.fDrawContext = drawContext;
                             args.fClip = &clip;
                             args.fColor = GrColor_WHITE;
                             args.fViewMatrix = &viewMatrix;
@@ -741,12 +701,12 @@
                             pr->drawPath(args);
                         } else {
                             GrPathRenderer::StencilPathArgs args;
-                            args.fTarget = fDrawTarget;
-                            args.fResourceProvider = this->getContext()->resourceProvider();
-                            args.fPipelineBuilder = &pipelineBuilder;
+                            args.fResourceProvider = context->resourceProvider();
+                            args.fDrawContext = drawContext;
                             args.fClip = &clip;
                             args.fViewMatrix = &viewMatrix;
                             args.fPath = &clipPath;
+                            args.fIsAA = element->isAA();
                             pr->stencilPath(args);
                         }
                     }
@@ -757,17 +717,21 @@
             // element directly or a bounding rect of the entire clip.
             clip.enableStencilClip(true);
             for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) {
-                pipelineBuilder.setUserStencil(*pass);
 
                 if (drawDirectToClip) {
                     if (Element::kRect_Type == element->getType()) {
-                        draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE,
-                                         viewMatrix, element->getRect());
+                        DrawNonAARect(drawContext, clip,
+                                      viewMatrix, element->getRect(), element->isAA(), *pass);
                     } else {
+                        GrPaint paint;
+                        paint.setXPFactory(GrDisableColorXPFactory::Create());
+                        paint.setAntiAlias(element->isAA());
+
                         GrPathRenderer::DrawPathArgs args;
-                        args.fTarget = fDrawTarget;
-                        args.fResourceProvider = this->getContext()->resourceProvider();
-                        args.fPipelineBuilder = &pipelineBuilder;
+                        args.fResourceProvider = context->resourceProvider();
+                        args.fPaint = &paint;
+                        args.fUserStencilSettings = *pass;
+                        args.fDrawContext = drawContext;
                         args.fClip = &clip;
                         args.fColor = GrColor_WHITE;
                         args.fViewMatrix = &viewMatrix;
@@ -780,8 +744,8 @@
                 } else {
                     // The view matrix is setup to do clip space -> stencil space translation, so
                     // draw rect in clip space.
-                    draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE, viewMatrix,
-                                     SkRect::Make(clipSpaceIBounds));
+                    DrawNonAARect(drawContext, clip, viewMatrix,
+                                  SkRect::Make(clipSpaceIBounds), false, *pass);
                 }
             }
         }
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index f7f7e5c..0c71f7c 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -14,7 +14,8 @@
 
 class GrAppliedClip;
 class GrClipStackClip;
-class GrDrawTarget;
+class GrDrawContext;
+class GrFixedClip;
 class GrPathRenderer;
 class GrPathRendererChain;
 class GrResourceProvider;
@@ -29,54 +30,42 @@
  * mask can be represented as a rectangle then scissoring is used. In all
  * cases scissoring is used to bound the range of the clip mask.
  */
-class GrClipMaskManager : SkNoncopyable {
+// This has to remain a class, for now, so it can be friended (by GrDrawContext & GrContext)
+class GrClipMaskManager {
 public:
-    GrClipMaskManager(GrDrawTarget* owner) : fDrawTarget(owner) {}
-
     /**
      * Creates a clip mask if necessary as a stencil buffer or alpha texture
      * and sets the GrGpu's scissor and stencil state. If the return is false
      * then the draw can be skipped. devBounds is optional but can help optimize
      * clipping.
      */
-    bool setupClipping(const GrPipelineBuilder&, const GrClipStackClip&, const SkRect* devBounds,
-                       GrAppliedClip*);
+    static bool SetupClipping(GrContext*, const GrPipelineBuilder&, GrDrawContext*,
+                              const GrClipStackClip&, const SkRect* devBounds, GrAppliedClip*);
 
 private:
-    inline GrContext* getContext();
-    inline const GrCaps* caps() const;
-    inline GrResourceProvider* resourceProvider();
+    static void DrawNonAARect(GrDrawContext* drawContext,
+                              const GrFixedClip& clip,
+                              const SkMatrix& viewMatrix,
+                              const SkRect& rect,
+                              bool isAA,
+                              const GrUserStencilSettings* stencilSettings);
 
     static bool PathNeedsSWRenderer(GrContext* context,
                                     bool hasUserStencilSettings,
-                                    const GrRenderTarget* rt,
+                                    const GrDrawContext*,
                                     const SkMatrix& viewMatrix,
                                     const SkClipStack::Element* element,
                                     GrPathRenderer** prOut,
                                     bool needsStencil);
-    static GrPathRenderer* GetPathRenderer(GrContext* context,
-                                           GrTexture* texture,
-                                           const SkMatrix& viewMatrix,
-                                           const SkClipStack::Element* element);
-
-    // Attempts to install a series of coverage effects to implement the clip. Return indicates
-    // whether the element list was successfully converted to processors. *fp may be nullptr even
-    // when the function succeeds because all the elements were ignored. TODO: Make clip reduction
-    // bounds-aware and stop checking bounds in this function. Similarly, we shouldn't need to pass
-    // abortIfAA, but we don't yet know if all the AA elements will be eliminated.
-    bool getAnalyticClipProcessor(const GrReducedClip::ElementList&,
-                                  bool abortIfAA,
-                                  SkVector& clipOffset,
-                                  const SkRect* devBounds,
-                                  sk_sp<const GrFragmentProcessor>* fp);
 
     // Draws the clip into the stencil buffer
-    bool createStencilClipMask(GrRenderTarget*,
-                               int32_t elementsGenID,
-                               GrReducedClip::InitialState initialState,
-                               const GrReducedClip::ElementList& elements,
-                               const SkIRect& clipSpaceIBounds,
-                               const SkIPoint& clipSpaceToStencilOffset);
+    static bool CreateStencilClipMask(GrContext*,
+                                      GrDrawContext*,
+                                      int32_t elementsGenID,
+                                      GrReducedClip::InitialState initialState,
+                                      const GrReducedClip::ElementList& elements,
+                                      const SkIRect& clipSpaceIBounds,
+                                      const SkIPoint& clipSpaceToStencilOffset);
 
     // Creates an alpha mask of the clip. The mask is a rasterization of elements through the
     // rect specified by clipSpaceIBounds.
@@ -97,16 +86,12 @@
 
    static bool UseSWOnlyPath(GrContext*,
                              const GrPipelineBuilder&,
-                             const GrRenderTarget* rt,
+                             const GrDrawContext*,
                              const SkVector& clipToMaskOffset,
                              const GrReducedClip::ElementList& elements);
 
-    GrTexture* createCachedMask(int width, int height, const GrUniqueKey& key, bool renderTarget);
-
-    static const int kMaxAnalyticElements = 4;
-
-    GrDrawTarget*   fDrawTarget;    // This is our owning draw target.
-
-    typedef SkNoncopyable INHERITED;
+    static GrTexture* CreateCachedMask(int width, int height, const GrUniqueKey& key,
+                                       bool renderTarget);
 };
+
 #endif // GrClipMaskManager_DEFINED
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp
index b34111c..581bf08 100644
--- a/src/gpu/GrDrawContext.cpp
+++ b/src/gpu/GrDrawContext.cpp
@@ -36,6 +36,7 @@
 #define ASSERT_SINGLE_OWNER_PRIV \
     SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fDrawContext->fSingleOwner);)
 #define RETURN_IF_ABANDONED        if (fDrawingManager->wasAbandoned()) { return; }
+#define RETURN_IF_ABANDONED_PRIV   if (fDrawContext->fDrawingManager->wasAbandoned()) { return; }
 #define RETURN_FALSE_IF_ABANDONED  if (fDrawingManager->wasAbandoned()) { return false; }
 #define RETURN_FALSE_IF_ABANDONED_PRIV  if (fDrawContext->fDrawingManager->wasAbandoned()) { return false; }
 #define RETURN_NULL_IF_ABANDONED   if (fDrawingManager->wasAbandoned()) { return nullptr; }
@@ -189,7 +190,7 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::clear");
 
     AutoCheckFlush acf(fDrawingManager);
-    this->getDrawTarget()->clear(rect, color, canIgnoreRect, fRenderTarget.get());
+    this->getDrawTarget()->clear(rect, color, canIgnoreRect, this);
 }
 
 
@@ -241,7 +242,7 @@
                                                     &localMatrix));
         GrPipelineBuilder pipelineBuilder(*paint, this->isUnifiedMultisampled());
         pipelineBuilder.setRenderTarget(fRenderTarget.get());
-        this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+        this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
     }
 }
 
@@ -322,7 +323,7 @@
                 // Will it blend?
                 GrColor clearColor;
                 if (paint.isConstantBlendedColor(&clearColor)) {
-                    this->getDrawTarget()->clear(nullptr, clearColor, true, fRenderTarget.get());
+                    this->getDrawTarget()->clear(nullptr, clearColor, true, this);
                     return;
                 }
             }
@@ -364,7 +365,7 @@
                                      snapToPixelCenters);
         }
 
-        this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+        this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
         return;
     }
 
@@ -374,6 +375,52 @@
     this->internalDrawPath(clip, paint, viewMatrix, path, *style);
 }
 
+void GrDrawContextPriv::clearStencilClip(const SkIRect& rect, bool insideClip) {
+    ASSERT_SINGLE_OWNER_PRIV
+    RETURN_IF_ABANDONED_PRIV
+    SkDEBUGCODE(fDrawContext->validate();)
+    GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContextPriv::clearStencilClip");
+
+    AutoCheckFlush acf(fDrawContext->fDrawingManager);
+    fDrawContext->getDrawTarget()->clearStencilClip(rect, insideClip,
+                                                    fDrawContext->accessRenderTarget());
+}
+
+void GrDrawContextPriv::stencilPath(const GrPipelineBuilder& pipelineBuilder,
+                                    const GrClip& clip, 
+                                    const SkMatrix& viewMatrix,
+                                    const GrPath* path,
+                                    GrPathRendering::FillType fill) {
+    fDrawContext->getDrawTarget()->stencilPath(pipelineBuilder, fDrawContext,
+                                               clip, viewMatrix, path, fill);
+}
+
+void GrDrawContextPriv::stencilRect(const GrFixedClip& clip,
+                                    const GrUserStencilSettings* ss,
+                                    bool doAA,
+                                    const SkMatrix& viewMatrix,
+                                    const SkRect& rect) {
+    ASSERT_SINGLE_OWNER_PRIV
+    RETURN_IF_ABANDONED_PRIV
+    SkDEBUGCODE(fDrawContext->validate();)
+    GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::stencilRect");
+
+    AutoCheckFlush acf(fDrawContext->fDrawingManager);
+
+    GrPaint paint;
+    paint.setAntiAlias(doAA);
+    paint.setXPFactory(GrDisableColorXPFactory::Create());
+
+    SkAutoTUnref<GrDrawBatch> batch(fDrawContext->getFillRectBatch(paint, viewMatrix, rect));
+    SkASSERT(batch);
+
+    GrPipelineBuilder pipelineBuilder(paint, fDrawContext->isUnifiedMultisampled());
+    pipelineBuilder.setRenderTarget(fDrawContext->accessRenderTarget());
+    pipelineBuilder.setUserStencil(ss);
+
+    fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, fDrawContext, clip, batch);
+}
+
 bool GrDrawContextPriv::drawAndStencilRect(const GrFixedClip& clip,
                                            const GrUserStencilSettings* ss,
                                            SkRegion::Op op,
@@ -398,7 +445,7 @@
         pipelineBuilder.setRenderTarget(fDrawContext->accessRenderTarget());
         pipelineBuilder.setUserStencil(ss);
 
-        fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+        fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, fDrawContext, clip, batch);
         return true;
     }
 
@@ -433,7 +480,7 @@
     if (batch) {
         GrPipelineBuilder pipelineBuilder(paint, this->isUnifiedMultisampled());
         pipelineBuilder.setRenderTarget(fRenderTarget.get());
-        this->drawBatch(&pipelineBuilder, clip, batch);
+        this->drawBatch(pipelineBuilder, clip, batch);
     }
 }
 
@@ -461,7 +508,7 @@
 
     GrPipelineBuilder pipelineBuilder(paint,  this->isUnifiedMultisampled());
     pipelineBuilder.setRenderTarget(fRenderTarget.get());
-    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+    this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
 }
 
 void GrDrawContext::drawVertices(const GrClip& clip,
@@ -507,7 +554,7 @@
 
     GrPipelineBuilder pipelineBuilder(paint,  this->isUnifiedMultisampled());
     pipelineBuilder.setRenderTarget(fRenderTarget.get());
-    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+    this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -533,7 +580,7 @@
 
     GrPipelineBuilder pipelineBuilder(paint,  this->isUnifiedMultisampled());
     pipelineBuilder.setRenderTarget(fRenderTarget.get());
-    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+    this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -567,7 +614,7 @@
         if (batch) {
             GrPipelineBuilder pipelineBuilder(paint,  this->isUnifiedMultisampled());
             pipelineBuilder.setRenderTarget(fRenderTarget.get());
-            this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+            this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
             return;
         }
     }
@@ -693,7 +740,7 @@
         if (batch) {
             GrPipelineBuilder pipelineBuilder(paint,  this->isUnifiedMultisampled());
             pipelineBuilder.setRenderTarget(fRenderTarget.get());
-            this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+            this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
             return;
         }
     }
@@ -724,7 +771,7 @@
 
     GrPipelineBuilder pipelineBuilder(paint,  this->isUnifiedMultisampled());
     pipelineBuilder.setRenderTarget(fRenderTarget.get());
-    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+    this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
 }
 
 
@@ -785,7 +832,7 @@
 
     GrPipelineBuilder pipelineBuilder(paint,  this->isUnifiedMultisampled());
     pipelineBuilder.setRenderTarget(fRenderTarget.get());
-    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+    this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
 }
 
 void GrDrawContext::drawPath(const GrClip& clip,
@@ -818,7 +865,7 @@
                 if (batch) {
                     GrPipelineBuilder pipelineBuilder(paint,  this->isUnifiedMultisampled());
                     pipelineBuilder.setRenderTarget(fRenderTarget.get());
-                    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+                    this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
                 }
                 return;
             }
@@ -836,7 +883,7 @@
             if (batch) {
                 GrPipelineBuilder pipelineBuilder(paint,  this->isUnifiedMultisampled());
                 pipelineBuilder.setRenderTarget(fRenderTarget.get());
-                this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
+                this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
                 return;
             }
         }
@@ -876,7 +923,7 @@
     // aa. If we have some future driver-mojo path AA that can do the right
     // thing WRT to the blend then we'll need some query on the PR.
     bool useCoverageAA = doAA && !fDrawContext->fRenderTarget->isUnifiedMultisampled();
-    bool hasUserStencilSettings = (&GrUserStencilSettings::kUnused != ss);
+    bool hasUserStencilSettings = !ss->isUnused();
     bool isStencilBufferMSAA = fDrawContext->fRenderTarget->isStencilBufferMultisampled();
 
     const GrPathRendererChain::DrawType type =
@@ -901,14 +948,11 @@
     GrPaint paint;
     paint.setCoverageSetOpXPFactory(op, invert);
 
-    GrPipelineBuilder pipelineBuilder(paint,  fDrawContext->isUnifiedMultisampled());
-    pipelineBuilder.setRenderTarget(fDrawContext->accessRenderTarget());
-    pipelineBuilder.setUserStencil(ss);
-
     GrPathRenderer::DrawPathArgs args;
-    args.fTarget = fDrawContext->getDrawTarget();
     args.fResourceProvider = fDrawContext->fDrawingManager->getContext()->resourceProvider();
-    args.fPipelineBuilder = &pipelineBuilder;
+    args.fPaint = &paint;
+    args.fUserStencilSettings = ss;
+    args.fDrawContext = fDrawContext;
     args.fClip = &clip;
     args.fColor = GrColor_WHITE;
     args.fViewMatrix = &viewMatrix;
@@ -1008,13 +1052,11 @@
         return;
     }
 
-    GrPipelineBuilder pipelineBuilder(paint,  this->isUnifiedMultisampled());
-    pipelineBuilder.setRenderTarget(fRenderTarget.get());
-
     GrPathRenderer::DrawPathArgs args;
-    args.fTarget = this->getDrawTarget();
     args.fResourceProvider = fDrawingManager->getContext()->resourceProvider();
-    args.fPipelineBuilder = &pipelineBuilder;
+    args.fPaint = &paint;
+    args.fUserStencilSettings = &GrUserStencilSettings::kUnused;
+    args.fDrawContext = this;
     args.fClip = &clip;
     args.fColor = paint.getColor();
     args.fViewMatrix = &viewMatrix;
@@ -1025,12 +1067,12 @@
     pr->drawPath(args);
 }
 
-void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, const GrClip& clip,
+void GrDrawContext::drawBatch(const GrPipelineBuilder& pipelineBuilder, const GrClip& clip,
                               GrDrawBatch* batch) {
     ASSERT_SINGLE_OWNER
     RETURN_IF_ABANDONED
     SkDEBUGCODE(this->validate();)
     GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrDrawContext::drawBatch");
 
-    this->getDrawTarget()->drawBatch(*pipelineBuilder, clip, batch);
+    this->getDrawTarget()->drawBatch(pipelineBuilder, this, clip, batch);
 }
diff --git a/src/gpu/GrDrawContextPriv.h b/src/gpu/GrDrawContextPriv.h
index 2fb98ee..bdd3b47 100644
--- a/src/gpu/GrDrawContextPriv.h
+++ b/src/gpu/GrDrawContextPriv.h
@@ -9,8 +9,10 @@
 #define GrDrawContextPriv_DEFINED
 
 #include "GrDrawContext.h"
+#include "GrPathRendering.h"
 
 class GrFixedClip;
+class GrPath;
 struct GrUserStencilSettings;
 
 /** Class that adds methods to GrDrawContext that are only intended for use internal to Skia.
@@ -18,6 +20,20 @@
     data members or virtual methods. */
 class GrDrawContextPriv {
 public:
+    void clearStencilClip(const SkIRect& rect, bool insideClip);
+
+    void stencilRect(const GrFixedClip& clip,
+                     const GrUserStencilSettings* ss,
+                     bool doAA,
+                     const SkMatrix& viewMatrix,
+                     const SkRect& rect);
+
+    void stencilPath(const GrPipelineBuilder&,
+                     const GrClip&,
+                     const SkMatrix& viewMatrix,
+                     const GrPath*,
+                     GrPathRendering::FillType);
+
     bool drawAndStencilRect(const GrFixedClip&,
                             const GrUserStencilSettings*,
                             SkRegion::Op op,
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index b38f697..6bbcc74 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -9,6 +9,7 @@
 
 #include "GrAuditTrail.h"
 #include "GrCaps.h"
+#include "GrDrawContext.h"
 #include "GrGpu.h"
 #include "GrPath.h"
 #include "GrPipeline.h"
@@ -46,7 +47,6 @@
     , fRenderTarget(rt) {
     // TODO: Stop extracting the context (currently needed by GrClipMaskManager)
     fContext = fGpu->getContext();
-    fClipMaskManager.reset(new GrClipMaskManager(this));
 
     fClipBatchToBounds = options.fClipBatchToBounds;
     fDrawBatchBounds = options.fDrawBatchBounds;
@@ -235,11 +235,12 @@
 }
 
 void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder,
+                             GrDrawContext* drawContext,
                              const GrClip& clip,
                              GrDrawBatch* batch) {
     // Setup clip
     GrAppliedClip appliedClip;
-    if (!clip.apply(fClipMaskManager, pipelineBuilder, &batch->bounds(), &appliedClip)) {
+    if (!clip.apply(fContext, pipelineBuilder, drawContext, &batch->bounds(), &appliedClip)) {
         return;
     }
 
@@ -310,6 +311,7 @@
 }
 
 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
+                               GrDrawContext* drawContext,
                                const GrClip& clip,
                                const SkMatrix& viewMatrix,
                                const GrPath* path,
@@ -320,7 +322,7 @@
 
     // Setup clip
     GrAppliedClip appliedClip;
-    if (!clip.apply(fClipMaskManager, pipelineBuilder, nullptr, &appliedClip)) {
+    if (!clip.apply(fContext, pipelineBuilder, drawContext, nullptr, &appliedClip)) {
         return;
     }
     // TODO: respect fClipBatchToBounds if we ever start computing bounds here.
@@ -351,8 +353,8 @@
 void GrDrawTarget::clear(const SkIRect* rect,
                          GrColor color,
                          bool canIgnoreRect,
-                         GrRenderTarget* renderTarget) {
-    SkIRect rtRect = SkIRect::MakeWH(renderTarget->width(), renderTarget->height());
+                         GrDrawContext* drawContext) {
+    SkIRect rtRect = SkIRect::MakeWH(drawContext->width(), drawContext->height());
     SkIRect clippedRect;
     if (!rect ||
         (canIgnoreRect && this->caps()->fullClearIsFree()) ||
@@ -371,21 +373,21 @@
         // The driver will ignore a clear if it is the only thing rendered to a
         // target before the target is read.
         if (rect == &rtRect) {
-            this->discard(renderTarget);
+            drawContext->discard();
         }
 
         GrPipelineBuilder pipelineBuilder;
         pipelineBuilder.setXPFactory(
             GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
-        pipelineBuilder.setRenderTarget(renderTarget);
+        pipelineBuilder.setRenderTarget(drawContext->accessRenderTarget());
 
         SkRect scalarRect = SkRect::Make(*rect);
         SkAutoTUnref<GrDrawBatch> batch(
                 GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(), scalarRect,
                                                     nullptr, nullptr));
-        this->drawBatch(pipelineBuilder, GrNoClip(), batch);
+        this->drawBatch(pipelineBuilder, drawContext, GrNoClip(), batch);
     } else {
-        GrBatch* batch = new GrClearBatch(*rect, color, renderTarget);
+        GrBatch* batch = new GrClearBatch(*rect, color, drawContext->accessRenderTarget());
         this->recordBatch(batch);
         batch->unref();
     }
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 2456558..627472f 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -9,7 +9,6 @@
 #define GrDrawTarget_DEFINED
 
 #include "GrClip.h"
-#include "GrClipMaskManager.h"
 #include "GrContext.h"
 #include "GrPathProcessor.h"
 #include "GrPrimitiveProcessor.h"
@@ -105,7 +104,7 @@
      */
     const GrCaps* caps() const { return fGpu->caps(); }
 
-    void drawBatch(const GrPipelineBuilder&, const GrClip&, GrDrawBatch*);
+    void drawBatch(const GrPipelineBuilder&, GrDrawContext*, const GrClip&, GrDrawBatch*);
 
     /**
      * Draws path into the stencil buffer. The fill must be either even/odd or
@@ -113,7 +112,8 @@
      * on the GrPipelineBuilder (if possible in the 3D API).  Note, we will never have an inverse
      * fill with stencil path
      */
-    void stencilPath(const GrPipelineBuilder&, const GrClip&, const SkMatrix& viewMatrix,
+    void stencilPath(const GrPipelineBuilder&, GrDrawContext*,
+                     const GrClip&, const SkMatrix& viewMatrix,
                      const GrPath*, GrPathRendering::FillType);
 
     /**
@@ -124,7 +124,7 @@
     void clear(const SkIRect* rect,
                GrColor color,
                bool canIgnoreRect,
-               GrRenderTarget* renderTarget);
+               GrDrawContext*);
 
     /** Discards the contents render target. */
     void discard(GrRenderTarget*);
@@ -166,6 +166,7 @@
 
 private:
     friend class GrDrawingManager; // for resetFlag & TopoSortTraits
+    friend class GrDrawContextPriv; // for clearStencilClip
 
     enum Flags {
         kClosed_Flag    = 0x01,   //!< This drawTarget can't accept any more batches
@@ -228,7 +229,6 @@
     void clearStencilClip(const SkIRect&, bool insideClip, GrRenderTarget*);
 
     SkSTArray<256, SkAutoTUnref<GrBatch>, true> fBatches;
-    SkAutoTDelete<GrClipMaskManager>            fClipMaskManager;
     // The context is only in service of the clip mask manager, remove once CMM doesn't need this.
     GrContext*                                  fContext;
     GrGpu*                                      fGpu;
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index 39f9ad2..20c6967 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -8,13 +8,16 @@
 #ifndef GrPathRenderer_DEFINED
 #define GrPathRenderer_DEFINED
 
-#include "GrDrawTarget.h"
+#include "GrDrawContext.h"
+#include "GrPaint.h"
+#include "GrResourceProvider.h"
 #include "GrStyle.h"
 
 #include "SkDrawProcs.h"
 #include "SkTArray.h"
 
 class SkPath;
+class GrFixedClip;
 struct GrPoint;
 
 /**
@@ -120,9 +123,11 @@
      * fGammaCorrect          true if gamma-correct rendering is to be used.
      */
     struct DrawPathArgs {
-        GrDrawTarget*               fTarget;
         GrResourceProvider*         fResourceProvider;
-        GrPipelineBuilder*          fPipelineBuilder;
+        const GrPaint*              fPaint;
+        const GrUserStencilSettings*fUserStencilSettings;
+
+        GrDrawContext*              fDrawContext;
         const GrClip*               fClip;
         GrColor                     fColor;
         const SkMatrix*             fViewMatrix;
@@ -132,9 +137,10 @@
         bool                        fGammaCorrect;
 
         void validate() const {
-            SkASSERT(fTarget);
             SkASSERT(fResourceProvider);
-            SkASSERT(fPipelineBuilder);
+            SkASSERT(fPaint);
+            SkASSERT(fUserStencilSettings);
+            SkASSERT(fDrawContext);
             SkASSERT(fClip);
             SkASSERT(fViewMatrix);
             SkASSERT(fPath);
@@ -151,17 +157,16 @@
         SkDEBUGCODE(args.validate();)
 #ifdef SK_DEBUG
         CanDrawPathArgs canArgs;
-        canArgs.fShaderCaps = args.fTarget->caps()->shaderCaps();
+        canArgs.fShaderCaps = args.fResourceProvider->caps()->shaderCaps();
         canArgs.fViewMatrix = args.fViewMatrix;
         canArgs.fPath = args.fPath;
         canArgs.fStyle = args.fStyle;
         canArgs.fAntiAlias = args.fAntiAlias;
 
-        canArgs.fHasUserStencilSettings = args.fPipelineBuilder->hasUserStencilSettings();
-        canArgs.fIsStencilBufferMSAA =
-                          args.fPipelineBuilder->getRenderTarget()->isStencilBufferMultisampled();
+        canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused();
+        canArgs.fIsStencilBufferMSAA = args.fDrawContext->isStencilBufferMultisampled();
         SkASSERT(this->canDrawPath(canArgs));
-        if (args.fPipelineBuilder->hasUserStencilSettings()) {
+        if (!args.fUserStencilSettings->isUnused()) {
             SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fPath));
             SkASSERT(args.fStyle->isSimpleFill());
         }
@@ -171,24 +176,23 @@
 
     /* Args to stencilPath().
      *
-     * fTarget                The target that the path will be rendered to.
      * fResourceProvider      The resource provider for creating gpu resources to render the path
-     * fPipelineBuilder       The pipeline builder.
+     * fDrawContext           The target of the draws
      * fViewMatrix            Matrix applied to the path.
      * fPath                  The path to draw.
+     * fIsAA                  Is the path to be drawn AA (only set when MSAA is available)
      */
     struct StencilPathArgs {
-        GrDrawTarget*       fTarget;
         GrResourceProvider* fResourceProvider;
-        GrPipelineBuilder*  fPipelineBuilder;
-        const GrClip*       fClip;
+        GrDrawContext*      fDrawContext;
+        const GrFixedClip*  fClip;
         const SkMatrix*     fViewMatrix;
         const SkPath*       fPath;
+        bool                fIsAA;
 
         void validate() const {
-            SkASSERT(fTarget);
             SkASSERT(fResourceProvider);
-            SkASSERT(fPipelineBuilder);
+            SkASSERT(fDrawContext);
             SkASSERT(fViewMatrix);
             SkASSERT(fPath);
             SkASSERT(!fPath->isEmpty());
@@ -232,14 +236,6 @@
                                  const SkMatrix& matrix,
                                  SkRect* bounds);
 
-    // Helper version that gets the dev width and height from a GrSurface.
-    static void GetPathDevBounds(const SkPath& path,
-                                 const GrSurface* device,
-                                 const SkMatrix& matrix,
-                                 SkRect* bounds) {
-        GetPathDevBounds(path, device->width(), device->height(), matrix, bounds);
-    }
-
 private:
     /**
      * Subclass overrides if it has any limitations of stenciling support.
@@ -272,17 +268,19 @@
                  GrUserStencilOp::kReplace,
                  0xffff>()
         );
-        args.fPipelineBuilder->setUserStencil(&kIncrementStencil);
-        args.fPipelineBuilder->setDisableColorXPFactory();
+
+        GrPaint paint;
+
         DrawPathArgs drawArgs;
-        drawArgs.fTarget = args.fTarget;
         drawArgs.fResourceProvider = args.fResourceProvider;
-        drawArgs.fPipelineBuilder = args.fPipelineBuilder;
-        drawArgs.fColor = 0xFFFFFFFF;
+        drawArgs.fPaint = &paint;
+        drawArgs.fUserStencilSettings = &kIncrementStencil;
+        drawArgs.fDrawContext = args.fDrawContext;
+        drawArgs.fColor = GrColor_WHITE;
         drawArgs.fViewMatrix = args.fViewMatrix;
         drawArgs.fPath = args.fPath;
         drawArgs.fStyle = &GrStyle::SimpleFill();
-        drawArgs.fAntiAlias = false;
+        drawArgs.fAntiAlias = false;  // In this case the MSAA handles the AA so we want to draw BW
         drawArgs.fGammaCorrect = false;
         this->drawPath(drawArgs);
     }
diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h
index ca1adee..11b427b 100644
--- a/src/gpu/GrPipelineBuilder.h
+++ b/src/gpu/GrPipelineBuilder.h
@@ -198,9 +198,7 @@
     /// @name Stencil
     ////
 
-    bool hasUserStencilSettings() const {
-        return &GrUserStencilSettings::kUnused != fUserStencilSettings;
-    }
+    bool hasUserStencilSettings() const { return !fUserStencilSettings->isUnused(); }
     const GrUserStencilSettings* getUserStencil() const { return fUserStencilSettings; }
 
     /**
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 849a933..6e99f07 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -8,7 +8,9 @@
 #include "GrSWMaskHelper.h"
 
 #include "GrCaps.h"
-#include "GrDrawTarget.h"
+#include "GrContext.h"
+#include "batches/GrDrawBatch.h"
+#include "GrDrawContext.h"
 #include "GrGpu.h"
 #include "GrPipelineBuilder.h"
 #include "GrStyle.h"
@@ -159,8 +161,9 @@
 }
 
 void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
-                                              GrDrawTarget* target,
-                                              GrPipelineBuilder* pipelineBuilder,
+                                              GrDrawContext* drawContext,
+                                              const GrPaint* paint,
+                                              const GrUserStencilSettings* userStencilSettings,
                                               const GrClip& clip,
                                               GrColor color,
                                               const SkMatrix& viewMatrix,
@@ -169,7 +172,6 @@
     if (!viewMatrix.invert(&invert)) {
         return;
     }
-    GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps(*pipelineBuilder);
 
     SkRect dstRect = SkRect::MakeLTRB(SK_Scalar1 * rect.fLeft,
                                       SK_Scalar1 * rect.fTop,
@@ -183,7 +185,11 @@
     maskMatrix.setIDiv(texture->width(), texture->height());
     maskMatrix.preTranslate(SkIntToScalar(-rect.fLeft), SkIntToScalar(-rect.fTop));
 
-    pipelineBuilder->addCoverageFragmentProcessor(
+    GrPipelineBuilder pipelineBuilder(*paint, drawContext->isUnifiedMultisampled());
+    pipelineBuilder.setRenderTarget(drawContext->accessRenderTarget());
+    pipelineBuilder.setUserStencil(userStencilSettings);
+
+    pipelineBuilder.addCoverageFragmentProcessor(
                          GrSimpleTextureEffect::Create(texture,
                                                        maskMatrix,
                                                        GrTextureParams::kNone_FilterMode,
@@ -191,5 +197,5 @@
 
     SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(),
                                                                         dstRect, nullptr, &invert));
-    target->drawBatch(*pipelineBuilder, clip, batch);
+    drawContext->drawBatch(pipelineBuilder, clip, batch);
 }
diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h
index 355379e..fac4e62 100644
--- a/src/gpu/GrSWMaskHelper.h
+++ b/src/gpu/GrSWMaskHelper.h
@@ -23,7 +23,6 @@
 class GrTexture;
 class SkPath;
 class SkStrokeRec;
-class GrDrawTarget;
 
 /**
  * The GrSWMaskHelper helps generate clip masks using the software rendering
@@ -87,8 +86,9 @@
     // This method is really only intended to be used with the
     // output of DrawPathMaskToTexture.
     static void DrawToTargetWithPathMask(GrTexture* texture,
-                                         GrDrawTarget* target,
-                                         GrPipelineBuilder* pipelineBuilder,
+                                         GrDrawContext*,
+                                         const GrPaint* paint,
+                                         const GrUserStencilSettings* userStencilSettings,
                                          const GrClip&,
                                          GrColor,
                                          const SkMatrix& viewMatrix,
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index aefaf27..dc0c6c0 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -6,6 +6,8 @@
  */
 
 #include "GrSoftwarePathRenderer.h"
+#include "GrAuditTrail.h"
+#include "GrClip.h"
 #include "GrSWMaskHelper.h"
 #include "GrTextureProvider.h"
 #include "batches/GrRectBatchFactory.h"
@@ -54,25 +56,35 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-static void draw_non_aa_rect(GrDrawTarget* drawTarget,
-                             const GrPipelineBuilder& pipelineBuilder,
-                             const GrClip& clip,
-                             GrColor color,
-                             const SkMatrix& viewMatrix,
-                             const SkRect& rect,
-                             const SkMatrix& localMatrix) {
-    SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
-                                                                        nullptr, &localMatrix));
-    drawTarget->drawBatch(pipelineBuilder, clip, batch);
+
 }
 
-void draw_around_inv_path(GrDrawTarget* target,
-                          GrPipelineBuilder* pipelineBuilder,
-                          const GrClip& clip,
-                          GrColor color,
-                          const SkMatrix& viewMatrix,
-                          const SkIRect& devClipBounds,
-                          const SkIRect& devPathBounds) {
+void GrSoftwarePathRenderer::DrawNonAARect(GrDrawContext* drawContext,
+                                           const GrPaint* paint,
+                                           const GrUserStencilSettings* userStencilSettings,
+                                           const GrClip& clip,
+                                           GrColor color,
+                                           const SkMatrix& viewMatrix,
+                                           const SkRect& rect,
+                                           const SkMatrix& localMatrix) {
+    SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, viewMatrix, rect,
+                                                                        nullptr, &localMatrix));
+
+    GrPipelineBuilder pipelineBuilder(*paint, drawContext->isUnifiedMultisampled());
+    pipelineBuilder.setRenderTarget(drawContext->accessRenderTarget());
+    pipelineBuilder.setUserStencil(userStencilSettings);
+
+    drawContext->drawBatch(pipelineBuilder, clip, batch);
+}
+
+void GrSoftwarePathRenderer::DrawAroundInvPath(GrDrawContext* drawContext,
+                                               const GrPaint* paint,
+                                               const GrUserStencilSettings* userStencilSettings,
+                                               const GrClip& clip,
+                                               GrColor color,
+                                               const SkMatrix& viewMatrix,
+                                               const SkIRect& devClipBounds,
+                                               const SkIRect& devPathBounds) {
     SkMatrix invert;
     if (!viewMatrix.invert(&invert)) {
         return;
@@ -82,44 +94,46 @@
     if (devClipBounds.fTop < devPathBounds.fTop) {
         rect.iset(devClipBounds.fLeft, devClipBounds.fTop,
                   devClipBounds.fRight, devPathBounds.fTop);
-        draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), rect, invert);
+        DrawNonAARect(drawContext, paint, userStencilSettings, clip, color,
+                      SkMatrix::I(), rect, invert);
     }
     if (devClipBounds.fLeft < devPathBounds.fLeft) {
         rect.iset(devClipBounds.fLeft, devPathBounds.fTop,
                   devPathBounds.fLeft, devPathBounds.fBottom);
-        draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), rect, invert);
+        DrawNonAARect(drawContext, paint, userStencilSettings, clip, color,
+                      SkMatrix::I(), rect, invert);
     }
     if (devClipBounds.fRight > devPathBounds.fRight) {
         rect.iset(devPathBounds.fRight, devPathBounds.fTop,
                   devClipBounds.fRight, devPathBounds.fBottom);
-        draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), rect, invert);
+        DrawNonAARect(drawContext, paint, userStencilSettings, clip, color,
+                      SkMatrix::I(), rect, invert);
     }
     if (devClipBounds.fBottom > devPathBounds.fBottom) {
         rect.iset(devClipBounds.fLeft, devPathBounds.fBottom,
                   devClipBounds.fRight, devClipBounds.fBottom);
-        draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), rect, invert);
+        DrawNonAARect(drawContext, paint, userStencilSettings, clip, color,
+                      SkMatrix::I(), rect, invert);
     }
 }
 
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // return true on success; false on failure
 bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrSoftwarePathRenderer::onDrawPath");
-    if (!fTexProvider || !args.fPipelineBuilder->getRenderTarget()) {
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
+                              "GrSoftwarePathRenderer::onDrawPath");
+    if (!fTexProvider) {
         return false;
     }
 
-    const int width = args.fPipelineBuilder->getRenderTarget()->width();
-    const int height = args.fPipelineBuilder->getRenderTarget()->height();
-
     SkIRect devPathBounds, devClipBounds;
-    if (!get_path_and_clip_bounds(width, height, *args.fClip, *args.fPath,
+    if (!get_path_and_clip_bounds(args.fDrawContext->width(), args.fDrawContext->height(),
+                                  *args.fClip, *args.fPath,
                                   *args.fViewMatrix, &devPathBounds, &devClipBounds)) {
         if (args.fPath->isInverseFillType()) {
-            draw_around_inv_path(args.fTarget, args.fPipelineBuilder, *args.fClip, args.fColor,
-                                 *args.fViewMatrix, devClipBounds, devPathBounds);
+            DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings,
+                              *args.fClip, args.fColor,
+                              *args.fViewMatrix, devClipBounds, devPathBounds);
         }
         return true;
     }
@@ -132,13 +146,15 @@
         return false;
     }
 
-    GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fTarget, args.fPipelineBuilder,
+    GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fDrawContext, args.fPaint,
+                                             args.fUserStencilSettings,
                                              *args.fClip, args.fColor, *args.fViewMatrix,
                                              devPathBounds);
 
     if (args.fPath->isInverseFillType()) {
-        draw_around_inv_path(args.fTarget, args.fPipelineBuilder, *args.fClip, args.fColor,
-                             *args.fViewMatrix, devClipBounds, devPathBounds);
+        DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings,
+                          *args.fClip, args.fColor,
+                          *args.fViewMatrix, devClipBounds, devPathBounds);
     }
 
     return true;
diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h
index edc47ce..4c756d5 100644
--- a/src/gpu/GrSoftwarePathRenderer.h
+++ b/src/gpu/GrSoftwarePathRenderer.h
@@ -19,8 +19,24 @@
 class GrSoftwarePathRenderer : public GrPathRenderer {
 public:
     GrSoftwarePathRenderer(GrTextureProvider* texProvider) : fTexProvider(texProvider) { }
-
 private:
+    static void DrawNonAARect(GrDrawContext* drawContext,
+                              const GrPaint* paint,
+                              const GrUserStencilSettings* userStencilSettings,
+                              const GrClip& clip,
+                              GrColor color,
+                              const SkMatrix& viewMatrix,
+                              const SkRect& rect,
+                              const SkMatrix& localMatrix);
+    static void DrawAroundInvPath(GrDrawContext* drawContext,
+                                  const GrPaint* paint,
+                                  const GrUserStencilSettings* userStencilSettings,
+                                  const GrClip& clip,
+                                  GrColor color,
+                                  const SkMatrix& viewMatrix,
+                                  const SkIRect& devClipBounds,
+                                  const SkIRect& devPathBounds);
+
     StencilSupport onGetStencilSupport(const SkPath&) const override {
         return GrPathRenderer::kNoSupport_StencilSupport;
     }
diff --git a/src/gpu/GrUserStencilSettings.h b/src/gpu/GrUserStencilSettings.h
index a07a083..32fb139 100644
--- a/src/gpu/GrUserStencilSettings.h
+++ b/src/gpu/GrUserStencilSettings.h
@@ -188,6 +188,8 @@
     const Face       fBack;
 
     static const GrUserStencilSettings& kUnused;
+
+    bool isUnused() const { return this == &kUnused; }
 };
 
 template<GrUserStencilTest Test, GrUserStencilOp PassOp, GrUserStencilOp FailOp>
diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp
index ffb206a..191c081 100644
--- a/src/gpu/batches/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp
@@ -995,7 +995,8 @@
 };
 
 bool GrAAConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrAAConvexPathRenderer::onDrawPath");
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
+                              "GrAAConvexPathRenderer::onDrawPath");
     if (args.fPath->isEmpty()) {
         return true;
     }
@@ -1006,7 +1007,12 @@
     geometry.fPath = *args.fPath;
 
     SkAutoTUnref<GrDrawBatch> batch(AAConvexPathBatch::Create(geometry));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
+
+    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->isUnifiedMultisampled());
+    pipelineBuilder.setRenderTarget(args.fDrawContext->accessRenderTarget());
+    pipelineBuilder.setUserStencil(args.fUserStencilSettings);
+
+    args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
 
     return true;
 
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
index 44b7ac0..e506e53 100644
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
@@ -528,7 +528,7 @@
 };
 
 bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrAADistanceFieldPathRenderer::onDrawPath");
     // we've already bailed on inverse filled paths, so this is safe
     if (args.fPath->isEmpty()) {
@@ -564,7 +564,12 @@
                                                                      *args.fViewMatrix, fAtlas,
                                                                      &fPathCache, &fPathList,
                                                                      args.fGammaCorrect));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
+
+    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->isUnifiedMultisampled());
+    pipelineBuilder.setRenderTarget(args.fDrawContext->accessRenderTarget());
+    pipelineBuilder.setUserStencil(args.fUserStencilSettings);
+
+    args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
 
     return true;
 }
diff --git a/src/gpu/batches/GrAAHairLinePathRenderer.cpp b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
index 556e251..a163138 100644
--- a/src/gpu/batches/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
@@ -963,14 +963,21 @@
 }
 
 bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),"GrAAHairlinePathRenderer::onDrawPath");
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
+                              "GrAAHairlinePathRenderer::onDrawPath");
     SkIRect devClipBounds;
-    GrRenderTarget* rt = args.fPipelineBuilder->getRenderTarget();
-    args.fClip->getConservativeBounds(rt->width(), rt->height(), &devClipBounds);
+    args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawContext->height(),
+                                      &devClipBounds);
 
     SkAutoTUnref<GrDrawBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, *args.fPath,
                                                           *args.fStyle, devClipBounds));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
+
+    GrPipelineBuilder pipelineBuilder(*args.fPaint,
+                                      args.fDrawContext->isStencilBufferMultisampled());
+    pipelineBuilder.setRenderTarget(args.fDrawContext->accessRenderTarget());
+    pipelineBuilder.setUserStencil(args.fUserStencilSettings);
+
+    args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
 
     return true;
 }
diff --git a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
index 97a17c9..ee5a7af 100644
--- a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
@@ -320,7 +320,7 @@
 };
 
 bool GrAALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrAALinearizingConvexPathRenderer::onDrawPath");
     if (args.fPath->isEmpty()) {
         return true;
@@ -335,7 +335,12 @@
     geometry.fMiterLimit = args.fStyle->strokeRec().getMiter();
 
     SkAutoTUnref<GrDrawBatch> batch(AAFlatteningConvexPathBatch::Create(geometry));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
+
+    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->isUnifiedMultisampled());
+    pipelineBuilder.setRenderTarget(args.fDrawContext->accessRenderTarget());
+    pipelineBuilder.setUserStencil(args.fUserStencilSettings);
+
+    args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
 
     return true;
 }
diff --git a/src/gpu/batches/GrDashLinePathRenderer.cpp b/src/gpu/batches/GrDashLinePathRenderer.cpp
index 165464f..1763f95 100644
--- a/src/gpu/batches/GrDashLinePathRenderer.cpp
+++ b/src/gpu/batches/GrDashLinePathRenderer.cpp
@@ -8,6 +8,7 @@
 #include "GrDashLinePathRenderer.h"
 
 #include "GrGpu.h"
+#include "GrAuditTrail.h"
 #include "effects/GrDashingEffect.h"
 
 bool GrDashLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
@@ -19,8 +20,9 @@
 }
 
 bool GrDashLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrDashLinePathRenderer::onDrawPath");
-    bool msaaIsEnabled = args.fPipelineBuilder->getRenderTarget()->isUnifiedMultisampled();
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
+                              "GrDashLinePathRenderer::onDrawPath");
+    bool msaaIsEnabled = args.fDrawContext->isUnifiedMultisampled();
     SkPoint pts[2];
     SkAssertResult(args.fPath->isLine(pts));
     SkAutoTUnref<GrDrawBatch> batch(GrDashingEffect::CreateDashLineBatch(args.fColor,
@@ -33,6 +35,10 @@
         return false;
     }
 
-    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
+    GrPipelineBuilder pipelineBuilder(*args.fPaint, msaaIsEnabled);
+    pipelineBuilder.setRenderTarget(args.fDrawContext->accessRenderTarget());
+    pipelineBuilder.setUserStencil(args.fUserStencilSettings);
+
+    args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
     return true;
 }
diff --git a/src/gpu/batches/GrDefaultPathRenderer.cpp b/src/gpu/batches/GrDefaultPathRenderer.cpp
index c29db53..9077d92 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.cpp
+++ b/src/gpu/batches/GrDefaultPathRenderer.cpp
@@ -417,8 +417,9 @@
     typedef GrVertexBatch INHERITED;
 };
 
-bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
-                                             GrPipelineBuilder* pipelineBuilder,
+bool GrDefaultPathRenderer::internalDrawPath(GrDrawContext* drawContext,
+                                             const GrPaint& paint,
+                                             const GrUserStencilSettings* userStencilSettings,
                                              const GrClip& clip,
                                              GrColor color,
                                              const SkMatrix& viewMatrix,
@@ -438,12 +439,6 @@
         SkASSERT(style->isSimpleFill());
     }
 
-    // Save the current xp on the draw state so we can reset it if needed
-    const GrXPFactory* xpFactory = pipelineBuilder->getXPFactory();
-    SkAutoTUnref<const GrXPFactory> backupXPFactory(SkSafeRef(xpFactory));
-    // face culling doesn't make sense here
-    SkASSERT(GrPipelineBuilder::kBoth_DrawFace == pipelineBuilder->getDrawFace());
-
     int                          passCount = 0;
     const GrUserStencilSettings* passes[3];
     GrPipelineBuilder::DrawFace  drawFace[3];
@@ -540,21 +535,13 @@
     SkScalar srcSpaceTol = GrPathUtils::scaleToleranceToSrc(tol, viewMatrix, path.getBounds());
 
     SkRect devBounds;
-    GetPathDevBounds(path, pipelineBuilder->getRenderTarget(), viewMatrix, &devBounds);
+    GetPathDevBounds(path, drawContext->width(), drawContext->height(), viewMatrix, &devBounds);
 
     for (int p = 0; p < passCount; ++p) {
-        pipelineBuilder->setDrawFace(drawFace[p]);
-        if (passes[p]) {
-            pipelineBuilder->setUserStencil(passes[p]);
-        }
-
         if (lastPassIsBounds && (p == passCount-1)) {
-            // Reset the XP Factory on pipelineBuilder
-            pipelineBuilder->setXPFactory(backupXPFactory);
             SkRect bounds;
             SkMatrix localMatrix = SkMatrix::I();
             if (reverse) {
-                SkASSERT(pipelineBuilder->getRenderTarget());
                 // draw over the dev bounds (which will be the whole dst surface for inv fill).
                 bounds = devBounds;
                 SkMatrix vmi;
@@ -574,12 +561,18 @@
             SkAutoTUnref<GrDrawBatch> batch(
                     GrRectBatchFactory::CreateNonAAFill(color, viewM, bounds, nullptr,
                                                         &localMatrix));
-            target->drawBatch(*pipelineBuilder, clip, batch);
-        } else {
-            if (passCount > 1) {
-                pipelineBuilder->setDisableColorXPFactory();
+
+            GrPipelineBuilder pipelineBuilder(paint, drawContext->isUnifiedMultisampled());
+            pipelineBuilder.setRenderTarget(drawContext->accessRenderTarget());
+            pipelineBuilder.setDrawFace(drawFace[p]);
+            if (passes[p]) {
+                pipelineBuilder.setUserStencil(passes[p]);
+            } else {
+                pipelineBuilder.setUserStencil(userStencilSettings);
             }
 
+            drawContext->drawBatch(pipelineBuilder, clip, batch);
+        } else {
             DefaultPathBatch::Geometry geometry;
             geometry.fColor = color;
             geometry.fPath = path;
@@ -589,7 +582,19 @@
                                                                      viewMatrix, isHairline,
                                                                      devBounds));
 
-            target->drawBatch(*pipelineBuilder, clip, batch);
+            GrPipelineBuilder pipelineBuilder(paint, drawContext->isUnifiedMultisampled());
+            pipelineBuilder.setRenderTarget(drawContext->accessRenderTarget());
+            pipelineBuilder.setDrawFace(drawFace[p]);
+            if (passes[p]) {
+                pipelineBuilder.setUserStencil(passes[p]);
+            } else {
+                pipelineBuilder.setUserStencil(userStencilSettings);
+            }
+            if (passCount > 1) {
+                pipelineBuilder.setDisableColorXPFactory();
+            }
+
+            drawContext->drawBatch(pipelineBuilder, clip, batch);
         }
     }
     return true;
@@ -604,9 +609,11 @@
 }
 
 bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrDefaultPathRenderer::onDrawPath");
-    return this->internalDrawPath(args.fTarget,
-                                  args.fPipelineBuilder,
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
+                              "GrDefaultPathRenderer::onDrawPath");
+    return this->internalDrawPath(args.fDrawContext,
+                                  *args.fPaint,
+                                  args.fUserStencilSettings,
                                   *args.fClip,
                                   args.fColor,
                                   *args.fViewMatrix,
@@ -616,11 +623,24 @@
 }
 
 void GrDefaultPathRenderer::onStencilPath(const StencilPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),"GrDefaultPathRenderer::onStencilPath");
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
+                              "GrDefaultPathRenderer::onStencilPath");
     SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
     SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
-    this->internalDrawPath(args.fTarget, args.fPipelineBuilder, *args.fClip, GrColor_WHITE,
-                           *args.fViewMatrix, *args.fPath, GrStyle::SimpleFill(), true);
+
+    GrPaint paint;
+    paint.setXPFactory(GrDisableColorXPFactory::Create());
+    paint.setAntiAlias(args.fIsAA);
+
+    this->internalDrawPath(args.fDrawContext,
+                           paint,
+                           &GrUserStencilSettings::kUnused,
+                           *args.fClip,
+                           GrColor_WHITE,
+                           *args.fViewMatrix,
+                           *args.fPath,
+                           GrStyle::SimpleFill(),
+                           true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/batches/GrDefaultPathRenderer.h b/src/gpu/batches/GrDefaultPathRenderer.h
index 6faf3ea..277d7a8 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.h
+++ b/src/gpu/batches/GrDefaultPathRenderer.h
@@ -30,8 +30,9 @@
 
     void onStencilPath(const StencilPathArgs&) override;
 
-    bool internalDrawPath(GrDrawTarget*,
-                          GrPipelineBuilder*,
+    bool internalDrawPath(GrDrawContext*,
+                          const GrPaint&,
+                          const GrUserStencilSettings*,
                           const GrClip&,
                           GrColor,
                           const SkMatrix& viewMatrix,
diff --git a/src/gpu/batches/GrMSAAPathRenderer.cpp b/src/gpu/batches/GrMSAAPathRenderer.cpp
index 2072175..887c527 100644
--- a/src/gpu/batches/GrMSAAPathRenderer.cpp
+++ b/src/gpu/batches/GrMSAAPathRenderer.cpp
@@ -7,7 +7,9 @@
 
 #include "GrMSAAPathRenderer.h"
 
+#include "GrAuditTrail.h"
 #include "GrBatchFlushState.h"
+#include "GrClip.h"
 #include "GrDefaultGeoProcFactory.h"
 #include "GrPathStencilSettings.h"
 #include "GrPathUtils.h"
@@ -566,19 +568,14 @@
     typedef GrVertexBatch INHERITED;
 };
 
-bool GrMSAAPathRenderer::internalDrawPath(GrDrawTarget* target,
-                                          GrPipelineBuilder* pipelineBuilder,
+bool GrMSAAPathRenderer::internalDrawPath(GrDrawContext* drawContext,
+                                          const GrPaint& paint,
+                                          const GrUserStencilSettings* userStencilSettings,
                                           const GrClip& clip,
                                           GrColor color,
                                           const SkMatrix& viewMatrix,
                                           const SkPath& path,
                                           bool stencilOnly) {
-
-    const GrXPFactory* xpFactory = pipelineBuilder->getXPFactory();
-    SkAutoTUnref<const GrXPFactory> backupXPFactory(SkSafeRef(xpFactory));
-    // face culling doesn't make sense here
-    SkASSERT(GrPipelineBuilder::kBoth_DrawFace == pipelineBuilder->getDrawFace());
-
     int                          passCount = 0;
     const GrUserStencilSettings* passes[3];
     GrPipelineBuilder::DrawFace  drawFace[3];
@@ -643,21 +640,13 @@
     }
 
     SkRect devBounds;
-    GetPathDevBounds(path, pipelineBuilder->getRenderTarget(), viewMatrix, &devBounds);
+    GetPathDevBounds(path, drawContext->width(), drawContext->height(), viewMatrix, &devBounds);
 
     for (int p = 0; p < passCount; ++p) {
-        pipelineBuilder->setDrawFace(drawFace[p]);
-        if (passes[p]) {
-            pipelineBuilder->setUserStencil(passes[p]);
-        }
-
         if (lastPassIsBounds && (p == passCount-1)) {
-            // Reset the XP Factory on pipelineBuilder
-            pipelineBuilder->setXPFactory(backupXPFactory);
             SkRect bounds;
             SkMatrix localMatrix = SkMatrix::I();
             if (reverse) {
-                SkASSERT(pipelineBuilder->getRenderTarget());
                 // draw over the dev bounds (which will be the whole dst surface for inv fill).
                 bounds = devBounds;
                 SkMatrix vmi;
@@ -677,12 +666,18 @@
             SkAutoTUnref<GrDrawBatch> batch(
                     GrRectBatchFactory::CreateNonAAFill(color, viewM, bounds, nullptr,
                                                         &localMatrix));
-            target->drawBatch(*pipelineBuilder, clip, batch);
-        } else {
-            if (passCount > 1) {
-                pipelineBuilder->setDisableColorXPFactory();
+
+            GrPipelineBuilder pipelineBuilder(paint, drawContext->isUnifiedMultisampled());
+            pipelineBuilder.setRenderTarget(drawContext->accessRenderTarget());
+            pipelineBuilder.setDrawFace(drawFace[p]);
+            if (passes[p]) {
+                pipelineBuilder.setUserStencil(passes[p]);
+            } else {
+                pipelineBuilder.setUserStencil(userStencilSettings);
             }
 
+            drawContext->drawBatch(pipelineBuilder, clip, batch);
+        } else {
             MSAAPathBatch::Geometry geometry;
             geometry.fColor = color;
             geometry.fPath = path;
@@ -690,12 +685,23 @@
 
             SkAutoTUnref<MSAAPathBatch> batch(MSAAPathBatch::Create(geometry, viewMatrix, 
                                                                     devBounds));
-            if (batch->isValid()) {
-                target->drawBatch(*pipelineBuilder, clip, batch);
-            }
-            else {
+            if (!batch->isValid()) {
                 return false;
             }
+
+            GrPipelineBuilder pipelineBuilder(paint, drawContext->isUnifiedMultisampled());
+            pipelineBuilder.setRenderTarget(drawContext->accessRenderTarget());
+            pipelineBuilder.setDrawFace(drawFace[p]);
+            if (passes[p]) {
+                pipelineBuilder.setUserStencil(passes[p]);
+            } else {
+                pipelineBuilder.setUserStencil(userStencilSettings);
+            }
+            if (passCount > 1) {
+                pipelineBuilder.setDisableColorXPFactory();
+            }
+
+            drawContext->drawBatch(pipelineBuilder, clip, batch);
         }
     }
     return true;
@@ -711,7 +717,8 @@
 }
 
 bool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrMSAAPathRenderer::onDrawPath");
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
+                              "GrMSAAPathRenderer::onDrawPath");
     SkPath tmpPath;
     const SkPath* path;
     if (args.fStyle->applies()) {
@@ -727,8 +734,9 @@
     } else {
         path = args.fPath;
     }
-    return this->internalDrawPath(args.fTarget,
-                                  args.fPipelineBuilder,
+    return this->internalDrawPath(args.fDrawContext,
+                                  *args.fPaint,
+                                  args.fUserStencilSettings,
                                   *args.fClip,
                                   args.fColor,
                                   *args.fViewMatrix,
@@ -737,11 +745,23 @@
 }
 
 void GrMSAAPathRenderer::onStencilPath(const StencilPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),"GrMSAAPathRenderer::onStencilPath");
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
+                              "GrMSAAPathRenderer::onStencilPath");
     SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
     SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
-    this->internalDrawPath(args.fTarget, args.fPipelineBuilder, *args.fClip, GrColor_WHITE,
-                           *args.fViewMatrix, *args.fPath, true);
+
+    GrPaint paint;
+    paint.setXPFactory(GrDisableColorXPFactory::Create());
+    paint.setAntiAlias(args.fIsAA);
+
+    this->internalDrawPath(args.fDrawContext,
+                           paint,
+                           &GrUserStencilSettings::kUnused,
+                           *args.fClip,
+                           GrColor_WHITE,
+                           *args.fViewMatrix,
+                           *args.fPath,
+                           true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/batches/GrMSAAPathRenderer.h b/src/gpu/batches/GrMSAAPathRenderer.h
index 53d0b1d..0c27e8c 100644
--- a/src/gpu/batches/GrMSAAPathRenderer.h
+++ b/src/gpu/batches/GrMSAAPathRenderer.h
@@ -21,8 +21,9 @@
 
     void onStencilPath(const StencilPathArgs&) override;
 
-    bool internalDrawPath(GrDrawTarget*,
-                          GrPipelineBuilder*,
+    bool internalDrawPath(GrDrawContext*,
+                          const GrPaint&,
+                          const GrUserStencilSettings*,
                           const GrClip&,
                           GrColor,
                           const SkMatrix& viewMatrix,
diff --git a/src/gpu/batches/GrPLSPathRenderer.cpp b/src/gpu/batches/GrPLSPathRenderer.cpp
index e698894..e84bd4d 100644
--- a/src/gpu/batches/GrPLSPathRenderer.cpp
+++ b/src/gpu/batches/GrPLSPathRenderer.cpp
@@ -985,7 +985,12 @@
     geometry.fPath = *args.fPath;
 
     SkAutoTUnref<GrDrawBatch> batch(PLSPathBatch::Create(geometry));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
+
+    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->isUnifiedMultisampled());
+    pipelineBuilder.setRenderTarget(args.fDrawContext->accessRenderTarget());
+    pipelineBuilder.setUserStencil(args.fUserStencilSettings);
+
+    args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
 
     SkDEBUGCODE(inPLSDraw = false;)
     return true;
diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
index 78ca31a..e43d05c 100644
--- a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
@@ -9,11 +9,13 @@
 #include "GrStencilAndCoverPathRenderer.h"
 #include "GrCaps.h"
 #include "GrContext.h"
+#include "GrDrawContextPriv.h"
 #include "GrDrawPathBatch.h"
 #include "GrGpu.h"
 #include "GrPath.h"
 #include "GrRenderTarget.h"
 #include "GrResourceProvider.h"
+#include "GrStencilPathBatch.h"
 #include "GrStyle.h"
 #include "batches/GrRectBatchFactory.h"
 
@@ -65,29 +67,32 @@
 }
 
 void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrStencilAndCoverPathRenderer::onStencilPath");
+
+    GrPaint paint;
+    paint.setXPFactory(GrDisableColorXPFactory::Create());
+    paint.setAntiAlias(args.fIsAA);
+
+    GrPipelineBuilder pipelineBuilder(paint, args.fDrawContext->isUnifiedMultisampled());    
+    pipelineBuilder.setRenderTarget(args.fDrawContext->accessRenderTarget());
+
     SkASSERT(!args.fPath->isInverseFillType());
-    SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, *args.fPath, GrStyle::SimpleFill()));
-    args.fTarget->stencilPath(*args.fPipelineBuilder, *args.fClip, *args.fViewMatrix, p,
-                              p->getFillType());
+    SkAutoTUnref<GrPath> path(get_gr_path(fResourceProvider, *args.fPath, GrStyle::SimpleFill()));
+    args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder,
+                                                     *args.fClip,
+                                                     *args.fViewMatrix,
+                                                     path,
+                                                     path->getFillType());
 }
 
 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrStencilAndCoverPathRenderer::onDrawPath");
     SkASSERT(!args.fStyle->strokeRec().isHairlineStyle());
     const SkPath& path = *args.fPath;
-    GrPipelineBuilder* pipelineBuilder = args.fPipelineBuilder;
     const SkMatrix& viewMatrix = *args.fViewMatrix;
 
-    SkASSERT(!pipelineBuilder->hasUserStencilSettings());
-
-    if (args.fAntiAlias) {
-        SkASSERT(pipelineBuilder->getRenderTarget()->isStencilBufferMultisampled());
-        pipelineBuilder->enableState(GrPipelineBuilder::kHWAntialias_Flag);
-    }
-
     SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, *args.fStyle));
 
     if (path.isInverseFillType()) {
@@ -104,16 +109,26 @@
                 0xffff>()
         );
 
-
-        pipelineBuilder->setUserStencil(&kInvertedCoverPass);
-
         // fake inverse with a stencil and cover
-        args.fTarget->stencilPath(*pipelineBuilder, *args.fClip, viewMatrix, p, p->getFillType());
+        {
+            GrPipelineBuilder pipelineBuilder(*args.fPaint,
+                                              args.fDrawContext->isUnifiedMultisampled());
+            pipelineBuilder.setRenderTarget(args.fDrawContext->accessRenderTarget());
+            pipelineBuilder.setUserStencil(&kInvertedCoverPass);
+            if (args.fAntiAlias) {
+                SkASSERT(args.fDrawContext->isStencilBufferMultisampled());
+                pipelineBuilder.enableState(GrPipelineBuilder::kHWAntialias_Flag);
+            }
+
+            args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder, *args.fClip,
+                                                             viewMatrix, p, p->getFillType());
+        }
 
         SkMatrix invert = SkMatrix::I();
         SkRect bounds =
-            SkRect::MakeLTRB(0, 0, SkIntToScalar(pipelineBuilder->getRenderTarget()->width()),
-                             SkIntToScalar(pipelineBuilder->getRenderTarget()->height()));
+            SkRect::MakeLTRB(0, 0,
+                             SkIntToScalar(args.fDrawContext->width()),
+                             SkIntToScalar(args.fDrawContext->height()));
         SkMatrix vmi;
         // mapRect through persp matrix may not be correct
         if (!viewMatrix.hasPerspective() && viewMatrix.invert(&vmi)) {
@@ -128,14 +143,26 @@
             }
         }
         const SkMatrix& viewM = viewMatrix.hasPerspective() ? SkMatrix::I() : viewMatrix;
-        if (pipelineBuilder->getRenderTarget()->hasMixedSamples()) {
-            pipelineBuilder->disableState(GrPipelineBuilder::kHWAntialias_Flag);
-        }
 
         SkAutoTUnref<GrDrawBatch> batch(
                 GrRectBatchFactory::CreateNonAAFill(args.fColor, viewM, bounds, nullptr,
                                                     &invert));
-        args.fTarget->drawBatch(*pipelineBuilder, *args.fClip, batch);
+
+        {
+            GrPipelineBuilder pipelineBuilder(*args.fPaint,
+                                              args.fDrawContext->isUnifiedMultisampled());
+            pipelineBuilder.setRenderTarget(args.fDrawContext->accessRenderTarget());
+            pipelineBuilder.setUserStencil(&kInvertedCoverPass);
+            if (args.fAntiAlias) {
+                SkASSERT(args.fDrawContext->isStencilBufferMultisampled());
+                pipelineBuilder.enableState(GrPipelineBuilder::kHWAntialias_Flag);
+            }
+            if (args.fDrawContext->hasMixedSamples()) {
+                pipelineBuilder.disableState(GrPipelineBuilder::kHWAntialias_Flag);
+            }
+
+            args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
+        }
     } else {
         static constexpr GrUserStencilSettings kCoverPass(
             GrUserStencilSettings::StaticInit<
@@ -147,12 +174,20 @@
                 0xffff>()
         );
 
-        pipelineBuilder->setUserStencil(&kCoverPass);
         SkAutoTUnref<GrDrawBatch> batch(
                 GrDrawPathBatch::Create(viewMatrix, args.fColor, p->getFillType(), p));
-        args.fTarget->drawBatch(*pipelineBuilder, *args.fClip, batch);
+
+        GrPipelineBuilder pipelineBuilder(*args.fPaint,
+                                          args.fDrawContext->isUnifiedMultisampled());
+        pipelineBuilder.setRenderTarget(args.fDrawContext->accessRenderTarget());
+        pipelineBuilder.setUserStencil(&kCoverPass);
+        if (args.fAntiAlias) {
+            SkASSERT(args.fDrawContext->isStencilBufferMultisampled());
+            pipelineBuilder.enableState(GrPipelineBuilder::kHWAntialias_Flag);
+        }
+
+        args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
     }
 
-    pipelineBuilder->disableUserStencil();
     return true;
 }
diff --git a/src/gpu/batches/GrTessellatingPathRenderer.cpp b/src/gpu/batches/GrTessellatingPathRenderer.cpp
index e697f78..e025435 100644
--- a/src/gpu/batches/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/batches/GrTessellatingPathRenderer.cpp
@@ -7,8 +7,10 @@
 
 #include "GrTessellatingPathRenderer.h"
 
+#include "GrAuditTrail.h"
 #include "GrBatchFlushState.h"
 #include "GrBatchTest.h"
+#include "GrClip.h"
 #include "GrDefaultGeoProcFactory.h"
 #include "GrMesh.h"
 #include "GrPathUtils.h"
@@ -278,16 +280,13 @@
 };
 
 bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
-    GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),
+    GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
                               "GrTessellatingPathRenderer::onDrawPath");
     SkASSERT(!args.fAntiAlias);
-    const GrRenderTarget* rt = args.fPipelineBuilder->getRenderTarget();
-    if (nullptr == rt) {
-        return false;
-    }
 
     SkIRect clipBoundsI;
-    args.fClip->getConservativeBounds(rt->width(), rt->height(), &clipBoundsI);
+    args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawContext->height(),
+                                      &clipBoundsI);
     SkRect clipBounds = SkRect::Make(clipBoundsI);
     SkMatrix vmi;
     if (!args.fViewMatrix->invert(&vmi)) {
@@ -297,7 +296,12 @@
     SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, *args.fPath,
                                                                   *args.fStyle, *args.fViewMatrix,
                                                                   clipBounds));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
+
+    GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->isUnifiedMultisampled());
+    pipelineBuilder.setRenderTarget(args.fDrawContext->accessRenderTarget());
+    pipelineBuilder.setUserStencil(args.fUserStencilSettings);
+
+    args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
 
     return true;
 }
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 6e8a5cc..72193dc 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -320,7 +320,7 @@
                                                           skPaint, props,
                                                           distanceAdjustTable, dc->isGammaCorrect(),
                                                           cache));
-        dc->drawBatch(pipelineBuilder, clip, batch);
+        dc->drawBatch(*pipelineBuilder, clip, batch);
     }
 }
 
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.cpp b/src/gpu/text/GrStencilAndCoverTextContext.cpp
index b74728e..00ec451 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/text/GrStencilAndCoverTextContext.cpp
@@ -647,7 +647,7 @@
                                          GrPathRendering::kWinding_FillType, glyphs, fInstanceData,
                                          bounds));
 
-        dc->drawBatch(pipelineBuilder, clip, batch);
+        dc->drawBatch(*pipelineBuilder, clip, batch);
     }
 
     if (fFallbackTextBlob) {
diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp
index 22779c2..6d562ea 100644
--- a/tests/TessellatingPathRendererTests.cpp
+++ b/tests/TessellatingPathRendererTests.cpp
@@ -232,18 +232,18 @@
     return path;
 }
 
-static void test_path(GrDrawTarget* dt, GrDrawContext* drawContext,
-                      GrResourceProvider* rp, const SkPath& path) {
+static void test_path(GrDrawContext* drawContext, GrResourceProvider* rp, const SkPath& path) {
     GrTessellatingPathRenderer tess;
-    GrPipelineBuilder pipelineBuilder;
-    pipelineBuilder.setXPFactory(
-        GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
-    pipelineBuilder.setRenderTarget(drawContext->accessRenderTarget());
+
+    GrPaint paint;
+    paint.setXPFactory(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
+
     GrNoClip noClip;
     GrStyle style(SkStrokeRec::kFill_InitStyle);
     GrPathRenderer::DrawPathArgs args;
-    args.fTarget = dt;
-    args.fPipelineBuilder = &pipelineBuilder;
+    args.fPaint = &paint;
+    args.fUserStencilSettings = &GrUserStencilSettings::kUnused;
+    args.fDrawContext = drawContext;
     args.fClip = &noClip;
     args.fResourceProvider = rp;
     args.fColor = GrColor_WHITE;
@@ -266,24 +266,23 @@
 
     GrTestTarget tt;
     ctxInfo.grContext()->getTestTarget(&tt, drawContext);
-    GrDrawTarget* dt = tt.target();
     GrResourceProvider* rp = tt.resourceProvider();
 
-    test_path(dt, drawContext.get(), rp, create_path_0());
-    test_path(dt, drawContext.get(), rp, create_path_1());
-    test_path(dt, drawContext.get(), rp, create_path_2());
-    test_path(dt, drawContext.get(), rp, create_path_3());
-    test_path(dt, drawContext.get(), rp, create_path_4());
-    test_path(dt, drawContext.get(), rp, create_path_5());
-    test_path(dt, drawContext.get(), rp, create_path_6());
-    test_path(dt, drawContext.get(), rp, create_path_7());
-    test_path(dt, drawContext.get(), rp, create_path_8());
-    test_path(dt, drawContext.get(), rp, create_path_9());
-    test_path(dt, drawContext.get(), rp, create_path_10());
-    test_path(dt, drawContext.get(), rp, create_path_11());
-    test_path(dt, drawContext.get(), rp, create_path_12());
-    test_path(dt, drawContext.get(), rp, create_path_13());
-    test_path(dt, drawContext.get(), rp, create_path_14());
-    test_path(dt, drawContext.get(), rp, create_path_15());
+    test_path(drawContext.get(), rp, create_path_0());
+    test_path(drawContext.get(), rp, create_path_1());
+    test_path(drawContext.get(), rp, create_path_2());
+    test_path(drawContext.get(), rp, create_path_3());
+    test_path(drawContext.get(), rp, create_path_4());
+    test_path(drawContext.get(), rp, create_path_5());
+    test_path(drawContext.get(), rp, create_path_6());
+    test_path(drawContext.get(), rp, create_path_7());
+    test_path(drawContext.get(), rp, create_path_8());
+    test_path(drawContext.get(), rp, create_path_9());
+    test_path(drawContext.get(), rp, create_path_10());
+    test_path(drawContext.get(), rp, create_path_11());
+    test_path(drawContext.get(), rp, create_path_12());
+    test_path(drawContext.get(), rp, create_path_13());
+    test_path(drawContext.get(), rp, create_path_14());
+    test_path(drawContext.get(), rp, create_path_15());
 }
 #endif
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index be539ca..8fdab2e 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -242,9 +242,9 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::testingOnly_drawBatch");
 
     if (clip) {
-        fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, *clip, batch);
+        fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, fDrawContext, *clip, batch);
     } else {
-        fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, GrNoClip(), batch);
+        fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, fDrawContext, GrNoClip(), batch);
     }
 }