Delazify wrapped backend textures/render target proxies

These methods will fail on DDL contexts.

This is in preparation for removing the ability to specify origin for lazy proxies.

Change-Id: Iadcedfd4fce8ea2590729c974128e5c58cec38a8
Reviewed-on: https://skia-review.googlesource.com/112802
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index 7f1a45e..27ad6a1 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -59,11 +59,6 @@
     bool instanceAttribSupport() const { return fInstanceAttribSupport; }
     bool usesMixedSamples() const { return fUsesMixedSamples; }
 
-    // Returns whether mixed samples is supported for the given backend render target.
-    bool isMixedSamplesSupportedForRT(const GrBackendRenderTarget& rt) const {
-        return this->usesMixedSamples() && this->onIsMixedSamplesSupportedForRT(rt);
-    }
-
     // Primitive restart functionality is core in ES 3.0, but using it will cause slowdowns on some
     // systems. This cap is only set if primitive restart will improve performance.
     bool usePrimitiveRestart() const { return fUsePrimitiveRestart; }
@@ -312,11 +307,6 @@
     virtual void onApplyOptionsOverrides(const GrContextOptions&) {}
     virtual void onDumpJSON(SkJSONWriter*) const {}
 
-    // Backends should implement this if they have any extra requirements for use of mixed
-    // samples for a specific GrBackendRenderTarget outside of basic support.
-    virtual bool onIsMixedSamplesSupportedForRT(const GrBackendRenderTarget&) const {
-        return true;
-    }
     // Backends should implement this if they have any extra requirements for use of window
     // rectangles for a specific GrBackendRenderTarget outside of basic support.
     virtual bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const {
diff --git a/src/core/SkDeferredDisplayListRecorder.cpp b/src/core/SkDeferredDisplayListRecorder.cpp
index 0775480..96bb575 100644
--- a/src/core/SkDeferredDisplayListRecorder.cpp
+++ b/src/core/SkDeferredDisplayListRecorder.cpp
@@ -83,7 +83,7 @@
     // DDL is being replayed into.
 
     sk_sp<GrRenderTargetProxy> proxy = proxyProvider->createLazyRenderTargetProxy(
-            [ lazyProxyData ] (GrResourceProvider* resourceProvider) {
+            [lazyProxyData](GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
                     return sk_sp<GrSurface>();
                 }
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 758a0d1..dbd49a7 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -408,51 +408,28 @@
         return nullptr;
     }
 
-    GrSurfaceDesc desc;
-    desc.fWidth = backendTex.width();
-    desc.fHeight = backendTex.height();
-    desc.fConfig = backendTex.config();
-    GrMipMapped mipMapped = backendTex.hasMipMaps() ? GrMipMapped::kYes : GrMipMapped::kNo;
+    // This is only supported on a direct GrContext.
+    if (!fResourceProvider) {
+        return nullptr;
+    }
+
+    sk_sp<GrTexture> tex = fResourceProvider->wrapBackendTexture(backendTex, ownership);
+    if (!tex) {
+        return nullptr;
+    }
 
     sk_sp<GrReleaseProcHelper> releaseHelper;
     if (releaseProc) {
         releaseHelper.reset(new GrReleaseProcHelper(releaseProc, releaseCtx));
+        // This gives the texture a ref on the releaseHelper
+        tex->setRelease(releaseHelper);
     }
 
-    sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
-            [backendTex, ownership, releaseHelper](GrResourceProvider* resourceProvider) {
-                if (!resourceProvider) {
-                    // If this had a releaseHelper it will get unrefed when we delete this lambda
-                    // and will call the release proc so that the client knows they can free the
-                    // underlying backend object.
-                    return sk_sp<GrTexture>();
-                }
+    SkASSERT(!tex->asRenderTarget());  // Strictly a GrTexture
+    // Make sure we match how we created the proxy with SkBudgeted::kNo
+    SkASSERT(SkBudgeted::kNo == tex->resourcePriv().isBudgeted());
 
-                sk_sp<GrTexture> tex = resourceProvider->wrapBackendTexture(backendTex,
-                                                                            ownership);
-                if (!tex) {
-                    return sk_sp<GrTexture>();
-                }
-                if (releaseHelper) {
-                    // This gives the texture a ref on the releaseHelper
-                    tex->setRelease(releaseHelper);
-                }
-                SkASSERT(!tex->asRenderTarget());   // Strictly a GrTexture
-                // Make sure we match how we created the proxy with SkBudgeted::kNo
-                SkASSERT(SkBudgeted::kNo == tex->resourcePriv().isBudgeted());
-
-                return tex;
-            },
-            desc, origin, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo);
-
-    if (fResourceProvider) {
-        // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however,
-        // we're better off instantiating the proxy immediately here.
-        if (!proxy->priv().doLazyInstantiation(fResourceProvider)) {
-            return nullptr;
-        }
-    }
-    return proxy;
+    return sk_sp<GrTextureProxy>(new GrTextureProxy(std::move(tex), origin));
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::wrapRenderableBackendTexture(
@@ -462,54 +439,27 @@
         return nullptr;
     }
 
+    // This is only supported on a direct GrContext.
+    if (!fResourceProvider) {
+        return nullptr;
+    }
+
     sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config());
     if (!sampleCnt) {
         return nullptr;
     }
 
