Switch SkImageSource image filter over to new onFilterImage interface

This CL relies on: https://codereview.chromium.org/1762013002/ (Swap over to using SkImageFilter::filterImage instead of filterImageDeprecated)

TBR=bsalomon@google.com

GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1772933002

Review URL: https://codereview.chromium.org/1772933002
diff --git a/include/effects/SkImageSource.h b/include/effects/SkImageSource.h
index 606bb0e..0846948 100644
--- a/include/effects/SkImageSource.h
+++ b/include/effects/SkImageSource.h
@@ -28,8 +28,8 @@
 protected:
     void flatten(SkWriteBuffer&) const override;
 
-    bool onFilterImageDeprecated(Proxy*, const SkBitmap& src, const Context&,
-                                 SkBitmap* result, SkIPoint* offset) const override;
+    SkSpecialImage* onFilterImage(SkSpecialImage* source, const Context&,
+                                  SkIPoint* offset) const override;
 
 private:
     explicit SkImageSource(const SkImage*);
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index a81e384..f5f8832 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -138,11 +138,25 @@
     GrTexture* onPeekTexture() const override { return as_IB(fImage.get())->peekTexture(); }
 
     bool getBitmapDeprecated(SkBitmap* result) const override {
-        return false;
+#if SK_SUPPORT_GPU
+        if (GrTexture* texture = as_IB(fImage.get())->peekTexture()) {
+            const SkImageInfo info = GrMakeInfoFromTexture(texture, 
+                                                           fImage->width(), fImage->height(),
+                                                           fImage->isOpaque());
+            if (!result->setInfo(info)) {
+                return false;
+            }
+
+            result->setPixelRef(new SkGrPixelRef(info, texture))->unref();
+            return true;
+        }
+#endif
+
+        return as_IB(fImage.get())->asBitmapForImageFilters(result);
     }
 
     bool testingOnlyOnGetROPixels(SkBitmap* result) const override {
-        return false;
+        return fImage->asLegacyBitmap(result, SkImage::kRO_LegacyBitmapMode);
     }
 
     SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override {
@@ -178,9 +192,11 @@
 }
 #endif
 
