Remove clip from GrPipelineBuilder

This eliminates a copy and will allow us to make the GrClip class
virutal.

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

Review-Url: https://codereview.chromium.org/1966903004
diff --git a/gm/constcolorprocessor.cpp b/gm/constcolorprocessor.cpp
index 4e0e68d..f3c5a65 100644
--- a/gm/constcolorprocessor.cpp
+++ b/gm/constcolorprocessor.cpp
@@ -107,10 +107,7 @@
                     GrColor color = kColors[procColor];
                     SkAutoTUnref<GrFragmentProcessor> fp(GrConstColorProcessor::Create(color, mode));
 
-                    GrClip clip;
-                    GrPipelineBuilder pipelineBuilder(grPaint,
-                                                      drawContext->accessRenderTarget(),
-                                                      clip);
+                    GrPipelineBuilder pipelineBuilder(grPaint, drawContext->accessRenderTarget());
                     pipelineBuilder.addColorFragmentProcessor(fp);
 
                     SkAutoTUnref<GrDrawBatch> batch(
diff --git a/include/gpu/GrDrawContext.h b/include/gpu/GrDrawContext.h
index 1f5b3d2..04b03d4 100644
--- a/include/gpu/GrDrawContext.h
+++ b/include/gpu/GrDrawContext.h
@@ -308,7 +308,7 @@
 
     // This entry point allows the GrTextContext-derived classes to add their batches to
     // the drawTarget.
-    void drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* batch);
+    void drawBatch(GrPipelineBuilder* pipelineBuilder, const GrClip&, GrDrawBatch* batch);
 
     GrDrawTarget* getDrawTarget();
 
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index c7b88ca..08a6920 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -50,12 +50,13 @@
 
 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, batch);
+    drawTarget->drawBatch(pipelineBuilder, clip, batch);
 }
 
 // Does the path in 'element' require SW rendering? If so, return true (and,
@@ -136,10 +137,9 @@
     return pr;
 }
 
-GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget, bool debugClipBatchToBounds)
+GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
     : fDrawTarget(drawTarget)
-    , fClipMode(kIgnoreClip_StencilClipMode)
-    , fDebugClipBatchToBounds(debugClipBatchToBounds) {
+    , fClipMode(kIgnoreClip_StencilClipMode) {
 }
 
 GrContext* GrClipMaskManager::getContext() {
@@ -284,74 +284,11 @@
     return !failed;
 }
 
-static void add_rect_to_clip(const GrClip& clip, const SkRect& devRect, GrClip* out) {
-    switch (clip.clipType()) {
-        case GrClip::kClipStack_ClipType: {
-            SkClipStack* stack = new SkClipStack;
-            *stack = *clip.clipStack();
-            // The stack is actually in clip space not device space.
-            SkRect clipRect = devRect;
-            SkPoint origin = { SkIntToScalar(clip.origin().fX), SkIntToScalar(clip.origin().fY) };
-            clipRect.offset(origin);
-            SkIRect iclipRect;
-            clipRect.roundOut(&iclipRect);
-            clipRect = SkRect::Make(iclipRect);
-            stack->clipDevRect(clipRect, SkRegion::kIntersect_Op, false);
-            out->setClipStack(stack, &clip.origin());
-            break;
-        }
-        case GrClip::kWideOpen_ClipType:
-            *out = GrClip(devRect);
-            break;
-        case GrClip::kIRect_ClipType: {
-            SkIRect intersect;
-            devRect.roundOut(&intersect);
-            if (intersect.intersect(clip.irect())) {
-                *out = GrClip(intersect);
-            } else {
-                *out = clip;
-            }
-            break;
-        }
-    }
-}
-
-bool GrClipMaskManager::setupScissorClip(const GrPipelineBuilder& pipelineBuilder,
-                                         const SkIRect& clipScissor,
-                                         const SkRect* devBounds,
-                                         GrAppliedClip* out) {
-    SkASSERT(kModifyClip_StencilClipMode != fClipMode); // TODO: Remove fClipMode.
-    fClipMode = kIgnoreClip_StencilClipMode;
-
-    GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
-
-    SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
-    SkIRect devBoundsScissor;
-    const SkIRect* scissor = &clipScissor;
-    bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds;
-    if (doDevBoundsClip) {
-        devBounds->roundOut(&devBoundsScissor);
-        if (devBoundsScissor.intersect(clipScissor)) {
-            scissor = &devBoundsScissor;
-        }
-    }
-
-    if (scissor->contains(clipSpaceRTIBounds)) {
-        // This counts as wide open
-        return true;
-    }
-
-    if (clipSpaceRTIBounds.intersect(*scissor)) {
-        out->fScissorState.set(clipSpaceRTIBounds);
-        return true;
-    }
-    return false;
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // sort out what kind of clip mask needs to be created: alpha, stencil,
 // scissor, or entirely software
 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
+                                      const GrClip& clip,
                                       const SkRect* devBounds,
                                       GrAppliedClip* out) {
     if (kRespectClip_StencilClipMode == fClipMode) {
@@ -369,13 +306,6 @@
     SkASSERT(rt);
 
     SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
-    GrClip devBoundsClip;
-    bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds;
-    if (doDevBoundsClip) {
-        add_rect_to_clip(pipelineBuilder.clip(), *devBounds, &devBoundsClip);
-    }
-    const GrClip& clip = doDevBoundsClip ? devBoundsClip : pipelineBuilder.clip();
-
     if (clip.isWideOpen(clipSpaceRTIBounds)) {
         return true;
     }
@@ -528,7 +458,7 @@
 }
 
 static bool stencil_element(GrDrawContext* dc,
-                            const SkIRect* scissorRect,
+                            const GrClip& clip,
                             const GrUserStencilSettings* ss,
                             const SkMatrix& viewMatrix,
                             const SkClipStack::Element* element) {
@@ -539,7 +469,7 @@
             SkDEBUGFAIL("Should never get here with an empty element.");
             break;
         case Element::kRect_Type:
-            return dc->drawContextPriv().drawAndStencilRect(scissorRect, ss,
+            return dc->drawContextPriv().drawAndStencilRect(clip, ss,
                                                             element->getOp(),
                                                             element->isInverseFilled(),
                                                             element->isAA(),
@@ -552,7 +482,7 @@
                 path.toggleInverseFillType();
             }
 
-            return dc->drawContextPriv().drawAndStencilPath(scissorRect, ss,
+            return dc->drawContextPriv().drawAndStencilPath(clip, ss,
                                                             element->getOp(),
                                                             element->isInverseFilled(),
                                                             element->isAA(), viewMatrix, path);
@@ -673,6 +603,8 @@
             }
 #endif
 
+            GrClip clip(maskSpaceIBounds);
+
             // draw directly into the result with the stencil set to make the pixels affected
             // by the clip shape be non-zero.
             static constexpr GrUserStencilSettings kStencilInElement(
@@ -684,7 +616,7 @@
                      GrUserStencilOp::kReplace,
                      0xffff>()
             );
-            if (!stencil_element(dc.get(), &maskSpaceIBounds, &kStencilInElement,
+            if (!stencil_element(dc.get(), clip, &kStencilInElement,
                                  translate, element)) {
                 texture->resourcePriv().removeUniqueKey();
                 return nullptr;
@@ -700,7 +632,7 @@
                      GrUserStencilOp::kZero,
                      0xffff>()
             );
-            if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, &kDrawOutsideElement,
+            if (!dc->drawContextPriv().drawAndStencilRect(clip, &kDrawOutsideElement,
                                                           op, !invert, false,
                                                           translate,
                                                           SkRect::Make(clipSpaceIBounds))) {
@@ -760,7 +692,6 @@
             const Element* element = iter.get();
 
             GrPipelineBuilder pipelineBuilder;
-            pipelineBuilder.setClip(clip);
             pipelineBuilder.setRenderTarget(rt);
 
             pipelineBuilder.setDisableColorXPFactory();
@@ -835,7 +766,7 @@
                 if (Element::kRect_Type == element->getType()) {
                     pipelineBuilder.setUserStencil(&kDrawToStencil);
 
-                    draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE, viewMatrix,
+                    draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE, viewMatrix,
                                      element->getRect());
                 } else {
                     if (!clipPath.isEmpty()) {
@@ -846,6 +777,7 @@
                             args.fTarget = fDrawTarget;
                             args.fResourceProvider = this->getContext()->resourceProvider();
                             args.fPipelineBuilder = &pipelineBuilder;
+                            args.fClip = &clip;
                             args.fColor = GrColor_WHITE;
                             args.fViewMatrix = &viewMatrix;
                             args.fPath = &clipPath;
@@ -858,6 +790,7 @@
                             args.fTarget = fDrawTarget;
                             args.fResourceProvider = this->getContext()->resourceProvider();
                             args.fPipelineBuilder = &pipelineBuilder;
+                            args.fClip = &clip;
                             args.fViewMatrix = &viewMatrix;
                             args.fPath = &clipPath;
                             pr->stencilPath(args);
@@ -874,13 +807,14 @@
 
                 if (drawDirectToClip) {
                     if (Element::kRect_Type == element->getType()) {
-                        draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE, viewMatrix,
-                                         element->getRect());
+                        draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE,
+                                         viewMatrix, element->getRect());
                     } else {
                         GrPathRenderer::DrawPathArgs args;
                         args.fTarget = fDrawTarget;
                         args.fResourceProvider = this->getContext()->resourceProvider();
                         args.fPipelineBuilder = &pipelineBuilder;
+                        args.fClip = &clip;
                         args.fColor = GrColor_WHITE;
                         args.fViewMatrix = &viewMatrix;
                         args.fPath = &clipPath;
@@ -892,7 +826,7 @@
                 } 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, GrColor_WHITE, viewMatrix,
+                    draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor_WHITE, viewMatrix,
                                      SkRect::Make(clipSpaceIBounds));
                 }
             }
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index 096dafd..2b70f02 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -17,6 +17,7 @@
 #include "SkTLList.h"
 #include "SkTypes.h"
 
+class GrClip;
 class GrDrawTarget;
 class GrPathRenderer;
 class GrPathRendererChain;
@@ -56,7 +57,7 @@
  */
 class GrClipMaskManager : SkNoncopyable {
 public:
-    GrClipMaskManager(GrDrawTarget* owner, bool debugClipBatchToBounds);
+    GrClipMaskManager(GrDrawTarget* owner);
 
     /**
      * Creates a clip mask if necessary as a stencil buffer or alpha texture
@@ -64,12 +65,8 @@
      * then the draw can be skipped. devBounds is optional but can help optimize
      * clipping.
      */
-    bool setupClipping(const GrPipelineBuilder&, const SkRect* devBounds, GrAppliedClip*);
-
-    bool setupScissorClip(const GrPipelineBuilder& pipelineBuilder,
-                          const SkIRect& scissor,
-                          const SkRect* devBounds,
-                          GrAppliedClip* out);
+    bool setupClipping(const GrPipelineBuilder&, const GrClip&, const SkRect* devBounds,
+                       GrAppliedClip*);
 
 private:
     inline GrContext* getContext();
@@ -150,7 +147,6 @@
 
     GrDrawTarget*   fDrawTarget;    // This is our owning draw target.
     StencilClipMode fClipMode;
-    bool            fDebugClipBatchToBounds;
 
     typedef SkNoncopyable INHERITED;
 };
diff --git a/src/gpu/GrDrawContext.cpp b/src/gpu/GrDrawContext.cpp
index 10b9b63..3db0449 100644
--- a/src/gpu/GrDrawContext.cpp
+++ b/src/gpu/GrDrawContext.cpp
@@ -235,8 +235,8 @@
         SkAutoTUnref<GrDrawBatch> batch(
                 GrRectBatchFactory::CreateNonAAFill(paint->getColor(), SkMatrix::I(), r, nullptr,
                                                     &localMatrix));
-        GrPipelineBuilder pipelineBuilder(*paint, fRenderTarget.get(), clip);
-        this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+        GrPipelineBuilder pipelineBuilder(*paint, fRenderTarget.get());
+        this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
     }
 }
 
@@ -357,14 +357,14 @@
     }
 
     if (batch) {
-        GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
+        GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
 
         if (snapToPixelCenters) {
             pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag,
                                      snapToPixelCenters);
         }
 
-        this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+        this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
         return;
     }
 
