Share code with SkRect

http://codereview.appspot.com/4523046/



git-svn-id: http://skia.googlecode.com/svn/trunk@1277 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/include/GrMatrix.h b/gpu/include/GrMatrix.h
index 1ebc0b4..19a6644 100644
--- a/gpu/include/GrMatrix.h
+++ b/gpu/include/GrMatrix.h
@@ -18,9 +18,7 @@
 #ifndef GrMatrix_DEFINED
 #define GrMatrix_DEFINED
 
-#include "GrPoint.h"
-
-struct GrRect;
+#include "GrRect.h"
 
 /*
  * 3x3 matrix
diff --git a/gpu/include/GrPathIter.h b/gpu/include/GrPathIter.h
index 2c84145..e67ff69 100644
--- a/gpu/include/GrPathIter.h
+++ b/gpu/include/GrPathIter.h
@@ -18,9 +18,7 @@
 #ifndef GrPathIter_DEFINED
 #define GrPathIter_DEFINED
 
-#include "GrPoint.h"
-
-struct GrRect;
+#include "GrRect.h"
 
 /**
  2D Path iterator. Porting layer creates a subclass of this. It allows Ganesh to
diff --git a/gpu/include/GrRect.h b/gpu/include/GrRect.h
index 7d03396..81f1545 100644
--- a/gpu/include/GrRect.h
+++ b/gpu/include/GrRect.h
@@ -19,465 +19,24 @@
 #define GrRect_DEFINED
 
 #include "GrPoint.h"
+#include "SkRect.h"
 
-struct GrIRect {
-    int32_t fLeft, fTop, fRight, fBottom;
-
-    GrIRect() {}
-    GrIRect(int32_t left, int32_t top, int32_t right, int32_t bottom) {
-        fLeft = left;
-        fTop = top;
-        fRight = right;
-        fBottom = bottom;
-    }
-
-    int32_t x() const { return fLeft; }
-    int32_t y() const { return fTop; }
-    int32_t width() const { return fRight - fLeft; }
-    int32_t height() const { return fBottom - fTop; }
-
-    bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
-    bool isInverted() const { return fLeft > fRight || fTop > fBottom; }
-
-    void setEmpty() { fLeft = fTop = fRight = fBottom = 0; }
-
-    void setXYWH(int32_t x, int32_t y, int32_t w, int32_t h) {
-        fLeft = x;
-        fTop = y;
-        fRight = x + w;
-        fBottom = y + h;
-    }
-
-    void setLTRB(int32_t l, int32_t t, int32_t r, int32_t b) {
-        fLeft = l;
-        fTop = t;
-        fRight = r;
-        fBottom = b;
-    }
-
-    /**
-     *  Make the largest representable rectangle
-     */
-    void setLargest() {
-        fLeft = fTop = GR_Int32Min;
-        fRight = fBottom = GR_Int32Max;
-    }
-
-    void setLargestInverted() {
-        fLeft = fTop = GR_Int32Max;
-        fRight = fBottom = GR_Int32Min;
-    }
-
-    bool quickReject(int l, int t, int r, int b) const {
-        return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
-    }
-
-    void unionWith(const GrIRect& r) {
-        if (fLeft > r.fLeft) fLeft = r.fLeft;
-        if (fTop > r.fTop) fTop = r.fTop;
-        if (fRight < r.fRight) fRight = r.fRight;
-        if (fBottom < r.fBottom) fBottom = r.fBottom;
-    }
-
-    /**
-     * Sets this rect to the intersection with a clip rect. If there is no
-     * intersection then this rect will be made empty and the function will
-     * return false.
-     */
-    bool intersectWith(const GrIRect& clipRect) {
-        if (fRight < clipRect.fLeft ||
-            fLeft > clipRect.fRight ||
-            fBottom < clipRect.fTop ||
-            fTop > clipRect.fBottom) {
-            this->setEmpty();
-            return false;
-        } else {
-            fLeft = GrMax(fLeft, clipRect.fLeft);
-            fRight = GrMin(fRight, clipRect.fRight);
-            fTop = GrMax(fTop, clipRect.fTop);
-            fBottom = GrMin(fBottom, clipRect.fBottom);
-            return true;
-        }
-    }
-
-    bool intersectWith(int left, int top,
-                       int right, int bottom) {
-        if (fRight < left ||
-            fLeft > right ||
-            fBottom < top ||
-            fTop > bottom) {
-            this->setEmpty();
-            return false;
-        } else {
-            fLeft = GrMax(fLeft, left);
-            fRight = GrMin(fRight, right);
-            fTop = GrMax(fTop, top);
-            fBottom = GrMin(fBottom, bottom);
-            return true;
-        }
-    }
-
-    /**
-     * Enlarge the rectangle to include rect.
-     */
-    void growToInclude(const GrIRect& rect) {
-        GrAssert(!rect.isEmpty());
-        fLeft  = GrMin(rect.fLeft, fLeft);
-        fRight = GrMax(rect.fRight, fRight);
-
-        fTop    = GrMin(rect.fTop, fTop);
-        fBottom = GrMax(rect.fBottom, fBottom);
-    }
-
-    friend bool operator==(const GrIRect& a, const GrIRect& b) {
-        return 0 == memcmp(&a, &b, sizeof(a));
-    }
-
-    friend bool operator!=(const GrIRect& a, const GrIRect& b) {
-        return 0 != memcmp(&a, &b, sizeof(a));
-    }
-
-    bool equalsLTRB(int l, int t, int r, int b) const {
-        return fLeft == l && fTop == t &&
-               fRight == r && fBottom == b;
-    }
-    bool equalsXYWH(int x, int y, int w, int h) const {
-        return fLeft == x && fTop == y &&
-               this->width() == w && this->height() == h;
-    }
-
-    bool contains(const GrIRect& r) const {
-        return fLeft   <= r.fLeft &&
-               fRight  >= r.fRight &&
-               fTop    <= r.fTop &&
-               fBottom >= r.fBottom;
-    }
-
-    static const GrIRect& EmptyIRect() {
-        static const GrIRect gEmpty(0,0,0,0);
-        return gEmpty;
-    }
-};
+typedef SkIRect GrIRect;
+typedef SkRect  GrRect;
 
 struct GrIRect16 {
     int16_t fLeft, fTop, fRight, fBottom;
-
+    
     int width() const { return fRight - fLeft; }
     int height() const { return fBottom - fTop; }
     int area() const { return this->width() * this->height(); }
     bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
-
+    
     void set(const GrIRect& r) {
-        fLeft   = GrToS16(r.fLeft);
-        fTop    = GrToS16(r.fTop);
-        fRight  = GrToS16(r.fRight);
-        fBottom = GrToS16(r.fBottom);
-    }
-};
-
-/**
- *  2D Rect struct
- */
-struct GrRect {
-    GrScalar fLeft, fTop, fRight, fBottom;
-
-    /**
-     *  Uninitialized rectangle.
-     */
-    GrRect() {}
-
-    /**
-     *  Initialize a rectangle to a point.
-     *  @param pt the point used to initialize the rectanglee.
-     */
-    explicit GrRect(const GrPoint& pt) {
-        setToPoint(pt);
-    }
-
-    GrRect(GrScalar left, GrScalar top, GrScalar right, GrScalar bottom) {
-        fLeft = left;
-        fTop = top;
-        fRight = right;
-        fBottom = bottom;
-    }
-
-    explicit GrRect(const GrIRect& src) {
-        fLeft = GrIntToScalar(src.fLeft);
-        fTop = GrIntToScalar(src.fTop);
-        fRight = GrIntToScalar(src.fRight);
-        fBottom = GrIntToScalar(src.fBottom);
-    }
-
-    GrScalar x() const { return fLeft; }
-    GrScalar y() const { return fTop; }
-    GrScalar width() const { return fRight - fLeft; }
-    GrScalar height() const { return fBottom - fTop; }
-
-    GrScalar left() const { return fLeft; }
-    GrScalar top() const { return fTop; }
-    GrScalar right() const { return fRight; }
-    GrScalar bottom() const { return fBottom; }
-
-    GrScalar diagonalLengthSqd() const {
-        GrScalar w = width();
-        GrScalar h = height();
-        return GrMul(w, w) + GrMul(h, h);
-    }
-
-    GrScalar diagonalLength() const {
-        // TODO: fixed point sqrt
-        return GrFloatToScalar(sqrtf(GrScalarToFloat(diagonalLengthSqd())));
-    }
-
-    /**
-     *  Returns true if the width or height is <= 0
-     */
-    bool isEmpty() const {
-        return fLeft >= fRight || fTop >= fBottom;
-    }
-
-    void setEmpty() {
-        fLeft = fTop = fRight = fBottom = 0;
-    }
-
-    /**
-     *  returns true if the rectangle is inverted either in x or y
-     */
-    bool isInverted() const {
-        return (fLeft > fRight) || (fTop > fBottom);
-    }
-
-    /**
-     * Returns true if the rects edges are integer-aligned.
-     */
-    bool isIRect() const {
-        return GrScalarIsInt(fLeft) && GrScalarIsInt(fTop) && 
-               GrScalarIsInt(fRight) && GrScalarIsInt(fBottom);
-    }
-
-    /**
-     * Does this rect contain a point.
-     */
-    bool contains(const GrPoint& point) const {
-        return point.fX >= fLeft && point.fX < fRight &&
-               point.fY >= fTop && point.fY < fBottom;
-    }
-
-    /**
-     * Returns true if the rect contains the point or the
-     * point lies on the edge of the rect.
-     */
-    bool containsInclusive(const GrPoint& point) const {
-        return point.fX >= fLeft && point.fX <= fRight &&
-               point.fY >= fTop && point.fY <= fBottom;
-    }
-
-    /**
-     * Does this rect fully contain another rect.
-     */
-    bool contains(const GrRect& r) const {
-        return fLeft   <= r.fLeft &&
-               fRight  >= r.fRight &&
-               fTop    <= r.fTop &&
-               fBottom >= r.fBottom;
-    }
-
-    /**
-     *  Offset the rectangle by (tx, ty), adding tx to the horizontal position
-     *  and adds ty to the vertical position.
-     */
-    void offset(GrScalar tx, GrScalar ty) {
-        fLeft  += tx;   fTop    += ty;
-        fRight += tx;   fBottom += ty;
-    }
-
-    /**
-     *  Inset the rectangle by dx,dy. If dx > 0 the rect becomes narrower,
-     *  if dx < 0 the rect becomes wider.
-     */
-    void inset(GrScalar dx, GrScalar dy) {
-        fLeft += dx;    fTop    += dy;
-        fRight -= dx;   fBottom -= dy;
-    }
-
-    /**
-     *  Initialize a rectangle to a point.
-     *  @param pt the point used to initialize the rectangle.
-     */
-    void setToPoint(const GrPoint& pt) {
-        fLeft = pt.fX;
-        fTop = pt.fY;
-        fRight = pt.fX;
-        fBottom = pt.fY;
-    }
-
-    void set(const GrIRect& r) {
-        fLeft = GrIntToScalar(r.fLeft);
-        fTop = GrIntToScalar(r.fTop);
-        fRight = GrIntToScalar(r.fRight);
-        fBottom = GrIntToScalar(r.fBottom);
-    }
-
-    void roundOut(GrIRect* r) const {
-        r->setLTRB(GrScalarFloorToInt(fLeft),
-                   GrScalarFloorToInt(fTop),
-                   GrScalarCeilToInt(fRight),
-                   GrScalarCeilToInt(fBottom));
-    }
-
-    /**
-     *  Set the rect to the union of the array of points. If the array is empty
-     *  the rect will be empty [0,0,0,0]
-     */
-    void setBounds(const GrPoint pts[], int count);
-
-    /**
-     *  Make the largest representable rectangle
-     *  Set the rect to fLeft = fTop = GR_ScalarMin and
-     *  fRight = fBottom = GR_ScalarMax.
-     */
-    void setLargest() {
-        fLeft = fTop = GR_ScalarMin;
-        fRight = fBottom = GR_ScalarMax;
-    }
-
-    /**
-     Set the rect to fLeft = fTop = GR_ScalarMax and
-     fRight = fBottom = GR_ScalarMin.
-     Useful for initializing a bounding rectangle.
-     */
-    void setLargestInverted() {
-        fLeft = fTop = GR_ScalarMax;
-        fRight = fBottom = GR_ScalarMin;
-    }
-
-    void setLTRB(GrScalar left,
-                 GrScalar top,
-                 GrScalar right,
-                 GrScalar bottom) {
-        fLeft = left;
-        fTop = top;
-        fRight = right;
-        fBottom = bottom;
-    }
-
-    void setXYWH(GrScalar x, GrScalar y, GrScalar width, GrScalar height) {
-        fLeft = x;
-        fTop = y;
-        fRight = x + width;
-        fBottom = y + height;
-    }
-
-    /**
-     Expand the edges of the rectangle to include a point.
-     Useful for constructing a bounding rectangle.
-     @param pt  the point used to grow the rectangle.
-     */
-    void growToInclude(const GrPoint& pt) {
-        fLeft  = GrMin(pt.fX, fLeft);
-        fRight = GrMax(pt.fX, fRight);
-
-        fTop    = GrMin(pt.fY, fTop);
-        fBottom = GrMax(pt.fY, fBottom);
-    }
-
-    void growToInclude(GrScalar x, GrScalar y) {
-        fLeft  = GrMin(x, fLeft);
-        fRight = GrMax(y, fRight);
-
-        fTop    = GrMin(x, fTop);
-        fBottom = GrMax(y, fBottom);
-    }
-
-    /**
-     * Grows a rect to include another rect.
-     * @param rect the rect to include
-     */
-    void growToInclude(const GrRect& rect) {
-        GrAssert(!rect.isEmpty());
-        fLeft  = GrMin(rect.fLeft, fLeft);
-        fRight = GrMax(rect.fRight, fRight);
-
-        fTop    = GrMin(rect.fTop, fTop);
-        fBottom = GrMax(rect.fBottom, fBottom);
-    }
-
-    /**
-     * Sets this rect to the intersection with a clip rect. If there is no
-     * intersection then this rect will be made empty.
-     */
-    bool intersectWith(const GrRect& clipRect) {
-        if (fRight < clipRect.fLeft ||
-            fLeft > clipRect.fRight ||
-            fBottom < clipRect.fTop ||
-            fTop > clipRect.fBottom) {
-            this->setEmpty();
-            return false;
-        } else {
-            fLeft = GrMax(fLeft, clipRect.fLeft);
-            fRight = GrMin(fRight, clipRect.fRight);
-            fTop = GrMax(fTop, clipRect.fTop);
-            fBottom = GrMin(fBottom, clipRect.fBottom);
-            return true;
-        }
-    }
-
-    bool intersectWith(GrScalar left, GrScalar top,
-                       GrScalar right, GrScalar bottom) {
-        if (fRight < left ||
-            fLeft > right ||
-            fBottom < top ||
-            fTop > bottom) {
-            this->setEmpty();
-            return false;
-        } else {
-            fLeft = GrMax(fLeft, left);
-            fRight = GrMin(fRight, right);
-            fTop = GrMax(fTop, top);
-            fBottom = GrMin(fBottom, bottom);
-            return true;
-        }
-    }
-
-    /**
-     *  Assigns 4 sequential points in order to construct a counter-clockwise
-     *  triangle fan, given the corners of this rect. Returns the address of
-     *  the next point, treating pts as an array.
-     */
-    GrPoint* setRectFan(GrPoint pts[4]) const {
-        pts->setRectFan(fLeft, fTop, fRight, fBottom);
-        return pts + 4;
-    }
-
-    /**
-     * Swaps (left and right) and/or (top and bottom) if they are inverted
-     */
-    void sort() {
-        if (fLeft > fRight) {
-            GrScalar temp = fLeft;
-            fLeft = fRight;
-            fRight = temp;
-        }
-        if (fTop > fBottom) {
-            GrScalar temp = fTop;
-            fTop = fBottom;
-            fBottom = temp;
-        }
-    }
-
-    void translate(GrScalar tx, GrScalar ty) {
-        fLeft += tx;
-        fRight += tx;
-
-        fTop += ty;
-        fBottom += ty;
-    }
-
-    bool operator ==(const GrRect& r) const {
-        return fLeft == r.fLeft     &&
-               fTop == r.fTop       &&
-               fRight == r.fRight   &&
-               fBottom == r.fBottom;
+        fLeft   = SkToS16(r.fLeft);
+        fTop    = SkToS16(r.fTop);
+        fRight  = SkToS16(r.fRight);
+        fBottom = SkToS16(r.fBottom);
     }
 };
 