-    GrSurfaceDesc desc;
-    desc.fWidth = backendTex.width();
-    desc.fHeight = backendTex.height();
-    desc.fConfig = backendTex.config();
-    desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fSampleCnt = sampleCnt;
-    GrMipMapped mipMapped = backendTex.hasMipMaps() ? GrMipMapped::kYes : GrMipMapped::kNo;
-
-    GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone;
-    if (fCaps->usesMixedSamples() && sampleCnt > 1) {
-        renderTargetFlags |= GrRenderTargetFlags::kMixedSampled;
-    }
-    if (fCaps->maxWindowRectangles() > 0) {
-        renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport;
+    sk_sp<GrTexture> tex =
+            fResourceProvider->wrapRenderableBackendTexture(backendTex, sampleCnt, ownership);
+    if (!tex) {
+        return nullptr;
     }
 
-    sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
-            [backendTex, sampleCnt, ownership](GrResourceProvider* resourceProvider) {
-                if (!resourceProvider) {
-                    return sk_sp<GrTexture>();
-                }
+    SkASSERT(tex->asRenderTarget());  // A GrTextureRenderTarget
+    // Make sure we match how we created the proxy with SkBudgeted::kNo
+    SkASSERT(SkBudgeted::kNo == tex->resourcePriv().isBudgeted());
 
-                sk_sp<GrTexture> tex = resourceProvider->wrapRenderableBackendTexture(
-                        backendTex, sampleCnt, ownership);
-                if (!tex) {
-                    return sk_sp<GrTexture>();
-                }
-                SkASSERT(tex->asRenderTarget());   // A GrTextureRenderTarget
-                // Make sure we match how we created the proxy with SkBudgeted::kNo
-                SkASSERT(SkBudgeted::kNo == tex->resourcePriv().isBudgeted());
-
-                return tex;
-            },
-            desc, origin, mipMapped, renderTargetFlags, SkBackingFit::kExact, SkBudgeted::kNo);
-
-    if (fResourceProvider) {
-        // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however,
-        // we're better off instantiating the proxy immediately here.
-        if (!proxy->priv().doLazyInstantiation(fResourceProvider)) {
-            return nullptr;
-        }
-    }
-    return proxy;
+    return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(std::move(tex), origin));
 }
 
 sk_sp<GrSurfaceProxy> GrProxyProvider::wrapBackendRenderTarget(
@@ -518,49 +468,21 @@
         return nullptr;
     }
 
