Update createWrappedRenderTargetProxy with BackendRT to work with lazy proxies.

This change also triggered a bunch of side changes thanks to WrappedProxyTest
fixing/improving how we handle wrapped proxies in genernal.

Bug: skia:
Change-Id: I743a458923cff1c2e947627d0e9154a4c808a668
Reviewed-on: https://skia-review.googlesource.com/108102
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/include/gpu/GrBackendSurface.h b/include/gpu/GrBackendSurface.h
index c8072c9..c2fc619 100644
--- a/include/gpu/GrBackendSurface.h
+++ b/include/gpu/GrBackendSurface.h
@@ -144,6 +144,8 @@
     // Returns true if the backend texture has been initialized.
     bool isValid() const { return fConfig != kUnknown_GrPixelConfig; }
 
+    GrPixelConfig testingOnly_getPixelConfig() const;
+
 private:
     // Friending for access to the GrPixelConfig
     friend class SkImage;
@@ -218,6 +220,8 @@
     // Returns true if the backend texture has been initialized.
     bool isValid() const { return fConfig != kUnknown_GrPixelConfig; }
 
+    GrPixelConfig testingOnly_getPixelConfig() const;
+
 private:
     // Friending for access to the GrPixelConfig
     friend class SkSurface;
@@ -225,6 +229,7 @@
     friend class SkImage_Gpu;
     friend class GrGpu;
     friend class GrGLGpu;
+    friend class GrProxyProvider;
     friend class GrVkGpu;
     GrPixelConfig config() const { return fConfig; }
 
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h
index 1b81b18..9d6ef0d 100644
--- a/include/gpu/GrCaps.h
+++ b/include/gpu/GrCaps.h
@@ -58,6 +58,11 @@
     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; }
@@ -137,6 +142,11 @@
 
     int maxWindowRectangles() const { return fMaxWindowRectangles; }
 
+    // Returns whether mixed samples is supported for the given backend render target.
+    bool isWindowRectanglesSupportedForRT(const GrBackendRenderTarget& rt) const {
+        return this->maxWindowRectangles() > 0 && this->onIsWindowRectanglesSupportedForRT(rt);
+    }
+
     // A tuned, platform-specific value for the maximum number of analytic fragment processors we
     // should use to implement a clip, before falling back on a mask.
     int maxClipAnalyticFPs() const { return fMaxClipAnalyticFPs; }
@@ -277,6 +287,17 @@
     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 {
+        return true;
+    }
+
     bool fSuppressPrints : 1;
     bool fWireframeMode  : 1;
 
diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h
index 1672fd9..783f54e 100644
--- a/include/private/GrRenderTargetProxy.h
+++ b/include/private/GrRenderTargetProxy.h
@@ -78,7 +78,8 @@
     // The minimal knowledge version is used for CCPR where we are generating an atlas but we do not
     // know the final size until flush time.
     GrRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType lazyType,
-                        const GrSurfaceDesc&, SkBackingFit, SkBudgeted, uint32_t flags);
+                        const GrSurfaceDesc&, SkBackingFit, SkBudgeted, uint32_t flags,
+                        GrRenderTargetFlags renderTargetFlags);
 
     // Wrapped version
     GrRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin);
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 0e72850..09298ab 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -211,6 +211,16 @@
         return nullptr;
     }
 
+    GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone;
+    if (SkToBool(flags & kRenderTarget_GrSurfaceFlag)) {
+        if (fCaps->usesMixedSamples() && sampleCnt > 1) {
+            renderTargetFlags |= GrRenderTargetFlags::kMixedSampled;
+        }
+        if (fCaps->maxWindowRectangles() > 0) {
+            renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport;
+        }
+    }
+
     GrSurfaceDesc desc;
     desc.fWidth = srcImage->width();
     desc.fHeight = srcImage->height();
@@ -232,7 +242,7 @@
                 GrMipLevel mipLevel = { pixMap.addr(), pixMap.rowBytes() };
 
                 return resourceProvider->createTexture(desc, budgeted, fit, mipLevel);
-            }, desc, GrMipMapped::kNo, fit, budgeted);
+            }, desc, GrMipMapped::kNo, renderTargetFlags, fit, budgeted);
 
     if (fResourceProvider) {
         // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however
@@ -451,6 +461,14 @@
     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<GrTextureProxy> proxy = this->createLazyProxy(
             [backendTex, sampleCnt] (GrResourceProvider* resourceProvider) {
                 if (!resourceProvider) {
@@ -467,7 +485,7 @@
                 SkASSERT(SkBudgeted::kNo == tex->resourcePriv().isBudgeted());
 
                 return tex;
-            }, desc, mipMapped, SkBackingFit::kExact, SkBudgeted::kNo);
+            }, desc, 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,
@@ -486,14 +504,49 @@
         return nullptr;
     }
 