@@ -374,7 +374,7 @@
     this->internalDrawPath(clip, paint, viewMatrix, path, *style);
 }
 
-bool GrDrawContextPriv::drawAndStencilRect(const SkIRect* scissorRect,
+bool GrDrawContextPriv::drawAndStencilRect(const GrClip& clip,
                                            const GrUserStencilSettings* ss,
                                            SkRegion::Op op,
                                            bool invert,
@@ -394,19 +394,17 @@
 
     SkAutoTUnref<GrDrawBatch> batch(fDrawContext->getFillRectBatch(paint, viewMatrix, rect));
     if (batch) {
-        GrPipelineBuilder pipelineBuilder(paint,
-                                          fDrawContext->accessRenderTarget(),
-                                          GrClip::WideOpen());
+        GrPipelineBuilder pipelineBuilder(paint, fDrawContext->accessRenderTarget());
         pipelineBuilder.setUserStencil(ss);
 
-        fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, batch, scissorRect);
+        fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
         return true;
     }
 
     SkPath path;
     path.setIsVolatile(true);
     path.addRect(rect);
-    return this->drawAndStencilPath(scissorRect, ss, op, invert, doAA, viewMatrix, path);
+    return this->drawAndStencilPath(clip, ss, op, invert, doAA, viewMatrix, path);
 }
 
 void GrDrawContext::fillRectToRect(const GrClip& clip,
@@ -432,8 +430,8 @@
     }
 
     if (batch) {
-        GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
-        this->drawBatch(&pipelineBuilder, batch);
+        GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
+        this->drawBatch(&pipelineBuilder, clip, batch);
     }
 }
 
@@ -459,8 +457,8 @@
                                                         nullptr, &localMatrix));
     }
 
-    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
-    this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
+    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
 }
 
 void GrDrawContext::drawVertices(const GrClip& clip,
@@ -504,8 +502,8 @@
                                                                 indexCount, colors, texCoords,
                                                                 bounds));
 
-    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
-    this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
+    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -529,8 +527,8 @@
     SkAutoTUnref<GrDrawBatch> batch(GrDrawAtlasBatch::Create(geometry, viewMatrix, spriteCount,
                                                              xform, texRect, colors));
 
