use special-image for imagefilters and save/restore layer

add special virtuals to device, in preparation for using them instead of bitmap for imagefilters

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2155933002

patch from issue 2155933002 at patchset 20001 (http://crrev.com/2155933002#ps20001)

use specialimages instead of bitmaps for imagefiltering

Review-Url: https://codereview.chromium.org/2155063002
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index 8875d22..e3a14e5 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -18,6 +18,13 @@
 #include "SkSpecialSurface.h"
 #include "SkSurfacePriv.h"
 
+// Currently the raster imagefilters can only handle certain imageinfos. Call this to know if
+// a given info is supported.
+static bool valid_for_imagefilters(const SkImageInfo& info) {
+    // no support for other swizzles/depths yet
+    return info.colorType() == kN32_SkColorType;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 class SkSpecialImage_Base : public SkSpecialImage {
 public:
@@ -315,7 +322,11 @@
                                                     const SkSurfaceProps* props) {
     SkASSERT(rect_fits(subset, image->width(), image->height()));
 
-    return sk_make_sp<SkSpecialImage_Image>(subset, image, props);
+    if (valid_for_imagefilters(as_IB(image.get())->onImageInfo())) {
+        return sk_make_sp<SkSpecialImage_Image>(subset, image, props);
+    } else {
+        return nullptr;
+    }
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -412,7 +423,16 @@
     SkASSERT(nullptr == bm.getTexture());
     SkASSERT(rect_fits(subset, bm.width(), bm.height()));
 
-    return sk_make_sp<SkSpecialImage_Raster>(subset, bm, props);
+    const SkBitmap* srcBM = &bm;
+    SkBitmap tmpStorage;
+    // ImageFilters only handle N32 at the moment, so force our src to be that
+    if (!valid_for_imagefilters(bm.info())) {
+        if (!bm.copyTo(&tmpStorage, kN32_SkColorType)) {
+            return nullptr;
+        }
+        srcBM = &tmpStorage;
+    }
+    return sk_make_sp<SkSpecialImage_Raster>(subset, *srcBM, props);
 }
 
 #if SK_SUPPORT_GPU