Removed GrClip & related classes

http://codereview.appspot.com/6450071/



git-svn-id: http://skia.googlecode.com/svn/trunk@4899 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp
index 2893a60..6a2445d 100644
--- a/gyp/gpu.gyp
+++ b/gyp/gpu.gyp
@@ -177,8 +177,7 @@
       ],
       'sources': [
         '../include/gpu/GrAARectRenderer.h',
-        '../include/gpu/GrClip.h',
-        '../include/gpu/GrClipIterator.h',
+        '../include/gpu/GrClipData.h',
         '../include/gpu/GrColor.h',
         '../include/gpu/GrConfig.h',
         '../include/gpu/GrContext.h',
@@ -224,7 +223,7 @@
         '../src/gpu/GrBinHashKey.h',
         '../src/gpu/GrBufferAllocPool.cpp',
         '../src/gpu/GrBufferAllocPool.h',
-        '../src/gpu/GrClip.cpp',
+        '../src/gpu/GrClipData.cpp',
         '../src/gpu/GrContext.cpp',
         '../src/gpu/GrCustomStage.cpp',
         '../src/gpu/GrDefaultPathRenderer.cpp',
diff --git a/include/gpu/GrClip.h b/include/gpu/GrClip.h
deleted file mode 100644
index 4e6211a..0000000
--- a/include/gpu/GrClip.h
+++ /dev/null
@@ -1,247 +0,0 @@
-
-/*
- * Copyright 2010 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-
-#ifndef GrClip_DEFINED
-#define GrClip_DEFINED
-
-#include "GrRect.h"
-#include "SkClipStack.h"
-
-class GrSurface;
-
-#include "GrClipIterator.h"
-
-#include "SkPath.h"
-#include "SkTArray.h"
-
-class GrClip {
-public:
-    GrClip();
-    GrClip(const GrClip& src);
-    GrClip(GrClipIterator* iter, const GrRect& conservativeBounds);
-    explicit GrClip(const GrIRect& rect);
-    explicit GrClip(const GrRect& rect);
-
-    ~GrClip();
-
-    GrClip& operator=(const GrClip& src);
-
-    const GrRect& getConservativeBounds() const { 
-        GrAssert(fConservativeBoundsValid);
-        return fConservativeBounds; 
-    }
-
-    bool requiresAA() const { return fRequiresAA; }
-
-    class Iter {
-    public:
-        enum IterStart {
-            kBottom_IterStart,
-            kTop_IterStart
-        };
-
-        /**
-         * Creates an uninitialized iterator. Must be reset()
-         */
-        Iter();
-
-        Iter(const GrClip& stack, IterStart startLoc);
-
-        struct Clip {
-            Clip() : fRect(NULL), fPath(NULL), fOp(SkRegion::kIntersect_Op), 
-                     fDoAA(false) {}
-
-            const SkRect*   fRect;  // if non-null, this is a rect clip
-            const SkPath*   fPath;  // if non-null, this is a path clip
-            SkRegion::Op    fOp;
-            bool            fDoAA;
-        };
-
-        /**
-         *  Return the clip for this element in the iterator. If next() returns
-         *  NULL, then the iterator is done. The type of clip is determined by
-         *  the pointers fRect and fPath:
-         *
-         *  fRect==NULL  fPath!=NULL    path clip
-         *  fRect!=NULL  fPath==NULL    rect clip
-         *  fRect==NULL  fPath==NULL    empty clip
-         */
-        const Clip* next();
-        const Clip* prev();
-
-        /**
-         * Moves the iterator to the topmost clip with the specified RegionOp 
-         * and returns that clip. If no clip with that op is found, 
-         * returns NULL.
-         */
-        const Clip* skipToTopmost(SkRegion::Op op);
-
-        /**
-         * Restarts the iterator on a clip stack.
-         */
-        void reset(const GrClip& stack, IterStart startLoc);
-
-    private:
-        const GrClip*      fStack;
-        Clip               fClip;
-        int                fCurIndex;
-
-        /**
-         * updateClip updates fClip to represent the clip in the index slot of
-         * GrClip's list. * It unifies functionality needed by both next() and
-         * prev().
-         */
-        const Clip* updateClip(int index);
-    };
-
-private:
-    int getElementCount() const { return fList.count(); }
-
-    GrClipType getElementType(int i) const { return fList[i].fType; }
-
-    const SkPath& getPath(int i) const {
-        GrAssert(kPath_ClipType == fList[i].fType);
-        return fList[i].fPath;
-    }
-
-    GrPathFill getPathFill(int i) const {
-        GrAssert(kPath_ClipType == fList[i].fType);
-        return fList[i].fPathFill;
-    }
-
-    const GrRect& getRect(int i) const {
-        GrAssert(kRect_ClipType == fList[i].fType);
-        return fList[i].fRect;
-    }
-
-    SkRegion::Op getOp(int i) const { return fList[i].fOp; }
-
-    bool getDoAA(int i) const   { return fList[i].fDoAA; }
-
-public:
-    bool isRect() const {
-        if (1 == fList.count() && kRect_ClipType == fList[0].fType && 
-            (SkRegion::kIntersect_Op == fList[0].fOp ||
-             SkRegion::kReplace_Op == fList[0].fOp)) {
-            // if we determined that the clip is a single rect
-            // we ought to have also used that rect as the bounds.
-            GrAssert(fConservativeBoundsValid);
-            GrAssert(fConservativeBounds == fList[0].fRect);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    // isWideOpen returns true if the clip has no elements (it is the 
-    // infinite plane) not that it has no area.
-    bool isWideOpen() const { return 0 == fList.count(); }
-
-    /**
-     *  Resets this clip to be empty
-     */
-    void setEmpty();
-
-    void setFromIterator(GrClipIterator* iter, const GrRect& conservativeBounds);
-    void setFromRect(const GrRect& rect);
-    void setFromIRect(const GrIRect& rect);
-
-    friend bool operator==(const GrClip& a, const GrClip& b) {
-        if (a.fList.count() != b.fList.count()) {
-            return false;
-        }
-        int count = a.fList.count();
-        for (int i = 0; i < count; ++i) {
-            if (a.fList[i] != b.fList[i]) {
-                return false;
-            }
-        }
-        return true;
-    }
-    friend bool operator!=(const GrClip& a, const GrClip& b) {
-        return !(a == b);
-    }
-
-private:
-    struct Element {
-        GrClipType   fType;
-        GrRect       fRect;
-        SkPath       fPath;
-        GrPathFill   fPathFill;
-        SkRegion::Op fOp;
-        bool         fDoAA;
-        bool operator ==(const Element& e) const {
-            if (e.fType != fType || e.fOp != fOp || e.fDoAA != fDoAA) {
-                return false;
-            }
-            switch (fType) {
-                case kRect_ClipType:
-                    return fRect == e.fRect;
-                case kPath_ClipType:
-                    return fPath == e.fPath;
-                default:
-                    GrCrash("Unknown clip element type.");
-                    return false; // suppress warning
-            }
-        }
-        bool operator !=(const Element& e) const { return !(*this == e); }
-    };
-
-    GrRect              fConservativeBounds;
-    bool                fConservativeBoundsValid;
-
-    bool                fRequiresAA;
-
-    enum {
-        kPreAllocElements = 4,
-    };
-    SkSTArray<kPreAllocElements, Element>   fList;
-};
-
-/**
- * GrClipData encapsulates the information required to construct the clip
- * masks. 'fOrigin' is only non-zero when saveLayer has been called
- * with an offset bounding box. The clips in 'fClipStack' are in 
- * device coordinates (i.e., they have been translated by -fOrigin w.r.t.
- * the canvas' device coordinates).
- */
-class GrClipData : public SkNoncopyable {
-public:
-    const SkClipStack*  fClipStack;
-    SkIPoint            fOrigin;
-
-    GrClipData() 
-        : fClipStack(NULL) {
-        fOrigin.setZero();
-    }
-
-    bool operator==(const GrClipData& other) const {
-        if (fOrigin != other.fOrigin) {
-            return false;
-        }
-
-        if (NULL != fClipStack && NULL != other.fClipStack) {
-            return *fClipStack == *other.fClipStack;
-        }
-
-        return fClipStack == other.fClipStack;
-    }
-
-    bool operator!=(const GrClipData& other) const { 
-        return !(*this == other); 
-    }
-
-    void getConservativeBounds(const GrSurface* surface, 
-                               GrIRect* devResult,
-                               bool* isIntersectionOfRects = NULL) const;
-};
-
-#endif
-
diff --git a/include/gpu/GrClipData.h b/include/gpu/GrClipData.h
new file mode 100644
index 0000000..c9d934d
--- /dev/null
+++ b/include/gpu/GrClipData.h
@@ -0,0 +1,58 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+
+#ifndef GrClip_DEFINED
+#define GrClip_DEFINED
+
+#include "GrRect.h"
+#include "SkClipStack.h"
+
+class GrSurface;
+
+/**
+ * GrClipData encapsulates the information required to construct the clip
+ * masks. 'fOrigin' is only non-zero when saveLayer has been called
+ * with an offset bounding box. The clips in 'fClipStack' are in 
+ * device coordinates (i.e., they have been translated by -fOrigin w.r.t.
+ * the canvas' device coordinates).
+ */
+class GrClipData : public SkNoncopyable {
+public:
+    const SkClipStack*  fClipStack;
+    SkIPoint            fOrigin;
+
+    GrClipData() 
+        : fClipStack(NULL) {
+        fOrigin.setZero();
+    }
+
+    bool operator==(const GrClipData& other) const {
+        if (fOrigin != other.fOrigin) {
+            return false;
+        }
+
+        if (NULL != fClipStack && NULL != other.fClipStack) {
+            return *fClipStack == *other.fClipStack;
+        }
+
+        return fClipStack == other.fClipStack;
+    }
+
+    bool operator!=(const GrClipData& other) const { 
+        return !(*this == other); 
+    }
+
+    void getConservativeBounds(const GrSurface* surface, 
+                               GrIRect* devResult,
+                               bool* isIntersectionOfRects = NULL) const;
+};
+
+#endif
+
diff --git a/include/gpu/GrClipIterator.h b/include/gpu/GrClipIterator.h
deleted file mode 100644
index 5d3bd45..0000000
--- a/include/gpu/GrClipIterator.h
+++ /dev/null
@@ -1,86 +0,0 @@
-
-/*
- * Copyright 2010 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-
-
-#ifndef GrClipIterator_DEFINED
-#define GrClipIterator_DEFINED
-
-#include "GrRect.h"
-#include "SkPath.h"
-#include "SkRegion.h"
-
-/**
- * A clip is a list of paths and/or rects with set operations to combine them.
- */
-class GrClipIterator {
-public:
-    virtual ~GrClipIterator() {}
-
-    /**
-     *  Returns true if there are no more rects to process
-     */
-    virtual bool isDone() const = 0;
-
-    /**
-     *  Rewind the iterator to replay the set of clip elements again
-     */
-    virtual void rewind() = 0;
-
-    /**
-     * Get the type of the current clip element
-     */
-    virtual GrClipType getType() const = 0;
-
-    /**
-     * Return the current path. It is an error to call this when isDone() is
-     * true or when getType() is kRect_Type.
-     */
-    virtual const SkPath* getPath() = 0;
-
-    /**
-     * Return the fill rule for the path. It is an error to call this when
-     * isDone() is true or when getType is kRect_Type.
-     */
-    virtual GrPathFill getPathFill() const = 0;
-
-    /**
-    * Return the current rect. It is an error to call this when isDone is true
-    * or when getType() is kPath_Type.
-    */
-    virtual void getRect(GrRect* rect) const = 0;
-
-    /**
-     * Gets the operation used to apply the current item to previously iterated
-     * items. Iterators should not produce a Replace op.
-     */
-    virtual SkRegion::Op getOp() const = 0;
-
-    /**
-     * Gets anti-aliasing setting desired for the current clip
-     */
-    virtual bool getDoAA() const = 0;
-
-    /**
-     *  Call to move to the next element in the list, previous path iter can be
-     *  made invalid.
-     */
-    virtual void next() = 0;
-};
-
-/**
- *  Call to rewind iter, first checking to see if iter is NULL
- */
-static inline void GrSafeRewind(GrClipIterator* iter) {
-    if (iter) {
-        iter->rewind();
-    }
-}
-
-#endif
-
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index d6ac363..6252cc2 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -10,12 +10,13 @@
 #ifndef GrContext_DEFINED
 #define GrContext_DEFINED
 
-#include "GrClip.h"
 #include "GrPaint.h"
 #include "GrAARectRenderer.h"
+#include "GrClipData.h"
 // not strictly needed but requires WK change in LayerTextureUpdaterCanvas to
 // remove.
 #include "GrRenderTarget.h" 
+#include "SkClipStack.h"
 
 class GrAutoScratchTexture;
 class GrDrawState;
diff --git a/include/gpu/GrContextFactory.h b/include/gpu/GrContextFactory.h
index 65bf597..9f14f3b 100644
--- a/include/gpu/GrContextFactory.h
+++ b/include/gpu/GrContextFactory.h
@@ -19,6 +19,7 @@
 #include "gl/SkNullGLContext.h"
 
 #include "GrContext.h"
+#include "SkTArray.h"
 
 /**
  * This is a simple class that is useful in test apps that use different 
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h
index 6c6e3da..35badfa 100644
--- a/include/gpu/SkGr.h
+++ b/include/gpu/SkGr.h
@@ -17,7 +17,6 @@
 #include "GrTypes.h"
 #include "GrContext.h"
 #include "GrFontScaler.h"
-#include "GrClipIterator.h"
 
 // skia headers
 #include "SkBitmap.h"
@@ -85,45 +84,6 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Classes
 
-class SkGrClipIterator : public GrClipIterator {
-public:
-    SkGrClipIterator() { fClipStack = NULL;  fCurr = NULL; }
-    SkGrClipIterator(const SkClipStack& clipStack) { this->reset(clipStack); }
-
-    void reset(const SkClipStack& clipStack);
-
-    // overrides
-    virtual bool isDone() const SK_OVERRIDE { return NULL == fCurr; }
-    virtual void next() SK_OVERRIDE { fCurr = fIter.next(); }
-    virtual void rewind() SK_OVERRIDE { this->reset(*fClipStack); }
-    virtual GrClipType getType() const SK_OVERRIDE;
-
-    virtual SkRegion::Op getOp() const SK_OVERRIDE;
-
-    virtual bool getDoAA() const SK_OVERRIDE;
-
-    virtual void getRect(GrRect* rect) const SK_OVERRIDE {
-        if (!fCurr->fRect) {
-            rect->setEmpty();
-        } else {
-            *rect = *fCurr->fRect;
-        }
-    }
-
-    virtual const SkPath* getPath() SK_OVERRIDE {
-        return fCurr->fPath;
-    }
-
-    virtual GrPathFill getPathFill() const SK_OVERRIDE;
-
-private:
-    const SkClipStack*                  fClipStack;
-    SkClipStack::B2TIter                fIter;
-    // SkClipStack's auto advances on each get
-    // so we store the current pos here.
-    const SkClipStack::B2TIter::Clip*   fCurr;
-};
-
 class SkGlyphCache;
 
 class SkGrFontScaler : public GrFontScaler {
diff --git a/src/gpu/GrClip.cpp b/src/gpu/GrClip.cpp
deleted file mode 100644
index 4fbac8a..0000000
--- a/src/gpu/GrClip.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-
-/*
- * Copyright 2010 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrClip.h"
-#include "GrSurface.h"
-#include "GrRect.h"
-
-GrClip::GrClip() 
-    : fRequiresAA(false) {
-    fConservativeBounds.setEmpty();
-    fConservativeBoundsValid = true;
-}
-
-GrClip::GrClip(const GrClip& src) {
-    *this = src;
-}
-
-GrClip::GrClip(const GrIRect& rect) {
-    this->setFromIRect(rect);
-}
-
-GrClip::GrClip(const GrRect& rect) {
-    this->setFromRect(rect);
-}
-
-GrClip::GrClip(GrClipIterator* iter, const GrRect& bounds) {
-    this->setFromIterator(iter, bounds);
-}
-
-GrClip::~GrClip() {}
-
-GrClip& GrClip::operator=(const GrClip& src) {
-    fList = src.fList;
-    fConservativeBounds = src.fConservativeBounds;
-    fConservativeBoundsValid = src.fConservativeBoundsValid;
-    fRequiresAA = src.fRequiresAA;
-    return *this;
-}
-
-void GrClip::setEmpty() {
-    fList.reset();
-    fConservativeBounds.setEmpty();
-    fConservativeBoundsValid = true;
-    fRequiresAA = false;
-}
-
-void GrClip::setFromRect(const GrRect& r) {
-    fList.reset();
-    if (r.isEmpty()) {
-        // use a canonical empty rect for == testing.
-        setEmpty();
-    } else {
-        fList.push_back();
-        fList.back().fRect = r;
-        fList.back().fType = kRect_ClipType;
-        fList.back().fOp = SkRegion::kReplace_Op;
-        fList.back().fDoAA = false;
-        fConservativeBounds = r;
-        fConservativeBoundsValid = true;
-        fRequiresAA = false;
-    }
-}
-
-void GrClip::setFromIRect(const GrIRect& r) {
-    fList.reset();
-    if (r.isEmpty()) {
-        // use a canonical empty rect for == testing.
-        setEmpty();
-    } else {
-        fList.push_back();
-        fList.back().fRect.set(r);
-        fList.back().fType = kRect_ClipType;
-        fList.back().fOp = SkRegion::kReplace_Op;
-        fList.back().fDoAA = false;
-        fConservativeBounds.set(r);
-        fConservativeBoundsValid = true;
-        fRequiresAA = false;
-    }
-}
-
-static void intersectWith(SkRect* dst, const SkRect& src) {
-    if (!dst->intersect(src)) {
-        dst->setEmpty();
-    }
-}
-
-void GrClip::setFromIterator(GrClipIterator* iter,
-                             const GrRect& conservativeBounds) {
-    fList.reset();
-    fRequiresAA = false;
-
-    int rectCount = 0;
-
-    // compute bounds for common case of series of intersecting rects.
-    bool isectRectValid = true;
-
-    if (iter) {
-        for (iter->rewind(); !iter->isDone(); iter->next()) {
-            Element& e = fList.push_back();
-            e.fType = iter->getType();
-            e.fOp = iter->getOp();
-            e.fDoAA = iter->getDoAA();
-            if (e.fDoAA) {
-                fRequiresAA = true;
-            }
-            // iterators should not emit replace
-            GrAssert(SkRegion::kReplace_Op != e.fOp);
-            switch (e.fType) {
-                case kRect_ClipType:
-                    iter->getRect(&e.fRect);
-                    ++rectCount;
-                    if (isectRectValid) {
-                        if (SkRegion::kIntersect_Op == e.fOp) {
-                            GrAssert(fList.count() <= 2);
-                            if (fList.count() > 1) {
-                                GrAssert(2 == rectCount);
-                                rectCount = 1;
-                                fList.pop_back();
-                                GrAssert(kRect_ClipType == fList.back().fType);
-                                intersectWith(&fList.back().fRect, e.fRect);
-                            }
-                        } else {
-                            isectRectValid = false;
-                        }
-                    }
-                    break;
-                case kPath_ClipType:
-                    e.fPath = *iter->getPath();
-                    e.fPathFill = iter->getPathFill();
-                    isectRectValid = false;
-                    break;
-                default:
-                    GrCrash("Unknown clip element type.");
-            }
-        }
-    }
-    fConservativeBoundsValid = false;
-    if (isectRectValid && rectCount) {
-        fConservativeBounds = fList[0].fRect;
-        fConservativeBoundsValid = true;
-    } else {
-        fConservativeBounds = conservativeBounds;
-        fConservativeBoundsValid = true;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-GrClip::Iter::Iter() 
-    : fStack(NULL)
-    , fCurIndex(0) {
-}
-
-GrClip::Iter::Iter(const GrClip& stack, IterStart startLoc)
-    : fStack(&stack) {
-    this->reset(stack, startLoc);
-}
-
-const GrClip::Iter::Clip* GrClip::Iter::updateClip(int index) {
-
-    if (NULL == fStack) {
-        return NULL;
-    }
-
-    GrAssert(0 <= index && index < fStack->getElementCount());
-
-
-
-    switch (fStack->getElementType(index)) {
-        case kRect_ClipType:
-            fClip.fRect = &fStack->getRect(index);
-            fClip.fPath = NULL;
-            break;
-        case kPath_ClipType:
-            fClip.fRect = NULL;
-            fClip.fPath = &fStack->getPath(index);
-            break;
-    }
-    fClip.fOp = fStack->getOp(index);
-    fClip.fDoAA = fStack->getDoAA(index);
-    return &fClip;
-}
-
-const GrClip::Iter::Clip* GrClip::Iter::next() {
-
-    if (NULL == fStack) {
-        return NULL;
-    }
-
-    if (0 > fCurIndex || fCurIndex >= fStack->getElementCount()) {
-        return NULL;
-    }
-
-    int oldIndex = fCurIndex;
-    ++fCurIndex;
-
-    return this->updateClip(oldIndex);
-}
-
-const GrClip::Iter::Clip* GrClip::Iter::prev() {
-
-    if (NULL == fStack) {
-        return NULL;
-    }
-
-    if (0 > fCurIndex || fCurIndex >= fStack->getElementCount()) {
-        return NULL;
-    }
-
-    int oldIndex = fCurIndex;
-    --fCurIndex;
-
-    return this->updateClip(oldIndex);
-}
-
-const GrClip::Iter::Clip* GrClip::Iter::skipToTopmost(SkRegion::Op op) {
-
-    GrAssert(SkRegion::kReplace_Op == op);
-
-    if (NULL == fStack) {
-        return NULL;
-    }
-
-    // GrClip removes all clips below the topmost replace
-    this->reset(*fStack, kBottom_IterStart);
-
-    return this->next();
-}
-
-void GrClip::Iter::reset(const GrClip& stack, IterStart startLoc) {
-    fStack = &stack;
-    if (kBottom_IterStart == startLoc) {
-        fCurIndex = 0;
-    } else {
-        fCurIndex = fStack->getElementCount()-1;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * getConservativeBounds returns the conservative bounding box of the clip
- * in device (as opposed to canvas) coordinates. If the bounding box is
- * the result of purely intersections of rects (with an initial replace)
- * isIntersectionOfRects will be set to true.
- */
-void GrClipData::getConservativeBounds(const GrSurface* surface,
-                                       GrIRect* devResult,
-                                       bool* isIntersectionOfRects) const {
-    GrRect devBounds;
-
-    fClipStack->getConservativeBounds(-fOrigin.fX, 
-                                      -fOrigin.fY,
-                                      surface->width(),
-                                      surface->height(),
-                                      &devBounds,
-                                      isIntersectionOfRects);
-
-    devBounds.roundOut(devResult);
-}
-
diff --git a/src/gpu/GrClipData.cpp b/src/gpu/GrClipData.cpp
new file mode 100644
index 0000000..488643d
--- /dev/null
+++ b/src/gpu/GrClipData.cpp
@@ -0,0 +1,35 @@
+
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrClipData.h"
+#include "GrSurface.h"
+#include "GrRect.h"
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * getConservativeBounds returns the conservative bounding box of the clip
+ * in device (as opposed to canvas) coordinates. If the bounding box is
+ * the result of purely intersections of rects (with an initial replace)
+ * isIntersectionOfRects will be set to true.
+ */
+void GrClipData::getConservativeBounds(const GrSurface* surface,
+                                       GrIRect* devResult,
+                                       bool* isIntersectionOfRects) const {
+    GrRect devBounds;
+
+    fClipStack->getConservativeBounds(-fOrigin.fX, 
+                                      -fOrigin.fY,
+                                      surface->width(),
+                                      surface->height(),
+                                      &devBounds,
+                                      isIntersectionOfRects);
+
+    devBounds.roundOut(devResult);
+}
+
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index ff47306..0abe862 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -651,10 +651,6 @@
         }
 
         if (SkRegion::kReplace_Op == op) {
-            // TODO: replace is actually a lot faster then intersection
-            // for this path - refactor the stencil path so it can handle
-            // replace ops and alter GrClip to allow them through
-
             // clear the accumulator and draw the new object directly into it
             fGpu->clear(NULL, 0x00000000, accum->asRenderTarget());
 
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index d22838e..a8a0074 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -9,7 +9,6 @@
 #ifndef GrClipMaskManager_DEFINED
 #define GrClipMaskManager_DEFINED
 
-#include "GrClip.h"
 #include "GrContext.h"
 #include "GrNoncopyable.h"
 #include "GrRect.h"
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index f801b26..49cbec4 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -14,7 +14,6 @@
 #include "effects/GrSingleTextureEffect.h"
 
 #include "GrBufferAllocPool.h"
-#include "GrClipIterator.h"
 #include "GrGpu.h"
 #include "GrIndexBuffer.h"
 #include "GrInOrderDrawBuffer.h"
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 3fb6201..030b092 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -11,7 +11,6 @@
 #ifndef GrDrawTarget_DEFINED
 #define GrDrawTarget_DEFINED
 
-#include "GrClip.h"
 #include "GrDrawState.h"
 #include "GrIndexBuffer.h"
 #include "GrMatrix.h"
@@ -20,8 +19,9 @@
 
 #include "SkXfermode.h"
 #include "SkTLazy.h"
+#include "SkTArray.h"
 
-class GrClipIterator;
+class GrClipData;
 class GrPath;
 class GrVertexBuffer;
 
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 0385b25..a9306f4 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -10,7 +10,6 @@
 #include "GrGpu.h"
 
 #include "GrBufferAllocPool.h"
-#include "GrClipIterator.h"
 #include "GrContext.h"
 #include "GrIndexBuffer.h"
 #include "GrStencilBuffer.h"
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index 4bdaa6e..73a9068 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -15,7 +15,6 @@
 #include "GrAllocPool.h"
 #include "GrAllocator.h"
 #include "GrPath.h"
-#include "GrClip.h"
 
 #include "SkClipStack.h"
 #include "SkTemplates.h"
diff --git a/src/gpu/GrStencil.cpp b/src/gpu/GrStencil.cpp
index ac2d6d8..decfd2d 100644
--- a/src/gpu/GrStencil.cpp
+++ b/src/gpu/GrStencil.cpp
@@ -195,7 +195,7 @@
 // only modify the in/out status of samples covered by the clip element.
 
 // this one only works if used right after stencil clip was cleared.
-// Our GrClip doesn't allow midstream replace ops.
+// Our clip mask creation code doesn't allow midstream replace ops.
 GR_STATIC_CONST_SAME_STENCIL(gReplaceClip,
     kReplace_StencilOp,
     kReplace_StencilOp,
diff --git a/src/gpu/GrStencilBuffer.h b/src/gpu/GrStencilBuffer.h
index 77843a3..9767b17 100644
--- a/src/gpu/GrStencilBuffer.h
+++ b/src/gpu/GrStencilBuffer.h
@@ -10,7 +10,7 @@
 #ifndef GrStencilBuffer_DEFINED
 #define GrStencilBuffer_DEFINED
 
-#include "GrClip.h"
+#include "GrClipData.h"
 #include "GrResource.h"
 
 class GrRenderTarget;
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index dca0858..f6ee7ef 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -164,69 +164,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkGrClipIterator::reset(const SkClipStack& clipStack) {
-    fClipStack = &clipStack;
-    fIter.reset(clipStack);
-    // Gr has no notion of replace, skip to the
-    // last replace in the clip stack.
-    int lastReplace = 0;
-    int curr = 0;
-    while (NULL != (fCurr = fIter.next())) {
-        if (SkRegion::kReplace_Op == fCurr->fOp) {
-            lastReplace = curr;
-        }
-        ++curr;
-    }
-    fIter.reset(clipStack);
-    for (int i = 0; i < lastReplace+1; ++i) {
-        fCurr = fIter.next();
-    }
-}
-
-GrClipType SkGrClipIterator::getType() const {
-    GrAssert(!this->isDone());
-    if (NULL == fCurr->fPath) {
-        return kRect_ClipType;
-    } else {
-        return kPath_ClipType;
-    }
-}
-
-SkRegion::Op SkGrClipIterator::getOp() const {
-    // we skipped to the last "replace" op
-    // when this iter was reset.
-    // GrClip doesn't allow replace, so treat it as
-    // intersect.
-    if (SkRegion::kReplace_Op == fCurr->fOp) {
-        return SkRegion::kIntersect_Op;
-    }
-
-    return fCurr->fOp;
-
-}
-
-bool SkGrClipIterator::getDoAA() const {
-    return fCurr->fDoAA;
-}
-
-GrPathFill SkGrClipIterator::getPathFill() const {
-    switch (fCurr->fPath->getFillType()) {
-        case SkPath::kWinding_FillType:
-            return kWinding_GrPathFill;
-        case SkPath::kEvenOdd_FillType:
-            return  kEvenOdd_GrPathFill;
-        case SkPath::kInverseWinding_FillType:
-            return kInverseWinding_GrPathFill;
-        case SkPath::kInverseEvenOdd_FillType:
-            return kInverseEvenOdd_GrPathFill;
-        default:
-            GrCrash("Unsupported path fill in clip.");
-            return kWinding_GrPathFill; // suppress warning
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
 GrPixelConfig SkBitmapConfig2GrPixelConfig(SkBitmap::Config config) {
     switch (config) {
         case SkBitmap::kA8_Config:
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 322e733..2acfbd7 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -9,6 +9,8 @@
 #ifndef GrGLCaps_DEFINED
 #define GrGLCaps_DEFINED
 
+#include "SkTArray.h"
+#include "SkTDArray.h"
 #include "GrGLStencilBuffer.h"
 
 class GrGLContextInfo;