Update SkSpecialImage API

This adds some temporary compatibility features:
   internal_getBM & internal_fromBM - to convert back & forth from Bitmaps in the ImageFilters
   internal_getProxy - to allow the special images to interface with the current ImagerFilter system

It also adds a unique ID, opaque flag and size method.
   The unique ID and size method are needed for the image filter's caching system.
   The opaque flag is need for swapping back & forth from Bitmaps

These are all calved off of https://codereview.chromium.org/1695823002/ (Get OffsetImageFilter really working with SkSpecialImages) which actually makes use of them.

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

Review URL: https://codereview.chromium.org/1705113002
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index 4fed2ac..50117b2 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -12,7 +12,9 @@
 ///////////////////////////////////////////////////////////////////////////////
 class SkSpecialImage_Base : public SkSpecialImage {
 public:
-    SkSpecialImage_Base(const SkIRect& subset) : INHERITED(subset) { }
+    SkSpecialImage_Base(SkImageFilter::Proxy* proxy, const SkIRect& subset, uint32_t uniqueID)
+        : INHERITED(proxy, subset, uniqueID) {
+    }
     virtual ~SkSpecialImage_Base() { }
 
     virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const = 0;
@@ -21,6 +23,9 @@
 
     virtual GrTexture* onPeekTexture() const { return nullptr; }
 
+    // Delete this entry point ASAP (see skbug.com/4965)
+    virtual bool getBitmap(SkBitmap* result) const = 0;
+
     virtual SkSpecialSurface* onNewSurface(const SkImageInfo& info) const { return nullptr; }
 
 private:
@@ -48,22 +53,70 @@
     return as_IB(this)->onNewSurface(info);
 }
 
+#if SK_SUPPORT_GPU
+#include "SkGr.h"
+#include "SkGrPixelRef.h"
+#endif
+
+SkSpecialImage* SkSpecialImage::internal_fromBM(SkImageFilter::Proxy* proxy,
+                                                const SkBitmap& src) {
+    // Need to test offset case! (see skbug.com/4967)
+    if (src.getTexture()) {
+        return SkSpecialImage::NewFromGpu(proxy,
+                                          src.bounds(),
+                                          src.getGenerationID(),
+                                          src.getTexture());
+    }
+
+    return SkSpecialImage::NewFromRaster(proxy, src.bounds(), src);
+}
+
+bool SkSpecialImage::internal_getBM(SkBitmap* result) {
+    const SkSpecialImage_Base* ib = as_IB(this);
+
+    // TODO: need to test offset case! (see skbug.com/4967)
+    return ib->getBitmap(result);
+}
+
+SkImageFilter::Proxy* SkSpecialImage::internal_getProxy() {
+    SkASSERT(fProxy);
+    return fProxy;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 #include "SkImage.h"
 #if SK_SUPPORT_GPU
-#include "SkGr.h"
 #include "SkGrPriv.h"
 #endif
 
 class SkSpecialImage_Image : public SkSpecialImage_Base {
 public:
-    SkSpecialImage_Image(const SkIRect& subset, const SkImage* image)
-        : INHERITED(subset)
+    SkSpecialImage_Image(SkImageFilter::Proxy* proxy, const SkIRect& subset, const SkImage* image)
+        : INHERITED(proxy, subset, image->uniqueID())
         , fImage(SkRef(image)) {
     }
 
     ~SkSpecialImage_Image() override { }
 
+    bool isOpaque() const override { return fImage->isOpaque(); }
+
+    size_t getSize() const override {
+#if SK_SUPPORT_GPU
+        if (fImage->getTexture()) {
+            return fImage->getTexture()->gpuMemorySize();
+        } else
+#endif
+        {
+            SkImageInfo info;
+            size_t rowBytes;
+
+            if (fImage->peekPixels(&info, &rowBytes)) {
+                return info.height() * rowBytes;
+            }
+        }
+        return 0;
+    }
+
     void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const override {
         SkRect dst = SkRect::MakeXYWH(x, y, this->subset().width(), this->subset().height());
 
@@ -77,6 +130,10 @@
 
     GrTexture* onPeekTexture() const override { return fImage->getTexture(); }
 
+    bool getBitmap(SkBitmap* result) const override {
+        return false;
+    }
+
     SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override {
 #if SK_SUPPORT_GPU
         GrTexture* texture = fImage->getTexture();
@@ -84,10 +141,10 @@
             GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info);
             desc.fFlags = kRenderTarget_GrSurfaceFlag;
 
-            return SkSpecialSurface::NewRenderTarget(texture->getContext(), desc);
+            return SkSpecialSurface::NewRenderTarget(this->proxy(), texture->getContext(), desc);
         }
 #endif
-        return SkSpecialSurface::NewRaster(info, nullptr);
+        return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr);
     }
 
 private:
@@ -107,7 +164,7 @@
 
 SkSpecialImage* SkSpecialImage::NewFromImage(const SkIRect& subset, const SkImage* image) {
     SkASSERT(rect_fits(subset, image->width(), image->height()));
-    return new SkSpecialImage_Image(subset, image);
+    return new SkSpecialImage_Image(nullptr, subset, image);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -117,8 +174,8 @@
 
 class SkSpecialImage_Raster : public SkSpecialImage_Base {
 public:
-    SkSpecialImage_Raster(const SkIRect& subset, const SkBitmap& bm)
-        : INHERITED(subset)
+    SkSpecialImage_Raster(SkImageFilter::Proxy* proxy, const SkIRect& subset, const SkBitmap& bm)
+        : INHERITED(proxy, subset, bm.getGenerationID())
         , fBitmap(bm) {
         if (bm.pixelRef()->isPreLocked()) {
             // we only preemptively lock if there is no chance of triggering something expensive
@@ -129,6 +186,10 @@
 
     ~SkSpecialImage_Raster() override { }
 
+    bool isOpaque() const override { return fBitmap.isOpaque(); }
+
+    size_t getSize() const override { return fBitmap.getSize(); }
+
     void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const override {
         SkRect dst = SkRect::MakeXYWH(x, y,
                                       this->subset().width(), this->subset().height());
@@ -152,8 +213,13 @@
         return false;
     }
 
+    bool getBitmap(SkBitmap* result) const override {
+        *result = fBitmap;
+        return true;
+    }
+
     SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override {
-        return SkSpecialSurface::NewRaster(info, nullptr);
+        return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr);
     }
 
 private:
@@ -162,10 +228,12 @@
     typedef SkSpecialImage_Base INHERITED;
 };
 
-SkSpecialImage* SkSpecialImage::NewFromRaster(const SkIRect& subset, const SkBitmap& bm) {
+SkSpecialImage* SkSpecialImage::NewFromRaster(SkImageFilter::Proxy* proxy,
+                                              const SkIRect& subset,
+                                              const SkBitmap& bm) {
     SkASSERT(nullptr == bm.getTexture());
     SkASSERT(rect_fits(subset, bm.width(), bm.height()));
-    return new SkSpecialImage_Raster(subset, bm);
+    return new SkSpecialImage_Raster(proxy, subset, bm);
 }
 
 #if SK_SUPPORT_GPU
@@ -173,23 +241,30 @@
 #include "GrTexture.h"
 
 class SkSpecialImage_Gpu : public SkSpecialImage_Base {
-public:
-    SkSpecialImage_Gpu(const SkIRect& subset, GrTexture* tex)
-        : INHERITED(subset)
-        , fTexture(SkRef(tex)) {
+public:                                       
+    SkSpecialImage_Gpu(SkImageFilter::Proxy* proxy, const SkIRect& subset,
+                       uint32_t uniqueID, GrTexture* tex, SkAlphaType at)
+        : INHERITED(proxy, subset, uniqueID)
+        , fTexture(SkRef(tex))
+        , fAlphaType(at) {
     }
 
     ~SkSpecialImage_Gpu() override { }
 
+    bool isOpaque() const override {
+        return GrPixelConfigIsOpaque(fTexture->config()) || fAlphaType == kOpaque_SkAlphaType;
+    }
+
+    size_t getSize() const override { return fTexture->gpuMemorySize(); }
+
     void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const override {
         SkRect dst = SkRect::MakeXYWH(x, y,
                                       this->subset().width(), this->subset().height());
 
         SkBitmap bm;
 
-        static const bool kUnknownOpacity = false;
         GrWrapTextureInBitmap(fTexture,
-                              fTexture->width(), fTexture->height(), kUnknownOpacity, &bm);
+                              fTexture->width(), fTexture->height(), this->isOpaque(), &bm);
 
         canvas->drawBitmapRect(bm, this->subset(),
                                dst, paint, SkCanvas::kStrict_SrcRectConstraint);
@@ -197,27 +272,48 @@
 
     GrTexture* onPeekTexture() const override { return fTexture; }
 
+    bool getBitmap(SkBitmap* result) const override {
+        const SkImageInfo info = GrMakeInfoFromTexture(fTexture, 
+                                                       this->width(), this->height(),
+                                                       this->isOpaque());
+        if (!result->setInfo(info)) {
+            return false;
+        }
+
+        result->setPixelRef(new SkGrPixelRef(info, fTexture))->unref();
+        return true;
+    }
+
     SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override {
         GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info);
         desc.fFlags = kRenderTarget_GrSurfaceFlag;
 
-        return SkSpecialSurface::NewRenderTarget(fTexture->getContext(), desc);
+        return SkSpecialSurface::NewRenderTarget(this->proxy(), fTexture->getContext(), desc);
     }
 
 private:
     SkAutoTUnref<GrTexture> fTexture;
+    const SkAlphaType       fAlphaType;
 
     typedef SkSpecialImage_Base INHERITED;
 };
 
-SkSpecialImage* SkSpecialImage::NewFromGpu(const SkIRect& subset, GrTexture* tex) {
+SkSpecialImage* SkSpecialImage::NewFromGpu(SkImageFilter::Proxy* proxy,
+                                           const SkIRect& subset, 
+                                           uint32_t uniqueID,
+                                           GrTexture* tex,
+                                           SkAlphaType at) {
     SkASSERT(rect_fits(subset, tex->width(), tex->height()));
-    return new SkSpecialImage_Gpu(subset, tex);
+    return new SkSpecialImage_Gpu(proxy, subset, uniqueID, tex, at);
 }
 
 #else
 
-SkSpecialImage* SkSpecialImage::NewFromGpu(const SkIRect& subset, GrTexture* tex) {
+SkSpecialImage* SkSpecialImage::NewFromGpu(SkImageFilter::Proxy* proxy,
+                                           const SkIRect& subset,
+                                           uint32_t uniqueID,
+                                           GrTexture* tex,
+                                           SkAlphaType at) {
     return nullptr;
 }