-SkSpecialImage* SkSpecialImage::NewFromImage(const SkIRect& subset, const SkImage* image) {
+SkSpecialImage* SkSpecialImage::NewFromImage(SkImageFilter::Proxy* proxy,
+                                             const SkIRect& subset,
+                                             const SkImage* image) {
     SkASSERT(rect_fits(subset, image->width(), image->height()));
-    return new SkSpecialImage_Image(nullptr, subset, image);
+    return new SkSpecialImage_Image(proxy, subset, image);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkSpecialImage.h b/src/core/SkSpecialImage.h
index e80f82b..e90de09 100644
--- a/src/core/SkSpecialImage.h
+++ b/src/core/SkSpecialImage.h
@@ -52,7 +52,9 @@
      */
     void draw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const;
 
-    static SkSpecialImage* NewFromImage(const SkIRect& subset, const SkImage*);
+    static SkSpecialImage* NewFromImage(SkImageFilter::Proxy*,
+                                        const SkIRect& subset,
+                                        const SkImage*);
     static SkSpecialImage* NewFromRaster(SkImageFilter::Proxy*,
                                          const SkIRect& subset,
                                          const SkBitmap&);
diff --git a/src/effects/SkImageSource.cpp b/src/effects/SkImageSource.cpp
index e9c98dc..25d37e3 100644
--- a/src/effects/SkImageSource.cpp
+++ b/src/effects/SkImageSource.cpp
@@ -8,9 +8,10 @@
 #include "SkImageSource.h"
 
 #include "SkCanvas.h"
-#include "SkDevice.h"
 #include "SkImage.h"
 #include "SkReadBuffer.h"
+#include "SkSpecialImage.h"
+#include "SkSpecialSurface.h"
 #include "SkWriteBuffer.h"
 #include "SkString.h"
 
@@ -64,27 +65,39 @@
     buffer.writeImage(fImage);
 }
 
-bool SkImageSource::onFilterImageDeprecated(Proxy* proxy, const SkBitmap& src, const Context& ctx,
-                                            SkBitmap* result, SkIPoint* offset) const {
+SkSpecialImage* SkImageSource::onFilterImage(SkSpecialImage* source, const Context& ctx,
+                                             SkIPoint* offset) const {
     SkRect dstRect;
     ctx.ctm().mapRect(&dstRect, fDstRect);
+
     SkRect bounds = SkRect::MakeIWH(fImage->width(), fImage->height());
     if (fSrcRect == bounds && dstRect == bounds) {
         // No regions cropped out or resized; return entire image.
         offset->fX = offset->fY = 0;
-        return fImage->asLegacyBitmap(result, SkImage::kRO_LegacyBitmapMode);
+        return SkSpecialImage::NewFromImage(source->internal_getProxy(),
+                                            SkIRect::MakeWH(fImage->width(), fImage->height()),
+                                            fImage);
     }
 
     const SkIRect dstIRect = dstRect.roundOut();
-    SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(dstIRect.width(), dstIRect.height()));
-    if (nullptr == device.get()) {
-        return false;
+
+    const SkImageInfo info = SkImageInfo::MakeN32(dstIRect.width(), dstIRect.height(),
+                                                  kPremul_SkAlphaType);
+
+    SkAutoTUnref<SkSpecialSurface> surf(source->newSurface(info));
+    if (!surf) {
+        return nullptr;
     }
 
-    SkCanvas canvas(device.get());
+    SkCanvas* canvas = surf->getCanvas();
+    SkASSERT(canvas);
+
+    // TODO: it seems like this clear shouldn't be necessary (see skbug.com/5075)
+    canvas->clear(0x0);
+
     SkPaint paint;
 
-    // Subtract off the integer component of the translation (will be applied in loc, below).
+    // Subtract off the integer component of the translation (will be applied in offset, below).
     dstRect.offset(-SkIntToScalar(dstIRect.fLeft), -SkIntToScalar(dstIRect.fTop));
     paint.setXfermodeMode(SkXfermode::kSrc_Mode);
     // FIXME: this probably shouldn't be necessary, but drawImageRect asserts
@@ -92,13 +105,11 @@
     paint.setFilterQuality(
         fSrcRect.width() == dstRect.width() && fSrcRect.height() == dstRect.height() ?
                kNone_SkFilterQuality : fFilterQuality);
-    canvas.drawImageRect(fImage, fSrcRect, dstRect, &paint, SkCanvas::kStrict_SrcRectConstraint);
+    canvas->drawImageRect(fImage, fSrcRect, dstRect, &paint, SkCanvas::kStrict_SrcRectConstraint);
 
-    *result = device.get()->accessBitmap(false);
     offset->fX = dstIRect.fLeft;
     offset->fY = dstIRect.fTop;
-
-    return true;
+    return surf->newImageSnapshot();
 }
 
 void SkImageSource::computeFastBounds(const SkRect& src, SkRect* dst) const {
diff --git a/tests/ImageFilterCacheTest.cpp b/tests/ImageFilterCacheTest.cpp
index 3494011..f355714 100644
--- a/tests/ImageFilterCacheTest.cpp
+++ b/tests/ImageFilterCacheTest.cpp
@@ -152,11 +152,13 @@
 static void test_image_backed(skiatest::Reporter* reporter, SkImage* srcImage) {
     const SkIRect& full = SkIRect::MakeWH(kFullSize, kFullSize);
 
-    SkAutoTUnref<SkSpecialImage> fullImg(SkSpecialImage::NewFromImage(full, srcImage));
+    SkAutoTUnref<SkSpecialImage> fullImg(SkSpecialImage::NewFromImage(nullptr, full, srcImage));
 
     const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
 
-    SkAutoTUnref<SkSpecialImage> subsetImg(SkSpecialImage::NewFromImage(subset, srcImage));
+    SkAutoTUnref<SkSpecialImage> subsetImg(SkSpecialImage::NewFromImage(nullptr,
+                                                                        subset,
+                                                                        srcImage));
 
     test_find_existing(reporter, fullImg, subsetImg);
     test_dont_find_if_diff_key(reporter, fullImg, subsetImg);
diff --git a/tests/SpecialImageTest.cpp b/tests/SpecialImageTest.cpp
index 3dd6da9..9bde7ee 100644
--- a/tests/SpecialImageTest.cpp
+++ b/tests/SpecialImageTest.cpp
@@ -108,7 +108,7 @@
 
     const SkIRect& subset = SkIRect::MakeXYWH(kPad, kPad, kSmallerSize, kSmallerSize);
 
-    SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromImage(subset, fullImage));
+    SkAutoTUnref<SkSpecialImage> img(SkSpecialImage::NewFromImage(nullptr, subset, fullImage));
     test_image(img, reporter, true, false);
 }