Convert AAClipCache's GrRects to GrIRects
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 15 May 2012 16:47:23 +0000 (16:47 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 15 May 2012 16:47:23 +0000 (16:47 +0000)
http://codereview.appspot.com/6210057/

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

include/core/SkRect.h
src/gpu/GrClipMaskManager.cpp
src/gpu/GrClipMaskManager.h
tests/ClipCacheTest.cpp

index 7026277..2fa3256 100644 (file)
@@ -144,7 +144,7 @@ struct SK_API SkIRect {
 
     /** Inset the rectangle by (dx,dy). If dx is positive, then the sides are moved inwards,
         making the rectangle narrower. If dx is negative, then the sides are moved outwards,
-        making the rectangle wider. The same hods true for dy and the top and bottom.
+        making the rectangle wider. The same holds true for dy and the top and bottom.
     */
     void inset(int32_t dx, int32_t dy) {
         fLeft   += dx;
@@ -153,6 +153,13 @@ struct SK_API SkIRect {
         fBottom -= dy;
     }
 
+   /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are
+       moved outwards, making the rectangle wider. If dx is negative, then the
+       sides are moved inwards, making the rectangle narrower. The same holds
+       true for dy and the top and bottom.
+    */
+    void outset(int32_t dx, int32_t dy)  { this->inset(-dx, -dy); }
+
     bool quickReject(int l, int t, int r, int b) const {
         return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
     }
@@ -481,7 +488,7 @@ struct SK_API SkRect {
 
    /** Outset the rectangle by (dx,dy). If dx is positive, then the sides are
        moved outwards, making the rectangle wider. If dx is negative, then the
-       sides are moved inwards, making the rectangle narrower. The same hods
+       sides are moved inwards, making the rectangle narrower. The same holds
        true for dy and the top and bottom.
     */
     void outset(SkScalar dx, SkScalar dy)  { this->inset(-dx, -dy); }
index 43b2743..15aae1e 100644 (file)
@@ -32,7 +32,7 @@ namespace {
 // sampler matrix this also alters the vertex layout
 void setup_drawstate_aaclip(GrGpu* gpu, 
                             GrTexture* result, 
-                            const GrRect &bound) {
+                            const GrIRect &bound) {
     GrDrawState* drawState = gpu->drawState();
     GrAssert(drawState);
 
@@ -40,7 +40,7 @@ void setup_drawstate_aaclip(GrGpu* gpu,
 
     GrMatrix mat;
     mat.setIDiv(result->width(), result->height());
-    mat.preTranslate(-bound.fLeft, -bound.fTop);
+    mat.preTranslate(SkIntToScalar(-bound.fLeft), SkIntToScalar(-bound.fTop));
     mat.preConcat(drawState->getViewMatrix());
 
     drawState->sampler(maskStage)->reset(GrSamplerState::kClamp_WrapMode,
@@ -89,7 +89,7 @@ bool GrClipMaskManager::createClipMask(GrGpu* gpu,
         // The clip geometry is complex enough that it will be more
         // efficient to create it entirely in software
         GrTexture* result = NULL;
-        GrRect bound;
+        GrIRect bound;
         if (this->createSoftwareClipMask(gpu, clipIn, &result, &bound)) {
             fClipMaskInAlpha = true;
 
@@ -108,7 +108,7 @@ bool GrClipMaskManager::createClipMask(GrGpu* gpu,
         // render target) we aren't going to use scissoring like the stencil
         // path does (see scissorSettings below)
         GrTexture* result = NULL;
-        GrRect bound;
+        GrIRect bound;
         if (this->createAlphaClipMask(gpu, clipIn, &result, &bound)) {
             fClipMaskInAlpha = true;
 
@@ -165,12 +165,25 @@ bool GrClipMaskManager::createClipMask(GrGpu* gpu,
 #endif
 
 namespace {
+/**
+ * Does "container" contain "containee"? If either is empty then
+ * no containment is possible.
+ */
+bool contains(const SkRect& container, const SkIRect& containee) {
+    return  !containee.isEmpty() && !container.isEmpty() &&
+            container.fLeft <= SkIntToScalar(containee.fLeft) && 
+            container.fTop <= SkIntToScalar(containee.fTop) &&
+            container.fRight >= SkIntToScalar(containee.fRight) && 
+            container.fBottom >= SkIntToScalar(containee.fBottom);
+}
+
+
 ////////////////////////////////////////////////////////////////////////////////
 // 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.
 int process_initial_clip_elements(const GrClip& clip,
-                                  const GrRect& bounds,
+                                  const GrIRect& bounds,
                                   bool* clearToInside,
                                   SkRegion::Op* startOp) {
 
@@ -196,7 +209,7 @@ int process_initial_clip_elements(const GrClip& clip,
                 // if this element contains the entire bounds then we
                 // can skip it.
                 if (kRect_ClipType == clip.getElementType(curr)
-                    && clip.getRect(curr).contains(bounds)) {
+                    && contains(clip.getRect(curr), bounds)) {
                     break;
                 }
                 // if everything is initially clearToInside then intersect is
@@ -378,7 +391,7 @@ void clear(GrGpu* gpu,
 
 // get a texture to act as a temporary buffer for AA clip boolean operations
 // TODO: given the expense of createTexture we may want to just cache this too
-void GrClipMaskManager::getTemp(const GrRect& bounds, 
+void GrClipMaskManager::getTemp(const GrIRect& bounds, 
                                 GrAutoScratchTexture* temp) {
     if (NULL != temp->texture()) {
         // we've already allocated the temp texture
@@ -387,8 +400,8 @@ void GrClipMaskManager::getTemp(const GrRect& bounds,
 
     const GrTextureDesc desc = {
         kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit,
-        SkScalarCeilToInt(bounds.width()),
-        SkScalarCeilToInt(bounds.height()),
+        bounds.width(),
+        bounds.height(),
         kAlpha_8_GrPixelConfig,
         0           // samples
     };
@@ -398,15 +411,15 @@ void GrClipMaskManager::getTemp(const GrRect& bounds,
 
 
 void GrClipMaskManager::setupCache(const GrClip& clipIn,
-                                   const GrRect& bounds) {
+                                   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
     fAACache.reset();
 
     const GrTextureDesc desc = {
         kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit,
-        SkScalarCeilToInt(bounds.width()),
-        SkScalarCeilToInt(bounds.height()),
+        bounds.width(),
+        bounds.height(),
         kAlpha_8_GrPixelConfig,
         0           // samples
     };
@@ -422,7 +435,7 @@ void GrClipMaskManager::setupCache(const GrClip& clipIn,
 bool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu,
                                          const GrClip& clipIn,
                                          GrTexture** result,
-                                         GrRect *resultBounds) {
+                                         GrIRect *resultBounds) {
     GrDrawState* origDrawState = gpu->drawState();
     GrAssert(origDrawState->isClipState());
 
@@ -449,28 +462,26 @@ bool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu,
         bounds = rtRect;
     }
 
-    bounds.roundOut();
+    GrIRect intBounds;
+    bounds.roundOut(&intBounds);
 
     // need to outset a pixel since the standard bounding box computation
     // path doesn't leave any room for antialiasing (esp. w.r.t. rects)
-    bounds.outset(SkIntToScalar(1), SkIntToScalar(1));
+    intBounds.outset(1, 1);
 
     // TODO: make sure we don't outset if bounds are still 0,0 @ min
 
-    GrAssert(SkScalarIsInt(bounds.width()));
-    GrAssert(SkScalarIsInt(bounds.height()));
-
     if (fAACache.canReuse(clipIn, 
-                          SkScalarCeilToInt(bounds.width()),
-                          SkScalarCeilToInt(bounds.height()))) {
+                          intBounds.width(),
+                          intBounds.height())) {
         *result = fAACache.getLastMask();
         fAACache.getLastBound(resultBounds);
         return true;
     }
 
-    this->setupCache(clipIn, bounds);
+    this->setupCache(clipIn, intBounds);
 
-    *resultBounds = bounds;
+    *resultBounds = intBounds;
     return false;
 }
 
@@ -479,7 +490,7 @@ bool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu,
 bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
                                             const GrClip& clipIn,
                                             GrTexture** result,
-                                            GrRect *resultBounds) {
+                                            GrIRect *resultBounds) {
 
     if (this->clipMaskPreamble(gpu, clipIn, result, resultBounds)) {
         return true;
@@ -504,7 +515,8 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
         // offset the paths & rects that will be used to compute it
         GrMatrix m;
 
-        m.setTranslate(-resultBounds->fLeft, -resultBounds->fTop);
+        m.setTranslate(SkIntToScalar(-resultBounds->fLeft), 
+                       SkIntToScalar(-resultBounds->fTop));
 
         drawState->setViewMatrix(m);
     }
@@ -541,7 +553,7 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
             // there is no point in intersecting a screen filling rectangle.
             if (SkRegion::kIntersect_Op == op &&
                 kRect_ClipType == clipIn.getElementType(c) &&
-                clipIn.getRect(c).contains(*resultBounds)) {
+                contains(clipIn.getRect(c), *resultBounds)) {
                 continue;
             }
 
@@ -564,7 +576,8 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
             if (0 != resultBounds->fTop || 0 != resultBounds->fLeft) {
                 GrMatrix m;
 
-                m.setTranslate(resultBounds->fLeft, resultBounds->fTop);
+                m.setTranslate(SkIntToScalar(resultBounds->fLeft), 
+                               SkIntToScalar(resultBounds->fTop));
 
                 drawState->preConcatViewMatrix(m);
             }
@@ -577,7 +590,8 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
             if (0 != resultBounds->fTop || 0 != resultBounds->fLeft) {
                 GrMatrix m;
 
-                m.setTranslate(-resultBounds->fLeft, -resultBounds->fTop);
+                m.setTranslate(SkIntToScalar(-resultBounds->fLeft), 
+                               SkIntToScalar(-resultBounds->fTop));
 
                 drawState->preConcatViewMatrix(m);
             }
@@ -643,9 +657,7 @@ bool GrClipMaskManager::createStencilClipMask(GrGpu* gpu,
                     "Ganesh only handles 16b or smaller stencil buffers");
         clipBit = (1 << (clipBit-1));
 
-        GrRect rtRect;
-        rtRect.setLTRB(0, 0,
-                       GrIntToScalar(rt->width()), GrIntToScalar(rt->height()));
+        GrIRect rtRect = GrIRect::MakeWH(rt->width(), rt->height());
 
         bool clearToInside;
         SkRegion::Op startOp = SkRegion::kReplace_Op; // suppress warning
@@ -681,7 +693,7 @@ bool GrClipMaskManager::createStencilClipMask(GrGpu* gpu,
                 // there is no point in intersecting a screen filling
                 // rectangle.
                 if (SkRegion::kIntersect_Op == op &&
-                    clipCopy.getRect(c).contains(rtRect)) {
+                    contains(clipCopy.getRect(c), rtRect)) {
                     continue;
                 }
             } else {
@@ -769,7 +781,7 @@ bool GrClipMaskManager::createStencilClipMask(GrGpu* gpu,
 bool GrClipMaskManager::createSoftwareClipMask(GrGpu* gpu,
                                                const GrClip& clipIn,
                                                GrTexture** result,
-                                               GrRect *resultBounds) {
+                                               GrIRect *resultBounds) {
 
     if (this->clipMaskPreamble(gpu, clipIn, result, resultBounds)) {
         return true;
index c87bb7c..02fc875 100644 (file)
@@ -151,7 +151,7 @@ public:
 
     void acquireMask(const GrClip& clip,
                      const GrTextureDesc& desc,
-                     const GrRect& bound) {
+                     const GrIRect& bound) {
 
         if (fStack.empty()) {
             GrAssert(false);
@@ -195,7 +195,7 @@ public:
         return back->fLastMask.texture()->height();
     }
 
-    void getLastBound(GrRect* bound) const {
+    void getLastBound(GrIRect* bound) const {
 
         if (fStack.empty()) {
             GrAssert(false);
@@ -237,7 +237,7 @@ private:
         void acquireMask(GrContext* context,
                          const GrClip& clip, 
                          const GrTextureDesc& desc,
-                         const GrRect& bound) {
+                         const GrIRect& bound) {
 
             fLastClip = clip;
 
@@ -263,7 +263,7 @@ private:
         // fLastBound stores the bounding box of the clip mask in canvas 
         // space. The left and top fields are used to offset the uvs for 
         // geometry drawn with this mask (in setupDrawStateAAClip)
-        GrRect                  fLastBound;
+        GrIRect                 fLastBound;
     };
 
     GrContext*   fContext;
@@ -322,15 +322,15 @@ private:
     bool createAlphaClipMask(GrGpu* gpu,
                              const GrClip& clipIn,
                              GrTexture** result,
-                             GrRect *resultBounds);
+                             GrIRect *resultBounds);
     bool createSoftwareClipMask(GrGpu* gpu,
                                 const GrClip& clipIn,
                                 GrTexture** result,
-                                GrRect *resultBounds);
+                                GrIRect *resultBounds);
     bool clipMaskPreamble(GrGpu* gpu,
                           const GrClip& clipIn,
                           GrTexture** result,
-                          GrRect *resultBounds);
+                          GrIRect *resultBounds);
 
     bool drawPath(GrGpu* gpu,
                   const SkPath& path,
@@ -346,10 +346,10 @@ private:
                      GrTexture* target,
                      GrTexture* texture);
 
-    void getTemp(const GrRect& bounds, GrAutoScratchTexture* temp);
+    void getTemp(const GrIRect& bounds, GrAutoScratchTexture* temp);
 
     void setupCache(const GrClip& clip, 
-                    const GrRect& bounds);
+                    const GrIRect& bounds);
 
     // determines the path renderer used to draw a clip path element.
     GrPathRenderer* getClipPathRenderer(GrGpu* gpu,
index 1fc5d45..a0888d8 100644 (file)
@@ -42,14 +42,14 @@ static void check_state(skiatest::Reporter* reporter,
                         const GrClipMaskCache& cache,
                         const GrClip& clip,
                         GrTexture* mask,
-                        const GrRect& bound) {
+                        const GrIRect& bound) {
     GrClip cacheClip;
     cache.getLastClip(&cacheClip);
     REPORTER_ASSERT(reporter, clip == cacheClip);
 
     REPORTER_ASSERT(reporter, mask == cache.getLastMask());
 
-    GrRect cacheBound;
+    GrIRect cacheBound;
     cache.getLastBound(&cacheBound);
     REPORTER_ASSERT(reporter, bound == cacheBound);
 }
@@ -66,18 +66,18 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
     GrClip emptyClip;
     emptyClip.setEmpty();
 
-    GrRect emptyBound;
+    GrIRect emptyBound;
     emptyBound.setEmpty();
 
     // check initial state
     check_state(reporter, cache, emptyClip, NULL, emptyBound);
 
     // set the current state
-    GrRect bound1;
+    GrIRect bound1;
     bound1.set(0, 0, 100, 100);
 
     GrClip clip1;
-    clip1.setFromRect(bound1);
+    clip1.setFromIRect(bound1);
 
     const GrTextureDesc desc = {
         kRenderTarget_GrTextureFlagBit,
@@ -107,12 +107,12 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
     REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
 
     // modify the new state
-    GrRect bound2;
+    GrIRect bound2;
     bound2.set(-10, -10, 10, 10);
 
     GrClip clip2;
     clip2.setEmpty();
-    clip2.setFromRect(bound2);
+    clip2.setFromIRect(bound2);
 
     cache.acquireMask(clip2, desc, bound2);