Add dev bounds to bmp txt context, use bounds to ignore clips

R=robertphillips@google.com, jvanverth@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/144283004

git-svn-id: http://skia.googlecode.com/svn/trunk@13413 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index 79309f3..4f43c75 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -39,6 +39,8 @@
 
     fVertices = NULL;
     fMaxVertices = 0;
+
+    fVertexBounds.setLargestInverted();
 }
 
 GrBitmapTextContext::~GrBitmapTextContext() {
@@ -105,12 +107,13 @@
         fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
         fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
                                           nGlyphs,
-                                          4, 6);
+                                          4, 6, &fVertexBounds);
 
         fDrawTarget->resetVertexSource();
         fVertices = NULL;
         fMaxVertices = 0;
         fCurrVertex = 0;
+        fVertexBounds.setLargestInverted();
         SkSafeSetNull(fCurrTexture);
     }
 }
@@ -616,10 +619,15 @@
     GrFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX);
     GrFixed ty = SkIntToFixed(glyph->fAtlasLocation.fY);
 
-    fVertices[2*fCurrVertex].setRectFan(SkFixedToFloat(vx),
-                                        SkFixedToFloat(vy),
-                                        SkFixedToFloat(vx + width),
-                                        SkFixedToFloat(vy + height),
+    SkRect r;
+    r.fLeft = SkFixedToFloat(vx);
+    r.fTop = SkFixedToFloat(vy);
+    r.fRight = SkFixedToFloat(vx + width);
+    r.fBottom = SkFixedToFloat(vy + height);
+
+    fVertexBounds.growToInclude(r);
+
+    fVertices[2*fCurrVertex].setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom,
                                         2 * sizeof(SkPoint));
     fVertices[2*fCurrVertex+1].setRectFan(SkFixedToFloat(texture->normalizeFixedX(tx)),
                                           SkFixedToFloat(texture->normalizeFixedY(ty)),
diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h
index 5817359..4122939 100755
--- a/src/gpu/GrBitmapTextContext.h
+++ b/src/gpu/GrBitmapTextContext.h
@@ -48,6 +48,7 @@
     int32_t                 fMaxVertices;
     GrTexture*              fCurrTexture;
     int                     fCurrVertex;
+    SkRect                  fVertexBounds;
 };
 
 #endif
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index caee6eb..83b3b01 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -110,7 +110,8 @@
 // sort out what kind of clip mask needs to be created: alpha, stencil,
 // scissor, or entirely software
 bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
-                                      GrDrawState::AutoRestoreEffects* are) {
+                                      GrDrawState::AutoRestoreEffects* are,
+                                      const SkRect* devBounds) {
     fCurrClipMaskType = kNone_ClipMaskType;
 
     ElementList elements(16);
@@ -154,9 +155,20 @@
         return true;
     }
 
-    // If there is only one clip element and it is a convex polygon we just install an effect that
-    // clips against the edges.
+    // If there is only one clip element we check whether the draw's bounds are contained
+    // fully within the clip. If not, we install an effect that handles the clip for some
+    // cases.
     if (1 == elements.count() && SkRegion::kReplace_Op == elements.tail()->getOp()) {
+        if (NULL != devBounds) {
+            SkRect boundsInClipSpace = *devBounds;
+            boundsInClipSpace.offset(SkIntToScalar(clipDataIn->fOrigin.fX),
+                                     SkIntToScalar(clipDataIn->fOrigin.fY));
+            if (elements.tail()->contains(boundsInClipSpace)) {
+                fGpu->disableScissor();
+                this->setGpuStencil();
+                return true;
+            }
+        }
         SkAutoTUnref<GrEffectRef> effect;
         if (SkClipStack::Element::kPath_Type == elements.tail()->getType()) {
             const SkPath& path = elements.tail()->getPath();
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index f44a8e7..3d34fb9 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -46,9 +46,12 @@
     /**
      * Creates a clip mask if necessary as a stencil buffer or alpha texture
      * and sets the GrGpu's scissor and stencil state. If the return is false
-     * then the draw can be skipped.
+     * then the draw can be skipped. The AutoRestoreEffects is initialized by
+     * the manager when it must install additional effects to implement the
+     * clip. devBounds is optional but can help optimize clipping.
      */
-    bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*);
+    bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*,
+                       const SkRect* devBounds);
 
     void releaseResources();
 
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 38a5a60..0909e08 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -668,13 +668,10 @@
             localMatrix->mapPointsWithStride(coords, vsize, 4);
         }
     }
-    SkTLazy<SkRect> bounds;
-    if (this->getDrawState().willEffectReadDstColor()) {
-        bounds.init();
-        this->getDrawState().getViewMatrix().mapRect(bounds.get(), rect);
-    }
+    SkRect bounds;
+    this->getDrawState().getViewMatrix().mapRect(&bounds, rect);
 
-    this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4, bounds.getMaybeNull());
+    this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4, &bounds);
 }
 
 void GrDrawTarget::clipWillBeSet(const GrClipData* clipData) {
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index af7037a..3a342b6 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -331,8 +331,9 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 bool GrGpu::setupClipAndFlushState(DrawType type, const GrDeviceCoordTexture* dstCopy,
-                                   GrDrawState::AutoRestoreEffects* are) {
-    if (!fClipMaskManager.setupClipping(this->getClip(), are)) {
+                                   GrDrawState::AutoRestoreEffects* are,
+                                   const SkRect* devBounds) {
+    if (!fClipMaskManager.setupClipping(this->getClip(), are, devBounds)) {
         return false;
     }
 
@@ -376,8 +377,7 @@
     this->handleDirtyContext();
     GrDrawState::AutoRestoreEffects are;
     if (!this->setupClipAndFlushState(PrimTypeToDrawType(info.primitiveType()),
-                                      info.getDstCopy(),
-                                      &are)) {
+                                      info.getDstCopy(), &are, info.getDevBounds())) {
         return;
     }
     this->onGpuDraw(info);
@@ -387,7 +387,7 @@
     this->handleDirtyContext();
 
     GrDrawState::AutoRestoreEffects are;
-    if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, &are)) {
+    if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, &are, NULL)) {
         return;
     }
 
@@ -402,7 +402,7 @@
     drawState()->setDefaultVertexAttribs();
 
     GrDrawState::AutoRestoreEffects are;
-    if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, &are)) {
+    if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, &are, NULL)) {
         return;
     }
 
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index f9028b9..00791be 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -359,7 +359,8 @@
     // prepares clip flushes gpu state before a draw
     bool setupClipAndFlushState(DrawType,
                                 const GrDeviceCoordTexture* dstCopy,
-                                GrDrawState::AutoRestoreEffects* are);
+                                GrDrawState::AutoRestoreEffects* are,
+                                const SkRect* devBounds);
 
     // Functions used to map clip-respecting stencil tests into normal
     // stencil funcs supported by GPUs.