-    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
-    this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
+    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -562,8 +560,8 @@
                                                                          stroke,
                                                                          shaderCaps));
         if (batch) {
-            GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
-            this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+            GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
+            this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
             return;
         }
     }
@@ -656,7 +654,6 @@
     path.addRRect(outer);
     path.setFillType(SkPath::kEvenOdd_FillType);
 
-    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
     this->internalDrawPath(clip, paint, viewMatrix, path, GrStyle::SimpleFill());
 }
 
@@ -688,8 +685,8 @@
                                                                         stroke,
                                                                         shaderCaps));
         if (batch) {
-            GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
-            this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+            GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
+            this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
             return;
         }
     }
@@ -718,8 +715,8 @@
                                                              imageWidth, imageHeight,
                                                              center, dst));
 
-    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
-    this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
+    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
 }
 
 
@@ -778,8 +775,8 @@
 
     AutoCheckFlush acf(fDrawingManager);
 
-    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
-    this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
+    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
 }
 
 void GrDrawContext::drawPath(const GrClip& clip,
@@ -810,8 +807,8 @@
                 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateAAFillNestedRects(
                     paint.getColor(), viewMatrix, rects));
                 if (batch) {
-                    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
-                    this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+                    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
+                    this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
                 }
                 return;
             }
@@ -827,8 +824,8 @@
                                                                             style.strokeRec(),
                                                                             shaderCaps));
             if (batch) {
-                GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
-                this->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+                GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
+                this->getDrawTarget()->drawBatch(pipelineBuilder, clip, batch);
                 return;
             }
         }
@@ -842,7 +839,7 @@
     this->internalDrawPath(clip, paint, viewMatrix, path, style);
 }
 
