Replace GrClip with SkClipStack
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 31 Jul 2012 19:15:58 +0000 (19:15 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 31 Jul 2012 19:15:58 +0000 (19:15 +0000)
http://codereview.appspot.com/6449070/

git-svn-id: http://skia.googlecode.com/svn/trunk@4865 2bbb7eff-a529-9590-31e7-b0007b416f81

14 files changed:
include/core/SkClipStack.h
include/gpu/GrClip.h
include/gpu/GrContext.h
include/gpu/SkGpuDevice.h
src/core/SkClipStack.cpp
src/gpu/GrClip.cpp
src/gpu/GrClipMaskManager.cpp
src/gpu/GrClipMaskManager.h
src/gpu/GrInOrderDrawBuffer.cpp
src/gpu/GrInOrderDrawBuffer.h
src/gpu/GrStencilBuffer.h
src/gpu/GrTextContext.cpp
src/gpu/SkGpuDevice.cpp
tests/ClipCacheTest.cpp

index c0fadb1..4c79c2f 100644 (file)
@@ -25,6 +25,7 @@ public:
     SkClipStack();
     SkClipStack(const SkClipStack& b);
     explicit SkClipStack(const SkRect& r);
+    explicit SkClipStack(const SkIRect& r);
     ~SkClipStack();
 
     SkClipStack& operator=(const SkClipStack& b);
@@ -182,7 +183,8 @@ public:
      * the translation (+offsetX, +offsetY) is applied before the clamp to the 
      * maximum rectangle: [0,maxWidth) x [0,maxHeight).
      * isIntersectionOfRects is an optional parameter that is true when 
-     * 'bounds' is the result of an intersection of rects.
+     * 'devBounds' is the result of an intersection of rects. In this case
+     * 'devBounds' is the exact answer/clip.
      */
     void getConservativeBounds(int offsetX,
                                int offsetY,
index cf646a1..4e6211a 100644 (file)
 #ifndef GrClip_DEFINED
 #define GrClip_DEFINED
 
-#include "GrClipIterator.h"
 #include "GrRect.h"
+#include "SkClipStack.h"
+
+class GrSurface;
+
+#include "GrClipIterator.h"
 
 #include "SkPath.h"
 #include "SkTArray.h"
 
-class GrSurface;
-
 class GrClip {
 public:
     GrClip();
@@ -212,7 +214,7 @@ private:
  */
 class GrClipData : public SkNoncopyable {
 public:
-    const GrClip*       fClipStack;
+    const SkClipStack*  fClipStack;
     SkIPoint            fOrigin;
 
     GrClipData() 
index 2f05458..d6ac363 100644 (file)
@@ -710,7 +710,7 @@ public:
         GrContext*        fContext;
         const GrClipData* fOldClip;
 
-        GrClip            fNewClipStack;
+        SkClipStack       fNewClipStack;
         GrClipData        fNewClipData;
     };
 
index f576ae4..539372a 100644 (file)
@@ -130,10 +130,7 @@ private:
 
     GrSkDrawProcs*  fDrawProcs;
 
-    // the clip stack - on loan to us from SkCanvas so it can be NULL.
-    const SkClipStack*  fClipStack;
-    GrClip              fGrClip;
-    GrClipData          fClipData;
+    GrClipData      fClipData;
 
     // state for our offscreen render-target
     TexCache            fCache;
index d2c2035..e9a02ec 100644 (file)
@@ -381,6 +381,14 @@ SkClipStack::SkClipStack(const SkRect& r) : fDeque(sizeof(Rec)) {
     }
 }
 
+SkClipStack::SkClipStack(const SkIRect& r) : fDeque(sizeof(Rec)) {
+    if (!r.isEmpty()) {
+        SkRect temp;
+        temp.set(r);
+        this->clipDevRect(temp, SkRegion::kReplace_Op, false);
+    }
+}
+
 SkClipStack::~SkClipStack() {
     reset();
 }
index e8ea9a6..4fbac8a 100644 (file)
@@ -6,8 +6,6 @@
  * found in the LICENSE file.
  */
 
-
-
 #include "GrClip.h"
 #include "GrSurface.h"
 #include "GrRect.h"
@@ -254,31 +252,15 @@ void GrClip::Iter::reset(const GrClip& stack, IterStart startLoc) {
 void GrClipData::getConservativeBounds(const GrSurface* surface,
                                        GrIRect* devResult,
                                        bool* isIntersectionOfRects) const {
+    GrRect devBounds;
 
-    // Until we switch to using the SkClipStack directly we need to take
-    // this belt and suspenders approach here. When the clip stack 
-    // reduces to a single clip, GrClip uses that rect as the conservative
-    // bounds rather than SkClipStack's bounds and the reduced rect
-    // was never trimmed to the render target's bounds.
-    SkRect temp = SkRect::MakeLTRB(0, 0, 
-                                   SkIntToScalar(surface->width()), 
-                                   SkIntToScalar(surface->height()));
-
-    // convervativeBounds starts off in canvas coordinates here
-    GrRect conservativeBounds = fClipStack->getConservativeBounds();
-
-    // but is translated into device coordinates here
-    conservativeBounds.offset(SkIntToScalar(-fOrigin.fX), 
-                              SkIntToScalar(-fOrigin.fY));
+    fClipStack->getConservativeBounds(-fOrigin.fX, 
+                                      -fOrigin.fY,
+                                      surface->width(),
+                                      surface->height(),
+                                      &devBounds,
+                                      isIntersectionOfRects);
 
-    if (!conservativeBounds.intersect(temp)) {
-        conservativeBounds.setEmpty();
-    }
-
-    conservativeBounds.roundOut(devResult);
-
-    if (NULL != isIntersectionOfRects) {
-        *isIntersectionOfRects = fClipStack->isRect();
-    }
+    devBounds.roundOut(devResult);
 }
 
index 71743a0..ff47306 100644 (file)
@@ -83,12 +83,12 @@ GrPathFill get_path_fill(const SkPath& path) {
 /**
  * Does any individual clip in 'clipIn' use anti-aliasing?
  */
-bool requires_AA(const GrClip& clipIn) {
+bool requires_AA(const SkClipStack& clipIn) {
 
-    GrClip::Iter iter;
-    iter.reset(clipIn, GrClip::Iter::kBottom_IterStart);
+    SkClipStack::Iter iter;
+    iter.reset(clipIn, SkClipStack::Iter::kBottom_IterStart);
 
-    const GrClip::Iter::Clip* clip = NULL;
+    const SkClipStack::Iter::Clip* clip = NULL;
     for (clip = iter.skipToTopmost(SkRegion::kReplace_Op);
          NULL != clip;
          clip = iter.next()) {
@@ -108,15 +108,15 @@ bool requires_AA(const GrClip& clipIn) {
  * will be used on any element. If so, it returns true to indicate that the
  * entire clip should be rendered in SW and then uploaded en masse to the gpu.
  */
-bool GrClipMaskManager::useSWOnlyPath(const GrClip& clipIn) {
+bool GrClipMaskManager::useSWOnlyPath(const SkClipStack& clipIn) {
 
     // TODO: generalize this function so that when
     // a clip gets complex enough it can just be done in SW regardless
     // of whether it would invoke the GrSoftwarePathRenderer.
     bool useSW = false;
 
-    GrClip::Iter iter(clipIn, GrClip::Iter::kBottom_IterStart);
-    const GrClip::Iter::Clip* clip = NULL;
+    SkClipStack::Iter iter(clipIn, SkClipStack::Iter::kBottom_IterStart);
+    const SkClipStack::Iter::Clip* clip = NULL;
 
     for (clip = iter.skipToTopmost(SkRegion::kReplace_Op);
          NULL != clip;
@@ -169,7 +169,6 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn) {
     }
 
     bool requiresAA = requires_AA(*clipDataIn->fClipStack);
-    GrAssert(requiresAA == clipDataIn->fClipStack->requiresAA());
 
 #if GR_SW_CLIP
     // If MSAA is enabled we can do everything in the stencil buffer.
@@ -281,8 +280,8 @@ bool contains(const SkRect& canvContainer,
 // determines how many elements at the head of the clip can be skipped and
 // whether the initial clear should be to the inside- or outside-the-clip value,
 // and what op should be used to draw the first element that isn't skipped.
-const GrClip::Iter::Clip* process_initial_clip_elements(
-                                  GrClip::Iter* iter,
+const SkClipStack::Iter::Clip* process_initial_clip_elements(
+                                  SkClipStack::Iter* iter,
                                   const GrIRect& devBounds,
                                   bool* clearToInside,
                                   SkRegion::Op* firstOp,
@@ -298,7 +297,7 @@ const GrClip::Iter::Clip* process_initial_clip_elements(
     bool done = false;
     *clearToInside = true;
 
-    const GrClip::Iter::Clip* clip = NULL;
+    const SkClipStack::Iter::Clip* clip = NULL;
 
     for (clip = iter->skipToTopmost(SkRegion::kReplace_Op);
          NULL != clip && !done;
@@ -469,7 +468,7 @@ void device_to_canvas(SkRect* rect, const SkIPoint& origin) {
 
 ////////////////////////////////////////////////////////////////////////////////
 bool GrClipMaskManager::drawClipShape(GrTexture* target,
-                                      const GrClip::Iter::Clip* clip,
+                                      const SkClipStack::Iter::Clip* clip,
                                       const GrIRect& resultBounds) {
     GrDrawState* drawState = fGpu->drawState();
     GrAssert(NULL != drawState);
@@ -535,7 +534,7 @@ void GrClipMaskManager::getTemp(const GrIRect& bounds,
 }
 
 
-void GrClipMaskManager::setupCache(const GrClip& clipIn,
+void GrClipMaskManager::setupCache(const SkClipStack& clipIn,
                                    const GrIRect& bounds) {
     // Since we are setting up the cache we know the last lookup was a miss
     // Free up the currently cached mask so it can be reused
@@ -628,9 +627,9 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
     bool clearToInside;
     SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
 
-    GrClip::Iter iter(*clipDataIn.fClipStack, 
-                      GrClip::Iter::kBottom_IterStart);
-    const GrClip::Iter::Clip* clip = process_initial_clip_elements(&iter,
+    SkClipStack::Iter iter(*clipDataIn.fClipStack, 
+                           SkClipStack::Iter::kBottom_IterStart);
+    const SkClipStack::Iter::Clip* clip = process_initial_clip_elements(&iter,
                                                               *devResultBounds,
                                                               &clearToInside,
                                                               &firstOp,
@@ -749,7 +748,7 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
 
         // The origin of 'newClipData' is (0, 0) so it is okay to place
         // a device-coordinate bound in 'newClipStack'
-        GrClip newClipStack(devClipBounds);
+        SkClipStack newClipStack(devClipBounds);
         GrClipData newClipData;
         newClipData.fClipStack = &newClipStack;
 
@@ -782,9 +781,9 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
         bool clearToInside;
         SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
 
-        GrClip::Iter iter(*oldClipData->fClipStack, 
-                          GrClip::Iter::kBottom_IterStart);
-        const GrClip::Iter::Clip* clip = process_initial_clip_elements(&iter,
+        SkClipStack::Iter iter(*oldClipData->fClipStack, 
+                               SkClipStack::Iter::kBottom_IterStart);
+        const SkClipStack::Iter::Clip* clip = process_initial_clip_elements(&iter,
                                                   devRTRect,
                                                   &clearToInside,
                                                   &firstOp,
@@ -1155,9 +1154,9 @@ bool GrClipMaskManager::createSoftwareClipMask(const GrClipData& clipDataIn,
     bool clearToInside;
     SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
 
-    GrClip::Iter iter(*clipDataIn.fClipStack, 
-                      GrClip::Iter::kBottom_IterStart);
-    const GrClip::Iter::Clip* clip = process_initial_clip_elements(&iter,
+    SkClipStack::Iter iter(*clipDataIn.fClipStack, 
+                           SkClipStack::Iter::kBottom_IterStart);
+    const SkClipStack::Iter::Clip* clip = process_initial_clip_elements(&iter,
                                               *devResultBounds,
                                               &clearToInside,
                                               &firstOp,
index 3ba26d3..d22838e 100644 (file)
@@ -16,6 +16,7 @@
 #include "GrStencil.h"
 #include "GrTexture.h"
 
+#include "SkClipStack.h"
 #include "SkDeque.h"
 #include "SkPath.h"
 #include "SkRefCnt.h"
@@ -44,7 +45,7 @@ public:
         }
     }
 
-    bool canReuse(const GrClip& clip, int width, int height) {
+    bool canReuse(const SkClipStack& clip, int width, int height) {
 
         if (fStack.empty()) {
             GrAssert(false);
@@ -93,11 +94,11 @@ public:
         }
     }
 
-    void getLastClip(GrClip* clip) const {
+    void getLastClip(SkClipStack* clip) const {
 
         if (fStack.empty()) {
             GrAssert(false);
-            clip->setEmpty();
+            clip->reset();
             return;
         }
 
@@ -130,7 +131,7 @@ public:
         return back->fLastMask.texture();
     }
 
-    void acquireMask(const GrClip& clip,
+    void acquireMask(const SkClipStack& clip,
                      const GrTextureDesc& desc,
                      const GrIRect& bound) {
 
@@ -216,7 +217,7 @@ private:
         }
 
         void acquireMask(GrContext* context,
-                         const GrClip& clip, 
+                         const SkClipStack& clip, 
                          const GrTextureDesc& desc,
                          const GrIRect& bound) {
 
@@ -228,7 +229,7 @@ private:
         }
 
         void reset () {
-            fLastClip.setEmpty();
+            fLastClip.reset();
 
             GrTextureDesc desc;
 
@@ -236,7 +237,7 @@ private:
             fLastBound.setEmpty();
         }
 
-        GrClip                  fLastClip;
+        SkClipStack             fLastClip;
         // The mask's width & height values are used in setupDrawStateAAClip to 
         // correctly scale the uvs for geometry drawn with this mask
         GrAutoScratchTexture    fLastMask;
@@ -339,10 +340,10 @@ private:
                           GrTexture** result,
                           GrIRect *devResultBounds);
 
-    bool useSWOnlyPath(const GrClip& clipIn);
+    bool useSWOnlyPath(const SkClipStack& clipIn);
 
     bool drawClipShape(GrTexture* target,
-                       const GrClip::Iter::Clip* clip,
+                       const SkClipStack::Iter::Clip* clip,
                        const GrIRect& resultBounds);
 
     void drawTexture(GrTexture* target,
@@ -350,7 +351,7 @@ private:
 
     void getTemp(const GrIRect& bounds, GrAutoScratchTexture* temp);
 
-    void setupCache(const GrClip& clip, 
+    void setupCache(const SkClipStack& clip, 
                     const GrIRect& bounds);
 
     /**
index d5d03cd..9f24c4e 100644 (file)
@@ -125,44 +125,52 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
         // the rect.
         bool disabledClip = false;
 
-        if (drawState->isClipState() && fClip->fClipStack->isRect()) {
-
-            GrClip::Iter iter(*fClip->fClipStack, GrClip::Iter::kBottom_IterStart);
-            const GrClip::Iter::Clip* clip = iter.next();
-            GrAssert(NULL != clip && NULL != clip->fRect);
-
-            GrRect clipRect = *clip->fRect;
-            // If the clip rect touches the edge of the viewport, extended it
-            // out (close) to infinity to avoid bogus intersections.
-            // We might consider a more exact clip to viewport if this
-            // conservative test fails.
-            const GrRenderTarget* target = drawState->getRenderTarget();
-            if (0 >= clipRect.fLeft) {
-                clipRect.fLeft = GR_ScalarMin;
-            }
-            if (target->width() <= clipRect.fRight) {
-                clipRect.fRight = GR_ScalarMax;
-            }
-            if (0 >= clipRect.top()) {
-                clipRect.fTop = GR_ScalarMin;
-            }
-            if (target->height() <= clipRect.fBottom) {
-                clipRect.fBottom = GR_ScalarMax;
-            }
-            int stride = VertexSize(layout);
-            bool insideClip = true;
-            for (int v = 0; v < 4; ++v) {
-                const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
-                if (!clipRect.contains(p)) {
-                    insideClip = false;
-                    break;
+        if (drawState->isClipState()) {
+            
+            GrRect devClipRect;
+            bool isIntersectionOfRects = false;
+
+            fClip->fClipStack->getConservativeBounds(-fClip->fOrigin.fX,
+                                                     -fClip->fOrigin.fY,
+                                                     drawState->getRenderTarget()->width(),
+                                                     drawState->getRenderTarget()->height(),
+                                                     &devClipRect,
+                                                     &isIntersectionOfRects);
+
+            if (isIntersectionOfRects) {
+                // If the clip rect touches the edge of the viewport, extended it
+                // out (close) to infinity to avoid bogus intersections.
+                // We might consider a more exact clip to viewport if this
+                // conservative test fails.
+                const GrRenderTarget* target = drawState->getRenderTarget();
+                if (0 >= devClipRect.fLeft) {
+                    devClipRect.fLeft = GR_ScalarMin;
+                }
+                if (target->width() <= devClipRect.fRight) {
+                    devClipRect.fRight = GR_ScalarMax;
+                }
+                if (0 >= devClipRect.top()) {
+                    devClipRect.fTop = GR_ScalarMin;
+                }
+                if (target->height() <= devClipRect.fBottom) {
+                    devClipRect.fBottom = GR_ScalarMax;
+                }
+                int stride = VertexSize(layout);
+                bool insideClip = true;
+                for (int v = 0; v < 4; ++v) {
+                    const GrPoint& p = *GetVertexPoint(geo.vertices(), v, stride);
+                    if (!devClipRect.contains(p)) {
+                        insideClip = false;
+                        break;
+                    }
+                }
+                if (insideClip) {
+                    drawState->disableState(GrDrawState::kClip_StateBit);
+                    disabledClip = true;
                 }
-            }
-            if (insideClip) {
-                drawState->disableState(GrDrawState::kClip_StateBit);
-                disabledClip = true;
             }
         }
+
         if (!this->needsNewClip() &&
             !this->needsNewState() &&
             fCurrQuad > 0 &&
@@ -833,7 +841,7 @@ void GrInOrderDrawBuffer::recordClip() {
 }
 
 void GrInOrderDrawBuffer::recordDefaultClip() {
-    fClips.push_back() = GrClip();
+    fClips.push_back() = SkClipStack();
     fClipOrigins.push_back() = SkIPoint::Make(0, 0);
     fCmds.push_back(kSetClip_Cmd);
 }
index 9dfb18e..4bdaa6e 100644 (file)
@@ -17,6 +17,7 @@
 #include "GrPath.h"
 #include "GrClip.h"
 
+#include "SkClipStack.h"
 #include "SkTemplates.h"
 
 class GrGpu;
@@ -232,7 +233,7 @@ private:
     GrSTAllocator<kStatePreallocCnt, GrDrawState>       fStates;
     GrSTAllocator<kClearPreallocCnt, Clear>             fClears;
 
-    GrSTAllocator<kClipPreallocCnt, GrClip>             fClips;
+    GrSTAllocator<kClipPreallocCnt, SkClipStack>        fClips;
     GrSTAllocator<kClipPreallocCnt, SkIPoint>           fClipOrigins;
 
     GrDrawTarget*                   fAutoFlushTarget;
index 506e5ce..77843a3 100644 (file)
@@ -98,7 +98,7 @@ private:
     int fBits;
     int fSampleCnt;
 
-    GrClip      fLastClipStack;
+    SkClipStack fLastClipStack;
     GrClipData  fLastClipData;
     int         fLastClipWidth;
     int         fLastClipHeight;
index 576a5bd..23b16dd 100644 (file)
@@ -70,20 +70,6 @@ void GrTextContext::flushGlyphs() {
     fDrawTarget = NULL;
 }
 
-namespace {
-
-// 'rect' enters in canvas coordinates and leaves in device coordinates
-void canvas_to_device(SkRect* rect, const SkIPoint& origin) {
-    GrAssert(NULL != rect);
-
-    rect->fLeft   -= SkIntToScalar(origin.fX);
-    rect->fTop    -= SkIntToScalar(origin.fY);
-    rect->fRight  -= SkIntToScalar(origin.fX);
-    rect->fBottom -= SkIntToScalar(origin.fY);
-}
-
-};
-
 GrTextContext::GrTextContext(GrContext* context,
                              const GrPaint& paint,
                              const GrMatrix* extMatrix) : fPaint(paint) {
@@ -101,17 +87,22 @@ GrTextContext::GrTextContext(GrContext* context,
 
     const GrClipData* clipData = context->getClip();
 
-    GrRect conservativeBound = clipData->fClipStack->getConservativeBounds();
-    canvas_to_device(&conservativeBound, clipData->fOrigin);
+    GrRect devConservativeBound;
+    clipData->fClipStack->getConservativeBounds(
+                                     -clipData->fOrigin.fX,
+                                     -clipData->fOrigin.fY,
+                                     context->getRenderTarget()->width(),
+                                     context->getRenderTarget()->height(),
+                                     &devConservativeBound);
 
     if (!fExtMatrix.isIdentity()) {
         GrMatrix inverse;
         if (fExtMatrix.invert(&inverse)) {
-            inverse.mapRect(&conservativeBound);
+            inverse.mapRect(&devConservativeBound);
         }
     }
 
-    conservativeBound.roundOut(&fClipRect);
+    devConservativeBound.roundOut(&fClipRect);
 
     // save the context's original matrix off and restore in destructor
     // this must be done before getTextTarget.
index ec8f26c..8860d6e 100644 (file)
@@ -167,14 +167,12 @@ static SkBitmap make_bitmap(GrContext* context, GrRenderTarget* renderTarget) {
 }
 
 SkGpuDevice::SkGpuDevice(GrContext* context, GrTexture* texture)
-: SkDevice(make_bitmap(context, texture->asRenderTarget()))
-, fClipStack(NULL) {
+: SkDevice(make_bitmap(context, texture->asRenderTarget())) {
     this->initFromRenderTarget(context, texture->asRenderTarget());
 }
 
 SkGpuDevice::SkGpuDevice(GrContext* context, GrRenderTarget* renderTarget)
-: SkDevice(make_bitmap(context, renderTarget))
-, fClipStack(NULL) {
+: SkDevice(make_bitmap(context, renderTarget)) {
     this->initFromRenderTarget(context, renderTarget);
 }
 
@@ -215,8 +213,8 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
                          SkBitmap::Config config,
                          int width,
                          int height)
-    : SkDevice(config, width, height, false /*isOpaque*/)
-    , fClipStack(NULL) {
+    : SkDevice(config, width, height, false /*isOpaque*/) {
+
     fNeedPrepareRenderTarget = false;
     fDrawProcs = NULL;
 
@@ -351,23 +349,18 @@ void SkGpuDevice::onAttachToCanvas(SkCanvas* canvas) {
     INHERITED::onAttachToCanvas(canvas);
 
     // Canvas promises that this ptr is valid until onDetachFromCanvas is called
-    fClipStack = canvas->getClipStack();
-
-    fClipData.fClipStack = NULL;
+    fClipData.fClipStack = canvas->getClipStack();
 }
 
 void SkGpuDevice::onDetachFromCanvas() {
     INHERITED::onDetachFromCanvas();
 
-    fClipStack = NULL;
-
     fClipData.fClipStack = NULL;
 }
 
 #ifdef SK_DEBUG
-static void check_bounds(const SkClipStack& clipStack,
+static void check_bounds(const GrClipData& clipData,
                          const SkRegion& clipRegion,
-                         const SkIPoint& origin,
                          int renderTargetWidth,
                          int renderTargetHeight) {
 
@@ -378,13 +371,13 @@ static void check_bounds(const SkClipStack& clipStack,
     SkClipStack::BoundsType boundType;
     SkRect canvTemp;
 
-    clipStack.getBounds(&canvTemp, &boundType);
+    clipData.fClipStack->getBounds(&canvTemp, &boundType);
     if (SkClipStack::kNormal_BoundsType == boundType) {
         SkIRect devTemp;
 
         canvTemp.roundOut(&devTemp);
 
-        devTemp.offset(-origin.fX, -origin.fY);
+        devTemp.offset(-clipData.fOrigin.fX, -clipData.fOrigin.fY);
 
         if (!devBound.intersect(devTemp)) {
             devBound.setEmpty();
@@ -397,55 +390,37 @@ static void check_bounds(const SkClipStack& clipStack,
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static void convert_matrixclip(GrContext* context, const SkMatrix& matrix,
-                               const SkClipStack& clipStack,
-                               GrClipData& clipData,
-                               const SkRegion& clipRegion,
-                               const SkIPoint& origin,
-                               int renderTargetWidth, int renderTargetHeight,
-                               GrClip* result) {
+static void set_matrix_and_clip(GrContext* context, const SkMatrix& matrix,
+                                GrClipData& clipData,
+                                const SkRegion& clipRegion,
+                                const SkIPoint& origin,
+                                int renderTargetWidth, int renderTargetHeight) {
     context->setMatrix(matrix);
 
-    SkGrClipIterator iter;
-    iter.reset(clipStack);
+    clipData.fOrigin = origin;
 
 #ifdef SK_DEBUG
-    check_bounds(clipStack, clipRegion, origin,
+    check_bounds(clipData, clipRegion,
                  renderTargetWidth, renderTargetHeight);
 #endif
 
-    SkRect devClipBounds;
-    bool isIntersectionOfRects = false;
-    clipStack.getConservativeBounds(0, 0,
-                                    renderTargetWidth,
-                                    renderTargetHeight,
-                                    &devClipBounds,
-                                    &isIntersectionOfRects);
-
-    result->setFromIterator(&iter, devClipBounds);
-
-    GrAssert(result->isRect() == isIntersectionOfRects);
-
-    clipData.fClipStack = result;
-    clipData.fOrigin = origin;
     context->setClip(&clipData);
 }
 
 // call this every draw call, to ensure that the context reflects our state,
 // and not the state from some other canvas/device
 void SkGpuDevice::prepareRenderTarget(const SkDraw& draw) {
-    GrAssert(NULL != fClipStack);
+    GrAssert(NULL != fClipData.fClipStack);
 
     if (fNeedPrepareRenderTarget ||
         fContext->getRenderTarget() != fRenderTarget) {
 
         fContext->setRenderTarget(fRenderTarget);
-        SkASSERT(draw.fClipStack && draw.fClipStack == fClipStack);
+        SkASSERT(draw.fClipStack && draw.fClipStack == fClipData.fClipStack);
 
-        convert_matrixclip(fContext, *draw.fMatrix, 
-                           *fClipStack, fClipData, *draw.fClip, this->getOrigin(),
-                           fRenderTarget->width(), fRenderTarget->height(),
-                           &fGrClip);
+        set_matrix_and_clip(fContext, *draw.fMatrix,
+                            fClipData, *draw.fClip, this->getOrigin(),
+                            fRenderTarget->width(), fRenderTarget->height());
         fNeedPrepareRenderTarget = false;
     }
 }
@@ -459,14 +434,14 @@ void SkGpuDevice::setMatrixClip(const SkMatrix& matrix, const SkRegion& clip,
 
 void SkGpuDevice::gainFocus(const SkMatrix& matrix, const SkRegion& clip) {
 
-    GrAssert(NULL != fClipStack);
+    GrAssert(NULL != fClipData.fClipStack);
 
     fContext->setRenderTarget(fRenderTarget);
 
     this->INHERITED::gainFocus(matrix, clip);
 
-    convert_matrixclip(fContext, matrix, *fClipStack, fClipData, clip, this->getOrigin(),
-                       fRenderTarget->width(), fRenderTarget->height(), &fGrClip);
+    set_matrix_and_clip(fContext, matrix, fClipData, clip, this->getOrigin(),
+                        fRenderTarget->width(), fRenderTarget->height());
 
     DO_DEFERRED_CLEAR;
 }
@@ -895,7 +870,7 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
 
     context->setRenderTarget(pathTexture->asRenderTarget());
 
-    GrClip newClipStack(srcRect);
+    SkClipStack newClipStack(srcRect);
     GrClipData newClipData;
     newClipData.fClipStack = &newClipStack;
     context->setClip(&newClipData);
@@ -1982,8 +1957,8 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
                          GrTexture* texture,
                          TexCache cacheEntry,
                          bool needClear)
-    : SkDevice(make_bitmap(context, texture->asRenderTarget()))
-    , fClipStack(NULL) {
+    : SkDevice(make_bitmap(context, texture->asRenderTarget())) {
+
     GrAssert(texture && texture->asRenderTarget());
     GrAssert(NULL == cacheEntry.texture() || texture == cacheEntry.texture());
     this->initFromRenderTarget(context, texture->asRenderTarget());
index 0a72be4..a02f0d3 100644 (file)
@@ -78,22 +78,9 @@ static void test_clip_bounds(skiatest::Reporter* reporter, GrContext* context) {
     REPORTER_ASSERT(reporter, screen == devStackBounds);
     REPORTER_ASSERT(reporter, isIntersectionOfRects);
 
-    // convert the SkClipStack to a GrClip
-    SkGrClipIterator iter;
-    iter.reset(stack);
-
-    GrClip clip;
-    clip.setFromIterator(&iter, devStackBounds);
-
-    const GrRect& canvGrClipBound = clip.getConservativeBounds();
-
-    // make sure that GrClip is behaving itself
-    REPORTER_ASSERT(reporter, clipRect == canvGrClipBound);
-    REPORTER_ASSERT(reporter, clip.isRect());
-
-    // wrap the GrClip in a GrClipData
+    // wrap the SkClipStack in a GrClipData
     GrClipData clipData;
-    clipData.fClipStack = &clip;
+    clipData.fClipStack = &stack;
 
     SkIRect devGrClipDataBound;
     clipData.getConservativeBounds(texture,
@@ -109,10 +96,10 @@ static void test_clip_bounds(skiatest::Reporter* reporter, GrContext* context) {
 // verify that the top state of the stack matches the passed in state
 static void check_state(skiatest::Reporter* reporter,
                         const GrClipMaskCache& cache,
-                        const GrClip& clip,
+                        const SkClipStack& clip,
                         GrTexture* mask,
                         const GrIRect& bound) {
-    GrClip cacheClip;
+    SkClipStack cacheClip;
     cache.getLastClip(&cacheClip);
     REPORTER_ASSERT(reporter, clip == cacheClip);
 
@@ -135,8 +122,8 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
 
     cache.setContext(context);
 
-    GrClip emptyClip;
-    emptyClip.setEmpty();
+    SkClipStack emptyClip;
+    emptyClip.reset();
 
     GrIRect emptyBound;
     emptyBound.setEmpty();
@@ -148,8 +135,7 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
     GrIRect bound1;
     bound1.set(0, 0, 100, 100);
 
-    GrClip clip1;
-    clip1.setFromIRect(bound1);
+    SkClipStack clip1(bound1);
 
     GrTextureDesc desc;
     desc.fFlags = kRenderTarget_GrTextureFlagBit;
@@ -180,9 +166,7 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
     GrIRect bound2;
     bound2.set(-10, -10, 10, 10);
 
-    GrClip clip2;
-    clip2.setEmpty();
-    clip2.setFromIRect(bound2);
+    SkClipStack clip2(bound2);
 
     cache.acquireMask(clip2, desc, bound2);