Minimize use of SkDraw's matrix in SkGpuDevice.

R=robertphillips@google.com
Review URL: https://codereview.appspot.com/6604068

git-svn-id: http://skia.googlecode.com/svn/trunk@5906 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index df7754d..d94a8dd 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -686,7 +686,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect,
-                          const SkPaint& paint) {
+                           const SkPaint& paint) {
     CHECK_FOR_NODRAW_ANNOTATION(paint);
     CHECK_SHOULD_DRAW(draw);
 
@@ -704,7 +704,7 @@
         usePath = true;
     }
     // until we aa rotated rects...
-    if (!usePath && paint.isAntiAlias() && !draw.fMatrix->rectStaysRect()) {
+    if (!usePath && paint.isAntiAlias() && !fContext->getMatrix().rectStaysRect()) {
         usePath = true;
     }
     // small miter limit means right angles show bevel...
@@ -773,10 +773,9 @@
     return false;
 }
 
-bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
-                           SkMaskFilter* filter, const SkMatrix& matrix,
-                           const SkRegion& clip, SkBounder* bounder,
-                           GrPaint* grp, GrPathFill pathFillType) {
+bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath,
+                           SkMaskFilter* filter, const SkRegion& clip,
+                           SkBounder* bounder, GrPaint* grp, GrPathFill pathFillType) {
 #ifdef SK_DISABLE_GPU_BLUR
     return false;
 #endif
@@ -786,13 +785,13 @@
         return false;
     }
     SkScalar radius = info.fIgnoreTransform ? info.fRadius
-                                            : matrix.mapRadius(info.fRadius);
+                                            : context->getMatrix().mapRadius(info.fRadius);
     radius = SkMinScalar(radius, MAX_BLUR_RADIUS);
     if (radius <= 0) {
         return false;
     }
 
-    SkRect srcRect = path.getBounds();
+    SkRect srcRect = devPath.getBounds();
     if (shouldDrawBlurWithCPU(srcRect, radius)) {
         return false;
     }
@@ -838,6 +837,8 @@
 
     SkAutoTUnref<GrTexture> blurTexture;
 
+    GrMatrix origMatrix = context->getMatrix();
+
     // We pass kPreserve here. We will replace the current matrix below.
     GrContext::AutoMatrix avm(context, GrContext::AutoMatrix::kPreserve_InitialMatrix);
 
@@ -846,8 +847,12 @@
         GrContext::AutoClip ac(context, srcRect);
 
         context->clear(NULL, 0);
-        GrPaint tempPaint;
 
+        // Draw hard shadow to pathTexture with path top-left at origin 0,0.
+        GrMatrix translate;
+        translate.setTranslate(offset.fX, offset.fY);
+
+        GrPaint tempPaint;
         if (grp->isAntiAlias()) {
             tempPaint.setAntiAlias(true);
             // AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst
@@ -858,11 +863,8 @@
             // use a zero dst coeff when dual source blending isn't available.
             tempPaint.setBlendFunc(kOne_GrBlendCoeff, kISC_GrBlendCoeff);
         }
-        // Draw hard shadow to pathTexture with path top-left at origin 0,0.
-        GrMatrix translate;
-        translate.setTranslate(offset.fX, offset.fY);
         context->setMatrix(translate);
-        context->drawPath(tempPaint, path, pathFillType);
+        context->drawPath(tempPaint, devPath, pathFillType);
 
         // switch to device coord drawing when going back to the main RT.
         context->setIdentityMatrix();
@@ -898,7 +900,7 @@
         }
     }
 
-    if (!grp->preConcatSamplerMatricesWithInverse(matrix)) {
+    if (!grp->preConcatSamplerMatricesWithInverse(origMatrix)) {
         return false;
     }
 
@@ -916,20 +918,18 @@
     return true;
 }
 
