Adding support for shadows when drawing bitmaps with skia gpu device

Added code to handle this case in SkGpuDevice::drawBitmap
Added test to cover this use case in SampleTextureDomain.cpp

BUG=http://code.google.com/p/chromium/issues/detail?id=83440
REVIEW=http://codereview.appspot.com/4530068/



git-svn-id: http://skia.googlecode.com/svn/trunk@1730 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/samplecode/SampleTextureDomain.cpp b/samplecode/SampleTextureDomain.cpp
index 1810723..1f895e5 100755
--- a/samplecode/SampleTextureDomain.cpp
+++ b/samplecode/SampleTextureDomain.cpp
@@ -1,6 +1,7 @@
 #include "SampleCode.h"
 #include "SkCanvas.h"
 #include "SkDevice.h"
+#include "SkBlurMaskFilter.h"
 
 namespace {
 SkBitmap make_bitmap() {
@@ -68,6 +69,27 @@
         srcRect.setXYWH(1, 1, 3, 3);
         dstRect.setXYWH(405.0f, 5.0f, 305.0f, 305.0f);
         canvas->drawBitmapRect(deviceBitmap, &srcRect, dstRect, &paint);
+
+        // Test that bitmap blurring using a subrect
+        // renders correctly 
+        srcRect.setXYWH(1, 1, 3, 3);
+        dstRect.setXYWH(5.0f, 405.0f, 305.0f, 305.0f);
+        SkMaskFilter* mf = SkBlurMaskFilter::Create(
+            5,
+            SkBlurMaskFilter::kNormal_BlurStyle,
+            SkBlurMaskFilter::kHighQuality_BlurFlag);
+        paint.setMaskFilter(mf)->unref();
+        canvas->drawBitmapRect(deviceBitmap, &srcRect, dstRect, &paint);
+
+        // Blur and a rotation + NULL src rect
+        // This should not trigger the texture domain code
+        // but it will test a code path in SkGpuDevice::drawBitmap
+        // that handles blurs with rects transformed to non-
+        // orthogonal rects. It also tests the NULL src rect handling
+        dstRect.setXYWH(-150.0f, -150.0f, 300.0f, 300.0f);
+        canvas->translate(550, 550);
+        canvas->rotate(45);
+        canvas->drawBitmapRect(fBM, NULL, dstRect, &paint);
     }
 private:
     typedef SkView INHERITED;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 5f08847..b9e7d47 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -961,6 +961,37 @@
         srcRect = *srcRectPtr;
     }
 
+    if (paint.getMaskFilter()){
+        SkBitmap        tmp;    // storage if we need a subset of bitmap
+        const SkBitmap* bitmapPtr = &bitmap;
+        if (srcRectPtr) {
+            if (!bitmap.extractSubset(&tmp, srcRect)) {
+                return;     // extraction failed
+            }
+            bitmapPtr = &tmp;
+        }
+        SkPaint paintWithTexture(paint);
+        paintWithTexture.setShader(SkShader::CreateBitmapShader( *bitmapPtr,
+            SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref();
+        paintWithTexture.getShader()->setLocalMatrix(m);
+
+        SkRect ScalarRect;
+        ScalarRect.set(srcRect);
+
+        if (m.rectStaysRect()) {
+            // Preferred drawing method, optimized for rectangles
+            m.mapRect(&ScalarRect);
+            this->drawRect(draw, ScalarRect, paintWithTexture);
+        } else {
+            // Slower drawing method, for warped or rotated rectangles
+            SkPath path;
+            path.addRect(ScalarRect);
+            path.transform(m);
+            this->drawPath(draw, path, paintWithTexture, NULL, true);
+        }
+        return;
+    }
+
     GrPaint grPaint;
     if (!this->skPaint2GrPaintNoShader(paint, true, &grPaint, false)) {
         return;