diff --git a/gpu/src/GrClip.cpp b/gpu/src/GrClip.cpp
index 425ad27..2d1680c 100644
--- a/gpu/src/GrClip.cpp
+++ b/gpu/src/GrClip.cpp
@@ -87,6 +87,12 @@
     }
 }
 
+static void intersectWith(SkRect* dst, const SkRect& src) {
+    if (!dst->intersect(src)) {
+        dst->setEmpty();
+    }
+}
+
 void GrClip::setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty,
                              const GrRect* conservativeBounds) {
     fList.reset();
@@ -118,7 +124,7 @@
                                 rectCount = 1;
                                 fList.pop_back();
                                 GrAssert(kRect_ClipType == fList.back().fType);
-                                fList.back().fRect.intersectWith(e.fRect);
+                                intersectWith(&fList.back().fRect, e.fRect);
                             }
                         } else {
                             isectRectValid = false;
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index ff3119a..8461187 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -550,7 +550,7 @@
     // clip gets applied in second pass
     target->disableState(GrDrawTarget::kClip_StateBit);
 
-    GrIRect clear(0, 0, scale * boundW, scale * boundH);
+    GrIRect clear = SkIRect::MakeWH(scale * boundW, scale * boundH);
     target->clear(&clear, 0x0);
 
     return true;
@@ -590,15 +590,14 @@
                          scale * GR_Scalar1 / src->height());
         sampler.setMatrix(sampleM);
         target->setSamplerState(kOffscreenStage, sampler);