-    GrSurfaceDesc desc;
-    desc.fWidth = backendRT.width();
-    desc.fHeight = backendRT.height();
-    desc.fConfig = backendRT.config();
-    desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fSampleCnt = backendRT.sampleCnt();
-
-    GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone;
-    if (fCaps->isMixedSamplesSupportedForRT(backendRT) && backendRT.sampleCnt() > 1) {
-        renderTargetFlags |= GrRenderTargetFlags::kMixedSampled;
-    }
-    if (fCaps->isWindowRectanglesSupportedForRT(backendRT)) {
-        renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport;
+    // This is only supported on a direct GrContext.
+    if (!fResourceProvider) {
+        return nullptr;
     }
 
-    sk_sp<GrRenderTargetProxy> proxy = this->createLazyRenderTargetProxy(
-            [backendRT](GrResourceProvider* resourceProvider) {
-                if (!resourceProvider) {
-                    return sk_sp<GrRenderTarget>();
-                }
-
-                sk_sp<GrRenderTarget> rt = resourceProvider->wrapBackendRenderTarget(backendRT);
-                if (!rt) {
-                    return sk_sp<GrRenderTarget>();
-                }
-                SkASSERT(!rt->asTexture());   // A GrRenderTarget that's not textureable
-                SkASSERT(!rt->getUniqueKey().isValid());
-                // Make sure we match how we created the proxy with SkBudgeted::kNo
-                SkASSERT(SkBudgeted::kNo == rt->resourcePriv().isBudgeted());
-
-                return rt;
-            },
-            desc, origin, renderTargetFlags, Textureable::kNo, GrMipMapped::kNo,
-            SkBackingFit::kExact, SkBudgeted::kNo);
-
-    if (fResourceProvider) {
-        // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however,
-        // we're better off instantiating the proxy immediately here.
-        if (!proxy->priv().doLazyInstantiation(fResourceProvider)) {
-            return nullptr;
-        }
+    sk_sp<GrRenderTarget> rt = fResourceProvider->wrapBackendRenderTarget(backendRT);
+    if (!rt) {
+        return nullptr;
     }
-    return proxy;
+    SkASSERT(!rt->asTexture());  // A GrRenderTarget that's not textureable
+    SkASSERT(!rt->getUniqueKey().isValid());
+    // Make sure we match how we created the proxy with SkBudgeted::kNo
+    SkASSERT(SkBudgeted::kNo == rt->resourcePriv().isBudgeted());
+
+    return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(std::move(rt), origin));
 }
 
 sk_sp<GrSurfaceProxy> GrProxyProvider::wrapBackendTextureAsRenderTarget(
@@ -569,55 +491,22 @@
         return nullptr;
     }
 
