Added dev- & canv- prefixes to Ganesh bounding boxes to indicate coordinate space
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 31 Jul 2012 15:18:21 +0000 (15:18 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Tue, 31 Jul 2012 15:18:21 +0000 (15:18 +0000)
http://codereview.appspot.com/6457061/

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

13 files changed:
include/core/SkClipStack.h
include/gpu/GrClip.h
src/core/SkClipStack.cpp
src/gpu/GrAAHairLinePathRenderer.cpp
src/gpu/GrClip.cpp
src/gpu/GrClipMaskManager.cpp
src/gpu/GrClipMaskManager.h
src/gpu/GrSoftwarePathRenderer.cpp
src/gpu/GrTextContext.cpp
src/gpu/SkGpuDevice.cpp
src/gpu/gl/GrGpuGL_program.cpp
tests/ClipCacheTest.cpp
tests/ClipStackTest.cpp

index 60ed9ed..c0fadb1 100644 (file)
@@ -51,13 +51,13 @@ public:
     /**
      * getBounds places the current finite bound in its first parameter. In its
      * second, it indicates which kind of bound is being returned. If 
-     * 'finiteBound' is a normal bounding box then it encloses all writeable
-     * pixels. If 'finiteBound' is an inside out bounding box then it 
+     * 'canvFiniteBound' is a normal bounding box then it encloses all writeable
+     * pixels. If 'canvFiniteBound' is an inside out bounding box then it 
      * encloses all the un-writeable pixels and the true/normal bound is the
      * infinite plane. isIntersectionOfRects is an optional parameter
-     * that is true if 'finiteBound' resulted from an intersection of rects.
+     * that is true if 'canvFiniteBound' resulted from an intersection of rects.
      */
-    void getBounds(SkRect* finiteBound, 
+    void getBounds(SkRect* canvFiniteBound, 
                    BoundsType* boundType,
                    bool* isIntersectionOfRects = NULL) const;
 
@@ -188,7 +188,7 @@ public:
                                int offsetY,
                                int maxWidth,
                                int maxHeight,
-                               SkRect* bounds,
+                               SkRect* devBounds,
                                bool* isIntersectionOfRects = NULL) const;
 
 private:
index bb07c28..cf646a1 100644 (file)
@@ -237,7 +237,7 @@ public:
     }
 
     void getConservativeBounds(const GrSurface* surface, 
-                               GrIRect* result,
+                               GrIRect* devResult,
                                bool* isIntersectionOfRects = NULL) const;
 };
 
index 673981b..d2c2035 100644 (file)
@@ -449,16 +449,16 @@ void SkClipStack::restore() {
     }
 }
 