-        GrRect rect(0, 0,
-                    scale * boundRect.width(),
-                    scale * boundRect.height());
+        GrRect rect = SkRect::MakeWH(scale * boundRect.width(),
+                                     scale * boundRect.height());
         target->drawSimpleRect(rect, NULL, 1 << kOffscreenStage);
         
         src = record->fEntry1->texture();
     } else if (OffscreenRecord::kFSAA_Downsample == record->fDownsample) {
         scale = 1;
-        GrIRect rect(0, 0, boundRect.width(), boundRect.height());
+        GrIRect rect = SkIRect::MakeWH(boundRect.width(), boundRect.height());
         src->asRenderTarget()->overrideResolveRect(rect);
     } else {
         GrAssert(OffscreenRecord::k4x4SinglePass_Downsample == 
@@ -624,8 +623,9 @@
     sampler.preConcatMatrix(sampleM);
     target->setSamplerState(kOffscreenStage, sampler);
 
-    GrRect dstRect(boundRect);
+    GrRect dstRect;
     int stages = (1 << kOffscreenStage) | (NULL == paint.getTexture() ? 0 : 1);
+    dstRect.set(boundRect);
     target->drawSimpleRect(dstRect, NULL, stages);
 
     this->unlockTexture(record->fEntry0);
@@ -840,6 +840,14 @@
                         0, 0, 16, aaStrokeRectIndexCount());
 }
 