-    sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config());
-    if (!sampleCnt) {
+    // This is only supported on a direct GrContext.
+    if (!fResourceProvider) {
         return nullptr;
     }
 
-    GrSurfaceDesc desc;
-    desc.fWidth = backendTex.width();
-    desc.fHeight = backendTex.height();
-    desc.fConfig = backendTex.config();
-    desc.fFlags = kRenderTarget_GrSurfaceFlag;
-    desc.fSampleCnt = sampleCnt;
-
-    GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone;
-    if (fCaps->usesMixedSamples() && sampleCnt > 1) {
-        renderTargetFlags |= GrRenderTargetFlags::kMixedSampled;
+    sk_sp<GrRenderTarget> rt =
+            fResourceProvider->wrapBackendTextureAsRenderTarget(backendTex, sampleCnt);
+    if (!rt) {
+        return nullptr;
     }
-    if (fCaps->maxWindowRectangles() > 0) {
-        renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport;
-    }
+    SkASSERT(!rt->asTexture());  // A GrRenderTarget that's not textureable
+    SkASSERT(!rt->getUniqueKey().isValid());
+    // Make sure we match how we created the proxy with SkBudgeted::kNo
+    SkASSERT(SkBudgeted::kNo == rt->resourcePriv().isBudgeted());
 
-    sk_sp<GrRenderTargetProxy> proxy = this->createLazyRenderTargetProxy(
-            [backendTex, sampleCnt](GrResourceProvider* resourceProvider) {
-                if (!resourceProvider) {
-                    return sk_sp<GrRenderTarget>();
-                }
-
-                sk_sp<GrRenderTarget> rt = resourceProvider->wrapBackendTextureAsRenderTarget(
-                        backendTex, sampleCnt);
-                if (!rt) {
-                    return sk_sp<GrRenderTarget>();
-                }
-                SkASSERT(!rt->asTexture());   // A GrRenderTarget that's not textureable
-                SkASSERT(!rt->getUniqueKey().isValid());
-                // Make sure we match how we created the proxy with SkBudgeted::kNo
-                SkASSERT(SkBudgeted::kNo == rt->resourcePriv().isBudgeted());
-
-                return rt;
-            },
-            desc, origin, renderTargetFlags, Textureable::kNo, GrMipMapped::kNo,
-            SkBackingFit::kExact, SkBudgeted::kNo);
-
-    if (fResourceProvider) {
-        // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however,
-        // we're better off instantiating the proxy immediately here.
-        if (!proxy->priv().doLazyInstantiation(fResourceProvider)) {
-            return nullptr;
-        }
-    }
-    return proxy;
+    return sk_sp<GrSurfaceProxy>(new GrRenderTargetProxy(std::move(rt), origin));
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 957811e..aec7a37 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2452,13 +2452,6 @@
     return true;
 }
 
-bool GrGLCaps::onIsMixedSamplesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
-    const GrGLFramebufferInfo* fbInfo = backendRT.getGLFramebufferInfo();
-    SkASSERT(fbInfo);
-    // Mixed samples are not supported for FBO 0;
-    return fbInfo->fFBOID != 0;
-}
-
 bool GrGLCaps::onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget& backendRT) const {
     const GrGLFramebufferInfo* fbInfo = backendRT.getGLFramebufferInfo();
     SkASSERT(fbInfo);
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index dbcccd5..5d3fa6a 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -435,7 +435,6 @@
 
     void onApplyOptionsOverrides(const GrContextOptions& options) override;
 
-    bool onIsMixedSamplesSupportedForRT(const GrBackendRenderTarget&) const override;
     bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const override;
 
     void initFSAASupport(const GrContextOptions& contextOptions, const GrGLContextInfo&,
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 78dcd59..a961313 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -307,9 +307,10 @@
         return nullptr;
     }
 
-    sk_sp<SkGpuDevice> device(SkGpuDevice::Make(context, std::move(rtc),
-                                                rtc->width(), rtc->height(),
-                                                SkGpuDevice::kUninit_InitContents));
+    int w = rtc->width();
+    int h = rtc->height();
+    sk_sp<SkGpuDevice> device(
+            SkGpuDevice::Make(context, std::move(rtc), w, h, SkGpuDevice::kUninit_InitContents));
     if (!device) {
         return nullptr;
     }
diff --git a/tests/DeferredDisplayListTest.cpp b/tests/DeferredDisplayListTest.cpp
index 4b425ae..b0c80c3 100644
--- a/tests/DeferredDisplayListTest.cpp
+++ b/tests/DeferredDisplayListTest.cpp
@@ -358,143 +358,50 @@
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DDLWrapBackendTest, reporter, ctxInfo) {
     GrContext* context = ctxInfo.grContext();
     GrGpu* gpu = context->contextPriv().getGpu();
-    for (auto lastStage : { DDLStage::kMakeImage, DDLStage::kDrawImage,
-                            DDLStage::kDetach, DDLStage::kDrawDDL } ) {
-        for (auto earlyImageReset : { false , true } ) {
-            GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
-                    nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, false, GrMipMapped::kNo);
-            if (!backendTex.isValid()) {
-                continue;
-            }
-
-            SurfaceParameters params;
-
-            sk_sp<SkSurface> s = params.make(context);
-            if (!s) {
-                gpu->deleteTestingOnlyBackendTexture(&backendTex);
-                continue;
-            }
-
-            SkSurfaceCharacterization c;
-            SkAssertResult(s->characterize(&c));
-
-            std::unique_ptr<SkDeferredDisplayListRecorder> recorder(
-                    new SkDeferredDisplayListRecorder(c));
-
-            SkCanvas* canvas = recorder->getCanvas();
-            if (!canvas) {
-                gpu->deleteTestingOnlyBackendTexture(&backendTex);
-                continue;
-            }
-
-            GrContext* deferredContext = canvas->getGrContext();
-            if (!deferredContext) {
-                gpu->deleteTestingOnlyBackendTexture(&backendTex);
-                continue;
-            }
-
-            sk_sp<SkImage> image = SkImage::MakeFromAdoptedTexture(deferredContext, backendTex,
-                                                                   kTopLeft_GrSurfaceOrigin,
-                                                                   kRGBA_8888_SkColorType,
-                                                                   kPremul_SkAlphaType, nullptr);
-            // Adopted Textures are not supported in DDL
-            REPORTER_ASSERT(reporter, !image);
-
-            TextureReleaseChecker releaseChecker;
-            image = SkImage::MakeFromTexture(deferredContext, backendTex,
-                                             kTopLeft_GrSurfaceOrigin,
-                                             kRGBA_8888_SkColorType,
-                                             kPremul_SkAlphaType, nullptr,
-                                             TextureReleaseChecker::Release, &releaseChecker);
-
-            REPORTER_ASSERT(reporter, image);
-            if (!image) {
-                gpu->deleteTestingOnlyBackendTexture(&backendTex);
-                continue;
-            }
-
-            if (DDLStage::kMakeImage == lastStage) {
-                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-                image.reset();
-                REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
-                recorder.reset();
-                REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
-                gpu->deleteTestingOnlyBackendTexture(&backendTex);
-                continue;
-            }
-
-            canvas->drawImage(image.get(), 0, 0);
-
-            if (earlyImageReset) {
-                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-                image.reset();
-                // Ref should still be held by DDL recorder since we did the draw
-                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-            }
-
-            if (DDLStage::kDrawImage == lastStage) {
-                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-                recorder.reset();
-                if (earlyImageReset) {
-                    REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
-                } else {
-                    REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-                    image.reset();
-                    REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
-                }
-                gpu->deleteTestingOnlyBackendTexture(&backendTex);
-                continue;
-            }
-
-            std::unique_ptr<SkDeferredDisplayList> ddl = recorder->detach();
-            if (DDLStage::kDetach == lastStage) {
-                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-                recorder.reset();
-#ifndef SK_RASTER_RECORDER_IMPLEMENTATION
-                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-#endif
-                ddl.reset();
-                if (earlyImageReset) {
-                    REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
-                } else {
-                    REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-                    image.reset();
-                    REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
-                }
-                gpu->deleteTestingOnlyBackendTexture(&backendTex);
-                continue;
-            }
-
-            REPORTER_ASSERT(reporter, s->draw(ddl.get()));
-
-            REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-            recorder.reset();
-#ifndef SK_RASTER_RECORDER_IMPLEMENTATION
-            REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-#endif
-            ddl.reset();
-#ifndef SK_RASTER_RECORDER_IMPLEMENTATION
-            REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-#endif
-
-            // Force all draws to flush and sync by calling a read pixels
-            SkImageInfo imageInfo = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
-                                                      kPremul_SkAlphaType);
-            SkBitmap bitmap;
-            bitmap.allocPixels(imageInfo);
-            s->readPixels(imageInfo, bitmap.getPixels(), bitmap.rowBytes(), 0, 0);
-
-            if (earlyImageReset) {
-                REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
-            } else {
-                REPORTER_ASSERT(reporter, 0 == releaseChecker.fReleaseCount);
-                image.reset();
-                REPORTER_ASSERT(reporter, 1 == releaseChecker.fReleaseCount);
-            }
-
-            gpu->deleteTestingOnlyBackendTexture(&backendTex);
-        }
+    GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
+            nullptr, kSize, kSize, kRGBA_8888_GrPixelConfig, false, GrMipMapped::kNo);
+    if (!backendTex.isValid()) {
+        return;
     }
