I'd really like to land this before the branch so speedy reviews are appreciated.

BUG=skia:

Committed: https://skia.googlesource.com/skia/+/586d5d640b19860dfbbd903a5188da1bbbe87336

Review URL: https://codereview.chromium.org/936943002
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index 2345ac1..d06df1c 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -70,9 +70,9 @@
     return !SkDraw::ShouldDrawTextAsPaths(paint, viewMatrix);
 }
 
-inline void GrBitmapTextContext::init(GrRenderTarget* rt, const GrPaint& paint,
-                                      const SkPaint& skPaint) {
-    GrTextContext::init(rt, paint, skPaint);
+inline void GrBitmapTextContext::init(GrRenderTarget* rt, const GrClip& clip,
+                                      const GrPaint& paint, const SkPaint& skPaint) {
+    GrTextContext::init(rt, clip, paint, skPaint);
 
     fStrike = NULL;
 
@@ -84,8 +84,8 @@
     fTotalVertexCount = 0;
 }
 
-void GrBitmapTextContext::onDrawText(GrRenderTarget* rt, const GrPaint& paint,
-                                     const SkPaint& skPaint,
+void GrBitmapTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
+                                     const GrPaint& paint, const SkPaint& skPaint,
                                      const SkMatrix& viewMatrix,
                                      const char text[], size_t byteLength,
                                      SkScalar x, SkScalar y) {
@@ -96,7 +96,7 @@
         return;
     }
 
-    this->init(rt, paint, skPaint);
+    this->init(rt, clip, paint, skPaint);
 
     SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
 
@@ -184,8 +184,8 @@
     this->finish();
 }
 
-void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrPaint& paint,
-                                        const SkPaint& skPaint,
+void GrBitmapTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
+                                        const GrPaint& paint, const SkPaint& skPaint,
                                         const SkMatrix& viewMatrix,
                                         const char text[], size_t byteLength,
                                         const SkScalar pos[], int scalarsPerPosition,
@@ -198,7 +198,7 @@
         return;
     }
 
-    this->init(rt, paint, skPaint);
+    this->init(rt, clip, paint, skPaint);
 
     SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
 
@@ -455,7 +455,7 @@
         SkPath tmpPath(*glyph->fPath);
         tmpPath.transform(translate);
         GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle);
-        fContext->drawPath(fRenderTarget, fPaint, SkMatrix::I(), tmpPath, strokeInfo);
+        fContext->drawPath(fRenderTarget, fClip, fPaint, SkMatrix::I(), tmpPath, strokeInfo);
 
         // remove this glyph from the vertices we need to allocate
         fTotalVertexCount -= kVerticesPerGlyph;
diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h
index c38bd07..2c50873 100644
--- a/src/gpu/GrBitmapTextContext.h
+++ b/src/gpu/GrBitmapTextContext.h
@@ -40,16 +40,16 @@
 
     bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) SK_OVERRIDE;
 
-    virtual void onDrawText(GrRenderTarget*, const GrPaint&, const SkPaint&,
+    virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
                             const SkMatrix& viewMatrix, const char text[], size_t byteLength,
                             SkScalar x, SkScalar y) SK_OVERRIDE;
-    virtual void onDrawPosText(GrRenderTarget*, const GrPaint&, const SkPaint&,
+    virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
                                const SkMatrix& viewMatrix,
                                const char text[], size_t byteLength,
                                const SkScalar pos[], int scalarsPerPosition,
                                const SkPoint& offset) SK_OVERRIDE;
 
-    void init(GrRenderTarget*, const GrPaint&, const SkPaint&);
+    void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&);
     void appendGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
     bool uploadGlyph(GrGlyph*, GrFontScaler*);
     void flush();                 // automatically called by destructor