+/**
+ * Returns true if the rects edges are integer-aligned.
+ */
+static bool isIRect(const GrRect& r) {
+    return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) && 
+           GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom);
+}
+
 static bool apply_aa_to_rect(GrDrawTarget* target,
                              GrGpu* gpu,
                              const GrPaint& paint,
@@ -884,7 +892,7 @@
     devRect->sort();
 
     if (width < 0) {
-        return !devRect->isIRect();
+        return !isIRect(*devRect);
     } else {
         return true;
     }
@@ -1163,13 +1171,12 @@
         bool needsStencil = pr->requiresStencilPass(target, path, fill);
 
         // compute bounds as intersection of rt size, clip, and path
-        GrIRect bound(0, 0, 
-                      target->getRenderTarget()->width(), 
-                      target->getRenderTarget()->height());
+        GrIRect bound = SkIRect::MakeWH(target->getRenderTarget()->width(), 
+                                        target->getRenderTarget()->height());
         if (target->getClip().hasConservativeBounds()) {
             GrIRect clipIBounds;
             target->getClip().getConservativeBounds().roundOut(&clipIBounds);
-            if (!bound.intersectWith(clipIBounds)) {
+            if (!bound.intersect(clipIBounds)) {
                 return;
             }
         }
@@ -1178,7 +1185,7 @@
             GrIRect pathIBounds;
             target->getViewMatrix().mapRect(&pathBounds, pathBounds);
             pathBounds.roundOut(&pathIBounds);
-            if (!bound.intersectWith(pathIBounds)) {
+            if (!bound.intersect(pathIBounds)) {
                 return;
             }
         }
diff --git a/gpu/src/GrGpu.cpp b/gpu/src/GrGpu.cpp
index 66105db..9950afd 100644
--- a/gpu/src/GrGpu.cpp
+++ b/gpu/src/GrGpu.cpp
@@ -399,7 +399,9 @@
                        GrIntToScalar(rt.width()), GrIntToScalar(rt.height()));
         if (fClip.hasConservativeBounds()) {
             bounds = fClip.getConservativeBounds();
-            bounds.intersectWith(rtRect);
+            if (!bounds.intersect(rtRect)) {
+                bounds.setEmpty();
+            }
         } else {
             bounds = rtRect;
         }
diff --git a/gpu/src/GrGpuGL.cpp b/gpu/src/GrGpuGL.cpp
index c63c766..e8c7afb 100644
--- a/gpu/src/GrGpuGL.cpp
+++ b/gpu/src/GrGpuGL.cpp
@@ -1175,10 +1175,9 @@
     if (NULL != rect) {
         // flushScissor expects rect to be clipped to the target.
         r = *rect;
-        GrIRect rtRect(0, 0, 
-                       fCurrDrawState.fRenderTarget->width(),
-                       fCurrDrawState.fRenderTarget->height());
-        if (r.intersectWith(rtRect)) {
+        GrIRect rtRect = SkIRect::MakeWH(fCurrDrawState.fRenderTarget->width(),
+                                         fCurrDrawState.fRenderTarget->height());
+        if (r.intersect(rtRect)) {
             rect = &r;
         } else {
             return;
diff --git a/gpu/src/GrMatrix.cpp b/gpu/src/GrMatrix.cpp
index b169d19..c88c6e1 100644
--- a/gpu/src/GrMatrix.cpp
+++ b/gpu/src/GrMatrix.cpp
@@ -717,33 +717,3 @@
     return count;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-#include "GrRect.h"
-
-void GrRect::setBounds(const GrPoint pts[], int count) {
-    if (count <= 0) {
-        this->setEmpty();
-    } else {
-        GrScalar L, R, T, B;
-        L = R = pts[0].fX;
-        T = B = pts[0].fY;
-        for (int i = 1; i < count; i++) {
-            GrScalar x = pts[i].fX;
-            GrScalar y = pts[i].fY;
-            if (x < L) {
-                L = x;
-            } else if (x > R) {
-                R = x;
-            }
-            if (y < T) {
-                T = y;
-            } else if (y > B) {
-                B = y;
-            }
-        }
-        this->setLTRB(L, T, R, B);
-    }
-}
-
-
-
diff --git a/gpu/src/GrPath.cpp b/gpu/src/GrPath.cpp
index 3687b80..aa89d37 100644
--- a/gpu/src/GrPath.cpp
+++ b/gpu/src/GrPath.cpp
@@ -104,7 +104,7 @@
         iter->offset(tx, ty);
         ++iter;
     }
-    fConservativeBounds.translate(tx, ty);
+    fConservativeBounds.offset(tx, ty);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -221,7 +221,7 @@
         }
         int n = NumPathCmdPoints(cmd);
         for (int i = 0; i < n; ++i) {
-            fConservativeBounds.growToInclude(pts[i]);
+            fConservativeBounds.growToInclude(pts[i].fX, pts[i].fY);
         }
         if (0 == subPathPts && n > 0) {
             previousPt = pts[0];
@@ -423,6 +423,13 @@
     this->rewind();
 }
 
+#ifdef SK_DEBUG
+static bool containsInclusive(const GrRect& rect, const GrPoint& point) {
+    return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
+            point.fY >= rect.fTop && point.fY <= rect.fBottom;
+}
+#endif
+
 GrPathCmd GrPath::Iter::next(GrPoint points[]) {
     if (fCmdIndex == fPath->fCmds.count()) {
         GrAssert(fPtIndex == fPath->fPts.count());
@@ -441,7 +448,7 @@
             }
             fLastPt = srcPts[0];
             GrAssert(fPtIndex <= fPath->fPts.count() + 1);
-            GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[0]));
+            GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[0]));
             fPtIndex += 1;
             break;
         case kLine_PathCmd:
@@ -451,7 +458,7 @@
             }
             fLastPt = srcPts[0];
             GrAssert(fPtIndex <= fPath->fPts.count() + 1);
-            GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[0]));
+            GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[0]));
             fPtIndex += 1;
             break;
         case kQuadratic_PathCmd:
@@ -462,8 +469,8 @@
             }
             fLastPt = srcPts[1];
             GrAssert(fPtIndex <= fPath->fPts.count() + 2);
-            GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[0]));
-            GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[1]));
+            GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[0]));
+            GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[1]));
             fPtIndex += 2;
             break;
         case kCubic_PathCmd:
@@ -475,9 +482,9 @@
             }
             fLastPt = srcPts[2];
             GrAssert(fPtIndex <= fPath->fPts.count() + 3);
-            GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[0]));
-            GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[1]));
-            GrAssert(fPath->getConservativeBounds().containsInclusive(srcPts[2]));
+            GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[0]));
+            GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[1]));
+            GrAssert(containsInclusive(fPath->getConservativeBounds(), srcPts[2]));
             fPtIndex += 3;
             break;
         case kClose_PathCmd:
diff --git a/gpu/src/GrTexture.cpp b/gpu/src/GrTexture.cpp
index 8ee531c..8df9c9e 100644
--- a/gpu/src/GrTexture.cpp
+++ b/gpu/src/GrTexture.cpp
@@ -32,8 +32,10 @@
 void GrRenderTarget::flagAsNeedingResolve(const GrIRect* rect) {
     if (kCanResolve_ResolveType == getResolveType()) {
         if (NULL != rect) {
-            fResolveRect.growToInclude(*rect);
-            fResolveRect.intersectWith(0, 0, this->width(), this->height());
+            fResolveRect.join(*rect);
+            if (!fResolveRect.intersect(0, 0, this->width(), this->height())) {
+                fResolveRect.setEmpty();
+            }
         } else {
             fResolveRect.setLTRB(0, 0, this->width(), this->height());
         }
@@ -45,7 +47,7 @@
     if (fResolveRect.isEmpty()) {
         fResolveRect.setLargestInverted();
     } else {
-        if (!fResolveRect.intersectWith(0, 0, this->width(), this->height())) {
+        if (!fResolveRect.intersect(0, 0, this->width(), this->height())) {
             fResolveRect.setLargestInverted();
         }
     }
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index 53c61ea..49acf63 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -94,6 +94,10 @@
         fRight  = right;
         fBottom = bottom;
     }
+    // alias for set(l, t, r, b)
+    void setLTRB(int32_t left, int32_t top, int32_t right, int32_t bottom) {
+        this->set(left, top, right, bottom);
+    }
 
     void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height) {
         fLeft = x;
@@ -101,6 +105,23 @@
         fRight = x + width;
         fBottom = y + height;
     }
+
+    /**
+     *  Make the largest representable rectangle
+     */
+    void setLargest() {
+        fLeft = fTop = SK_MinS32;
+        fRight = fBottom = SK_MaxS32;
+    }
+    
+    /**
+     *  Make the largest representable rectangle, but inverted (e.g. fLeft will
+     *  be max 32bit and right will be min 32bit).
+     */
+    void setLargestInverted() {
+        fLeft = fTop = SK_MaxS32;
+        fRight = fBottom = SK_MinS32;
+    }
     
     /** Offset set the rectangle by adding dx to its left and right,
         and adding dy to its top and bottom.
@@ -127,6 +148,10 @@
         fBottom -= dy;
     }
 
+    bool quickReject(int l, int t, int r, int b) const {
+        return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
+    }
+    
     /** Returns true if (x,y) is inside the rectangle and the rectangle is not
         empty. The left and top are considered to be inside, while the right
         and bottom are not. Thus for the rectangle (0, 0, 5, 10), the
@@ -263,6 +288,11 @@
         When this returns, left <= right && top <= bottom
     */
     void sort();
+
+    static const SkIRect& EmptyIRect() {
+        static const SkIRect gEmpty = {0};
+        return gEmpty;
+    }
 };
 
 /** \struct SkRect
@@ -304,6 +334,10 @@
     */
     bool        isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
     bool        hasValidCoordinates() const;