-bool drawWithMaskFilter(GrContext* context, const SkPath& path,
-                        SkMaskFilter* filter, const SkMatrix& matrix,
-                        const SkRegion& clip, SkBounder* bounder,
+bool drawWithMaskFilter(GrContext* context, const SkPath& devPath,
+                        SkMaskFilter* filter, const SkRegion& clip, SkBounder* bounder,
                         GrPaint* grp, SkPaint::Style style) {
     SkMask  srcM, dstM;
 
-    if (!SkDraw::DrawToMask(path, &clip.getBounds(), filter, &matrix, &srcM,
-                            SkMask::kComputeBoundsAndRenderImage_CreateMode,
-                            style)) {
+    if (!SkDraw::DrawToMask(devPath, &clip.getBounds(), filter, &context->getMatrix(), &srcM,
+                            SkMask::kComputeBoundsAndRenderImage_CreateMode, style)) {
         return false;
     }
     SkAutoMaskFreeImage autoSrc(srcM.fImage);
 
-    if (!filter->filterMask(&dstM, srcM, matrix, NULL)) {
+    if (!filter->filterMask(&dstM, srcM, context->getMatrix(), NULL)) {
         return false;
     }
     // this will free-up dstM when we're done (allocated in filterMask())
@@ -945,12 +945,12 @@
     // we now have a device-aligned 8bit mask in dstM, ready to be drawn using
     // the current clip (and identity matrix) and grpaint settings
 
-    GrContext::AutoMatrix avm(context, GrMatrix::I());
-
-    if (!grp->preConcatSamplerMatricesWithInverse(matrix)) {
+    if (!grp->preConcatSamplerMatricesWithInverse(context->getMatrix())) {
         return false;
     }
 
+    GrContext::AutoMatrix avm(context, GrMatrix::I());
+
     GrTextureDesc desc;
     desc.fWidth = dstM.fBounds.width();
     desc.fHeight = dstM.fBounds.height();
@@ -1010,7 +1010,7 @@
     // can we cheat, and threat a thin stroke as a hairline w/ coverage
     // if we can, we draw lots faster (raster device does this same test)
     SkScalar hairlineCoverage;
-    if (SkDrawTreatAsHairline(paint, *draw.fMatrix, &hairlineCoverage)) {
+    if (SkDrawTreatAsHairline(paint, fContext->getMatrix(), &hairlineCoverage)) {
         doFill = false;
         grPaint.setCoverage(SkScalarRoundToInt(hairlineCoverage * grPaint.getCoverage()));
     }
@@ -1050,17 +1050,15 @@
         SkPath* devPathPtr = pathIsMutable ? pathPtr : &tmpPath;
 
         // transform the path into device space
-        pathPtr->transform(*draw.fMatrix, devPathPtr);
+        pathPtr->transform(fContext->getMatrix(), devPathPtr);
         GrPathFill pathFillType = doFill ?
             skToGrFillType(devPathPtr->getFillType()) : kHairLine_GrPathFill;
         if (!drawWithGPUMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(),
-                                   *draw.fMatrix, *draw.fClip, draw.fBounder,
-                                   &grPaint, pathFillType)) {
+                                   *draw.fClip, draw.fBounder, &grPaint, pathFillType)) {
             SkPaint::Style style = doFill ? SkPaint::kFill_Style :
                 SkPaint::kStroke_Style;
             drawWithMaskFilter(fContext, *devPathPtr, paint.getMaskFilter(),
-                               *draw.fMatrix, *draw.fClip, draw.fBounder,
-                               &grPaint, style);
+                               *draw.fClip, draw.fBounder, &grPaint, style);
         }
         return;
     }
@@ -1235,11 +1233,11 @@
         paintWithTexture.setShader(SkShader::CreateBitmapShader(*bitmapPtr,
             SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref();
 
-        // Transform 'newM' needs to be concatenated to the draw matrix,
+        // Transform 'newM' needs to be concatenated to the current matrix,
         // rather than transforming the primitive directly, so that 'newM' will
         // also affect the behavior of the mask filter.
         SkMatrix drawMatrix;
-        drawMatrix.setConcat(*draw.fMatrix, newM);
+        drawMatrix.setConcat(fContext->getMatrix(), newM);
         SkDraw transformedDraw(draw);
         transformedDraw.fMatrix = &drawMatrix;
 
@@ -1258,16 +1256,15 @@
 
     if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) {
         // take the simple case
-        this->internalDrawBitmap(draw, bitmap, srcRect, m, params, &grPaint);
+        this->internalDrawBitmap(bitmap, srcRect, m, params, &grPaint);
     } else {
-        this->drawTiledBitmap(draw, bitmap, srcRect, m, params, &grPaint);
+        this->drawTiledBitmap(bitmap, srcRect, m, params, &grPaint);
     }
 }
 
 // Break 'bitmap' into several tiles to draw it since it has already
 // been determined to be too large to fit in VRAM
-void SkGpuDevice::drawTiledBitmap(const SkDraw& draw,
-                                  const SkBitmap& bitmap,
+void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
                                   const SkRect& srcRect,
                                   const SkMatrix& m,
                                   const GrTextureParams& params,
@@ -1279,9 +1276,13 @@
     // compute clip bounds in local coordinates
     SkRect clipRect;
     {
-        clipRect.set(draw.fClip->getBounds());
+        const GrRenderTarget* rt = fContext->getRenderTarget();
+        clipRect.setWH(SkIntToScalar(rt->width()), SkIntToScalar(rt->height()));
+        if (!fContext->getClip()->fClipStack->intersectRectWithClip(&clipRect)) {
+            return;
+        }
         SkMatrix matrix, inverse;
-        matrix.setConcat(*draw.fMatrix, m);
+        matrix.setConcat(fContext->getMatrix(), m);
         if (!matrix.invert(&inverse)) {
             return;
         }
@@ -1316,7 +1317,7 @@
                 tmpM.preTranslate(SkIntToScalar(iTileR.fLeft),
                                   SkIntToScalar(iTileR.fTop));
 
-                this->internalDrawBitmap(draw, tmpB, tileR, tmpM, params, grPaint);
+                this->internalDrawBitmap(tmpB, tileR, tmpM, params, grPaint);
             }
         }
     }
@@ -1372,8 +1373,7 @@
  *  internalDrawBitmap assumes that the specified bitmap will fit in a texture
  *  and that non-texture portion of the GrPaint has already been setup.
  */
-void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
-                                     const SkBitmap& bitmap,
+void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
                                      const SkRect& srcRect,
                                      const SkMatrix& m,
                                      const GrTextureParams& params,
@@ -1411,11 +1411,11 @@
         // Need texture domain if drawing a sub rect.
         needsTextureDomain = srcRect.width() < bitmap.width() ||
                              srcRect.height() < bitmap.height();
-        if (m.rectStaysRect() && draw.fMatrix->rectStaysRect()) {
+        if (m.rectStaysRect() && fContext->getMatrix().rectStaysRect()) {
             // sampling is axis-aligned
             GrRect transformedRect;
             SkMatrix srcToDeviceMatrix(m);
-            srcToDeviceMatrix.postConcat(*draw.fMatrix);
+            srcToDeviceMatrix.postConcat(fContext->getMatrix());
             srcToDeviceMatrix.mapRect(&transformedRect, srcRect);
 
             if (hasAlignedSamples(srcRect, transformedRect)) {
@@ -1802,7 +1802,7 @@
                           const SkPaint& paint) {
     CHECK_SHOULD_DRAW(draw);
 
-    if (draw.fMatrix->hasPerspective()) {
+    if (fContext->getMatrix().hasPerspective()) {
         // this guy will just call our drawPath()
         draw.drawText((const char*)text, byteLength, x, y, paint);
     } else {
@@ -1829,7 +1829,7 @@
                              const SkPaint& paint) {
     CHECK_SHOULD_DRAW(draw);
 
-    if (draw.fMatrix->hasPerspective()) {
+    if (fContext->getMatrix().hasPerspective()) {
         // this guy will just call our drawPath()
         draw.drawPosText((const char*)text, byteLength, pos, constY,
                          scalarsPerPos, paint);