-void SkClipStack::getBounds(SkRect* finiteBound, 
+void SkClipStack::getBounds(SkRect* canvFiniteBound, 
                             BoundsType* boundType,
                             bool* isIntersectionOfRects) const {
-    SkASSERT(NULL != finiteBound && NULL != boundType);
+    SkASSERT(NULL != canvFiniteBound && NULL != boundType);
 
     Rec* rec = (Rec*)fDeque.back();
 
     if (NULL == rec) {
         // the clip is wide open - the infinite plane w/ no pixels un-writeable
-        finiteBound->setEmpty();
+        canvFiniteBound->setEmpty();
         *boundType = kInsideOut_BoundsType;
         if (NULL != isIntersectionOfRects) {
             *isIntersectionOfRects = false;
@@ -466,7 +466,7 @@ void SkClipStack::getBounds(SkRect* finiteBound,
         return;
     }
 
-    *finiteBound = rec->fFiniteBound;
+    *canvFiniteBound = rec->fFiniteBound;
     *boundType = rec->fFiniteBoundType;
     if (NULL != isIntersectionOfRects) {
         *isIntersectionOfRects = rec->fIsIntersectionOfRects;
@@ -673,24 +673,26 @@ void SkClipStack::getConservativeBounds(int offsetX,
                                         int offsetY,
                                         int maxWidth,
                                         int maxHeight,
-                                        SkRect* bounds,
+                                        SkRect* devBounds,
                                         bool* isIntersectionOfRects) const {
-    SkASSERT(NULL != bounds);
+    SkASSERT(NULL != devBounds);
 
-    bounds->setLTRB(0, 0, 
-                    SkIntToScalar(maxWidth), SkIntToScalar(maxHeight));
+    devBounds->setLTRB(0, 0, 
+                       SkIntToScalar(maxWidth), SkIntToScalar(maxHeight));
 
     SkRect temp;
     SkClipStack::BoundsType boundType;
     
+    // temp starts off in canvas space here
     this->getBounds(&temp, &boundType, isIntersectionOfRects);
     if (SkClipStack::kInsideOut_BoundsType == boundType) {
         return;
     }
 
+    // but is converted to device space here
     temp.offset(SkIntToScalar(offsetX), SkIntToScalar(offsetY));
 
-    if (!bounds->intersect(temp)) {
-        bounds->setEmpty();
+    if (!devBounds->intersect(temp)) {
+        devBounds->setEmpty();
     }
 }
index 13d6155..43e87d6 100644 (file)
@@ -198,7 +198,7 @@ int num_quad_subdivs(const SkPoint p[3]) {
 int generate_lines_and_quads(const SkPath& path,
                              const SkMatrix& m,
                              const SkVector& translate,
-                             GrIRect clip,
+                             const GrIRect& devClipBounds,
                              PtArray* lines,
                              PtArray* quads,
                              IntArray* quadSubdivCnts) {
@@ -223,7 +223,7 @@ int generate_lines_and_quads(const SkPath& path,
                 bounds.setBounds(devPts, 2);
                 bounds.outset(SK_Scalar1, SK_Scalar1);
                 bounds.roundOut(&ibounds);
-                if (SkIRect::Intersects(clip, ibounds)) {
+                if (SkIRect::Intersects(devClipBounds, ibounds)) {
                     SkPoint* pts = lines->push_back_n(2);
                     pts[0] = devPts[0];
                     pts[1] = devPts[1];
@@ -235,7 +235,7 @@ int generate_lines_and_quads(const SkPath& path,
                 bounds.setBounds(devPts, 3);
                 bounds.outset(SK_Scalar1, SK_Scalar1);
                 bounds.roundOut(&ibounds);
-                if (SkIRect::Intersects(clip, ibounds)) {
+                if (SkIRect::Intersects(devClipBounds, ibounds)) {
                     int subdiv = num_quad_subdivs(devPts);
                     GrAssert(subdiv >= -1);
                     if (-1 == subdiv) {
@@ -262,7 +262,7 @@ int generate_lines_and_quads(const SkPath& path,
                 bounds.setBounds(devPts, 4);
                 bounds.outset(SK_Scalar1, SK_Scalar1);
                 bounds.roundOut(&ibounds);
-                if (SkIRect::Intersects(clip, ibounds)) {
+                if (SkIRect::Intersects(devClipBounds, ibounds)) {
                     PREALLOC_PTARRAY(32) q;
                     // we don't need a direction if we aren't constraining the subdivision
                     static const SkPath::Direction kDummyDir = SkPath::kCCW_Direction;
@@ -290,7 +290,7 @@ int generate_lines_and_quads(const SkPath& path,
                         }
                         bounds.outset(SK_Scalar1, SK_Scalar1);
                         bounds.roundOut(&ibounds);
-                        if (SkIRect::Intersects(clip, ibounds)) {
+                        if (SkIRect::Intersects(devClipBounds, ibounds)) {
                             int subdiv = num_quad_subdivs(qInDevSpace);
                             GrAssert(subdiv >= -1);
                             if (-1 == subdiv) {
@@ -511,8 +511,9 @@ bool GrAAHairLinePathRenderer::createGeom(
     const GrDrawState& drawState = target->getDrawState();
     int rtHeight = drawState.getRenderTarget()->height();
 
-    GrIRect clip;
-    target->getClip()->getConservativeBounds(drawState.getRenderTarget(), &clip);
+    GrIRect devClipBounds;
+    target->getClip()->getConservativeBounds(drawState.getRenderTarget(), 
+                                             &devClipBounds);
 
     GrVertexLayout layout = GrDrawTarget::kEdge_VertexLayoutBit;
     GrMatrix viewM = drawState.getViewMatrix();
@@ -524,7 +525,7 @@ bool GrAAHairLinePathRenderer::createGeom(
     if (NULL == translate) {
         translate = &gZeroVec;
     }
-    *quadCnt = generate_lines_and_quads(path, viewM, *translate, clip,
+    *quadCnt = generate_lines_and_quads(path, viewM, *translate, devClipBounds,
                                         &lines, &quads, &qSubdivs);
 
     *lineCnt = lines.count() / 2;
index a3905ba..e8ea9a6 100644 (file)
@@ -252,7 +252,7 @@ void GrClip::Iter::reset(const GrClip& stack, IterStart startLoc) {
  * isIntersectionOfRects will be set to true.
  */
 void GrClipData::getConservativeBounds(const GrSurface* surface,
-                                       GrIRect* result,
+                                       GrIRect* devResult,
                                        bool* isIntersectionOfRects) const {
 
     // Until we switch to using the SkClipStack directly we need to take
@@ -264,8 +264,10 @@ void GrClipData::getConservativeBounds(const GrSurface* surface,
                                    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));
 
@@ -273,7 +275,7 @@ void GrClipData::getConservativeBounds(const GrSurface* surface,
         conservativeBounds.setEmpty();
     }
 
-    conservativeBounds.roundOut(result);
+    conservativeBounds.roundOut(devResult);
 
     if (NULL != isIntersectionOfRects) {
         *isIntersectionOfRects = fClipStack->isRect();
index 97c102f..71743a0 100644 (file)
@@ -38,7 +38,7 @@ namespace {
 // sampler matrix this also alters the vertex layout
 void setup_drawstate_aaclip(GrGpu* gpu, 
                             GrTexture* result, 
-                            const GrIRect &bound) {
+                            const GrIRect &devBound) {
     GrDrawState* drawState = gpu->drawState();
     GrAssert(drawState);
 
@@ -46,7 +46,8 @@ void setup_drawstate_aaclip(GrGpu* gpu,
 
     GrMatrix mat;
     mat.setIDiv(result->width(), result->height());
-    mat.preTranslate(SkIntToScalar(-bound.fLeft), SkIntToScalar(-bound.fTop));
+    mat.preTranslate(SkIntToScalar(-devBound.fLeft), 
+                     SkIntToScalar(-devBound.fTop));
     mat.preConcat(drawState->getViewMatrix());
 
     drawState->sampler(maskStage)->reset(mat);
@@ -158,11 +159,12 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn) {
     // GrDrawTarget should have filtered this for us
     GrAssert(NULL != rt);
 
-    GrIRect bounds;
+    GrIRect devClipBounds;
     bool isIntersectionOfRects = false;
 
-    clipDataIn->getConservativeBounds(rt, &bounds, &isIntersectionOfRects);
-    if (bounds.isEmpty()) {
+    clipDataIn->getConservativeBounds(rt, &devClipBounds, 
+                                      &isIntersectionOfRects);
+    if (devClipBounds.isEmpty()) {
         return false;
     }
 
@@ -180,9 +182,9 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn) {
         // The clip geometry is complex enough that it will be more
         // efficient to create it entirely in software
         GrTexture* result = NULL;
-        GrIRect bound;
-        if (this->createSoftwareClipMask(*clipDataIn, &result, &bound)) {
-            setup_drawstate_aaclip(fGpu, result, bound);
+        GrIRect devBound;
+        if (this->createSoftwareClipMask(*clipDataIn, &result, &devBound)) {
+            setup_drawstate_aaclip(fGpu, result, devBound);
             fGpu->disableScissor();
             this->setGpuStencil();
             return true;
@@ -202,9 +204,9 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn) {
         // render target) we aren't going to use scissoring like the stencil
         // path does (see scissorSettings below)
         GrTexture* result = NULL;
-        GrIRect bound;
-        if (this->createAlphaClipMask(*clipDataIn, &result, &bound)) {
-            setup_drawstate_aaclip(fGpu, result, bound);
+        GrIRect devBound;
+        if (this->createAlphaClipMask(*clipDataIn, &result, &devBound)) {
+            setup_drawstate_aaclip(fGpu, result, devBound);
             fGpu->disableScissor();
             this->setGpuStencil();
             return true;
@@ -227,22 +229,23 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn) {
     // If the clip is a rectangle then just set the scissor. Otherwise, create
     // a stencil mask.
     if (isIntersectionOfRects) {
-        fGpu->enableScissor(bounds);
+        fGpu->enableScissor(devClipBounds);
         this->setGpuStencil();
         return true;
     }
 
     // use the stencil clip if we can't represent the clip as a rectangle.
-    bool useStencil = !clipDataIn->fClipStack->isWideOpen() && !bounds.isEmpty();
+    bool useStencil = !clipDataIn->fClipStack->isWideOpen() && 
+                      !devClipBounds.isEmpty();
 
     if (useStencil) {
-        this->createStencilClipMask(*clipDataIn, bounds);
+        this->createStencilClipMask(*clipDataIn, devClipBounds);
     }
     // This must occur after createStencilClipMask. That function may change
     // the scissor. Also, it only guarantees that the stencil mask is correct
     // within the bounds it was passed, so we must use both stencil and scissor
     // test to the bounds for the final draw.
-    fGpu->enableScissor(bounds);
+    fGpu->enableScissor(devClipBounds);
     this->setGpuStencil();
     return true;
 }
@@ -259,19 +262,19 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn) {
 
 namespace {
 /**
- * Does "container" contain "containee"? If either is empty then
- * no containment is possible. "container" is in canvas coordinates while
- * "containee" is in device coordiates. "origin" provides the mapping between
+ * Does "canvContainer" contain "devContainee"? If either is empty then
+ * no containment is possible. "canvContainer" is in canvas coordinates while
+ * "devContainee" is in device coordiates. "origin" provides the mapping between
  * the two.
  */
-bool contains(const SkRect& container, 
-              const SkIRect& containee,
+bool contains(const SkRect& canvContainer, 
+              const SkIRect& devContainee,
               const SkIPoint& origin) {
-    return  !containee.isEmpty() && !container.isEmpty() &&
-            container.fLeft <= SkIntToScalar(containee.fLeft+origin.fX) && 
-            container.fTop <= SkIntToScalar(containee.fTop+origin.fY) &&
-            container.fRight >= SkIntToScalar(containee.fRight+origin.fX) && 
-            container.fBottom >= SkIntToScalar(containee.fBottom+origin.fY);
+    return  !devContainee.isEmpty() && !canvContainer.isEmpty() &&
+            canvContainer.fLeft <= SkIntToScalar(devContainee.fLeft+origin.fX) && 
+            canvContainer.fTop <= SkIntToScalar(devContainee.fTop+origin.fY) &&
+            canvContainer.fRight >= SkIntToScalar(devContainee.fRight+origin.fX) && 
+            canvContainer.fBottom >= SkIntToScalar(devContainee.fBottom+origin.fY);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -280,7 +283,7 @@ bool contains(const SkRect& container,
 // 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 GrIRect& bounds,
+                                  const GrIRect& devBounds,
                                   bool* clearToInside,
                                   SkRegion::Op* firstOp,
                                   const GrClipData& clipData) {
@@ -311,7 +314,7 @@ const GrClip::Iter::Clip* process_initial_clip_elements(
                 // if this element contains the entire bounds then we
                 // can skip it.
                 if (NULL != clip->fRect &&
-                    contains(*clip->fRect, bounds, clipData.fOrigin)) {
+                    contains(*clip->fRect, devBounds, clipData.fOrigin)) {
                     break;
                 }
                 // if everything is initially clearToInside then intersect is
@@ -452,6 +455,16 @@ bool draw_path(GrContext* context,
     return true;
 }
 
+// 'rect' enters in device coordinates and leaves in canvas coordinates
+void device_to_canvas(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);
+}
+
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -544,7 +557,7 @@ void GrClipMaskManager::setupCache(const GrClip& clipIn,
 // Returns true if there is no more work to be done (i.e., we got a cache hit)
 bool GrClipMaskManager::clipMaskPreamble(const GrClipData& clipDataIn,
                                          GrTexture** result,
-                                         GrIRect* resultBounds) {
+                                         GrIRect* devResultBounds) {
     GrDrawState* origDrawState = fGpu->drawState();
     GrAssert(origDrawState->isClipState());
 
@@ -554,26 +567,26 @@ bool GrClipMaskManager::clipMaskPreamble(const GrClipData& clipDataIn,
     // unlike the stencil path the alpha path is not bound to the size of the
     // render target - determine the minimum size required for the mask
     // Note: intBounds is in device (as opposed to canvas) coordinates
-    GrIRect intBounds;
-    clipDataIn.getConservativeBounds(rt, &intBounds);
+    GrIRect devClipBounds;
+    clipDataIn.getConservativeBounds(rt, &devClipBounds);
 
     // need to outset a pixel since the standard bounding box computation
     // path doesn't leave any room for antialiasing (esp. w.r.t. rects)
-    intBounds.outset(1, 1);
+    devClipBounds.outset(1, 1);
 
     // TODO: make sure we don't outset if bounds are still 0,0 @ min
 
     if (fAACache.canReuse(*clipDataIn.fClipStack, 
-                          intBounds.width(),
-                          intBounds.height())) {
+                          devClipBounds.width(),
+                          devClipBounds.height())) {
         *result = fAACache.getLastMask();
-        fAACache.getLastBound(resultBounds);
+        fAACache.getLastBound(devResultBounds);
         return true;
     }
 
-    this->setupCache(*clipDataIn.fClipStack, intBounds);
+    this->setupCache(*clipDataIn.fClipStack, devClipBounds);
 
-    *resultBounds = intBounds;
+    *devResultBounds = devClipBounds;
     return false;
 }
 
@@ -581,11 +594,11 @@ bool GrClipMaskManager::clipMaskPreamble(const GrClipData& clipDataIn,
 // Create a 8-bit clip mask in alpha
 bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
                                             GrTexture** result,
-                                            GrIRect *resultBounds) {
-    GrAssert(NULL != resultBounds);
+                                            GrIRect *devResultBounds) {
+    GrAssert(NULL != devResultBounds);
     GrAssert(kNone_ClipMaskType == fCurrClipMaskType);
 
-    if (this->clipMaskPreamble(clipDataIn, result, resultBounds)) {
+    if (this->clipMaskPreamble(clipDataIn, result, devResultBounds)) {
         fCurrClipMaskType = kAlpha_ClipMaskType;
         return true;
     }
@@ -603,13 +616,13 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
 
     GrDrawTarget::AutoGeometryPush agp(fGpu);
 
-    if (0 != resultBounds->fTop || 0 != resultBounds->fLeft ||
+    if (0 != devResultBounds->fTop || 0 != devResultBounds->fLeft ||
         0 != clipDataIn.fOrigin.fX || 0 != clipDataIn.fOrigin.fY) {
         // if we were able to trim down the size of the mask we need to 
         // offset the paths & rects that will be used to compute it
         drawState->viewMatrix()->setTranslate(
-                SkIntToScalar(-resultBounds->fLeft-clipDataIn.fOrigin.fX), 
-                SkIntToScalar(-resultBounds->fTop-clipDataIn.fOrigin.fY));
+                SkIntToScalar(-devResultBounds->fLeft-clipDataIn.fOrigin.fX), 
+                SkIntToScalar(-devResultBounds->fTop-clipDataIn.fOrigin.fY));
     }
 
     bool clearToInside;
@@ -618,7 +631,7 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
     GrClip::Iter iter(*clipDataIn.fClipStack, 
                       GrClip::Iter::kBottom_IterStart);
     const GrClip::Iter::Clip* clip = process_initial_clip_elements(&iter,
-                                                              *resultBounds,
+                                                              *devResultBounds,
                                                               &clearToInside,
                                                               &firstOp,
                                                               clipDataIn);
@@ -647,17 +660,17 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
             fGpu->clear(NULL, 0x00000000, accum->asRenderTarget());
 
             setup_boolean_blendcoeffs(drawState, op);
-            this->drawClipShape(accum, clip, *resultBounds);
+            this->drawClipShape(accum, clip, *devResultBounds);
 
         } else if (SkRegion::kReverseDifference_Op == op ||
                    SkRegion::kIntersect_Op == op) {
             // there is no point in intersecting a screen filling rectangle.
             if (SkRegion::kIntersect_Op == op && NULL != clip->fRect &&
-                contains(*clip->fRect, *resultBounds, clipDataIn.fOrigin)) {
+                contains(*clip->fRect, *devResultBounds, clipDataIn.fOrigin)) {
                 continue;
             }
 
-            getTemp(*resultBounds, &temp);
+            getTemp(*devResultBounds, &temp);
             if (NULL == temp.texture()) {
                 fAACache.reset();
                 return false;
@@ -667,12 +680,12 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
             fGpu->clear(NULL, 0x00000000, temp.texture()->asRenderTarget());
 
             setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op);
-            this->drawClipShape(temp.texture(), clip, *resultBounds);
+            this->drawClipShape(temp.texture(), clip, *devResultBounds);
 
             // TODO: rather than adding these two translations here
             // compute the bounding box needed to render the texture
             // into temp
-            if (0 != resultBounds->fTop || 0 != resultBounds->fLeft ||
+            if (0 != devResultBounds->fTop || 0 != devResultBounds->fLeft ||
                 0 != clipDataIn.fOrigin.fX || 0 != clipDataIn.fOrigin.fY) {
                 // In order for the merge of the temp clip into the accumulator
                 // to work we need to disable the translation
@@ -684,18 +697,18 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
             setup_boolean_blendcoeffs(drawState, op);
             this->drawTexture(accum, temp.texture());
 
-            if (0 != resultBounds->fTop || 0 != resultBounds->fLeft ||
+            if (0 != devResultBounds->fTop || 0 != devResultBounds->fLeft ||
                 0 != clipDataIn.fOrigin.fX || 0 != clipDataIn.fOrigin.fY) {
                 drawState->viewMatrix()->setTranslate(
-                        SkIntToScalar(-resultBounds->fLeft-clipDataIn.fOrigin.fX), 
-                        SkIntToScalar(-resultBounds->fTop-clipDataIn.fOrigin.fY));
+                  SkIntToScalar(-devResultBounds->fLeft-clipDataIn.fOrigin.fX), 
+                  SkIntToScalar(-devResultBounds->fTop-clipDataIn.fOrigin.fY));
             }
 
         } else {
             // all the remaining ops can just be directly draw into 
             // the accumulation buffer
             setup_boolean_blendcoeffs(drawState, op);
-            this->drawClipShape(accum, clip, *resultBounds);
+            this->drawClipShape(accum, clip, *devResultBounds);
         }
     }
 
@@ -705,10 +718,10 @@ bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// Create a 1-bit clip mask in the stencil buffer. 'bounds' are in device 
+// Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device 
 // (as opposed to canvas) coordinates
 bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
-                                              const GrIRect& bounds) {
+                                              const GrIRect& devClipBounds) {
 
     GrAssert(kNone_ClipMaskType == fCurrClipMaskType);
 
@@ -734,7 +747,9 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
         // we finish drawing it into the stencil.
         const GrClipData* oldClipData = fGpu->getClip();
 
-        GrClip newClipStack(bounds);
+        // The origin of 'newClipData' is (0, 0) so it is okay to place
+        // a device-coordinate bound in 'newClipStack'
+        GrClip newClipStack(devClipBounds);
         GrClipData newClipData;
         newClipData.fClipStack = &newClipStack;
 
@@ -748,12 +763,9 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
         if (0 != clipDataIn.fOrigin.fX || 0 != clipDataIn.fOrigin.fY) {
             // Add the saveLayer's offset to the view matrix rather than 
             // offset each individual draw
-            GrMatrix m;
-
-            m.setTranslate(SkIntToScalar(-clipDataIn.fOrigin.fX), 
+            drawState->viewMatrix()->setTranslate(
+                           SkIntToScalar(-clipDataIn.fOrigin.fX), 
                            SkIntToScalar(-clipDataIn.fOrigin.fY));
-
-            drawState->setViewMatrix(m);
         }
 
 #if !VISUALIZE_COMPLEX_CLIP
@@ -765,7 +777,7 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
                     "Ganesh only handles 16b or smaller stencil buffers");
         clipBit = (1 << (clipBit-1));
 
-        GrIRect rtRect = GrIRect::MakeWH(rt->width(), rt->height());
+        GrIRect devRTRect = GrIRect::MakeWH(rt->width(), rt->height());
 
         bool clearToInside;
         SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
@@ -773,12 +785,12 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
         GrClip::Iter iter(*oldClipData->fClipStack, 
                           GrClip::Iter::kBottom_IterStart);
         const GrClip::Iter::Clip* clip = process_initial_clip_elements(&iter,
-                                                  rtRect,
+                                                  devRTRect,
                                                   &clearToInside,
                                                   &firstOp,
                                                   clipDataIn);
 
-        fGpu->clearStencilClip(bounds, clearToInside);
+        fGpu->clearStencilClip(devClipBounds, clearToInside);
         bool first = true;
 
         // walk through each clip element and perform its set op
@@ -818,7 +830,7 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
                 // there is no point in intersecting a screen filling
                 // rectangle.
                 if (SkRegion::kIntersect_Op == op &&
-                    contains(*clip->fRect, rtRect, oldClipData->fOrigin)) {
+                    contains(*clip->fRect, devRTRect, oldClipData->fOrigin)) {
                     continue;
                 }
             } else if (NULL != clip->fPath) {
@@ -889,16 +901,14 @@ bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
                     }
                 } else {
                     SET_RANDOM_COLOR
-                    // 'bounds' is already in device coordinates so the 
+                    // 'devClipBounds' is already in device coordinates so the 
                     // translation in the view matrix is inappropriate. 
-                    // Apply the inverse translation so the drawn rect will
+                    // Convert it to canvas space so the drawn rect will
                     // be in the correct location
-                    GrRect rect = GrRect::MakeLTRB(
-                            SkIntToScalar(bounds.fLeft+clipDataIn.fOrigin.fX),
-                            SkIntToScalar(bounds.fTop+clipDataIn.fOrigin.fY),
-                            SkIntToScalar(bounds.fRight+clipDataIn.fOrigin.fX),
-                            SkIntToScalar(bounds.fBottom+clipDataIn.fOrigin.fY));
-                    fGpu->drawSimpleRect(rect, NULL);
+                    GrRect canvClipBounds;
+                    canvClipBounds.set(devClipBounds);
+                    device_to_canvas(&canvClipBounds, clipDataIn.fOrigin);
+                    fGpu->drawSimpleRect(canvClipBounds, NULL);
                 }
             }
         }
@@ -1122,10 +1132,10 @@ GrPathFill invert_fill(GrPathFill fill) {
 
 bool GrClipMaskManager::createSoftwareClipMask(const GrClipData& clipDataIn,
                                                GrTexture** result,
-                                               GrIRect* resultBounds) {
+                                               GrIRect* devResultBounds) {
     GrAssert(kNone_ClipMaskType == fCurrClipMaskType);
 
-    if (this->clipMaskPreamble(clipDataIn, result, resultBounds)) {
+    if (this->clipMaskPreamble(clipDataIn, result, devResultBounds)) {
         return true;
     }
 
@@ -1140,7 +1150,7 @@ bool GrClipMaskManager::createSoftwareClipMask(const GrClipData& clipDataIn,
     GrMatrix matrix;
     matrix.setTranslate(SkIntToScalar(-clipDataIn.fOrigin.fX), 
                         SkIntToScalar(-clipDataIn.fOrigin.fY));
-    helper.init(*resultBounds, &matrix);
+    helper.init(*devResultBounds, &matrix);
 
     bool clearToInside;
     SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
@@ -1148,7 +1158,7 @@ bool GrClipMaskManager::createSoftwareClipMask(const GrClipData& clipDataIn,
     GrClip::Iter iter(*clipDataIn.fClipStack, 
                       GrClip::Iter::kBottom_IterStart);
     const GrClip::Iter::Clip* clip = process_initial_clip_elements(&iter,
-                                              *resultBounds,
+                                              *devResultBounds,
                                               &clearToInside,
                                               &firstOp,
                                               clipDataIn);
@@ -1173,11 +1183,8 @@ bool GrClipMaskManager::createSoftwareClipMask(const GrClipData& clipDataIn,
             // difference we invert all the pixels before clearing the ones
             // outside the geometry.
             if (SkRegion::kReverseDifference_Op == op) {
-                SkRect temp = SkRect::MakeLTRB(
-                                       SkIntToScalar(resultBounds->left()),
-                                       SkIntToScalar(resultBounds->top()),
-                                       SkIntToScalar(resultBounds->right()),
-                                       SkIntToScalar(resultBounds->bottom()));
+                SkRect temp;
+                temp.set(*devResultBounds);
 
                 // invert the entire scene
                 helper.draw(temp, SkRegion::kXOR_Op, false, 0xFF);
index 81be5ed..3ba26d3 100644 (file)
@@ -328,16 +328,16 @@ private:
     GrClipMaskCache fAACache;       // cache for the AA path
 
     bool createStencilClipMask(const GrClipData& clipDataIn,
-                               const GrIRect& bounds);
+                               const GrIRect& devClipBounds);
     bool createAlphaClipMask(const GrClipData& clipDataIn,
                              GrTexture** result,
-                             GrIRect *resultBounds);
+                             GrIRect *devResultBounds);
     bool createSoftwareClipMask(const GrClipData& clipDataIn,
                                 GrTexture** result,
-                                GrIRect *resultBounds);
+                                GrIRect *devResultBounds);
     bool clipMaskPreamble(const GrClipData& clipDataIn,
                           GrTexture** result,
-                          GrIRect *resultBounds);
+                          GrIRect *devResultBounds);
 
     bool useSWOnlyPath(const GrClip& clipIn);
 
index 5b570b4..16b859f 100644 (file)
@@ -37,17 +37,20 @@ namespace {
 bool get_path_and_clip_bounds(const GrDrawTarget* target,
                               const SkPath& path,
                               const GrMatrix& matrix,
-                              GrIRect* pathBounds,
-                              GrIRect* clipBounds) {
+                              GrIRect* devPathBounds,
+                              GrIRect* devClipBounds) {
     // compute bounds as intersection of rt size, clip, and path
     const GrRenderTarget* rt = target->getDrawState().getRenderTarget();
     if (NULL == rt) {
         return false;
     }
-    *pathBounds = GrIRect::MakeWH(rt->width(), rt->height());
+    *devPathBounds = GrIRect::MakeWH(rt->width(), rt->height());
 
-    target->getClip()->getConservativeBounds(rt, clipBounds);
-    if (!pathBounds->intersect(*clipBounds)) {
+    target->getClip()->getConservativeBounds(rt, devClipBounds);
+
+    // TODO: getConservativeBounds already intersects with the 
+    // render target's bounding box. Remove this next line
+    if (!devPathBounds->intersect(*devClipBounds)) {
         return false;
     }
 
@@ -56,13 +59,13 @@ bool get_path_and_clip_bounds(const GrDrawTarget* target,
         matrix.mapRect(&pathSBounds, path.getBounds());
         GrIRect pathIBounds;
         pathSBounds.roundOut(&pathIBounds);
-        if (!pathBounds->intersect(pathIBounds)) {
+        if (!devPathBounds->intersect(pathIBounds)) {
             // set the correct path bounds, as this would be used later.
-            *pathBounds = pathIBounds;
+            *devPathBounds = pathIBounds;
             return false;
         }
     } else {
-        *pathBounds = GrIRect::EmptyIRect();
+        *devPathBounds = GrIRect::EmptyIRect();
         return false;
     }
     return true;
@@ -70,31 +73,31 @@ bool get_path_and_clip_bounds(const GrDrawTarget* target,
 
 ////////////////////////////////////////////////////////////////////////////////
 void draw_around_inv_path(GrDrawTarget* target,
-                          const GrIRect& clipBounds,
-                          const GrIRect& pathBounds) {
+                          const GrIRect& devClipBounds,
+                          const GrIRect& devPathBounds) {
     GrDrawTarget::AutoDeviceCoordDraw adcd(target);
     if (!adcd.succeeded()) {
         return;
     }
     GrRect rect;
-    if (clipBounds.fTop < pathBounds.fTop) {
-        rect.iset(clipBounds.fLeft, clipBounds.fTop, 
-                    clipBounds.fRight, pathBounds.fTop);
+    if (devClipBounds.fTop < devPathBounds.fTop) {
+        rect.iset(devClipBounds.fLeft, devClipBounds.fTop, 
+                  devClipBounds.fRight, devPathBounds.fTop);
         target->drawSimpleRect(rect, NULL);
     }
-    if (clipBounds.fLeft < pathBounds.fLeft) {
-        rect.iset(clipBounds.fLeft, pathBounds.fTop, 
-                    pathBounds.fLeft, pathBounds.fBottom);
+    if (devClipBounds.fLeft < devPathBounds.fLeft) {
+        rect.iset(devClipBounds.fLeft, devPathBounds.fTop, 
+                  devPathBounds.fLeft, devPathBounds.fBottom);
         target->drawSimpleRect(rect, NULL);
     }
-    if (clipBounds.fRight > pathBounds.fRight) {
-        rect.iset(pathBounds.fRight, pathBounds.fTop, 
-                    clipBounds.fRight, pathBounds.fBottom);
+    if (devClipBounds.fRight > devPathBounds.fRight) {
+        rect.iset(devPathBounds.fRight, devPathBounds.fTop, 
+                  devClipBounds.fRight, devPathBounds.fBottom);
         target->drawSimpleRect(rect, NULL);
     }
-    if (clipBounds.fBottom > pathBounds.fBottom) {
-        rect.iset(clipBounds.fLeft, pathBounds.fBottom, 
-                    clipBounds.fRight, clipBounds.fBottom);
+    if (devClipBounds.fBottom > devPathBounds.fBottom) {
+        rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, 
+                  devClipBounds.fRight, devClipBounds.fBottom);
         target->drawSimpleRect(rect, NULL);
     }
 }
@@ -120,27 +123,27 @@ bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path,
         vm.postTranslate(translate->fX, translate->fY);
     }
 
-    GrIRect pathBounds, clipBounds;
+    GrIRect devPathBounds, devClipBounds;
     if (!get_path_and_clip_bounds(target, path, vm,
-                                  &pathBounds, &clipBounds)) {
+                                  &devPathBounds, &devClipBounds)) {
         if (GrIsFillInverted(fill)) {
-            draw_around_inv_path(target, clipBounds, pathBounds);
+            draw_around_inv_path(target, devClipBounds, devPathBounds);
         }
         return true;
     }
 
     SkAutoTUnref<GrTexture> texture(
             GrSWMaskHelper::DrawPathMaskToTexture(fContext, path, 
-                                                  pathBounds, fill, 
+                                                  devPathBounds, fill, 
                                                   antiAlias, &vm));
     if (NULL == texture) {
         return false;
     }
 
-    GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, pathBounds);
+    GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, devPathBounds);
 
     if (GrIsFillInverted(fill)) {
-        draw_around_inv_path(target, clipBounds, pathBounds);
+        draw_around_inv_path(target, devClipBounds, devPathBounds);
     }
 
     return true;
index ab04bb4..576a5bd 100644 (file)
@@ -70,6 +70,20 @@ 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) {
@@ -88,8 +102,7 @@ GrTextContext::GrTextContext(GrContext* context,
     const GrClipData* clipData = context->getClip();
 
     GrRect conservativeBound = clipData->fClipStack->getConservativeBounds();
-    conservativeBound.offset(SkIntToScalar(-clipData->fOrigin.fX), 
-                             SkIntToScalar(-clipData->fOrigin.fY));
+    canvas_to_device(&conservativeBound, clipData->fOrigin);
 
     if (!fExtMatrix.isIdentity()) {
         GrMatrix inverse;
index dcfb57b..ec8f26c 100644 (file)
@@ -371,26 +371,27 @@ static void check_bounds(const SkClipStack& clipStack,
                          int renderTargetWidth,
                          int renderTargetHeight) {
 
-    SkIRect bound;
-    SkClipStack::BoundsType boundType;
-    SkRect temp;
+    SkIRect devBound;
+
+    devBound.setLTRB(0, 0, renderTargetWidth, renderTargetHeight);
 
-    bound.setLTRB(0, 0, renderTargetWidth, renderTargetHeight);
+    SkClipStack::BoundsType boundType;
+    SkRect canvTemp;
 
-    clipStack.getBounds(&temp, &boundType);
+    clipStack.getBounds(&canvTemp, &boundType);
     if (SkClipStack::kNormal_BoundsType == boundType) {
-        SkIRect temp2;
+        SkIRect devTemp;
 
-        temp.roundOut(&temp2);
+        canvTemp.roundOut(&devTemp);
 
-        temp2.offset(-origin.fX, -origin.fY);
+        devTemp.offset(-origin.fX, -origin.fY);
 
-        if (!bound.intersect(temp2)) {
-            bound.setEmpty();
+        if (!devBound.intersect(devTemp)) {
+            devBound.setEmpty();
         }
     }
 
-//    GrAssert(bound.contains(clipRegion.getBounds()));
+//    GrAssert(devBound.contains(clipRegion.getBounds()));
 }
 #endif
 
@@ -413,15 +414,15 @@ static void convert_matrixclip(GrContext* context, const SkMatrix& matrix,
                  renderTargetWidth, renderTargetHeight);
 #endif
 
-    SkRect bounds;
+    SkRect devClipBounds;
     bool isIntersectionOfRects = false;
     clipStack.getConservativeBounds(0, 0,
                                     renderTargetWidth,
                                     renderTargetHeight,
-                                    &bounds,
+                                    &devClipBounds,
                                     &isIntersectionOfRects);
 
-    result->setFromIterator(&iter, bounds);
+    result->setFromIterator(&iter, devClipBounds);
 
     GrAssert(result->isRect() == isIntersectionOfRects);
 
index b492fd4..6d6d916 100644 (file)
@@ -427,15 +427,16 @@ bool GrGpuGL::flushGraphicsState(DrawType type) {
     this->flushScissor();
     this->flushAAState(type);
 
-    GrIRect* rect = NULL;
-    GrIRect clipBounds;
+    GrIRect* devRect = NULL;
+    GrIRect devClipBounds;
     if (drawState.isClipState()) {
-        fClip->getConservativeBounds(drawState.getRenderTarget(), &clipBounds);
-        rect = &clipBounds;
+        fClip->getConservativeBounds(drawState.getRenderTarget(), 
+                                     &devClipBounds);
+        devRect = &devClipBounds;
     }
     // This must come after textures are flushed because a texture may need
     // to be msaa-resolved (which will modify bound FBO state).
-    this->flushRenderTarget(rect);
+    this->flushRenderTarget(devRect);
 
     return true;
 }
index 516a614..0a72be4 100644 (file)
@@ -68,14 +68,14 @@ static void test_clip_bounds(skiatest::Reporter* reporter, GrContext* context) {
     stack.clipDevRect(clipRect, SkRegion::kReplace_Op, false);
 
     bool isIntersectionOfRects = true;
-    SkRect stackBounds;
+    SkRect devStackBounds;
 
     stack.getConservativeBounds(0, 0, kXSize, kYSize, 
-                                &stackBounds, 
+                                &devStackBounds, 
                                 &isIntersectionOfRects);
 
     // make sure that the SkClipStack is behaving itself
-    REPORTER_ASSERT(reporter, screen == stackBounds);
+    REPORTER_ASSERT(reporter, screen == devStackBounds);
     REPORTER_ASSERT(reporter, isIntersectionOfRects);
 
     // convert the SkClipStack to a GrClip
@@ -83,25 +83,25 @@ static void test_clip_bounds(skiatest::Reporter* reporter, GrContext* context) {
     iter.reset(stack);
 
     GrClip clip;
-    clip.setFromIterator(&iter, stackBounds);
+    clip.setFromIterator(&iter, devStackBounds);
 
-    const GrRect& grBound = clip.getConservativeBounds();
+    const GrRect& canvGrClipBound = clip.getConservativeBounds();
 
     // make sure that GrClip is behaving itself
-    REPORTER_ASSERT(reporter, clipRect == grBound);
+    REPORTER_ASSERT(reporter, clipRect == canvGrClipBound);
     REPORTER_ASSERT(reporter, clip.isRect());
 
     // wrap the GrClip in a GrClipData
     GrClipData clipData;
     clipData.fClipStack = &clip;
 
-    SkIRect intGrBound;
+    SkIRect devGrClipDataBound;
     clipData.getConservativeBounds(texture,
-                                   &intGrBound,
+                                   &devGrClipDataBound,
                                    &isIntersectionOfRects);
 
     // make sure that GrClipData is behaving itself
-    REPORTER_ASSERT(reporter, intScreen == intGrBound);
+    REPORTER_ASSERT(reporter, intScreen == devGrClipDataBound);
     REPORTER_ASSERT(reporter, isIntersectionOfRects);
 }
 
index 160c544..afbbd7e 100644 (file)
@@ -235,7 +235,7 @@ static void test_bounds(skiatest::Reporter* reporter, bool useRects) {
     clipB.addRoundRect(rectB, SkIntToScalar(5), SkIntToScalar(5));
 
     SkClipStack stack;
-    SkRect bound;
+    SkRect devClipBound;
     bool isIntersectionOfRects = false;
 
     int testCase = 0;
@@ -262,7 +262,7 @@ static void test_bounds(skiatest::Reporter* reporter, bool useRects) {
 
             REPORTER_ASSERT(reporter, !stack.isWideOpen());
 
-            stack.getConservativeBounds(0, 0, 100, 100, &bound,
+            stack.getConservativeBounds(0, 0, 100, 100, &devClipBound,
                                         &isIntersectionOfRects);
 
             if (useRects) {
@@ -273,7 +273,7 @@ static void test_bounds(skiatest::Reporter* reporter, bool useRects) {
             }
 
             SkASSERT(testCase < gNumCases);
-            REPORTER_ASSERT(reporter, bound == gAnswerRectsBW[testCase]);
+            REPORTER_ASSERT(reporter, devClipBound == gAnswerRectsBW[testCase]);
             ++testCase;
 
             stack.restore();