+
+    SurfaceParameters params;
+
+    sk_sp<SkSurface> s = params.make(context);
+    if (!s) {
+        gpu->deleteTestingOnlyBackendTexture(&backendTex);
+        return;
+    }
+
+    SkSurfaceCharacterization c;
+    SkAssertResult(s->characterize(&c));
+
+    std::unique_ptr<SkDeferredDisplayListRecorder> recorder(new SkDeferredDisplayListRecorder(c));
+
+    SkCanvas* canvas = recorder->getCanvas();
+    if (!canvas) {
+        gpu->deleteTestingOnlyBackendTexture(&backendTex);
+        return;
+    }
+
+    GrContext* deferredContext = canvas->getGrContext();
+    if (!deferredContext) {
+        gpu->deleteTestingOnlyBackendTexture(&backendTex);
+        return;
+    }
+
+    // Wrapped Backend Textures are not supported in DDL
+    sk_sp<SkImage> image =
+            SkImage::MakeFromAdoptedTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
+                                            kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
+    REPORTER_ASSERT(reporter, !image);
+
+    TextureReleaseChecker releaseChecker;
+    image = SkImage::MakeFromTexture(deferredContext, backendTex, kTopLeft_GrSurfaceOrigin,
+                                     kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr,
+                                     TextureReleaseChecker::Release, &releaseChecker);
+    REPORTER_ASSERT(reporter, !image);
+
+    gpu->deleteTestingOnlyBackendTexture(&backendTex);
 }
 
 
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index 9d52281..8f5eb13 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -48,12 +48,17 @@
     REPORTER_ASSERT(reporter, rtProxy->numStencilSamples() == numSamples);
 
     GrSurfaceProxy::UniqueID idBefore = rtProxy->uniqueID();