-bool GrDrawContextPriv::drawAndStencilPath(const SkIRect* scissorRect,
+bool GrDrawContextPriv::drawAndStencilPath(const GrClip& clip,
                                            const GrUserStencilSettings* ss,
                                            SkRegion::Op op,
                                            bool invert,
@@ -855,7 +852,7 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::drawPath");
 
     if (path.isEmpty() && path.isInverseFillType()) {
-        this->drawAndStencilRect(scissorRect, ss, op, invert, false, SkMatrix::I(),
+        this->drawAndStencilRect(clip, ss, op, invert, false, SkMatrix::I(),
                                  SkRect::MakeIWH(fDrawContext->width(),
                                                  fDrawContext->height()));
         return true;
@@ -893,20 +890,14 @@
     GrPaint paint;
     paint.setCoverageSetOpXPFactory(op, invert);
 
-    // TODO: it is unfortunate that we have to convert this to a GrClip to
-    // call drawPath.
-    GrClip clip;
-    if (scissorRect) {
-        clip.setIRect(*scissorRect);
-    }
-
-    GrPipelineBuilder pipelineBuilder(paint, fDrawContext->accessRenderTarget(), clip);
+    GrPipelineBuilder pipelineBuilder(paint, fDrawContext->accessRenderTarget());
     pipelineBuilder.setUserStencil(ss);
 
     GrPathRenderer::DrawPathArgs args;
     args.fTarget = fDrawContext->getDrawTarget();
     args.fResourceProvider = fDrawContext->fDrawingManager->getContext()->resourceProvider();
     args.fPipelineBuilder = &pipelineBuilder;
+    args.fClip = &clip;
     args.fColor = GrColor_WHITE;
     args.fViewMatrix = &viewMatrix;
     args.fPath = &path;
@@ -1005,12 +996,13 @@
         return;
     }
 
-    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get(), clip);
+    GrPipelineBuilder pipelineBuilder(paint, fRenderTarget.get());
 
     GrPathRenderer::DrawPathArgs args;
     args.fTarget = this->getDrawTarget();
     args.fResourceProvider = fDrawingManager->getContext()->resourceProvider();
     args.fPipelineBuilder = &pipelineBuilder;
+    args.fClip = &clip;
     args.fColor = paint.getColor();
     args.fViewMatrix = &viewMatrix;
     args.fPath = canDrawArgs.fPath;
@@ -1020,11 +1012,12 @@
     pr->drawPath(args);
 }
 
-void GrDrawContext::drawBatch(GrPipelineBuilder* pipelineBuilder, GrDrawBatch* batch) {
+void GrDrawContext::drawBatch(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, batch);
+    this->getDrawTarget()->drawBatch(*pipelineBuilder, clip, batch);
 }
diff --git a/src/gpu/GrDrawContextPriv.h b/src/gpu/GrDrawContextPriv.h
index 973315b..7f70f89 100644
--- a/src/gpu/GrDrawContextPriv.h
+++ b/src/gpu/GrDrawContextPriv.h
@@ -17,7 +17,7 @@
     data members or virtual methods. */
 class GrDrawContextPriv {
 public:
-    bool drawAndStencilRect(const SkIRect* scissorRect,
+    bool drawAndStencilRect(const GrClip&,
                             const GrUserStencilSettings*,
                             SkRegion::Op op,
                             bool invert,
@@ -25,7 +25,7 @@
                             const SkMatrix& viewMatrix,
                             const SkRect&);
 
-    bool drawAndStencilPath(const SkIRect* scissorRect,
+    bool drawAndStencilPath(const GrClip&,
                             const GrUserStencilSettings*,
                             SkRegion::Op op,
                             bool invert,
@@ -34,7 +34,8 @@
                             const SkPath&);
 
     void testingOnly_drawBatch(const GrPipelineBuilder& pipelineBuilder,
-                               GrDrawBatch* batch);
+                               GrDrawBatch* batch,
+                               const GrClip* = nullptr);
 
 private:
     explicit GrDrawContextPriv(GrDrawContext* drawContext) : fDrawContext(drawContext) {}
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 26b271f..0db31f2 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -46,8 +46,9 @@
     , fRenderTarget(rt) {
     // TODO: Stop extracting the context (currently needed by GrClipMaskManager)
     fContext = fGpu->getContext();
-    fClipMaskManager.reset(new GrClipMaskManager(this, options.fClipBatchToBounds));
+    fClipMaskManager.reset(new GrClipMaskManager(this));
 
+    fClipBatchToBounds = options.fClipBatchToBounds;
     fDrawBatchBounds = options.fDrawBatchBounds;
     fMaxBatchLookback = (options.fMaxBatchLookback < 0) ? kDefaultMaxBatchLookback :
                                                           options.fMaxBatchLookback;
@@ -129,6 +130,7 @@
 #endif
 
 bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder,
+                                           const GrClip& clip,
                                            const GrPipelineOptimizations& optimizations,
                                            GrXferProcessor::DstTexture* dstTexture,
                                            const SkRect& batchBounds) {
@@ -152,7 +154,7 @@
     }
 
     SkIRect copyRect;
-    pipelineBuilder.clip().getConservativeBounds(rt->width(), rt->height(), &copyRect);
+    clip.getConservativeBounds(rt->width(), rt->height(), &copyRect);
 
     SkIRect drawIBounds;
     bounds.roundOut(&drawIBounds);
@@ -233,40 +235,31 @@
 }
 
 void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder,
-                             GrDrawBatch* batch,
-                             const SkIRect* scissorRect) {
+                             const GrClip& clip,
+                             GrDrawBatch* batch) {
     // Setup clip
-    GrAppliedClip clip;
-
-    if (scissorRect) {
-        SkASSERT(GrClip::kWideOpen_ClipType == pipelineBuilder.clip().clipType());
-        if (!fClipMaskManager->setupScissorClip(pipelineBuilder, *scissorRect,
-                                                &batch->bounds(), &clip)) {
-            return;
-        }
-    } else {
-        if (!fClipMaskManager->setupClipping(pipelineBuilder, &batch->bounds(), &clip)) {
-            return;
-        }
+    GrAppliedClip appliedClip;
+    if (!fClipMaskManager->setupClipping(pipelineBuilder, clip, &batch->bounds(), &appliedClip)) {
+        return;
     }
 
     GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
-    if (clip.clipCoverageFragmentProcessor()) {
+    if (appliedClip.clipCoverageFragmentProcessor()) {
         arfps.set(&pipelineBuilder);
-        arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor());
+        arfps.addCoverageFragmentProcessor(appliedClip.clipCoverageFragmentProcessor());
     }
 
     GrPipeline::CreateArgs args;
     args.fPipelineBuilder = &pipelineBuilder;
     args.fCaps = this->caps();
-    args.fScissor = &clip.scissorState();
-    args.fHasStencilClip = clip.hasStencilClip();
-    if (pipelineBuilder.hasUserStencilSettings() || clip.hasStencilClip()) {
+    args.fScissor = &appliedClip.scissorState();
+    args.fHasStencilClip = appliedClip.hasStencilClip();
+    if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()) {
         fResourceProvider->attachStencilAttachment(pipelineBuilder.getRenderTarget());
     }
     batch->getPipelineOptimizations(&args.fOpts);
     GrScissorState finalScissor;
-    if (args.fOpts.fOverrides.fUsePLSDstRead) {
+    if (args.fOpts.fOverrides.fUsePLSDstRead || fClipBatchToBounds) {
         GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
         GrGLIRect viewport;
         viewport.fLeft = 0;
@@ -282,10 +275,10 @@
                                viewport.fWidth);
         ibounds.fBottom = SkTPin(SkScalarCeilToInt(batch->bounds().fBottom), viewport.fBottom,
                                 viewport.fHeight);
-        if (clip.scissorState().enabled()) {
-            const SkIRect& scissorRect = clip.scissorState().rect();
+        if (appliedClip.scissorState().enabled()) {
+            const SkIRect& scissorRect = appliedClip.scissorState().rect();
             if (!ibounds.intersect(scissorRect)) {
-                ibounds = scissorRect;
+                return;
             }
         }
         finalScissor.set(ibounds);
@@ -296,7 +289,7 @@
     args.fOpts.fCoveragePOI.completeCalculations(
                                                pipelineBuilder.fCoverageFragmentProcessors.begin(),
                                                pipelineBuilder.numCoverageFragmentProcessors());
-    if (!this->setupDstReadIfNecessary(pipelineBuilder, args.fOpts, &args.fDstTexture,
+    if (!this->setupDstReadIfNecessary(pipelineBuilder, clip, args.fOpts, &args.fDstTexture,
                                        batch->bounds())) {
         return;
     }
@@ -314,6 +307,7 @@
 }
 
 void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
+                               const GrClip& clip,
                                const SkMatrix& viewMatrix,
                                const GrPath* path,
                                GrPathRendering::FillType fill) {
@@ -322,15 +316,16 @@
     SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport());
 
     // Setup clip
-    GrAppliedClip clip;
-    if (!fClipMaskManager->setupClipping(pipelineBuilder, nullptr, &clip)) {
+    GrAppliedClip appliedClip;
+    if (!fClipMaskManager->setupClipping(pipelineBuilder, clip, nullptr, &appliedClip)) {
         return;
     }
+    // TODO: respect fClipBatchToBounds if we ever start computing bounds here.
 
     GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
-    if (clip.clipCoverageFragmentProcessor()) {
+    if (appliedClip.clipCoverageFragmentProcessor()) {
         arfps.set(&pipelineBuilder);
-        arfps.addCoverageFragmentProcessor(clip.clipCoverageFragmentProcessor());
+        arfps.addCoverageFragmentProcessor(appliedClip.clipCoverageFragmentProcessor());
     }
 
     GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
@@ -339,9 +334,9 @@
     GrBatch* batch = GrStencilPathBatch::Create(viewMatrix,
                                                 pipelineBuilder.isHWAntialias(),
                                                 fill,
-                                                clip.hasStencilClip(),
+                                                appliedClip.hasStencilClip(),
                                                 stencilAttachment->bits(),
-                                                clip.scissorState(),
+                                                appliedClip.scissorState(),
                                                 pipelineBuilder.getRenderTarget(),
                                                 path);
     this->recordBatch(batch);
@@ -383,7 +378,7 @@
         SkAutoTUnref<GrDrawBatch> batch(
                 GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(), scalarRect,
                                                     nullptr, nullptr));
-        this->drawBatch(pipelineBuilder, batch);
+        this->drawBatch(pipelineBuilder, GrClip::WideOpen(), batch);
     } else {
         GrBatch* batch = new GrClearBatch(*rect, color, renderTarget);
         this->recordBatch(batch);
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 9deacc2..2456558 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -105,7 +105,7 @@
      */
     const GrCaps* caps() const { return fGpu->caps(); }
 
-    void drawBatch(const GrPipelineBuilder&, GrDrawBatch*, const SkIRect* scissorRect = nullptr);
+    void drawBatch(const GrPipelineBuilder&, const GrClip&, GrDrawBatch*);
 
     /**
      * Draws path into the stencil buffer. The fill must be either even/odd or
@@ -113,8 +113,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 SkMatrix& viewMatrix, const GrPath*,
-                     GrPathRendering::FillType);
+    void stencilPath(const GrPipelineBuilder&, const GrClip&, const SkMatrix& viewMatrix,
+                     const GrPath*, GrPathRendering::FillType);
 
     /**
      * Clear the passed in render target. Ignores the GrPipelineBuilder and clip. Clears the whole
@@ -217,6 +217,7 @@
     // but couldn't be made. Otherwise, returns true.  This method needs to be protected because it
     // needs to be accessed by GLPrograms to setup a correct drawstate
     bool setupDstReadIfNecessary(const GrPipelineBuilder&,
+        const GrClip&,
         const GrPipelineOptimizations& optimizations,
         GrXferProcessor::DstTexture*,
         const SkRect& batchBounds);
@@ -241,6 +242,7 @@
     SkTDArray<GrDrawTarget*>                    fDependencies;
     GrRenderTarget*                             fRenderTarget;
 
+    bool                                        fClipBatchToBounds;
     bool                                        fDrawBatchBounds;
     int                                         fMaxBatchLookback;
     int                                         fMaxBatchLookahead;
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index a7609db..39f9ad2 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -111,6 +111,7 @@
      * fTarget                The target that the path will be rendered to
      * fResourceProvider      The resource provider for creating gpu resources to render the path
      * fPipelineBuilder       The pipelineBuilder
+     * fClip                  The clip
      * fColor                 Color to render with
      * fViewMatrix            The viewMatrix
      * fPath                  the path to draw.
@@ -122,6 +123,7 @@
         GrDrawTarget*               fTarget;
         GrResourceProvider*         fResourceProvider;
         GrPipelineBuilder*          fPipelineBuilder;
+        const GrClip*               fClip;
         GrColor                     fColor;
         const SkMatrix*             fViewMatrix;
         const SkPath*               fPath;
@@ -133,6 +135,7 @@
             SkASSERT(fTarget);
             SkASSERT(fResourceProvider);
             SkASSERT(fPipelineBuilder);
+            SkASSERT(fClip);
             SkASSERT(fViewMatrix);
             SkASSERT(fPath);
             SkASSERT(fStyle);
@@ -178,6 +181,7 @@
         GrDrawTarget*       fTarget;
         GrResourceProvider* fResourceProvider;
         GrPipelineBuilder*  fPipelineBuilder;
+        const GrClip*       fClip;
         const SkMatrix*     fViewMatrix;
         const SkPath*       fPath;
 
diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp
index 4731cbb..fd97e58 100644
--- a/src/gpu/GrPipelineBuilder.cpp
+++ b/src/gpu/GrPipelineBuilder.cpp
@@ -22,7 +22,7 @@
     SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
 }
 
-GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, GrRenderTarget* rt, const GrClip& clip)
+GrPipelineBuilder::GrPipelineBuilder(const GrPaint& paint, GrRenderTarget* rt)
     : GrPipelineBuilder() {
     SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
 
@@ -38,8 +38,6 @@
 
     this->setRenderTarget(rt);
 
-    fClip = clip;
-
     this->setState(GrPipelineBuilder::kHWAntialias_Flag,
                    rt->isUnifiedMultisampled() && paint.isAntiAlias());
     this->setState(GrPipelineBuilder::kDisableOutputConversionToSRGB_Flag,
diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h
index 18f817b..0104be7 100644
--- a/src/gpu/GrPipelineBuilder.h
+++ b/src/gpu/GrPipelineBuilder.h
@@ -10,7 +10,6 @@
 
 #include "GrBlend.h"
 #include "GrCaps.h"
-#include "GrClip.h"
 #include "GrGpuResourceRef.h"
 #include "GrProcOptInfo.h"
 #include "GrRenderTarget.h"
@@ -37,7 +36,7 @@
      * no GrPaint equivalents are set to default values with the exception of vertex attribute state
      * which is unmodified by this function and clipping which will be enabled.
      */
-    GrPipelineBuilder(const GrPaint&, GrRenderTarget*, const GrClip&);
+    GrPipelineBuilder(const GrPaint&, GrRenderTarget*);
 
     virtual ~GrPipelineBuilder();
 
@@ -322,9 +321,6 @@
 
     bool usePLSDstRead(const GrDrawBatch* batch) const;
 
-    void setClip(const GrClip& clip) { fClip = clip; }
-    const GrClip& clip() const { return fClip; }
-
 private:
     // Some of the auto restore objects assume that no effects are removed during their lifetime.
     // This is used to assert that this condition holds.
@@ -339,7 +335,6 @@
     mutable SkAutoTUnref<const GrXPFactory> fXPFactory;
     FragmentProcessorArray                  fColorFragmentProcessors;
     FragmentProcessorArray                  fCoverageFragmentProcessors;
-    GrClip                                  fClip;
 
     friend class GrPipeline;
     friend class GrDrawTarget;
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 937b343..c89c58e 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -322,6 +322,7 @@
 void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
                                               GrDrawTarget* target,
                                               GrPipelineBuilder* pipelineBuilder,
+                                              const GrClip& clip,
                                               GrColor color,
                                               const SkMatrix& viewMatrix,
                                               const SkIRect& rect) {
@@ -351,5 +352,5 @@
 
     SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, SkMatrix::I(),
                                                                         dstRect, nullptr, &invert));
-    target->drawBatch(*pipelineBuilder, batch);
+    target->drawBatch(*pipelineBuilder, clip, batch);
 }
diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h
index ee38ab7..63d7d64 100644
--- a/src/gpu/GrSWMaskHelper.h
+++ b/src/gpu/GrSWMaskHelper.h
@@ -94,6 +94,7 @@
     static void DrawToTargetWithPathMask(GrTexture* texture,
                                          GrDrawTarget* target,
                                          GrPipelineBuilder* pipelineBuilder,
+                                         const GrClip&,
                                          GrColor,
                                          const SkMatrix& viewMatrix,
                                          const SkIRect& rect);
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index dc0dbd2..d964e1f 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -22,6 +22,7 @@
 // path bounds will be a subset of the clip bounds. returns false if
 // path bounds would be empty.
 bool get_path_and_clip_bounds(const GrPipelineBuilder* pipelineBuilder,
+                              const GrClip& clip,
                               const SkPath& path,
                               const SkMatrix& matrix,
                               SkIRect* devPathBounds,
@@ -32,7 +33,7 @@
         return false;
     }
 
-    pipelineBuilder->clip().getConservativeBounds(rt->width(), rt->height(), devClipBounds);
+    clip.getConservativeBounds(rt->width(), rt->height(), devClipBounds);
 
     if (devClipBounds->isEmpty()) {
         *devPathBounds = SkIRect::MakeWH(rt->width(), rt->height());
@@ -60,17 +61,19 @@
 ////////////////////////////////////////////////////////////////////////////////
 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, batch);
+    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,
@@ -84,22 +87,22 @@
     if (devClipBounds.fTop < devPathBounds.fTop) {
         rect.iset(devClipBounds.fLeft, devClipBounds.fTop,
                   devClipBounds.fRight, devPathBounds.fTop);
-        draw_non_aa_rect(target, *pipelineBuilder, color, SkMatrix::I(), rect, invert);
+        draw_non_aa_rect(target, *pipelineBuilder, 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, color, SkMatrix::I(), rect, invert);
+        draw_non_aa_rect(target, *pipelineBuilder, 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, color, SkMatrix::I(), rect, invert);
+        draw_non_aa_rect(target, *pipelineBuilder, 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, color, SkMatrix::I(), rect, invert);
+        draw_non_aa_rect(target, *pipelineBuilder, clip, color, SkMatrix::I(), rect, invert);
     }
 }
 
@@ -114,10 +117,10 @@
     }
 
     SkIRect devPathBounds, devClipBounds;
-    if (!get_path_and_clip_bounds(args.fPipelineBuilder, *args.fPath,
+    if (!get_path_and_clip_bounds(args.fPipelineBuilder, *args.fClip, *args.fPath,
                                   *args.fViewMatrix, &devPathBounds, &devClipBounds)) {
         if (args.fPath->isInverseFillType()) {
-            draw_around_inv_path(args.fTarget, args.fPipelineBuilder, args.fColor,
+            draw_around_inv_path(args.fTarget, args.fPipelineBuilder, *args.fClip, args.fColor,
                                  *args.fViewMatrix, devClipBounds, devPathBounds);
         }
         return true;
@@ -132,11 +135,12 @@
     }
 
     GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fTarget, args.fPipelineBuilder,
-                                             args.fColor, *args.fViewMatrix, devPathBounds);
+                                             *args.fClip, args.fColor, *args.fViewMatrix,
+                                             devPathBounds);
 
     if (args.fPath->isInverseFillType()) {
-        draw_around_inv_path(args.fTarget, args.fPipelineBuilder, args.fColor, *args.fViewMatrix,
-                             devClipBounds, devPathBounds);
+        draw_around_inv_path(args.fTarget, args.fPipelineBuilder, *args.fClip, args.fColor,
+                             *args.fViewMatrix, devClipBounds, devPathBounds);
     }
 
     return true;
diff --git a/src/gpu/batches/GrAAConvexPathRenderer.cpp b/src/gpu/batches/GrAAConvexPathRenderer.cpp
index f557c9b..ffb206a 100644
--- a/src/gpu/batches/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAAConvexPathRenderer.cpp
@@ -1006,7 +1006,7 @@
     geometry.fPath = *args.fPath;
 
     SkAutoTUnref<GrDrawBatch> batch(AAConvexPathBatch::Create(geometry));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
+    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
 
     return true;
 
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
index d6ac346..44b7ac0 100644
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp
@@ -564,7 +564,7 @@
                                                                      *args.fViewMatrix, fAtlas,
                                                                      &fPathCache, &fPathList,
                                                                      args.fGammaCorrect));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
