drawBitmapRect() should not touch the CTM when mask filters are present

Blur sigma calculations are CTM dependent, so we cannot take the
drawBitmap() fast path in the presence of mask filters.

BUG=skia:5682
R=reed@google.com
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2286873002

Review-Url: https://codereview.chromium.org/2286873002
diff --git a/gm/drawbitmaprect.cpp b/gm/drawbitmaprect.cpp
index 0747ab0..ea9a09f 100644
--- a/gm/drawbitmaprect.cpp
+++ b/gm/drawbitmaprect.cpp
@@ -93,17 +93,43 @@
     return image;
 }
 
-static void canvasproc(SkCanvas* canvas, SkImage*, const SkBitmap& bm, const SkIRect& srcR,
-                       const SkRect& dstR) {
-    canvas->drawBitmapRect(bm, srcR, dstR, nullptr);
+static void bitmapproc(SkCanvas* canvas, SkImage*, const SkBitmap& bm, const SkIRect& srcR,
+                       const SkRect& dstR, const SkPaint* paint) {
+    canvas->drawBitmapRect(bm, srcR, dstR, paint);
+}
+
+static void bitmapsubsetproc(SkCanvas* canvas, SkImage*, const SkBitmap& bm, const SkIRect& srcR,
+                             const SkRect& dstR, const SkPaint* paint) {
+    if (!bm.bounds().contains(srcR)) {
+        bitmapproc(canvas, nullptr, bm, srcR, dstR, paint);
+        return;
+    }
+
+    SkBitmap subset;
+    if (bm.extractSubset(&subset, srcR)) {
+        canvas->drawBitmapRect(subset, dstR, paint);
+    }
 }
 
 static void imageproc(SkCanvas* canvas, SkImage* image, const SkBitmap&, const SkIRect& srcR,
-                      const SkRect& dstR) {
-    canvas->drawImageRect(image, srcR, dstR, nullptr);
+                      const SkRect& dstR, const SkPaint* paint) {
+    canvas->drawImageRect(image, srcR, dstR, paint);
 }
 
-typedef void DrawRectRectProc(SkCanvas*, SkImage*, const SkBitmap&, const SkIRect&, const SkRect&);
+static void imagesubsetproc(SkCanvas* canvas, SkImage* image, const SkBitmap& bm,
+                            const SkIRect& srcR, const SkRect& dstR, const SkPaint* paint) {
+    if (!image->bounds().contains(srcR)) {
+        imageproc(canvas, image, bm, srcR, dstR, paint);
+        return;
+    }
+
+    if (sk_sp<SkImage> subset = image->makeSubset(srcR)) {
+        canvas->drawImageRect(subset, dstR, paint);
+    }
+}
+
+typedef void DrawRectRectProc(SkCanvas*, SkImage*, const SkBitmap&, const SkIRect&, const SkRect&,
+                              const SkPaint*);
 
 static const int gSize = 1024;
 static const int gBmpSize = 2048;
@@ -164,7 +190,7 @@
             for (int h = 1; h <= kMaxSrcRectSize; h *= 4) {
 
                 SkIRect srcRect = SkIRect::MakeXYWH((gBmpSize - w) / 2, (gBmpSize - h) / 2, w, h);
-                fProc(canvas, fImage.get(), fLargeBitmap, srcRect, dstRect);
+                fProc(canvas, fImage.get(), fLargeBitmap, srcRect, dstRect, nullptr);
 
                 SkString label;
                 label.appendf("%d x %d", w, h);
@@ -206,9 +232,10 @@
             paint.setMaskFilter(SkBlurMaskFilter::Make(
                 kNormal_SkBlurStyle,
                 SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)),
-                SkBlurMaskFilter::kHighQuality_BlurFlag |
-                SkBlurMaskFilter::kIgnoreTransform_BlurFlag));
-            canvas->drawBitmapRect(bm, srcRect, dstRect, &paint);
+                SkBlurMaskFilter::kHighQuality_BlurFlag));
+
+            sk_sp<SkImage> image(SkImage::MakeFromBitmap(bm));
+            fProc(canvas, image.get(), bm, srcRect, dstRect, &paint);
         }
     }
 
@@ -216,5 +243,7 @@
     typedef skiagm::GM INHERITED;
 };
 
-DEF_GM( return new DrawBitmapRectGM(canvasproc, nullptr); )
-DEF_GM( return new DrawBitmapRectGM(imageproc, "-imagerect"); )
+DEF_GM( return new DrawBitmapRectGM(bitmapproc      , nullptr); )
+DEF_GM( return new DrawBitmapRectGM(bitmapsubsetproc, "-subset"); )
+DEF_GM( return new DrawBitmapRectGM(imageproc       , "-imagerect"); )
+DEF_GM( return new DrawBitmapRectGM(imagesubsetproc , "-imagerect-subset"); )