+    SkScalar    left() const { return fLeft; }
+    SkScalar    top() const { return fTop; }
+    SkScalar    right() const { return fRight; }
+    SkScalar    bottom() const { return fBottom; }
     SkScalar    width() const { return fRight - fLeft; }
     SkScalar    height() const { return fBottom - fTop; }
     SkScalar    centerX() const { return SkScalarHalf(fLeft + fRight); }
@@ -338,7 +372,11 @@
         fRight  = right;
         fBottom = bottom;
     }
-    
+    // alias for set(l, t, r, b)
+    void setLTRB(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
+        this->set(left, top, right, bottom);
+    }
+
     /** Initialize the rect with the 4 specified integers. The routine handles
         converting them to scalars (by calling SkIntToScalar)
      */
@@ -355,6 +393,11 @@
     */
     void set(const SkPoint pts[], int count);
 
+    // alias for set(pts, count)
+    void setBounds(const SkPoint pts[], int count) {
+        this->set(pts, count);
+    }
+
     void setXYWH(SkScalar x, SkScalar y, SkScalar width, SkScalar height) {
         fLeft = x;
         fTop = y;
@@ -362,6 +405,23 @@
         fBottom = y + height;
     }
 
+    /**
+     *  Make the largest representable rectangle
+     */
+    void setLargest() {
+        fLeft = fTop = SK_ScalarMin;
+        fRight = fBottom = SK_ScalarMax;
+    }
+    
+    /**
+     *  Make the largest representable rectangle, but inverted (e.g. fLeft will
+     *  be max and right will be min).
+     */
+    void setLargestInverted() {
+        fLeft = fTop = SK_ScalarMax;
+        fRight = fBottom = SK_ScalarMin;
+    }
+
     /** Offset set the rectangle by adding dx to its left and right,
         and adding dy to its top and bottom.
     */