diff --git a/src/gpu/GrClip.cpp b/src/gpu/GrClip.cpp
index 1dc6edc..63d8f51 100644
--- a/src/gpu/GrClip.cpp
+++ b/src/gpu/GrClip.cpp
@@ -21,8 +21,6 @@
 void GrClip::getConservativeBounds(int width, int height, SkIRect* devResult,
                                    bool* isIntersectionOfRects) const {
     switch (fClipType) {
-        default:
-            SkFAIL("incomplete switch\n");
         case kWideOpen_ClipType: {
             devResult->setLTRB(0, 0, width, height);
             if (isIntersectionOfRects) {
@@ -35,6 +33,15 @@
                 *isIntersectionOfRects = true;
             }
         } break;
+        case kRect_ClipType: {
+            devResult->setLTRB(SkScalarCeilToInt(this->rect().fLeft),
+                               SkScalarCeilToInt(this->rect().fTop),
+                               SkScalarCeilToInt(this->rect().fRight),
+                               SkScalarCeilToInt(this->rect().fBottom));
+            if (isIntersectionOfRects) {
+                *isIntersectionOfRects = true;
+            }
+        } break;
         case kClipStack_ClipType: {
             SkRect devBounds;
             this->clipStack()->getConservativeBounds(-this->origin().fX,
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index b28b75c..99c74e3 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -231,29 +231,47 @@
     bool ignoreClip = clip.isWideOpen(clipSpaceRTIBounds);
     if (!ignoreClip) {
         // The clip mask manager always draws with a single IRect so we special case that logic here
-        if (GrClip::kIRect_ClipType == clip.clipType()) {
-            initialState = GrReducedClip::kAllIn_InitialState;
-            clipSpaceIBounds = clip.irect();
-            SkNEW_INSERT_AT_LLIST_HEAD(&elements,
-                                       Element,
-                                       (SkRect::Make(clipSpaceIBounds),
-                                        SkRegion::kIntersect_Op, false));
-        } else {
-            clipSpaceRTIBounds.offset(clip.origin());
-            GrReducedClip::ReduceClipStack(*clip.clipStack(),
-                                           clipSpaceRTIBounds,
-                                           &elements,
-                                           &genID,
-                                           &initialState,
-                                           &clipSpaceIBounds,
-                                           &requiresAA);
-            if (elements.isEmpty()) {
-                if (GrReducedClip::kAllIn_InitialState == initialState) {
-                    ignoreClip = clipSpaceIBounds == clipSpaceRTIBounds;
-                } else {
-                    return false;
+        // Image filters just use a rect, so we also special case that logic
+        switch (clip.clipType()) {
+            case GrClip::kWideOpen_ClipType:
+                // we should have handled this case above
+                SkASSERT(false);
+            case GrClip::kIRect_ClipType: {
+                initialState = GrReducedClip::kAllIn_InitialState;
+                clipSpaceIBounds = clip.irect();
+                SkNEW_INSERT_AT_LLIST_HEAD(&elements,
+                                           Element,
+                                           (SkRect::Make(clipSpaceIBounds),
+                                            SkRegion::kIntersect_Op, false));
+            } break;
+            case GrClip::kRect_ClipType: {
+                initialState = GrReducedClip::kAllIn_InitialState;
+                clipSpaceIBounds.setLTRB(SkScalarCeilToInt(clip.rect().fLeft),
+                                         SkScalarCeilToInt(clip.rect().fTop),
+                                         SkScalarCeilToInt(clip.rect().fRight),
+                                         SkScalarCeilToInt(clip.rect().fBottom));
+                SkNEW_INSERT_AT_LLIST_HEAD(&elements,
+                                           Element,
+                                           (SkRect::Make(clipSpaceIBounds),
+                                            SkRegion::kIntersect_Op, false));
+            } break;
+            case GrClip::kClipStack_ClipType: {
+                clipSpaceRTIBounds.offset(clip.origin());
+                GrReducedClip::ReduceClipStack(*clip.clipStack(),
+                                               clipSpaceRTIBounds,
+                                               &elements,
+                                               &genID,
+                                               &initialState,
+                                               &clipSpaceIBounds,
+                                               &requiresAA);
+                if (elements.isEmpty()) {
+                    if (GrReducedClip::kAllIn_InitialState == initialState) {
+                        ignoreClip = clipSpaceIBounds == clipSpaceRTIBounds;
+                    } else {
+                        return false;
+                    }
                 }
-            }
+            } break;
         }
     }
 
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 0395e1b..b574614 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -86,7 +86,6 @@
 
 GrContext::GrContext(const Options& opts) : fOptions(opts) {
     fGpu = NULL;
-    fClip = NULL;
     fPathRendererChain = NULL;
     fSoftwarePathRenderer = NULL;
     fResourceCache = NULL;
@@ -363,7 +362,7 @@
 
     AutoCheckFlush acf(this);
     GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::clear", this);
-    GrDrawTarget* target = this->prepareToDraw(NULL, renderTarget, NULL, &acf);
+    GrDrawTarget* target = this->prepareToDraw();
     if (NULL == target) {
         return;
     }
@@ -371,6 +370,7 @@
 }
 
 void GrContext::drawPaint(GrRenderTarget* rt,
+                          const GrClip& clip,
                           const GrPaint& origPaint,
                           const SkMatrix& viewMatrix) {
     // set rect to be big enough to fill the space, but not super-huge, so we
@@ -398,7 +398,7 @@
             return;
         }
         inverse.mapRect(&r);
-        this->drawRect(rt, *paint, viewMatrix, r);
+        this->drawRect(rt, clip, *paint, viewMatrix, r);
     } else {
         SkMatrix localMatrix;
         if (!viewMatrix.invert(&localMatrix)) {
@@ -408,7 +408,7 @@
 
         AutoCheckFlush acf(this);
         GrPipelineBuilder pipelineBuilder;
-        GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, paint, &acf);
+        GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, paint, &acf);
         if (NULL == target) {
             return;
         }
@@ -502,6 +502,7 @@
 }
 
 void GrContext::drawRect(GrRenderTarget* rt,
+                         const GrClip& clip,
                          const GrPaint& paint,
                          const SkMatrix& viewMatrix,
                          const SkRect& rect,
@@ -509,13 +510,13 @@
     if (strokeInfo && strokeInfo->isDashed()) {
         SkPath path;
         path.addRect(rect);
-        this->drawPath(rt, paint, viewMatrix, path, *strokeInfo);
+        this->drawPath(rt, clip, paint, viewMatrix, path, *strokeInfo);
         return;
     }
 
     AutoCheckFlush acf(this);
     GrPipelineBuilder pipelineBuilder;
-    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
     if (NULL == target) {
         return;
     }
@@ -529,13 +530,13 @@
         SkRect rtRect;
         pipelineBuilder.getRenderTarget()->getBoundsRect(&rtRect);
         SkRect clipSpaceRTRect = rtRect;
-        bool checkClip = fClip && GrClip::kWideOpen_ClipType != fClip->clipType();
+        bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType();
         if (checkClip) {
-            clipSpaceRTRect.offset(SkIntToScalar(this->getClip()->origin().fX),
-                                   SkIntToScalar(this->getClip()->origin().fY));
+            clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX),
+                                   SkIntToScalar(clip.origin().fY));
         }
         // Does the clip contain the entire RT?
-        if (!checkClip || fClip->clipStack()->quickContains(clipSpaceRTRect)) {
+        if (!checkClip || clip.quickContains(clipSpaceRTRect)) {
             SkMatrix invM;
             if (!viewMatrix.invert(&invM)) {
                 return;
@@ -634,6 +635,7 @@
 }
 
 void GrContext::drawNonAARectToRect(GrRenderTarget* rt,
+                                    const GrClip& clip,
                                     const GrPaint& paint,
                                     const SkMatrix& viewMatrix,
                                     const SkRect& rectToDraw,
@@ -641,7 +643,7 @@
                                     const SkMatrix* localMatrix) {
     AutoCheckFlush acf(this);
     GrPipelineBuilder pipelineBuilder;
-    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
     if (NULL == target) {
         return;
     }
@@ -681,6 +683,7 @@
 }
 
 void GrContext::drawVertices(GrRenderTarget* rt,
+                             const GrClip& clip,
                              const GrPaint& paint,
                              const SkMatrix& viewMatrix,
                              GrPrimitiveType primitiveType,
@@ -694,7 +697,7 @@
     GrPipelineBuilder pipelineBuilder;
     GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope
 
-    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
     if (NULL == target) {
         return;
     }
@@ -743,6 +746,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void GrContext::drawRRect(GrRenderTarget*rt,
+                          const GrClip& clip,
                           const GrPaint& paint,
                           const SkMatrix& viewMatrix,
                           const SkRRect& rrect,
@@ -754,13 +758,13 @@
     if (strokeInfo.isDashed()) {
         SkPath path;
         path.addRRect(rrect);
-        this->drawPath(rt, paint, viewMatrix, path, strokeInfo);
+        this->drawPath(rt, clip, paint, viewMatrix, path, strokeInfo);
         return;
     }
 
     AutoCheckFlush acf(this);
     GrPipelineBuilder pipelineBuilder;
-    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
     if (NULL == target) {
         return;
     }
@@ -787,6 +791,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void GrContext::drawDRRect(GrRenderTarget* rt,
+                           const GrClip& clip,
                            const GrPaint& paint,
                            const SkMatrix& viewMatrix,
                            const SkRRect& outer,
@@ -797,7 +802,7 @@
 
     AutoCheckFlush acf(this);
     GrPipelineBuilder pipelineBuilder;
-    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
 
     GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target);
 
@@ -822,7 +827,8 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void GrContext::drawOval(GrRenderTarget*rt,
+void GrContext::drawOval(GrRenderTarget* rt,
+                         const GrClip& clip,
                          const GrPaint& paint,
                          const SkMatrix& viewMatrix,
                          const SkRect& oval,
@@ -834,13 +840,13 @@
     if (strokeInfo.isDashed()) {
         SkPath path;
         path.addOval(oval);
-        this->drawPath(rt, paint, viewMatrix, path, strokeInfo);
+        this->drawPath(rt, clip, paint, viewMatrix, path, strokeInfo);
         return;
     }
 
     AutoCheckFlush acf(this);
     GrPipelineBuilder pipelineBuilder;
-    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
     if (NULL == target) {
         return;
     }
@@ -918,6 +924,7 @@
 }
 
 void GrContext::drawPath(GrRenderTarget* rt,
+                         const GrClip& clip,
                          const GrPaint& paint,
                          const SkMatrix& viewMatrix,
                          const SkPath& path,
@@ -925,7 +932,7 @@
 
     if (path.isEmpty()) {
        if (path.isInverseFillType()) {
-           this->drawPaint(rt, paint, viewMatrix);
+           this->drawPaint(rt, clip, paint, viewMatrix);
        }
        return;
     }
@@ -936,7 +943,7 @@
         if (path.isLine(pts)) {
             AutoCheckFlush acf(this);
             GrPipelineBuilder pipelineBuilder;
-            GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf);
+            GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
             if (NULL == target) {
                 return;
             }
@@ -953,11 +960,11 @@
         GrStrokeInfo newStrokeInfo(strokeInfo, false);
         SkStrokeRec* stroke = newStrokeInfo.getStrokeRecPtr();
         if (SkDashPath::FilterDashPath(effectPath.init(), path, stroke, NULL, info)) {
-            this->drawPath(rt, paint, viewMatrix, *effectPath.get(), newStrokeInfo);
+            this->drawPath(rt, clip, paint, viewMatrix, *effectPath.get(), newStrokeInfo);
             return;
         }
 
-        this->drawPath(rt, paint, viewMatrix, path, newStrokeInfo);
+        this->drawPath(rt, clip, paint, viewMatrix, path, newStrokeInfo);
         return;
     }
 
@@ -968,7 +975,7 @@
     // OK.
     AutoCheckFlush acf(this);
     GrPipelineBuilder pipelineBuilder;
-    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, &paint, &acf);
+    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
     if (NULL == target) {
         return;
     }
@@ -1197,7 +1204,10 @@
     // drawing a rect to the render target.
     // The bracket ensures we pop the stack if we wind up flushing below.
     {
-        GrDrawTarget* drawTarget = this->prepareToDraw(NULL, NULL, NULL, NULL);
+        GrDrawTarget* drawTarget = this->prepareToDraw();
+        if (!drawTarget) {
+            return false;
+        }
         GrDrawTarget::AutoGeometryPush agp(drawTarget);
 
         GrPipelineBuilder pipelineBuilder;
@@ -1383,7 +1393,7 @@
     SkASSERT(renderTarget);
     ASSERT_OWNED_RESOURCE(renderTarget);
     AutoCheckFlush acf(this);
-    GrDrawTarget* target = this->prepareToDraw(NULL, NULL, NULL, NULL);
+    GrDrawTarget* target = this->prepareToDraw();
     if (NULL == target) {
         return;
     }
@@ -1401,7 +1411,7 @@
     // Since we're going to the draw target and not GPU, no need to check kNoFlush
     // here.
 
-    GrDrawTarget* target = this->prepareToDraw(NULL, NULL, NULL, NULL);
+    GrDrawTarget* target = this->prepareToDraw();
     if (NULL == target) {
         return;
     }
@@ -1420,16 +1430,22 @@
 
 GrDrawTarget* GrContext::prepareToDraw(GrPipelineBuilder* pipelineBuilder,
                                        GrRenderTarget* rt,
+                                       const GrClip& clip,
                                        const GrPaint* paint,
                                        const AutoCheckFlush* acf) {
     if (NULL == fGpu) {
         return NULL;
     }
 
-    if (pipelineBuilder) {
-        ASSERT_OWNED_RESOURCE(rt);
-        SkASSERT(rt && paint && acf);
-        pipelineBuilder->setFromPaint(*paint, rt, fClip);
+    ASSERT_OWNED_RESOURCE(rt);
+    SkASSERT(rt && paint && acf);
+    pipelineBuilder->setFromPaint(*paint, rt, clip);
+    return fDrawBuffer;
+}
+
+GrDrawTarget* GrContext::prepareToDraw() {
+    if (NULL == fGpu) {
+        return NULL;
     }
     return fDrawBuffer;
 }
@@ -1513,7 +1529,7 @@
 }
 
 GrDrawTarget* GrContext::getTextTarget() {
-    return this->prepareToDraw(NULL, NULL, NULL, NULL);
+    return this->prepareToDraw();
 }
 
 const GrIndexBuffer* GrContext::getQuadIndexBuffer() const {
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index d2b34e6..47d408f 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -112,9 +112,9 @@
     return true;
 }
 
-inline void GrDistanceFieldTextContext::init(GrRenderTarget* rt, const GrPaint& paint,
-                                             const SkPaint& skPaint) {
-    GrTextContext::init(rt, paint, skPaint);
+inline void GrDistanceFieldTextContext::init(GrRenderTarget* rt, const GrClip& clip,
+                                             const GrPaint& paint, const SkPaint& skPaint) {
+    GrTextContext::init(rt, clip, paint, skPaint);
 
     fStrike = NULL;
 
@@ -207,7 +207,8 @@
     }
 }
 
-void GrDistanceFieldTextContext::onDrawText(GrRenderTarget* rt, const GrPaint& paint,
+void GrDistanceFieldTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
+                                            const GrPaint& paint,
                                             const SkPaint& skPaint, const SkMatrix& viewMatrix,
                                             const char text[], size_t byteLength,
                                             SkScalar x, SkScalar y) {
@@ -268,11 +269,12 @@
     y -= alignY;
     SkPoint offset = SkPoint::Make(x, y);
 
-    this->drawPosText(rt, paint, skPaint, viewMatrix, text, byteLength, positions.begin(), 2,
+    this->drawPosText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, positions.begin(), 2,
                       offset);
 }
 
-void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrPaint& paint,
+void GrDistanceFieldTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
+                                               const GrPaint& paint,
                                                const SkPaint& skPaint, const SkMatrix& viewMatrix,
                                                const char text[], size_t byteLength,
                                                const SkScalar pos[], int scalarsPerPosition,
@@ -287,7 +289,7 @@
     }
 
     fViewMatrix = viewMatrix;
-    this->init(rt, paint, skPaint);
+    this->init(rt, clip, paint, skPaint);
 
     SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
 
@@ -362,7 +364,7 @@
     this->finish();
     
     if (fallbackTxt.count() > 0) {
-        fFallbackTextContext->drawPosText(rt, paint, skPaint, viewMatrix, fallbackTxt.begin(),
+        fFallbackTextContext->drawPosText(rt, clip, paint, skPaint, viewMatrix, fallbackTxt.begin(),
                                           fallbackTxt.count(), fallbackPos.begin(),
                                           scalarsPerPosition, offset);
     }
@@ -571,7 +573,7 @@
             tmpPath.transform(ctm);
 
             GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle);
-            fContext->drawPath(fRenderTarget, fPaint, fViewMatrix, tmpPath, strokeInfo);
+            fContext->drawPath(fRenderTarget, fClip, fPaint, fViewMatrix, tmpPath, strokeInfo);
 
             // remove this glyph from the vertices we need to allocate
             fTotalVertexCount -= kVerticesPerGlyph;
diff --git a/src/gpu/GrDistanceFieldTextContext.h b/src/gpu/GrDistanceFieldTextContext.h
index ecba340..129c6e9 100644
--- a/src/gpu/GrDistanceFieldTextContext.h
+++ b/src/gpu/GrDistanceFieldTextContext.h
@@ -52,17 +52,17 @@
 
     bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) SK_OVERRIDE;
 
-    virtual void onDrawText(GrRenderTarget*, const GrPaint&, const SkPaint&,
+    virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
                             const SkMatrix& viewMatrix,
                             const char text[], size_t byteLength,
                             SkScalar x, SkScalar y) SK_OVERRIDE;
-    virtual void onDrawPosText(GrRenderTarget*, const GrPaint&, const SkPaint&,
+    virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
                                const SkMatrix& viewMatrix,
                                const char text[], size_t byteLength,
                                const SkScalar pos[], int scalarsPerPosition,
                                const SkPoint& offset) SK_OVERRIDE;
 
-    void init(GrRenderTarget*, const GrPaint&, const SkPaint&);
+    void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&);
     bool appendGlyph(GrGlyph::PackedID, SkScalar left, SkScalar top, GrFontScaler*);
     bool uploadGlyph(GrGlyph*, GrFontScaler*);
     void setupCoverageEffect(const SkColor& filteredColor);
diff --git a/src/gpu/GrPipelineBuilder.cpp b/src/gpu/GrPipelineBuilder.cpp
index faa20b1..89bf15f 100644
--- a/src/gpu/GrPipelineBuilder.cpp
+++ b/src/gpu/GrPipelineBuilder.cpp
@@ -47,7 +47,7 @@
     return *this;
 }
 
-void GrPipelineBuilder::setFromPaint(const GrPaint& paint, GrRenderTarget* rt, const GrClip* clip) {
+void GrPipelineBuilder::setFromPaint(const GrPaint& paint, GrRenderTarget* rt, const GrClip& clip) {
     SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numFragmentStages());
 
     fColorStages.reset();
@@ -70,9 +70,7 @@
     fStencilSettings.setDisabled();
     fFlagBits = 0;
 
-    if (clip) {
-        fClip = *clip;
-    }
+    fClip = clip;
 
     this->setState(GrPipelineBuilder::kDither_StateBit, paint.isDither());
     this->setState(GrPipelineBuilder::kHWAntialias_StateBit, paint.isAntiAlias());
diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h
index 54b06db..96807d5 100644
--- a/src/gpu/GrPipelineBuilder.h
+++ b/src/gpu/GrPipelineBuilder.h
@@ -45,7 +45,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.
      */
-    void setFromPaint(const GrPaint&, GrRenderTarget*, const GrClip*);
+    void setFromPaint(const GrPaint&, GrRenderTarget*, const GrClip&);
 
     /// @}
 
diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
index 6dbfe9f..4b121da 100644
--- a/src/gpu/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/GrStencilAndCoverTextContext.cpp
@@ -65,6 +65,7 @@
 }
 
 void GrStencilAndCoverTextContext::onDrawText(GrRenderTarget* rt,
+                                              const GrClip& clip,
                                               const GrPaint& paint,
                                               const SkPaint& skPaint,
                                               const SkMatrix& viewMatrix,
@@ -92,7 +93,7 @@
     // will turn off the use of device-space glyphs when perspective transforms
     // are in use.
 
-    this->init(rt, paint, skPaint, byteLength, kMaxAccuracy_RenderMode, viewMatrix);
+    this->init(rt, clip, paint, skPaint, byteLength, kMaxAccuracy_RenderMode, viewMatrix);
 
     // Transform our starting point.
     if (fUsingDeviceSpaceGlyphs) {
@@ -155,6 +156,7 @@
 }
 
 void GrStencilAndCoverTextContext::onDrawPosText(GrRenderTarget* rt,
+                                                 const GrClip& clip,
                                                  const GrPaint& paint,
                                                  const SkPaint& skPaint,
                                                  const SkMatrix& viewMatrix,
@@ -179,7 +181,7 @@
     // transform is not part of SkPaint::measureText API, and thus we use the
     // same glyphs as what were measured.
 
-    this->init(rt, paint, skPaint, byteLength, kMaxPerformance_RenderMode, viewMatrix);
+    this->init(rt, clip, paint, skPaint, byteLength, kMaxPerformance_RenderMode, viewMatrix);
 
     SkDrawCacheProc glyphCacheProc = fSkPaint.getDrawCacheProc();
 
@@ -232,12 +234,13 @@
 }
 
 void GrStencilAndCoverTextContext::init(GrRenderTarget* rt,
+                                        const GrClip& clip,
                                         const GrPaint& paint,
                                         const SkPaint& skPaint,
                                         size_t textByteLength,
                                         RenderMode renderMode,
                                         const SkMatrix& viewMatrix) {
-    GrTextContext::init(rt, paint, skPaint);
+    GrTextContext::init(rt, clip, paint, skPaint);
 
     fContextInitialMatrix = viewMatrix;
     fViewMatrix = viewMatrix;
@@ -442,7 +445,7 @@
             inverse.mapPoints(&fGlyphPositions[fFallbackGlyphsIdx], fallbackGlyphCount);
         }
 
-        fFallbackTextContext->drawPosText(fRenderTarget, paintFallback, skPaintFallback,
+        fFallbackTextContext->drawPosText(fRenderTarget, fClip, paintFallback, skPaintFallback,
                                           fViewMatrix, (char*)&fGlyphIndices[fFallbackGlyphsIdx],
                                           2 * fallbackGlyphCount,
                                           get_xy_scalar_array(&fGlyphPositions[fFallbackGlyphsIdx]),
diff --git a/src/gpu/GrStencilAndCoverTextContext.h b/src/gpu/GrStencilAndCoverTextContext.h
index 3b4cd9b..3753795 100644
--- a/src/gpu/GrStencilAndCoverTextContext.h
+++ b/src/gpu/GrStencilAndCoverTextContext.h
@@ -71,18 +71,18 @@
 
     bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) SK_OVERRIDE;
 
-    virtual void onDrawText(GrRenderTarget*, const GrPaint&, const SkPaint&,
+    virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
                             const SkMatrix& viewMatrix,
                             const char text[], size_t byteLength,
                             SkScalar x, SkScalar y) SK_OVERRIDE;
-    virtual void onDrawPosText(GrRenderTarget*, const GrPaint&, const SkPaint&,
+    virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
                                const SkMatrix& viewMatrix,
                                const char text[], size_t byteLength,
                                const SkScalar pos[], int scalarsPerPosition,
                                const SkPoint& offset) SK_OVERRIDE;
 
-    void init(GrRenderTarget*, const GrPaint&, const SkPaint&, size_t textByteLength, RenderMode,
-              const SkMatrix& viewMatrix);
+    void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
+              size_t textByteLength, RenderMode, const SkMatrix& viewMatrix);
     bool mapToFallbackContext(SkMatrix* inverse);
     void appendGlyph(const SkGlyph&, const SkPoint&);
     void flush();
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 895e977..cef99c6 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -7,10 +7,11 @@
 
 #include "GrTextContext.h"
 #include "GrContext.h"
+#include "GrDrawTarget.h"
+#include "GrFontScaler.h"
 
 #include "SkAutoKern.h"
 #include "SkGlyphCache.h"
-#include "GrFontScaler.h"
 
 GrTextContext::GrTextContext(GrContext* context, const SkDeviceProperties& properties) :
                             fFallbackTextContext(NULL),
@@ -21,12 +22,13 @@
     SkDELETE(fFallbackTextContext);
 }
 
-void GrTextContext::init(GrRenderTarget* rt, const GrPaint& grPaint, const SkPaint& skPaint) {
-    fClip = fContext->getClip();
+void GrTextContext::init(GrRenderTarget* rt, const GrClip& clip, const GrPaint& grPaint,
+                         const SkPaint& skPaint) {
+    fClip = clip;
 
     fRenderTarget.reset(SkRef(rt));
 
-    fClip->getConservativeBounds(fRenderTarget->width(), fRenderTarget->height(), &fClipRect);
+    fClip.getConservativeBounds(fRenderTarget->width(), fRenderTarget->height(), &fClipRect);
 
     fDrawTarget = fContext->getTextTarget();
 
@@ -34,15 +36,15 @@
     fSkPaint = skPaint;
 }
 
-bool GrTextContext::drawText(GrRenderTarget* rt, const GrPaint& paint, const SkPaint& skPaint,
-                             const SkMatrix& viewMatrix,
+bool GrTextContext::drawText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint,
+                             const SkPaint& skPaint, const SkMatrix& viewMatrix,
                              const char text[], size_t byteLength,
                              SkScalar x, SkScalar y) {
 
     GrTextContext* textContext = this;
     do {
         if (textContext->canDraw(skPaint, viewMatrix)) {
-            textContext->onDrawText(rt, paint, skPaint, viewMatrix, text, byteLength, x, y);
+            textContext->onDrawText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, x, y);
             return true;
         }
         textContext = textContext->fFallbackTextContext;
@@ -51,8 +53,8 @@
     return false;
 }
 
-bool GrTextContext::drawPosText(GrRenderTarget* rt, const GrPaint& paint, const SkPaint& skPaint,
-                                const SkMatrix& viewMatrix,
+bool GrTextContext::drawPosText(GrRenderTarget* rt, const GrClip& clip, const GrPaint& paint,
+                                const SkPaint& skPaint, const SkMatrix& viewMatrix,
                                 const char text[], size_t byteLength,
                                 const SkScalar pos[], int scalarsPerPosition,
                                 const SkPoint& offset) {
@@ -60,7 +62,7 @@
     GrTextContext* textContext = this;
     do {
         if (textContext->canDraw(skPaint, viewMatrix)) {
-            textContext->onDrawPosText(rt, paint, skPaint, viewMatrix, text, byteLength, pos,
+            textContext->onDrawPosText(rt, clip, paint, skPaint, viewMatrix, text, byteLength, pos,
                                        scalarsPerPosition, offset);
             return true;
         }
diff --git a/src/gpu/GrTextContext.h b/src/gpu/GrTextContext.h
index 581ff64..d333c63 100644
--- a/src/gpu/GrTextContext.h
+++ b/src/gpu/GrTextContext.h
@@ -15,6 +15,7 @@
 
 #include "SkPostConfig.h"
 
+class GrClip;
 class GrContext;
 class GrDrawTarget;
 class GrFontScaler;
@@ -26,9 +27,11 @@
 public:
     virtual ~GrTextContext();
 
-    bool drawText(GrRenderTarget* rt, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix,
-                  const char text[], size_t byteLength, SkScalar x, SkScalar y);
-    bool drawPosText(GrRenderTarget* rt, const GrPaint&, const SkPaint&, const SkMatrix& viewMatrix,
+    bool drawText(GrRenderTarget* rt, const GrClip&,  const GrPaint&, const SkPaint&,
+                  const SkMatrix& viewMatrix, const char text[], size_t byteLength, SkScalar x,
+                  SkScalar y);
+    bool drawPosText(GrRenderTarget* rt, const GrClip&, const GrPaint&, const SkPaint&,
+                     const SkMatrix& viewMatrix,
                      const char text[], size_t byteLength,
                      const SkScalar pos[], int scalarsPerPosition,
                      const SkPoint& offset);
@@ -39,7 +42,7 @@
     SkDeviceProperties             fDeviceProperties;
 
     SkAutoTUnref<GrRenderTarget>   fRenderTarget;
-    const GrClip*                  fClip;
+    GrClip                         fClip;
     GrDrawTarget*                  fDrawTarget;
     SkIRect                        fClipRect;
     GrPaint                        fPaint;
@@ -49,16 +52,16 @@
 
     virtual bool canDraw(const SkPaint& paint, const SkMatrix& viewMatrix) = 0;
 
-    virtual void onDrawText(GrRenderTarget*, const GrPaint&, const SkPaint&,
+    virtual void onDrawText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
                             const SkMatrix& viewMatrix, const char text[], size_t byteLength,
                             SkScalar x, SkScalar y) = 0;
-    virtual void onDrawPosText(GrRenderTarget*, const GrPaint&, const SkPaint&,
+    virtual void onDrawPosText(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&,
                                const SkMatrix& viewMatrix,
                                const char text[], size_t byteLength,
                                const SkScalar pos[], int scalarsPerPosition,
                                const SkPoint& offset) = 0;
 
-    void init(GrRenderTarget*, const GrPaint&, const SkPaint&);
+    void init(GrRenderTarget*, const GrClip&, const GrPaint&, const SkPaint&);
     void finish() { fDrawTarget = NULL; }
 
     static GrFontScaler* GetGrFontScaler(SkGlyphCache* cache);
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index d384cd1..edbb82e 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -220,10 +220,6 @@
 
     delete fTextContext;
 
-    if (fContext->getClip() == &fClipData) {
-        fContext->setClip(NULL);
-    }
-
     fRenderTarget->unref();
     fContext->unref();
 }
@@ -281,7 +277,7 @@
 
 void SkGpuDevice::onDetachFromCanvas() {
     INHERITED::onDetachFromCanvas();
-    fClipData.reset();
+    fClip.reset();
     fClipStack.reset(NULL);
 }
 
@@ -292,9 +288,7 @@
 
     SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack);
 
-    fClipData.setClipStack(fClipStack, &this->getOrigin());
-
-    fContext->setClip(&fClipData);
+    fClip.setClipStack(fClipStack, &this->getOrigin());
 
     DO_DEFERRED_CLEAR();
 }
@@ -366,7 +360,7 @@
     GrPaint grPaint;
     SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
 
-    fContext->drawPaint(fRenderTarget, grPaint, *draw.fMatrix);
+    fContext->drawPaint(fRenderTarget, fClip, grPaint, *draw.fMatrix);
 }
 
 // must be in SkCanvas::PointMode order
@@ -394,7 +388,7 @@
         path.setIsVolatile(true);
         path.moveTo(pts[0]);
         path.lineTo(pts[1]);
-        fContext->drawPath(fRenderTarget, grPaint, *draw.fMatrix, path, strokeInfo);
+        fContext->drawPath(fRenderTarget, fClip, grPaint, *draw.fMatrix, path, strokeInfo);
         return;
     }
 
@@ -409,6 +403,7 @@
     SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
 
     fContext->drawVertices(fRenderTarget,
+                           fClip,
                            grPaint,
                            *draw.fMatrix,
                            gPointMode2PrimtiveType[mode],
@@ -479,7 +474,7 @@
     GrPaint grPaint;
     SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
 
-    fContext->drawRect(fRenderTarget, grPaint, *draw.fMatrix, rect, &strokeInfo);
+    fContext->drawRect(fRenderTarget, fClip, grPaint, *draw.fMatrix, rect, &strokeInfo);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -514,6 +509,7 @@
                     if (paint.getMaskFilter()->directFilterRRectMaskGPU(fContext,
                                                                         fRenderTarget,
                                                                         &grPaint,
+                                                                        fClip,
                                                                         *draw.fMatrix,
                                                                         strokeInfo.getStrokeRec(),
                                                                         devRRect)) {
@@ -546,7 +542,7 @@
         return;
     }
 
-    fContext->drawRRect(fRenderTarget, grPaint, *draw.fMatrix, rect, strokeInfo);
+    fContext->drawRRect(fRenderTarget, fClip, grPaint, *draw.fMatrix, rect, strokeInfo);
 }
 
 void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
@@ -561,7 +557,7 @@
         SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
 
         if (NULL == paint.getMaskFilter() && NULL == paint.getPathEffect()) {
-            fContext->drawDRRect(fRenderTarget, grPaint, *draw.fMatrix, outer, inner);
+            fContext->drawDRRect(fRenderTarget, fClip, grPaint, *draw.fMatrix, outer, inner);
             return;
         }
     }
@@ -608,7 +604,7 @@
     GrPaint grPaint;
     SkPaint2GrPaintShader(this->context(), fRenderTarget, paint, *draw.fMatrix, true, &grPaint);
 
-    fContext->drawOval(fRenderTarget, grPaint, *draw.fMatrix, oval, strokeInfo);
+    fContext->drawOval(fRenderTarget, fClip, grPaint, *draw.fMatrix, oval, strokeInfo);
 }
 
 #include "SkMaskFilter.h"
@@ -623,6 +619,7 @@
 // Return true if the mask was successfully drawn.
 bool draw_mask(GrContext* context,
                GrRenderTarget* rt,
+               const GrClip& clip,
                const SkMatrix& viewMatrix,
                const SkRect& maskRect,
                GrPaint* grp,
@@ -638,12 +635,13 @@
     if (!viewMatrix.invert(&inverse)) {
         return false;
     }
-    context->drawNonAARectWithLocalMatrix(rt, *grp, SkMatrix::I(), maskRect, inverse);
+    context->drawNonAARectWithLocalMatrix(rt, clip, *grp, SkMatrix::I(), maskRect, inverse);
     return true;
 }
 
 bool draw_with_mask_filter(GrContext* context,
                            GrRenderTarget* rt,
+                           const GrClip& clipData,
                            const SkMatrix& viewMatrix,
                            const SkPath& devPath,
                            SkMaskFilter* filter,
@@ -685,7 +683,7 @@
 
     SkRect maskRect = SkRect::Make(dstM.fBounds);
 
-    return draw_mask(context, rt, viewMatrix, maskRect, grp, texture);
+    return draw_mask(context, rt, clipData, viewMatrix, maskRect, grp, texture);
 }
 
 // Create a mask of 'devPath' and place the result in 'mask'.
@@ -717,18 +715,19 @@
 
     SkRect clipRect = SkRect::MakeWH(maskRect.width(), maskRect.height());
 
-    GrContext::AutoClip ac(context, clipRect);
-
     context->clear(NULL, 0x0, true, mask->asRenderTarget());
 
     GrPaint tempPaint;
     tempPaint.setAntiAlias(doAA);
     tempPaint.setCoverageSetOpXPFactory(SkRegion::kReplace_Op);
 
+    // setup new clip
+    GrClip clip(clipRect);
+
     // Draw the mask into maskTexture with the path's top-left at the origin using tempPaint.
     SkMatrix translate;
     translate.setTranslate(-maskRect.fLeft, -maskRect.fTop);
-    context->drawPath(mask->asRenderTarget(), tempPaint, translate, devPath, strokeInfo);
+    context->drawPath(mask->asRenderTarget(), clip, tempPaint, translate, devPath, strokeInfo);
     return mask;
 }
 
@@ -833,6 +832,7 @@
             if (paint.getMaskFilter()->directFilterMaskGPU(fContext,
                                                            fRenderTarget,
                                                            &grPaint,
+                                                           fClip,
                                                            viewMatrix,
                                                            stroke,
                                                            *devPathPtr)) {
@@ -855,7 +855,12 @@
                 if (paint.getMaskFilter()->filterMaskGPU(mask, viewMatrix, maskRect, &filtered, true)) {
                     // filterMaskGPU gives us ownership of a ref to the result
                     SkAutoTUnref<GrTexture> atu(filtered);
-                    if (draw_mask(fContext, fRenderTarget, viewMatrix, maskRect, &grPaint,
+                    if (draw_mask(fContext,
+                                  fRenderTarget,
+                                  fClip,
+                                  viewMatrix,
+                                  maskRect,
+                                  &grPaint,
                                   filtered)) {
                         // This path is completely drawn
                         return;
@@ -868,12 +873,12 @@
         // GPU path fails
         SkPaint::Style style = stroke.isHairlineStyle() ? SkPaint::kStroke_Style :
                                                           SkPaint::kFill_Style;
-        draw_with_mask_filter(fContext, fRenderTarget, viewMatrix, *devPathPtr,
+        draw_with_mask_filter(fContext, fRenderTarget, fClip, viewMatrix, *devPathPtr,
                               paint.getMaskFilter(), *draw.fClip, &grPaint, style);
         return;
     }
 
-    fContext->drawPath(fRenderTarget, grPaint, viewMatrix, *pathPtr, strokeInfo);
+    fContext->drawPath(fRenderTarget, fClip, grPaint, viewMatrix, *pathPtr, strokeInfo);
 }
 
 static const int kBmpSmallTileSize = 1 << 10;
@@ -906,12 +911,12 @@
 // pixels from the bitmap are necessary.
 static void determine_clipped_src_rect(const GrContext* context,
                                        const GrRenderTarget* rt,
+                                       const GrClip& clip,
                                        const SkMatrix& viewMatrix,
                                        const SkBitmap& bitmap,
                                        const SkRect* srcRectPtr,
                                        SkIRect* clippedSrcIRect) {
-    const GrClip* clip = context->getClip();
-    clip->getConservativeBounds(rt, clippedSrcIRect, NULL);
+    clip.getConservativeBounds(rt, clippedSrcIRect, NULL);
     SkMatrix inv;
     if (!viewMatrix.invert(&inv)) {
         clippedSrcIRect->setEmpty();
@@ -948,8 +953,8 @@
 
     // if it's larger than the max tile size, then we have no choice but tiling.
     if (bitmap.width() > maxTileSize || bitmap.height() > maxTileSize) {
-        determine_clipped_src_rect(fContext, fRenderTarget, viewMatrix, bitmap, srcRectPtr,
-                                   clippedSrcRect);
+        determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, bitmap,
+                                   srcRectPtr, clippedSrcRect);
         *tileSize = determine_tile_size(bitmap, *clippedSrcRect, maxTileSize);
         return true;
     }
@@ -978,7 +983,7 @@
     }
 
     // Figure out how much of the src we will need based on the src rect and clipping.
-    determine_clipped_src_rect(fContext, fRenderTarget, viewMatrix, bitmap, srcRectPtr,
+    determine_clipped_src_rect(fContext, fRenderTarget, fClip, viewMatrix, bitmap, srcRectPtr,
                                clippedSrcRect);
     *tileSize = kBmpSmallTileSize; // already know whole bitmap fits in one max sized tile.
     size_t usedTileBytes = get_tile_count(*clippedSrcRect, kBmpSmallTileSize) *
@@ -1452,7 +1457,8 @@
                                        SkColor2GrColor(paint.getColor());
     SkPaint2GrPaintNoShader(this->context(), fRenderTarget, paint, paintColor, false, &grPaint);
 
-    fContext->drawNonAARectToRect(fRenderTarget, grPaint, viewMatrix, dstRect, paintRect);
+    fContext->drawNonAARectToRect(fRenderTarget, fClip, grPaint, viewMatrix, dstRect,
+                                  paintRect);
 }
 
 bool SkGpuDevice::filterTexture(GrContext* context, GrTexture* texture,
@@ -1466,8 +1472,6 @@
     SkDeviceImageFilterProxy proxy(this, SkSurfaceProps(0, getLeakyProperties().pixelGeometry()));
 
     if (filter->canFilterImageGPU()) {
-        // Set the clip wide open and the matrix to identity.
-        GrContext::AutoWideOpenIdentityDraw awo(context);
         return filter->filterImageGPU(&proxy, wrap_texture(texture), ctx, result, offset);
     } else {
         return false;
@@ -1523,6 +1527,7 @@
                             SkColor2GrColorJustAlpha(paint.getColor()), false, &grPaint);
 
     fContext->drawNonAARectToRect(fRenderTarget,
+                                  fClip,
                                   grPaint,
                                   SkMatrix::I(),
                                   SkRect::MakeXYWH(SkIntToScalar(left),
@@ -1645,7 +1650,8 @@
     SkRect srcRect = SkRect::MakeWH(SK_Scalar1 * w / devTex->width(),
                                     SK_Scalar1 * h / devTex->height());
 
-    fContext->drawNonAARectToRect(fRenderTarget, grPaint, SkMatrix::I(), dstRect, srcRect);
+    fContext->drawNonAARectToRect(fRenderTarget, fClip, grPaint, SkMatrix::I(), dstRect,
+                                  srcRect);
 }
 
 bool SkGpuDevice::canHandleImageFilter(const SkImageFilter* filter) {
@@ -1779,6 +1785,7 @@
         colors = convertedColors.get();
     }
     fContext->drawVertices(fRenderTarget,
+                           fClip,
                            grPaint,
                            *draw.fMatrix,
                            primType,
@@ -1803,8 +1810,8 @@
 
     SkDEBUGCODE(this->validate();)
 
-    if (!fTextContext->drawText(fRenderTarget, grPaint, paint, *draw.fMatrix, (const char *)text,
-                                byteLength, x, y)) {
+    if (!fTextContext->drawText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix,
+                                (const char *)text, byteLength, x, y)) {
         // this will just call our drawPath()
         draw.drawText_asPaths((const char*)text, byteLength, x, y, paint);
     }
@@ -1821,8 +1828,8 @@
 
     SkDEBUGCODE(this->validate();)
 
-    if (!fTextContext->drawPosText(fRenderTarget, grPaint, paint, *draw.fMatrix, (const char *)text,
-                                   byteLength, pos, scalarsPerPos, offset)) {
+    if (!fTextContext->drawPosText(fRenderTarget, fClip, grPaint, paint, *draw.fMatrix,
+                                   (const char *)text, byteLength, pos, scalarsPerPos, offset)) {
         // this will just call our drawPath()
         draw.drawPosText_asPaths((const char*)text, byteLength, pos, scalarsPerPos, offset, paint);
     }
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index a6cc4ef..8dafcfc 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -137,7 +137,7 @@
     GrSkDrawProcs*                  fDrawProcs;
     SkAutoTUnref<const SkClipStack> fClipStack;
     SkIPoint                        fClipOrigin;
-    GrClip                          fClipData;
+    GrClip                          fClip;
     GrTextContext*                  fTextContext;
     SkSurfaceProps                  fSurfaceProps;
     GrRenderTarget*                 fRenderTarget;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index d069fe0..b0814af 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -243,9 +243,8 @@
     SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight));
     SkRect localRect = SkRect::MakeWH(1.f, 1.f);
 
-    GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip);
-    context->drawNonAARectToRect(stretched->asRenderTarget(), paint, SkMatrix::I(), rect,
-                                 localRect);
+    context->drawNonAARectToRect(stretched->asRenderTarget(), GrClip::WideOpen(), paint,
+                                 SkMatrix::I(), rect, localRect);
 
     return stretched;
 }
@@ -392,8 +391,8 @@
     paint.addColorProcessor(yuvToRgbProcessor);
     SkRect r = SkRect::MakeWH(SkIntToScalar(yuvInfo.fSize[0].fWidth),
                               SkIntToScalar(yuvInfo.fSize[0].fHeight));
-    GrContext::AutoClip ac(ctx, GrContext::AutoClip::kWideOpen_InitialClip);
-    ctx->drawRect(renderTarget, paint, SkMatrix::I(), r);
+
+    ctx->drawRect(renderTarget, GrClip::WideOpen(), paint, SkMatrix::I(), r);
 
     return result;
 }
@@ -706,8 +705,6 @@
     // asFragmentProcessor(). Since these calls get passed back to the client, we don't really
     // want them messing around with the context.
     {
-        GrContext::AutoClip ac(context, GrContext::AutoClip::kWideOpen_InitialClip);
-
         // Allow the shader to modify paintColor and also create an effect to be installed as
         // the first color effect on the GrPaint.
         GrFragmentProcessor* fp = NULL;
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index 46dde19..fedc470 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -205,8 +205,6 @@
         {kDivByAlpha_RoundUp_PMConversion, kMulByAlpha_RoundDown_PMConversion},
     };
 
-    GrContext::AutoWideOpenIdentityDraw awoid(context);
-
     bool failed = true;
 
     for (size_t i = 0; i < SK_ARRAY_COUNT(kConversionRules) && failed; ++i) {
@@ -231,19 +229,31 @@
 
         GrPaint paint1;
         paint1.addColorProcessor(pmToUPM1);
-        context->drawNonAARectToRect(readTex->asRenderTarget(), paint1, SkMatrix::I(), kDstRect,
+        context->drawNonAARectToRect(readTex->asRenderTarget(),
+                                     GrClip::WideOpen(),
+                                     paint1,
+                                     SkMatrix::I(),
+                                     kDstRect,
                                      kSrcRect);
 
         readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, firstRead);
 
         GrPaint paint2;
         paint2.addColorProcessor(upmToPM);
-        context->drawNonAARectToRect(tempTex->asRenderTarget(), paint2, SkMatrix::I(), kDstRect,
+        context->drawNonAARectToRect(tempTex->asRenderTarget(),
+                                     GrClip::WideOpen(),
+                                     paint2,
+                                     SkMatrix::I(),
+                                     kDstRect,
                                      kSrcRect);
 
         GrPaint paint3;
         paint3.addColorProcessor(pmToUPM2);
-        context->drawNonAARectToRect(readTex->asRenderTarget(), paint3, SkMatrix::I(), kDstRect,
+        context->drawNonAARectToRect(readTex->asRenderTarget(),
+                                     GrClip::WideOpen(),
+                                     paint3,
+                                     SkMatrix::I(),
+                                     kDstRect,
                                      kSrcRect);
 
         readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, secondRead);