+    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
 
     return true;
 }
diff --git a/src/gpu/batches/GrAAHairLinePathRenderer.cpp b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
index db4bbdf..556e251 100644
--- a/src/gpu/batches/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/batches/GrAAHairLinePathRenderer.cpp
@@ -966,11 +966,11 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),"GrAAHairlinePathRenderer::onDrawPath");
     SkIRect devClipBounds;
     GrRenderTarget* rt = args.fPipelineBuilder->getRenderTarget();
-    args.fPipelineBuilder->clip().getConservativeBounds(rt->width(), rt->height(), &devClipBounds);
+    args.fClip->getConservativeBounds(rt->width(), rt->height(), &devClipBounds);
 
     SkAutoTUnref<GrDrawBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, *args.fPath,
                                                           *args.fStyle, devClipBounds));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
+    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
 
     return true;
 }
diff --git a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
index 91d3338..97a17c9 100644
--- a/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/batches/GrAALinearizingConvexPathRenderer.cpp
@@ -335,7 +335,7 @@
     geometry.fMiterLimit = args.fStyle->strokeRec().getMiter();
 
     SkAutoTUnref<GrDrawBatch> batch(AAFlatteningConvexPathBatch::Create(geometry));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
+    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
 
     return true;
 }
diff --git a/src/gpu/batches/GrDashLinePathRenderer.cpp b/src/gpu/batches/GrDashLinePathRenderer.cpp
index 8cb8046..165464f 100644
--- a/src/gpu/batches/GrDashLinePathRenderer.cpp
+++ b/src/gpu/batches/GrDashLinePathRenderer.cpp
@@ -33,6 +33,6 @@
         return false;
     }
 
