Reduce use of SkImage_Base::peekTexture

Change-Id: I079093c9706df4911d47fba04b786e59240e8cb4
Reviewed-on: https://skia-review.googlesource.com/7792
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp
index 7ddc84d..c168bc9 100644
--- a/gm/image_pict.cpp
+++ b/gm/image_pict.cpp
@@ -226,7 +226,7 @@
             surface->getCanvas()->translate(-100, -100);
             surface->getCanvas()->drawPicture(pic);
             sk_sp<SkImage> image(surface->makeImageSnapshot());
-            fProxy = GrSurfaceProxy::MakeWrapped(sk_ref_sp(as_IB(image)->peekTexture()));
+            fProxy = as_IB(image)->asTextureProxyRef();
         }
     }
 protected:
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index 8b2801e..1d1a557 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -23,6 +23,7 @@
 #include "GrTextureProxy.h"
 #include "SkGr.h"
 #include "SkGrPriv.h"
+#include "SkImage_Gpu.h"
 #endif
 
 // Currently the raster imagefilters can only handle certain imageinfos. Call this to know if
@@ -186,9 +187,11 @@
     SkASSERT(rect_fits(subset, image->width(), image->height()));
 
 #if SK_SUPPORT_GPU
-    if (GrTexture* texture = as_IB(image)->peekTexture()) {
-        return MakeFromGpu(subset, image->uniqueID(), sk_ref_sp(texture),
-                           sk_ref_sp(as_IB(image)->onImageInfo().colorSpace()), props);
+    if (sk_sp<GrTextureProxy> proxy = as_IB(image)->asTextureProxyRef()) {
+        GrContext* context = ((SkImage_Gpu*) as_IB(image))->context();
+
+        return MakeDeferredFromGpu(context, subset, image->uniqueID(), std::move(proxy),
+                                   sk_ref_sp(as_IB(image)->onImageInfo().colorSpace()), props);
     } else
 #endif
     {
@@ -345,7 +348,6 @@
 #if SK_SUPPORT_GPU
 ///////////////////////////////////////////////////////////////////////////////
 #include "GrTexture.h"
-#include "SkImage_Gpu.h"
 
 static sk_sp<SkImage> wrap_proxy_in_image(GrContext* context, GrSurfaceProxy* proxy,
                                           SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace) {
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index f443a64..b658def 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -820,7 +820,7 @@
                                   const SkMatrix& srcToDstRect) const {
     ASSERT_SINGLE_OWNER
     // if image is explictly texture backed then just use the texture
-    if (as_IB(image)->peekTexture()) {
+    if (image->isTextureBacked()) {
         return false;
     }
 
@@ -1314,13 +1314,14 @@
 sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkImage* image) {
     SkPixmap pm;
     if (image->isTextureBacked()) {
-        GrTexture* texture = as_IB(image)->peekTexture();
+        sk_sp<GrTextureProxy> proxy = as_IB(image)->asTextureProxyRef();
 
-        return SkSpecialImage::MakeFromGpu(SkIRect::MakeWH(image->width(), image->height()),
-                                           image->uniqueID(),
-                                           sk_ref_sp(texture),
-                                           as_IB(image)->onImageInfo().refColorSpace(),
-                                           &this->surfaceProps());
+        return SkSpecialImage::MakeDeferredFromGpu(fContext.get(),
+                                                   SkIRect::MakeWH(image->width(), image->height()),
+                                                   image->uniqueID(),
+                                                   std::move(proxy),
+                                                   as_IB(image)->onImageInfo().refColorSpace(),
+                                                   &this->surfaceProps());
     } else if (image->peekPixels(&pm)) {
         SkBitmap bm;
 
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index e2a4e40..42493b2 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -14,6 +14,7 @@
 
 #if SK_SUPPORT_GPU
     #include "GrTexture.h"
+    #include "GrTextureProxy.h"
 #endif
 
 #include <new>
@@ -45,6 +46,7 @@
 
     virtual GrTexture* peekTexture() const { return nullptr; }
 #if SK_SUPPORT_GPU
+    virtual sk_sp<GrTextureProxy> asTextureProxyRef() const { return nullptr; }
     virtual sk_sp<GrTexture> refPinnedTexture(uint32_t* uniqueID) const { return nullptr; }
 #endif
     virtual SkImageCacherator* peekCacherator() const { return nullptr; }
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index c425d27..ef25844 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -93,8 +93,13 @@
     return true;
 }
 
-sk_sp<GrSurfaceProxy> SkImage_Gpu::refProxy() const {
-    return GrSurfaceProxy::MakeWrapped(fTexture);
+sk_sp<GrTextureProxy> SkImage_Gpu::asTextureProxyRef() const {
+    sk_sp<GrSurfaceProxy> sProxy = GrSurfaceProxy::MakeWrapped(fTexture);
+    if (!sProxy) {
+        return nullptr;
+    }
+
+    return sk_ref_sp(sProxy->asTextureProxy());
 }
 
 GrTexture* SkImage_Gpu::asTextureRef(GrContext* ctx, const GrSamplerParams& params,
@@ -104,7 +109,7 @@
     if (texColorSpace) {
         *texColorSpace = this->fColorSpace;
     }
-    GrTextureAdjuster adjuster(this->peekTexture(), this->alphaType(), this->bounds(),
+    GrTextureAdjuster adjuster(fTexture.get(), this->alphaType(), this->bounds(),
                                this->uniqueID(), this->fColorSpace.get());
     return adjuster.refTextureSafeForParams(params, nullptr, scaleAdjust);
 }
diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h
index 31e268c..c918b5c 100644
--- a/src/image/SkImage_Gpu.h
+++ b/src/image/SkImage_Gpu.h
@@ -43,8 +43,8 @@
                             sk_sp<SkColorSpace>*, SkScalar scaleAdjust[2]) const override;
     sk_sp<SkImage> onMakeSubset(const SkIRect&) const override;
 
-    sk_sp<GrSurfaceProxy> refProxy() const;
     GrTexture* peekTexture() const override { return fTexture.get(); }
+    sk_sp<GrTextureProxy> asTextureProxyRef() const override;
     sk_sp<GrTexture> refPinnedTexture(uint32_t* uniqueID) const override {
         *uniqueID = this->uniqueID();
         return fTexture;
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index e350b09..cf127e5 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -138,8 +138,11 @@
     // image because onCopyOnWrite is only called when there is a cached image.
     sk_sp<SkImage> image(this->refCachedImage(SkBudgeted::kNo));
     SkASSERT(image);
-    if (rt->asTexture() == as_IB(image)->peekTexture()) {
-        this->fDevice->replaceRenderTargetContext(SkSurface::kRetain_ContentChangeMode == mode);
+    // MDB TODO: this is unfortunate. The snapping of an Image_Gpu from a surface currently
+    // funnels down to a GrTexture. Once Image_Gpus are proxy-backed we should be able to 
+    // compare proxy uniqueIDs.
+    if (rt->asTexture()->getTextureHandle() == image->getTextureHandle(false)) {
+        fDevice->replaceRenderTargetContext(SkSurface::kRetain_ContentChangeMode == mode);
         SkTextureImageApplyBudgetedDecision(image.get());
     } else if (kDiscard_ContentChangeMode == mode) {
         this->SkSurface_Gpu::onDiscard();
diff --git a/tests/SpecialImageTest.cpp b/tests/SpecialImageTest.cpp
index 33f3948..551efff 100644
--- a/tests/SpecialImageTest.cpp
+++ b/tests/SpecialImageTest.cpp
@@ -51,7 +51,7 @@
 
 // Basic test of the SkSpecialImage public API (e.g., peekTexture, peekPixels & draw)
 static void test_image(const sk_sp<SkSpecialImage>& img, skiatest::Reporter* reporter,
-                       GrContext* context, bool peekTextureSucceeds,
+                       GrContext* context, bool isGPUBacked,
                        int offset, int size) {
     const SkIRect subset = img->subset();
     REPORTER_ASSERT(reporter, offset == subset.left());
@@ -61,7 +61,7 @@
 
     //--------------
     // Test that peekTexture reports the correct backing type
-    REPORTER_ASSERT(reporter, peekTextureSucceeds == img->isTextureBacked());
+    REPORTER_ASSERT(reporter, isGPUBacked == img->isTextureBacked());
 
 #if SK_SUPPORT_GPU
     //--------------
@@ -118,9 +118,9 @@
 
         REPORTER_ASSERT(reporter, tightImg->width() == subset.width());
         REPORTER_ASSERT(reporter, tightImg->height() == subset.height());
-        REPORTER_ASSERT(reporter, peekTextureSucceeds == !!tightImg->getTexture());
+        REPORTER_ASSERT(reporter, isGPUBacked == !!tightImg->isTextureBacked());
         SkPixmap tmpPixmap;
-        REPORTER_ASSERT(reporter, peekTextureSucceeds != !!tightImg->peekPixels(&tmpPixmap));
+        REPORTER_ASSERT(reporter, isGPUBacked != !!tightImg->peekPixels(&tmpPixmap));
     }
     {
         SkImageFilter::OutputProperties outProps(img->getColorSpace());
@@ -128,10 +128,10 @@
 
         REPORTER_ASSERT(reporter, tightSurf->width() == subset.width());
         REPORTER_ASSERT(reporter, tightSurf->height() == subset.height());
-        REPORTER_ASSERT(reporter, peekTextureSucceeds ==
+        REPORTER_ASSERT(reporter, isGPUBacked ==
                      !!tightSurf->getTextureHandle(SkSurface::kDiscardWrite_BackendHandleAccess));
         SkPixmap tmpPixmap;
-        REPORTER_ASSERT(reporter, peekTextureSucceeds != !!tightSurf->peekPixels(&tmpPixmap));
+        REPORTER_ASSERT(reporter, isGPUBacked != !!tightSurf->peekPixels(&tmpPixmap));
     }
 }
 
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 29aee9c..2097ab3 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -415,20 +415,22 @@
 DEF_TEST(SurfaceGetTexture, reporter) {
     auto surface(create_surface());
     sk_sp<SkImage> image(surface->makeImageSnapshot());
-    REPORTER_ASSERT(reporter, as_IB(image)->peekTexture() == nullptr);
+    REPORTER_ASSERT(reporter, !as_IB(image)->isTextureBacked());
     surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
-    REPORTER_ASSERT(reporter, as_IB(image)->peekTexture() == nullptr);
+    REPORTER_ASSERT(reporter, !as_IB(image)->isTextureBacked());
 }
 #if SK_SUPPORT_GPU
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SurfacepeekTexture_Gpu, reporter, ctxInfo) {
     for (auto& surface_func : { &create_gpu_surface, &create_gpu_scratch_surface }) {
         auto surface(surface_func(ctxInfo.grContext(), kPremul_SkAlphaType, nullptr));
         sk_sp<SkImage> image(surface->makeImageSnapshot());
-        GrTexture* texture = as_IB(image)->peekTexture();
-        REPORTER_ASSERT(reporter, texture);
-        REPORTER_ASSERT(reporter, 0 != texture->getTextureHandle());
+
+        REPORTER_ASSERT(reporter, as_IB(image)->isTextureBacked());
+        GrBackendObject textureHandle = image->getTextureHandle(false);
+        REPORTER_ASSERT(reporter, 0 != textureHandle);
         surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode);
-        REPORTER_ASSERT(reporter, as_IB(image)->peekTexture() == texture);
+        REPORTER_ASSERT(reporter, as_IB(image)->isTextureBacked());
+        REPORTER_ASSERT(reporter, textureHandle == image->getTextureHandle(false));
     }
 }
 #endif
@@ -441,8 +443,10 @@
 
 static SkBudgeted is_budgeted(const sk_sp<SkSurface>& surf) {
     SkSurface_Gpu* gsurf = (SkSurface_Gpu*)surf.get();
-    return gsurf->getDevice()->accessRenderTargetContext()
-        ->accessRenderTarget()->resourcePriv().isBudgeted();
+
+    GrRenderTargetProxy* proxy = gsurf->getDevice()->accessRenderTargetContext()
+                                                                        ->asRenderTargetProxy();
+    return proxy->isBudgeted();
 }
 
 static SkBudgeted is_budgeted(SkImage* image) {
@@ -676,7 +680,7 @@
         [] (SkSurface* s){
             sk_sp<SkImage> i(s->makeImageSnapshot());
             SkImage_Gpu* gpuImage = (SkImage_Gpu *) as_IB(i);
-            sk_sp<GrSurfaceProxy> proxy = gpuImage->refProxy();
+            sk_sp<GrTextureProxy> proxy = gpuImage->asTextureProxyRef();
             GrContext* context = gpuImage->context();
             return context->contextPriv().makeWrappedSurfaceContext(std::move(proxy),
                                                                     gpuImage->refColorSpace());