-    sk_sp<GrRenderTarget> rt(fResourceProvider->wrapBackendRenderTarget(backendRT));
-    if (!rt) {
-        return nullptr;
-    }
-    SkASSERT(!rt->asTexture()); // Strictly a GrRenderTarget
-    SkASSERT(!rt->getUniqueKey().isValid());
+    GrSurfaceDesc desc;
+    desc.fOrigin = origin;
+    desc.fWidth = backendRT.width();
+    desc.fHeight = backendRT.height();
+    desc.fConfig = backendRT.config();
+    desc.fFlags = kRenderTarget_GrSurfaceFlag;
+    desc.fSampleCnt = backendRT.sampleCnt();
 
-    return sk_sp<GrSurfaceProxy>(new GrRenderTargetProxy(std::move(rt), origin));
+    GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone;
+    if (fCaps->isMixedSamplesSupportedForRT(backendRT) && backendRT.sampleCnt() > 1) {
+        renderTargetFlags |= GrRenderTargetFlags::kMixedSampled;
+    }
+    if (fCaps->isWindowRectanglesSupportedForRT(backendRT)) {
+        renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport;
+    }
+
+    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, 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;
 }
 
 sk_sp<GrSurfaceProxy> GrProxyProvider::createWrappedRenderTargetProxy(const GrBackendTexture& tex,
@@ -517,10 +570,30 @@
                                                        const GrSurfaceDesc& desc,
                                                        GrMipMapped mipMapped,
                                                        SkBackingFit fit, SkBudgeted budgeted) {
+    return this->createLazyProxy(std::move(callback), desc, mipMapped, GrRenderTargetFlags::kNone,
+                                 fit, budgeted);
+}
+
+sk_sp<GrTextureProxy> GrProxyProvider::createLazyProxy(LazyInstantiateCallback&& callback,
+                                                       const GrSurfaceDesc& desc,
+                                                       GrMipMapped mipMapped,
+                                                       GrRenderTargetFlags renderTargetFlags,
+                                                       SkBackingFit fit, SkBudgeted budgeted) {
     SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
              (desc.fWidth > 0 && desc.fHeight > 0));
     uint32_t flags = GrResourceProvider::kNoPendingIO_Flag;
 
+#ifdef SK_DEBUG
+    if (SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)) {
+        if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kMixedSampled)) {
+            SkASSERT(fCaps->usesMixedSamples() && desc.fSampleCnt > 1);
+        }
+        if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kWindowRectsSupport)) {
+            SkASSERT(fCaps->maxWindowRectangles() > 0);
+        }
+    }
+#endif
+
     using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType;
     // For non-ddl draws always make lazy proxy's single use.
     LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse
@@ -528,7 +601,8 @@
 
     return sk_sp<GrTextureProxy>(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags) ?
                                  new GrTextureRenderTargetProxy(std::move(callback), lazyType, desc,
-                                                                mipMapped, fit, budgeted, flags) :
+                                                                mipMapped, fit, budgeted, flags,
+                                                                renderTargetFlags) :
                                  new GrTextureProxy(std::move(callback), lazyType, desc, mipMapped,
                                                     fit, budgeted, flags));
 }
@@ -536,13 +610,24 @@
 sk_sp<GrRenderTargetProxy> GrProxyProvider::createLazyRenderTargetProxy(
                                                 LazyInstantiateCallback&& callback,
                                                 const GrSurfaceDesc& desc,
+                                                GrRenderTargetFlags renderTargetFlags,
                                                 Textureable textureable,
                                                 GrMipMapped mipMapped,
                                                 SkBackingFit fit, SkBudgeted budgeted) {
     SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
              (desc.fWidth > 0 && desc.fHeight > 0));
+    SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags));
     uint32_t flags = GrResourceProvider::kNoPendingIO_Flag;
 
+#ifdef SK_DEBUG
+    if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kMixedSampled)) {
+        SkASSERT(fCaps->usesMixedSamples() && desc.fSampleCnt > 1);
+    }
+    if (SkToBool(renderTargetFlags & GrRenderTargetFlags::kWindowRectsSupport)) {
+        SkASSERT(fCaps->maxWindowRectangles() > 0);
+    }
+#endif
+
     using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType;
     // For non-ddl draws always make lazy proxy's single use.
     LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse
@@ -551,11 +636,13 @@
     if (Textureable::kYes == textureable) {
         return sk_sp<GrRenderTargetProxy>(new GrTextureRenderTargetProxy(std::move(callback),
                                                                          lazyType, desc, mipMapped,
-                                                                         fit, budgeted, flags));
+                                                                         fit, budgeted, flags,
+                                                                         renderTargetFlags));
     }
 
     return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(std::move(callback), lazyType, desc,
-                                                              fit, budgeted, flags));
+                                                              fit, budgeted, flags,
+                                                              renderTargetFlags));
 }
 
 sk_sp<GrTextureProxy> GrProxyProvider::createFullyLazyProxy(LazyInstantiateCallback&& callback,
@@ -563,8 +650,12 @@
                                                             GrSurfaceOrigin origin,
                                                             GrPixelConfig config) {
     GrSurfaceDesc desc;
+    GrRenderTargetFlags renderTargetFlags = GrRenderTargetFlags::kNone;
     if (Renderable::kYes == renderable) {
         desc.fFlags = kRenderTarget_GrSurfaceFlag;
+        if (fCaps->maxWindowRectangles() > 0) {
+            renderTargetFlags |= GrRenderTargetFlags::kWindowRectsSupport;
+        }
     }
     desc.fOrigin = origin;
     desc.fWidth = -1;
@@ -572,7 +663,7 @@
     desc.fConfig = config;
     desc.fSampleCnt = 1;
 
-    return this->createLazyProxy(std::move(callback), desc, GrMipMapped::kNo,
+    return this->createLazyProxy(std::move(callback), desc, GrMipMapped::kNo, renderTargetFlags,
                                  SkBackingFit::kApprox, SkBudgeted::kYes);
 
 }
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index 01b3b1f..dfd06df 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -168,6 +168,10 @@
      * callback should cleanup any resources it captured and return an empty sk_sp<GrTextureProxy>.
      */
     sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&,
+                                          GrMipMapped, GrRenderTargetFlags, SkBackingFit,
+                                          SkBudgeted);
+
+    sk_sp<GrTextureProxy> createLazyProxy(LazyInstantiateCallback&&, const GrSurfaceDesc&,
                                           GrMipMapped, SkBackingFit, SkBudgeted);
 
     /**
@@ -178,7 +182,8 @@
                                                Renderable, GrSurfaceOrigin, GrPixelConfig);
 
     sk_sp<GrRenderTargetProxy> createLazyRenderTargetProxy(LazyInstantiateCallback&&,
-                                                           const GrSurfaceDesc&, Textureable,
+                                                           const GrSurfaceDesc&,
+                                                           GrRenderTargetFlags, Textureable,
                                                            GrMipMapped, SkBackingFit, SkBudgeted);
 
     // 'proxy' is about to be used as a texture src or drawn to. This query can be used to
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
index 7d872ef..e0dbe8f 100644
--- a/src/gpu/GrRenderTargetProxy.cpp
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -39,11 +39,12 @@
                                          LazyInstantiationType lazyType,
                                          const GrSurfaceDesc& desc,
                                          SkBackingFit fit, SkBudgeted budgeted,
-                                         uint32_t flags)
+                                         uint32_t flags,
+                                         GrRenderTargetFlags renderTargetFlags)
         : INHERITED(std::move(callback), lazyType, desc, fit, budgeted, flags)
         , fSampleCnt(desc.fSampleCnt)
         , fNeedsStencil(false)
-        , fRenderTargetFlags(GrRenderTargetFlags::kNone) {
+        , fRenderTargetFlags(renderTargetFlags) {
     SkASSERT(SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags));
 }
 
diff --git a/src/gpu/GrTextureRenderTargetProxy.cpp b/src/gpu/GrTextureRenderTargetProxy.cpp
index 50077c4..213359b 100644
--- a/src/gpu/GrTextureRenderTargetProxy.cpp
+++ b/src/gpu/GrTextureRenderTargetProxy.cpp
@@ -36,12 +36,14 @@
                                                        GrMipMapped mipMapped,
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted,
-                                                       uint32_t flags)
+                                                       uint32_t flags,
+                                                       GrRenderTargetFlags renderTargetFlags)
         : GrSurfaceProxy(std::move(callback), lazyType, desc, fit, budgeted, flags)
         // Since we have virtual inheritance, we initialize GrSurfaceProxy directly. Send null
         // callbacks to the texture and RT proxies simply to route to the appropriate constructors.
         , GrTextureProxy(LazyInstantiateCallback(), lazyType, desc, mipMapped, fit, budgeted, flags)
-        , GrRenderTargetProxy(LazyInstantiateCallback(), lazyType, desc, fit, budgeted, flags) {
+        , GrRenderTargetProxy(LazyInstantiateCallback(), lazyType, desc, fit, budgeted, flags,
+                              renderTargetFlags) {
 }
 
 // Wrapped version
diff --git a/src/gpu/GrTextureRenderTargetProxy.h b/src/gpu/GrTextureRenderTargetProxy.h
index 06a84c2..a236189 100644
--- a/src/gpu/GrTextureRenderTargetProxy.h
+++ b/src/gpu/GrTextureRenderTargetProxy.h
@@ -34,7 +34,7 @@
     // Lazy-callback version
     GrTextureRenderTargetProxy(LazyInstantiateCallback&&, LazyInstantiationType,
                                const GrSurfaceDesc& desc, GrMipMapped, SkBackingFit, SkBudgeted,
-                               uint32_t flags);
+                               uint32_t flags, GrRenderTargetFlags);
 
     // Wrapped version
     GrTextureRenderTargetProxy(sk_sp<GrSurface>, GrSurfaceOrigin);
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index c872acd..4fb9ffd 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2411,6 +2411,20 @@
     }
 }
 
+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);
+    // Window Rectangles are not supported for FBO 0;
+    return fbInfo->fFBOID != 0;
+}
+
 int GrGLCaps::getRenderTargetSampleCount(int requestedCount, GrPixelConfig config) const {
     requestedCount = SkTMax(1, requestedCount);
     int count = fConfigTable[config].fColorSampleCounts.count();
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 6c8fe5c..8bac68c 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -431,6 +431,9 @@
 
     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&,
                          const GrGLInterface*);
     void initBlendEqationSupport(const GrGLContextInfo&);
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index dff230c..3a46438 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -20,6 +20,7 @@
 #include "GrSurfaceProxyPriv.h"
 #include "GrTexture.h"
 #include "GrTextureProxy.h"
+#include "SkGr.h"
 
 // Check that the surface proxy's member vars are set as expected
 static void check_surface(skiatest::Reporter* reporter,
@@ -42,8 +43,7 @@
                                GrRenderTargetProxy* rtProxy,
                                int numSamples,
                                SkBackingFit fit,
-                               int expectedMaxWindowRects,
-                               bool wasWrapped) {
+                               int expectedMaxWindowRects) {
     REPORTER_ASSERT(reporter, rtProxy->maxWindowRectangles(caps) == expectedMaxWindowRects);
     REPORTER_ASSERT(reporter, rtProxy->numStencilSamples() == numSamples);
 
@@ -52,13 +52,8 @@
     GrRenderTarget* rt = rtProxy->priv().peekRenderTarget();
 
     REPORTER_ASSERT(reporter, rtProxy->uniqueID() == idBefore);
-    if (wasWrapped) {
-        // Wrapped resources share their uniqueID with the wrapping RenderTargetProxy
-        REPORTER_ASSERT(reporter, rtProxy->uniqueID().asUInt() == rt->uniqueID().asUInt());
-    } else {
-        // Deferred resources should always have a different ID from their instantiated rendertarget
-        REPORTER_ASSERT(reporter, rtProxy->uniqueID().asUInt() != rt->uniqueID().asUInt());
-    }
+    // Deferred resources should always have a different ID from their instantiated rendertarget
+    REPORTER_ASSERT(reporter, rtProxy->uniqueID().asUInt() != rt->uniqueID().asUInt());
 
     if (SkBackingFit::kExact == fit) {
         REPORTER_ASSERT(reporter, rt->width() == rtProxy->width());
@@ -78,21 +73,15 @@
 static void check_texture(skiatest::Reporter* reporter,
                           GrResourceProvider* provider,
                           GrTextureProxy* texProxy,
-                          SkBackingFit fit,
-                          bool wasWrapped) {
+                          SkBackingFit fit) {
     GrSurfaceProxy::UniqueID idBefore = texProxy->uniqueID();
 
     REPORTER_ASSERT(reporter, texProxy->instantiate(provider));
     GrTexture* tex = texProxy->priv().peekTexture();
 
     REPORTER_ASSERT(reporter, texProxy->uniqueID() == idBefore);
-    if (wasWrapped) {
-        // Wrapped resources share their uniqueID with the wrapping TextureProxy
-        REPORTER_ASSERT(reporter, texProxy->uniqueID().asUInt() == tex->uniqueID().asUInt());
-    } else {
-        // Deferred resources should always have a different ID from their instantiated texture
-        REPORTER_ASSERT(reporter, texProxy->uniqueID().asUInt() != tex->uniqueID().asUInt());
-    }
+    // Deferred resources should always have a different ID from their instantiated texture
+    REPORTER_ASSERT(reporter, texProxy->uniqueID().asUInt() != tex->uniqueID().asUInt());
 
     if (SkBackingFit::kExact == fit) {
         REPORTER_ASSERT(reporter, tex->width() == texProxy->width());
@@ -154,7 +143,7 @@
                                     check_rendertarget(reporter, caps, resourceProvider,
                                                        proxy->asRenderTargetProxy(),
                                                        supportedSamples,
-                                                       fit, caps.maxWindowRectangles(), false);
+                                                       fit, caps.maxWindowRectangles());
                                 }
                             }
 
@@ -182,7 +171,7 @@
                                     check_surface(reporter, proxy.get(), origin,
                                                   widthHeight, widthHeight, config, budgeted);
                                     check_texture(reporter, resourceProvider,
-                                                  proxy->asTextureProxy(), fit, false);
+                                                  proxy->asTextureProxy(), fit);
                                 }
                             }
 
@@ -198,71 +187,87 @@
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) {
     GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider();
     GrResourceProvider* resourceProvider = ctxInfo.grContext()->contextPriv().resourceProvider();
+    GrGpu* gpu = ctxInfo.grContext()->contextPriv().getGpu();
     const GrCaps& caps = *ctxInfo.grContext()->caps();
 
     static const int kWidthHeight = 100;
 
+    if (kOpenGL_GrBackend != ctxInfo.backend()) {
+        return;
+    }
     for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) {
-        for (auto config : { kAlpha_8_GrPixelConfig, kRGBA_8888_GrPixelConfig }) {
-            for (auto budgeted : { SkBudgeted::kYes, SkBudgeted::kNo }) {
-                for (auto numSamples : {1, 4}) {
-                    int supportedNumSamples = caps.getRenderTargetSampleCount(numSamples, config);
+        for (auto colorType : { kAlpha_8_SkColorType, kRGBA_8888_SkColorType }) {
+            for (auto numSamples : {1, 4}) {
+                GrPixelConfig config = SkImageInfo2GrPixelConfig(colorType, nullptr, caps);
+                int supportedNumSamples = caps.getRenderTargetSampleCount(numSamples, config);
 
-                    GrSurfaceDesc desc;
-                    desc.fOrigin = origin;
-                    desc.fWidth = kWidthHeight;
-                    desc.fHeight = kWidthHeight;
-                    desc.fConfig = config;
-                    desc.fSampleCnt = supportedNumSamples;
+                if (!supportedNumSamples) {
+                    continue;
+                }
 
-                    // External on-screen render target.
-                    if (supportedNumSamples && kOpenGL_GrBackend == ctxInfo.backend()) {
-                        GrGLFramebufferInfo fboInfo;
-                        fboInfo.fFBOID = 0;
-                        GrBackendRenderTarget backendRT(kWidthHeight, kWidthHeight, numSamples, 8,
-                                                        config, fboInfo);
+                // External on-screen render target.
+                {
+                    GrGLFramebufferInfo fboInfo;
+                    fboInfo.fFBOID = 0;
+                    GrBackendRenderTarget backendRT(kWidthHeight, kWidthHeight, numSamples, 8,
+                                                    config, fboInfo);
 
-                        sk_sp<GrSurfaceProxy> sProxy(proxyProvider->createWrappedRenderTargetProxy(
-                                                                                backendRT, origin));
-                        check_surface(reporter, sProxy.get(), origin,
-                                      kWidthHeight, kWidthHeight, config, SkBudgeted::kNo);
-                        check_rendertarget(reporter, caps, resourceProvider,
-                                           sProxy->asRenderTargetProxy(),
-                                           supportedNumSamples, SkBackingFit::kExact, 0, true);
+                    sk_sp<GrSurfaceProxy> sProxy(proxyProvider->createWrappedRenderTargetProxy(
+                            backendRT, origin));
+                    check_surface(reporter, sProxy.get(), origin,
+                                  kWidthHeight, kWidthHeight,
+                                  backendRT.testingOnly_getPixelConfig(), SkBudgeted::kNo);
+                    check_rendertarget(reporter, caps, resourceProvider,
+                                       sProxy->asRenderTargetProxy(),
+                                       supportedNumSamples, SkBackingFit::kExact, 0);
+                }
+
+                {
+                    GrBackendTexture backendTex =
+                            gpu->createTestingOnlyBackendTexture(nullptr, kWidthHeight,
+                                                                 kWidthHeight, colorType, true,
+                                                                 GrMipMapped::kNo);
+
+                    sk_sp<GrSurfaceProxy> sProxy =
+                            proxyProvider->createWrappedTextureProxy(backendTex, origin,
+                                                                     supportedNumSamples);
+                    if (!sProxy) {
+                        continue;  // This can fail on Mesa
                     }
 
-                    if (supportedNumSamples) {
-                        // Internal offscreen render target.
-                        desc.fFlags = kRenderTarget_GrSurfaceFlag;
+                    check_surface(reporter, sProxy.get(), origin,
+                                  kWidthHeight, kWidthHeight,
+                                  backendTex.testingOnly_getPixelConfig(), SkBudgeted::kNo);
+                    check_rendertarget(reporter, caps, resourceProvider,
+                                       sProxy->asRenderTargetProxy(),
+                                       supportedNumSamples, SkBackingFit::kExact,
+                                       caps.maxWindowRectangles());
 
-                        sk_sp<GrSurfaceProxy> sProxy = proxyProvider->createInstantiatedProxy(
-                                                        desc, SkBackingFit::kExact, budgeted);
-                        if (!sProxy) {
-                            continue;  // This can fail on Mesa
-                        }
+                    gpu->deleteTestingOnlyBackendTexture(&backendTex);
+                }
 
-                        check_surface(reporter, sProxy.get(), origin,
-                                      kWidthHeight, kWidthHeight, config, budgeted);
-                        check_rendertarget(reporter, caps, resourceProvider,
-                                           sProxy->asRenderTargetProxy(),
-                                           supportedNumSamples, SkBackingFit::kExact,
-                                           caps.maxWindowRectangles(), true);
-                    } else {
-                        // Internal offscreen texture
-                        SkASSERT(kNone_GrSurfaceFlags == desc.fFlags );
-                        desc.fSampleCnt = 1;
+                {
+                    // Internal offscreen texture
+                    GrBackendTexture backendTex =
+                            gpu->createTestingOnlyBackendTexture(nullptr, kWidthHeight,
+                                                                 kWidthHeight, colorType, false,
+                                                                 GrMipMapped::kNo);
 
-                        sk_sp<GrSurfaceProxy> sProxy = proxyProvider->createInstantiatedProxy(
-                                                          desc, SkBackingFit::kExact, budgeted);
-                        if (!sProxy) {
-                            continue;
-                        }
-
-                        check_surface(reporter, sProxy.get(), origin,
-                                      kWidthHeight, kWidthHeight, config, budgeted);
-                        check_texture(reporter, resourceProvider, sProxy->asTextureProxy(),
-                                      SkBackingFit::kExact, true);
+                    sk_sp<GrSurfaceProxy> sProxy =
+                            proxyProvider->createWrappedTextureProxy(backendTex, origin,
+                                                                     kBorrow_GrWrapOwnership,
+                                                                     nullptr, nullptr);
+                    if (!sProxy) {
+                        continue;
                     }
+
+                    check_surface(reporter, sProxy.get(), origin,
+                                  kWidthHeight, kWidthHeight,
+                                  backendTex.testingOnly_getPixelConfig(), SkBudgeted::kNo);
+                    check_texture(reporter, resourceProvider, sProxy->asTextureProxy(),
+                                  SkBackingFit::kExact);
+
+                    gpu->deleteTestingOnlyBackendTexture(&backendTex);
                 }
             }
         }
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index 06d9b83..c338680 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -305,6 +305,16 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
+GrPixelConfig GrBackendTexture::testingOnly_getPixelConfig() const {
+    return fConfig;
+}
+
+GrPixelConfig GrBackendRenderTarget::testingOnly_getPixelConfig() const {
+    return fConfig;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
 #define DRAW_OP_TEST_EXTERN(Op) \
     extern std::unique_ptr<GrDrawOp> Op##__Test(GrPaint&&, SkRandom*, GrContext*, GrFSAAType)
 #define DRAW_OP_TEST_ENTRY(Op) Op##__Test