-    args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
+    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
     return true;
 }
diff --git a/src/gpu/batches/GrDefaultPathRenderer.cpp b/src/gpu/batches/GrDefaultPathRenderer.cpp
index 747be2d..c29db53 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.cpp
+++ b/src/gpu/batches/GrDefaultPathRenderer.cpp
@@ -419,6 +419,7 @@
 
 bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
                                              GrPipelineBuilder* pipelineBuilder,
+                                             const GrClip& clip,
                                              GrColor color,
                                              const SkMatrix& viewMatrix,
                                              const SkPath& path,
@@ -573,7 +574,7 @@
             SkAutoTUnref<GrDrawBatch> batch(
                     GrRectBatchFactory::CreateNonAAFill(color, viewM, bounds, nullptr,
                                                         &localMatrix));
-            target->drawBatch(*pipelineBuilder, batch);
+            target->drawBatch(*pipelineBuilder, clip, batch);
         } else {
             if (passCount > 1) {
                 pipelineBuilder->setDisableColorXPFactory();
@@ -588,7 +589,7 @@
                                                                      viewMatrix, isHairline,
                                                                      devBounds));
 
-            target->drawBatch(*pipelineBuilder, batch);
+            target->drawBatch(*pipelineBuilder, clip, batch);
         }
     }
     return true;
@@ -606,6 +607,7 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(), "GrDefaultPathRenderer::onDrawPath");
     return this->internalDrawPath(args.fTarget,
                                   args.fPipelineBuilder,
+                                  *args.fClip,
                                   args.fColor,
                                   *args.fViewMatrix,
                                   *args.fPath,
@@ -617,8 +619,8 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),"GrDefaultPathRenderer::onStencilPath");
     SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
     SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
-    this->internalDrawPath(args.fTarget, args.fPipelineBuilder, GrColor_WHITE, *args.fViewMatrix,
-                           *args.fPath, GrStyle::SimpleFill(), true);
+    this->internalDrawPath(args.fTarget, args.fPipelineBuilder, *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 8a74d3a..6faf3ea 100644
--- a/src/gpu/batches/GrDefaultPathRenderer.h
+++ b/src/gpu/batches/GrDefaultPathRenderer.h
@@ -32,6 +32,7 @@
 
     bool internalDrawPath(GrDrawTarget*,
                           GrPipelineBuilder*,
+                          const GrClip&,
                           GrColor,
                           const SkMatrix& viewMatrix,
                           const SkPath&,
diff --git a/src/gpu/batches/GrMSAAPathRenderer.cpp b/src/gpu/batches/GrMSAAPathRenderer.cpp
index 8b1319b..2072175 100644
--- a/src/gpu/batches/GrMSAAPathRenderer.cpp
+++ b/src/gpu/batches/GrMSAAPathRenderer.cpp
@@ -568,6 +568,7 @@
 
 bool GrMSAAPathRenderer::internalDrawPath(GrDrawTarget* target,
                                           GrPipelineBuilder* pipelineBuilder,
+                                          const GrClip& clip,
                                           GrColor color,
                                           const SkMatrix& viewMatrix,
                                           const SkPath& path,
@@ -676,7 +677,7 @@
             SkAutoTUnref<GrDrawBatch> batch(
                     GrRectBatchFactory::CreateNonAAFill(color, viewM, bounds, nullptr,
                                                         &localMatrix));
-            target->drawBatch(*pipelineBuilder, batch);
+            target->drawBatch(*pipelineBuilder, clip, batch);
         } else {
             if (passCount > 1) {
                 pipelineBuilder->setDisableColorXPFactory();
@@ -690,7 +691,7 @@
             SkAutoTUnref<MSAAPathBatch> batch(MSAAPathBatch::Create(geometry, viewMatrix, 
                                                                     devBounds));
             if (batch->isValid()) {
-                target->drawBatch(*pipelineBuilder, batch);
+                target->drawBatch(*pipelineBuilder, clip, batch);
             }
             else {
                 return false;
@@ -728,6 +729,7 @@
     }
     return this->internalDrawPath(args.fTarget,
                                   args.fPipelineBuilder,
+                                  *args.fClip,
                                   args.fColor,
                                   *args.fViewMatrix,
                                   *path,
@@ -738,8 +740,8 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),"GrMSAAPathRenderer::onStencilPath");
     SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
     SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
-    this->internalDrawPath(args.fTarget, args.fPipelineBuilder, GrColor_WHITE, *args.fViewMatrix,
-                           *args.fPath, true);
+    this->internalDrawPath(args.fTarget, args.fPipelineBuilder, *args.fClip, GrColor_WHITE,
+                           *args.fViewMatrix, *args.fPath, true);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/batches/GrMSAAPathRenderer.h b/src/gpu/batches/GrMSAAPathRenderer.h
index 434a962..53d0b1d 100644
--- a/src/gpu/batches/GrMSAAPathRenderer.h
+++ b/src/gpu/batches/GrMSAAPathRenderer.h
@@ -23,6 +23,7 @@
 
     bool internalDrawPath(GrDrawTarget*,
                           GrPipelineBuilder*,
+                          const GrClip&,
                           GrColor,
                           const SkMatrix& viewMatrix,
                           const SkPath&,
diff --git a/src/gpu/batches/GrPLSPathRenderer.cpp b/src/gpu/batches/GrPLSPathRenderer.cpp
index c26b4c0..e698894 100644
--- a/src/gpu/batches/GrPLSPathRenderer.cpp
+++ b/src/gpu/batches/GrPLSPathRenderer.cpp
@@ -985,7 +985,7 @@
     geometry.fPath = *args.fPath;
 
     SkAutoTUnref<GrDrawBatch> batch(PLSPathBatch::Create(geometry));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
+    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
 
     SkDEBUGCODE(inPLSDraw = false;)
     return true;
diff --git a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
index af0c397..78ca31a 100644
--- a/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/batches/GrStencilAndCoverPathRenderer.cpp
@@ -69,7 +69,8 @@
                               "GrStencilAndCoverPathRenderer::onStencilPath");
     SkASSERT(!args.fPath->isInverseFillType());
     SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, *args.fPath, GrStyle::SimpleFill()));
-    args.fTarget->stencilPath(*args.fPipelineBuilder, *args.fViewMatrix, p, p->getFillType());
+    args.fTarget->stencilPath(*args.fPipelineBuilder, *args.fClip, *args.fViewMatrix, p,
+                              p->getFillType());
 }
 
 bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