@@ -433,6 +493,15 @@
     void join(const SkRect& r) {
         this->join(r.fLeft, r.fTop, r.fRight, r.fBottom);
     }
+    // alias for join()
+    void growToInclude(const SkRect& r) { this->join(r); }
+
+    void growToInclude(SkScalar x, SkScalar y) {
+        fLeft  = SkMinScalar(x, fLeft);
+        fRight = SkMaxScalar(y, fRight);
+        fTop    = SkMinScalar(x, fTop);
+        fBottom = SkMaxScalar(y, fBottom);
+    }
     
     /** Returns true if (p.fX,p.fY) is inside the rectangle. The left and top coordinates of
         the rectangle are considered to be inside, while the right and bottom coordinates
diff --git a/include/gpu/SkGr.h b/include/gpu/SkGr.h
index bcb6766..eef70b1 100644
--- a/include/gpu/SkGr.h
+++ b/include/gpu/SkGr.h
@@ -104,27 +104,8 @@
 
 #include "SkColorPriv.h"
 
-static inline GrRect Sk2Gr(const SkRect& src) {
-    return GrRect(SkScalarToGrScalar(src.fLeft),
-                  SkScalarToGrScalar(src.fTop),
-                  SkScalarToGrScalar(src.fRight),
-                  SkScalarToGrScalar(src.fBottom));
-}
-
 class SkGr {
 public:
-    static inline SkIRect& SetIRect(SkIRect* dst, const GrIRect& src) {
-        GR_STATIC_ASSERT(sizeof(*dst) == sizeof(src));
-        memcpy(dst, &src, sizeof(*dst));
-        return *dst;
-    }
-
-    static inline GrIRect& SetIRect(GrIRect* dst, const SkIRect& src) {
-        GR_STATIC_ASSERT(sizeof(*dst) == sizeof(src));
-        memcpy(dst, &src, sizeof(*dst));
-        return *dst;
-    }
-
     /**
      *  Convert the SkBitmap::Config to the corresponding PixelConfig, or
      *  kUnknown_PixelConfig if the conversion cannot be done.
@@ -203,7 +184,7 @@
         if (!fCurr->fRect) {
             rect->setEmpty();
         } else {
-            *rect = Sk2Gr(*fCurr->fRect);
+            *rect = *fCurr->fRect;
         }
     }
 
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 2a50177..afd5bd3 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -691,7 +691,7 @@
     if (!this->skPaint2GrPaintShader(paint, &act, *draw.fMatrix,  &grPaint)) {
         return;
     }
-    fContext->drawRect(grPaint, Sk2Gr(rect), doStroke ? width : -1);
+    fContext->drawRect(grPaint, rect, doStroke ? width : -1);
 }
 
 #include "SkMaskFilter.h"
@@ -967,7 +967,8 @@
 
     grPaint->setTexture(texture);
 
-    GrRect dstRect(0, 0, GrIntToScalar(srcRect.width()), GrIntToScalar(srcRect.height()));
+    GrRect dstRect = SkRect::MakeWH(GrIntToScalar(srcRect.width()),
+                                    GrIntToScalar(srcRect.height()));
     GrRect paintRect;
     paintRect.setLTRB(GrFixedToScalar((srcRect.fLeft << 16)   / bitmap.width()),
                       GrFixedToScalar((srcRect.fTop << 16)    / bitmap.height()),
@@ -1003,10 +1004,11 @@
     grPaint.setTexture(texture);
 
     fContext->drawRectToRect(grPaint,
-                             GrRect(GrIntToScalar(left), GrIntToScalar(top),
-                                    GrIntToScalar(left + bitmap.width()),
-                                    GrIntToScalar(top + bitmap.height())),
-                             GrRect(0, 0, GR_Scalar1, GR_Scalar1));
+                             GrRect::MakeXYWH(GrIntToScalar(left),
+                                              GrIntToScalar(top),
+                                              GrIntToScalar(bitmap.width()),
+                                              GrIntToScalar(bitmap.height())),
+                             GrRect::MakeWH(GR_Scalar1, GR_Scalar1));
 }
 
 void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* dev,
@@ -1030,11 +1032,11 @@
     grPaint.fSampler.setClampNoFilter();
 
     fContext->drawRectToRect(grPaint,
-                             GrRect(GrIntToScalar(x),
-                                    GrIntToScalar(y),
-                                    GrIntToScalar(x + w),
-                                    GrIntToScalar(y + h)),
-                             GrRect(0, 0, GR_Scalar1, GR_Scalar1));
+                             GrRect::MakeXYWH(GrIntToScalar(x),
+                                              GrIntToScalar(y),
+                                              GrIntToScalar(w),
+                                              GrIntToScalar(h)),
+                             GrRect::MakeWH(GR_Scalar1, GR_Scalar1));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 23918f9..f65cf1e 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -144,7 +144,7 @@
 }
 
 bool SkGrPathIter::getConservativeBounds(GrRect* rect) const {
-    *rect = Sk2Gr(fPath->getBounds());
+    *rect = fPath->getBounds();
     return true;
 }