+    bool preinstantiated = rtProxy->priv().isInstantiated();
     REPORTER_ASSERT(reporter, rtProxy->instantiate(provider));
     GrRenderTarget* rt = rtProxy->priv().peekRenderTarget();
 
     REPORTER_ASSERT(reporter, rtProxy->uniqueID() == idBefore);
     // Deferred resources should always have a different ID from their instantiated rendertarget
-    REPORTER_ASSERT(reporter, rtProxy->uniqueID().asUInt() != rt->uniqueID().asUInt());
+    if (preinstantiated) {
+        REPORTER_ASSERT(reporter, rtProxy->uniqueID().asUInt() == rt->uniqueID().asUInt());
+    } else {
+        REPORTER_ASSERT(reporter, rtProxy->uniqueID().asUInt() != rt->uniqueID().asUInt());
+    }
 
     if (SkBackingFit::kExact == fit) {
         REPORTER_ASSERT(reporter, rt->width() == rtProxy->width());
@@ -76,12 +81,17 @@
                           SkBackingFit fit) {
     GrSurfaceProxy::UniqueID idBefore = texProxy->uniqueID();
 
+    bool preinstantiated = texProxy->priv().isInstantiated();
     REPORTER_ASSERT(reporter, texProxy->instantiate(provider));
     GrTexture* tex = texProxy->priv().peekTexture();
 
     REPORTER_ASSERT(reporter, texProxy->uniqueID() == idBefore);
     // Deferred resources should always have a different ID from their instantiated texture
-    REPORTER_ASSERT(reporter, texProxy->uniqueID().asUInt() != tex->uniqueID().asUInt());
+    if (preinstantiated) {
+        REPORTER_ASSERT(reporter, texProxy->uniqueID().asUInt() == tex->uniqueID().asUInt());
+    } else {
+        REPORTER_ASSERT(reporter, texProxy->uniqueID().asUInt() != tex->uniqueID().asUInt());
+    }
 
     if (SkBackingFit::kExact == fit) {
         REPORTER_ASSERT(reporter, tex->width() == texProxy->width());