@@ -107,7 +108,7 @@
         pipelineBuilder->setUserStencil(&kInvertedCoverPass);
 
         // fake inverse with a stencil and cover
-        args.fTarget->stencilPath(*pipelineBuilder, viewMatrix, p, p->getFillType());
+        args.fTarget->stencilPath(*pipelineBuilder, *args.fClip, viewMatrix, p, p->getFillType());
 
         SkMatrix invert = SkMatrix::I();
         SkRect bounds =
@@ -134,7 +135,7 @@
         SkAutoTUnref<GrDrawBatch> batch(
                 GrRectBatchFactory::CreateNonAAFill(args.fColor, viewM, bounds, nullptr,
                                                     &invert));
-        args.fTarget->drawBatch(*pipelineBuilder, batch);
+        args.fTarget->drawBatch(*pipelineBuilder, *args.fClip, batch);
     } else {
         static constexpr GrUserStencilSettings kCoverPass(
             GrUserStencilSettings::StaticInit<
@@ -149,7 +150,7 @@
         pipelineBuilder->setUserStencil(&kCoverPass);
         SkAutoTUnref<GrDrawBatch> batch(
                 GrDrawPathBatch::Create(viewMatrix, args.fColor, p->getFillType(), p));
-        args.fTarget->drawBatch(*pipelineBuilder, batch);
+        args.fTarget->drawBatch(*pipelineBuilder, *args.fClip, batch);
     }
 
     pipelineBuilder->disableUserStencil();
diff --git a/src/gpu/batches/GrTessellatingPathRenderer.cpp b/src/gpu/batches/GrTessellatingPathRenderer.cpp
index 728ec74..e697f78 100644
--- a/src/gpu/batches/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/batches/GrTessellatingPathRenderer.cpp
@@ -287,7 +287,7 @@
     }
 
     SkIRect clipBoundsI;
-    args.fPipelineBuilder->clip().getConservativeBounds(rt->width(), rt->height(), &clipBoundsI);
+    args.fClip->getConservativeBounds(rt->width(), rt->height(), &clipBoundsI);
     SkRect clipBounds = SkRect::Make(clipBoundsI);
     SkMatrix vmi;
     if (!args.fViewMatrix->invert(&vmi)) {
@@ -297,7 +297,7 @@
     SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, *args.fPath,
                                                                   *args.fStyle, *args.fViewMatrix,
                                                                   clipBounds));
-    args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
+    args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
 
     return true;
 }
diff --git a/src/gpu/text/GrAtlasTextBlob.cpp b/src/gpu/text/GrAtlasTextBlob.cpp
index 7d807da..ed44ed5 100644
--- a/src/gpu/text/GrAtlasTextBlob.cpp
+++ b/src/gpu/text/GrAtlasTextBlob.cpp
@@ -300,8 +300,8 @@
 
 inline
 void GrAtlasTextBlob::flushRun(GrDrawContext* dc, GrPipelineBuilder* pipelineBuilder,
-                               int run, const SkMatrix& viewMatrix, SkScalar x, SkScalar y,
-                               GrColor color,
+                               const GrClip& clip, int run, const SkMatrix& viewMatrix, SkScalar x,
+                               SkScalar y, GrColor color,
                                const SkPaint& skPaint, const SkSurfaceProps& props,
                                const GrDistanceFieldAdjustTable* distanceAdjustTable,
                                GrBatchFontCache* cache) {
@@ -317,7 +317,7 @@
                                                           skPaint, props,
                                                           distanceAdjustTable, dc->isGammaCorrect(),
                                                           cache));
-        dc->drawBatch(pipelineBuilder, batch);
+        dc->drawBatch(pipelineBuilder, clip, batch);
     }
 }
 
@@ -416,7 +416,7 @@
                                   SkScalar x, SkScalar y) {
     // We loop through the runs of the blob, flushing each.  If any run is too large, then we flush
     // it as paths
-    GrPipelineBuilder pipelineBuilder(grPaint, dc->accessRenderTarget(), clip);
+    GrPipelineBuilder pipelineBuilder(grPaint, dc->accessRenderTarget());
 
     GrColor color = grPaint.getColor();
 
@@ -427,7 +427,7 @@
                                   drawFilter, viewMatrix, clipBounds, x, y);
             continue;
         }
-        this->flushRun(dc, &pipelineBuilder, run, viewMatrix, x, y, color, skPaint, props,
+        this->flushRun(dc, &pipelineBuilder, clip, run, viewMatrix, x, y, color, skPaint, props,
                        distanceAdjustTable, context->getBatchFontCache());
     }
 
@@ -445,11 +445,11 @@
                                      const SkMatrix& viewMatrix,
                                      const SkIRect& clipBounds,
                                      SkScalar x, SkScalar y) {
-    GrPipelineBuilder pipelineBuilder(grPaint, dc->accessRenderTarget(), clip);
+    GrPipelineBuilder pipelineBuilder(grPaint, dc->accessRenderTarget());
 
     GrColor color = grPaint.getColor();
     for (int run = 0; run < fRunCount; run++) {
-        this->flushRun(dc, &pipelineBuilder, run, viewMatrix, x, y, color, skPaint, props,
+        this->flushRun(dc, &pipelineBuilder, clip, run, viewMatrix, x, y, color, skPaint, props,
                        distanceAdjustTable, context->getBatchFontCache());
     }
 
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h
index 084de62..e0e9bb8 100644
--- a/src/gpu/text/GrAtlasTextBlob.h
+++ b/src/gpu/text/GrAtlasTextBlob.h
@@ -289,7 +289,7 @@
     void appendLargeGlyph(GrGlyph* glyph, GrFontScaler* scaler, const SkGlyph& skGlyph,
                           SkScalar x, SkScalar y, SkScalar scale, bool applyVM);
 
-    inline void flushRun(GrDrawContext* dc, GrPipelineBuilder* pipelineBuilder,
+    inline void flushRun(GrDrawContext* dc, GrPipelineBuilder* pipelineBuilder, const GrClip&,
                          int run, const SkMatrix& viewMatrix, SkScalar x, SkScalar y, GrColor color,
                          const SkPaint& skPaint, const SkSurfaceProps& props,
                          const GrDistanceFieldAdjustTable* distanceAdjustTable,
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.cpp b/src/gpu/text/GrStencilAndCoverTextContext.cpp
index 8600582..eb6abb3 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/text/GrStencilAndCoverTextContext.cpp
@@ -82,9 +82,9 @@
     } else if (this->canDraw(skPaint, viewMatrix)) {
         if (skPaint.getTextSize() > 0) {
             TextRun run(skPaint);
-            GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip);
+            GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget());
             run.setText(text, byteLength, x, y);
-            run.draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, props, 0, 0,
+            run.draw(context, dc, &pipelineBuilder, clip, paint.getColor(), viewMatrix, props, 0, 0,
                      clipBounds, fFallbackTextContext, skPaint);
         }
         return;
@@ -117,9 +117,9 @@
     } else if (this->canDraw(skPaint, viewMatrix)) {
         if (skPaint.getTextSize() > 0) {
             TextRun run(skPaint);
-            GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip);
+            GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget());
             run.setPosText(text, byteLength, pos, scalarsPerPosition, offset);
-            run.draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, props, 0, 0,
+            run.draw(context, dc, &pipelineBuilder, clip, paint.getColor(), viewMatrix, props, 0, 0,
                      clipBounds, fFallbackTextContext, skPaint);
         }
         return;
@@ -225,11 +225,11 @@
     }
 
     const TextBlob& blob = this->findOrCreateTextBlob(skBlob, skPaint);
-    GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget(), clip);
+    GrPipelineBuilder pipelineBuilder(paint, dc->accessRenderTarget());
 
     TextBlob::Iter iter(blob);
     for (TextRun* run = iter.get(); run; run = iter.next()) {
-        run->draw(context, dc, &pipelineBuilder, paint.getColor(), viewMatrix, props,  x, y,
+        run->draw(context, dc, &pipelineBuilder, clip, paint.getColor(), viewMatrix, props,  x, y,
                   clipBounds, fFallbackTextContext, skPaint);
         run->releaseGlyphCache();
     }
@@ -597,6 +597,7 @@
 void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
                                                  GrDrawContext* dc,
                                                  GrPipelineBuilder* pipelineBuilder,
+                                                 const GrClip& clip,
                                                  GrColor color,
                                                  const SkMatrix& viewMatrix,
                                                  const SkSurfaceProps& props,
@@ -643,7 +644,7 @@
                                          GrPathRendering::kWinding_FillType, glyphs, fInstanceData,
                                          bounds));
 
-        dc->drawBatch(pipelineBuilder, batch);
+        dc->drawBatch(pipelineBuilder, clip, batch);
     }
 
     if (fFallbackTextBlob) {
@@ -653,9 +654,8 @@
             fallbackSkPaint.setStrokeWidth(fStyle.strokeRec().getWidth() * fTextRatio);
         }
 
-        fallbackTextContext->drawTextBlob(ctx, dc, pipelineBuilder->clip(), fallbackSkPaint,
-                                          viewMatrix, props, fFallbackTextBlob, x, y, nullptr,
-                                          clipBounds);
+        fallbackTextContext->drawTextBlob(ctx, dc, clip, fallbackSkPaint, viewMatrix, props,
+                                          fFallbackTextBlob, x, y, nullptr, clipBounds);
     }
 }
 
diff --git a/src/gpu/text/GrStencilAndCoverTextContext.h b/src/gpu/text/GrStencilAndCoverTextContext.h
index 2c13ca0..64bcd4d 100644
--- a/src/gpu/text/GrStencilAndCoverTextContext.h
+++ b/src/gpu/text/GrStencilAndCoverTextContext.h
@@ -78,8 +78,8 @@
         void setPosText(const char text[], size_t byteLength, const SkScalar pos[],
                         int scalarsPerPosition, const SkPoint& offset);
 
-        void draw(GrContext*, GrDrawContext*, GrPipelineBuilder*, GrColor, const SkMatrix&,
-                  const SkSurfaceProps&,
+        void draw(GrContext*, GrDrawContext*, GrPipelineBuilder*, const GrClip&, GrColor,
+                  const SkMatrix&, const SkSurfaceProps&,
                   SkScalar x, SkScalar y, const SkIRect& clipBounds,
                   GrAtlasTextContext* fallbackTextContext, const SkPaint& originalSkPaint) const;
 
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index 2606c3f..a59cffa 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -331,9 +331,6 @@
     // dummy scissor state
     GrScissorState scissor;
 
-    // wide open clip
-    GrClip clip;
-
     SkRandom random;
     static const int NUM_TESTS = 1024;
     for (int t = 0; t < NUM_TESTS; t++) {
@@ -347,7 +344,6 @@
 
         GrPipelineBuilder pipelineBuilder;
         pipelineBuilder.setRenderTarget(rt.get());
-        pipelineBuilder.setClip(clip);
 
         SkAutoTUnref<GrDrawBatch> batch(GrRandomDrawBatch(&random, context));
         SkASSERT(batch);
@@ -387,7 +383,6 @@
             GrPipelineBuilder builder;
             builder.setXPFactory(GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref();
             builder.setRenderTarget(rt.get());
-            builder.setClip(clip);
 
             SkAutoTUnref<const GrFragmentProcessor> fp(
                 GrProcessorTestFactory<GrFragmentProcessor>::CreateIdx(i, &ptd));
diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp
index 932eb5e..62ad6e2 100644
--- a/tests/TessellatingPathRendererTests.cpp
+++ b/tests/TessellatingPathRendererTests.cpp
@@ -243,6 +243,7 @@
     GrPathRenderer::DrawPathArgs args;
     args.fTarget = dt;
     args.fPipelineBuilder = &pipelineBuilder;
+    args.fClip = &GrClip::WideOpen();
     args.fResourceProvider = rp;
     args.fColor = GrColor_WHITE;
     args.fViewMatrix = &SkMatrix::I();
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index 6f9d2c4..874567d 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -253,13 +253,15 @@
 #define RETURN_IF_ABANDONED        if (fDrawContext->fDrawingManager->abandoned()) { return; }
 
 void GrDrawContextPriv::testingOnly_drawBatch(const GrPipelineBuilder& pipelineBuilder,
-                                              GrDrawBatch* batch) {
+                                              GrDrawBatch* batch,
+                                              const GrClip* clip) {
     ASSERT_SINGLE_OWNER
     RETURN_IF_ABANDONED
     SkDEBUGCODE(fDrawContext->validate();)
     GR_AUDIT_TRAIL_AUTO_FRAME(fDrawContext->fAuditTrail, "GrDrawContext::testingOnly_drawBatch");
 
-    fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, batch);
+    const GrClip& drawClip = clip ? *clip : GrClip::WideOpen();
+    fDrawContext->getDrawTarget()->drawBatch(pipelineBuilder, drawClip, batch);
 }
 
 #undef ASSERT_SINGLE_OWNER