Add GrProxyProvider

This pulls all the proxy tracking & creation functionality out of the GrResourceCache and GrResourceProvider and consolidates it in the GrProxyProvider.

Change-Id: I7256f7c544319a70c1bd93dd5a9ccbe5fa0a544f
Reviewed-on: https://skia-review.googlesource.com/91501
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp
index 9b3ba36..064b1aa 100644
--- a/src/gpu/GrBitmapTextureMaker.cpp
+++ b/src/gpu/GrBitmapTextureMaker.cpp
@@ -10,7 +10,7 @@
 #include "GrContext.h"
 #include "GrContextPriv.h"
 #include "GrGpuResourcePriv.h"
-#include "GrResourceProvider.h"
+#include "GrProxyProvider.h"
 #include "GrSurfaceContext.h"
 #include "SkBitmap.h"
 #include "SkGr.h"
@@ -37,11 +37,11 @@
         return nullptr;
     }
 
+    GrProxyProvider* proxyProvider = this->context()->contextPriv().proxyProvider();
     sk_sp<GrTextureProxy> proxy;
 
     if (fOriginalKey.isValid()) {
-        proxy = this->context()->resourceProvider()->findOrCreateProxyByUniqueKey(
-                                                            fOriginalKey, kTopLeft_GrSurfaceOrigin);
+        proxy = proxyProvider->findOrCreateProxyByUniqueKey(fOriginalKey, kTopLeft_GrSurfaceOrigin);
         if (proxy && (!willBeMipped || GrMipMapped::kYes == proxy->mipMapped())) {
             return proxy;
         }
@@ -53,13 +53,11 @@
                                                              dstColorSpace);
         }
         if (!proxy) {
-            proxy = GrUploadBitmapToTextureProxy(this->context()->resourceProvider(), fBitmap,
-                                                 dstColorSpace);
+            proxy = GrUploadBitmapToTextureProxy(proxyProvider, fBitmap, dstColorSpace);
         }
         if (proxy) {
             if (fOriginalKey.isValid()) {
-                this->context()->resourceProvider()->assignUniqueKeyToProxy(fOriginalKey,
-                                                                            proxy.get());
+                proxyProvider->assignUniqueKeyToProxy(fOriginalKey, proxy.get());
             }
             if (!willBeMipped || GrMipMapped::kYes == proxy->mipMapped()) {
                 SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
@@ -86,10 +84,8 @@
                 // mipmapped version. The texture backing the unmipped version will remain in the
                 // resource cache until the last texture proxy referencing it is deleted at which
                 // time it too will be deleted or recycled.
-                this->context()->resourceProvider()->removeUniqueKeyFromProxy(fOriginalKey,
-                                                                              proxy.get());
-                this->context()->resourceProvider()->assignUniqueKeyToProxy(fOriginalKey,
-                                                                            mippedProxy.get());
+                proxyProvider->removeUniqueKeyFromProxy(fOriginalKey, proxy.get());
+                proxyProvider->assignUniqueKeyToProxy(fOriginalKey, mippedProxy.get());
                 GrInstallBitmapUniqueKeyInvalidator(fOriginalKey, fBitmap.pixelRef());
             }
             return mippedProxy;
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 0f647e0..ce77369 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -14,7 +14,7 @@
 #include "GrFixedClip.h"
 #include "GrGpuResourcePriv.h"
 #include "GrRenderTargetContextPriv.h"
-#include "GrResourceProvider.h"
+#include "GrProxyProvider.h"
 #include "GrStencilAttachment.h"
 #include "GrSWMaskHelper.h"
 #include "GrTextureProxy.h"
@@ -324,12 +324,12 @@
 
 sk_sp<GrTextureProxy> GrClipStackClip::createAlphaClipMask(GrContext* context,
                                                            const GrReducedClip& reducedClip) const {
-    GrResourceProvider* resourceProvider = context->resourceProvider();
+    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
     GrUniqueKey key;
     create_clip_mask_key(reducedClip.maskGenID(), reducedClip.scissor(),
                          reducedClip.numAnalyticFPs(), &key);
 
-    sk_sp<GrTextureProxy> proxy(resourceProvider->findOrCreateProxyByUniqueKey(
+    sk_sp<GrTextureProxy> proxy(proxyProvider->findOrCreateProxyByUniqueKey(
                                                                 key, kBottomLeft_GrSurfaceOrigin));
     if (proxy) {
         return proxy;
@@ -355,7 +355,7 @@
     }
 
     SkASSERT(result->origin() == kBottomLeft_GrSurfaceOrigin);
-    resourceProvider->assignUniqueKeyToProxy(key, result.get());
+    proxyProvider->assignUniqueKeyToProxy(key, result.get());
     add_invalidate_on_pop_message(*fStack, reducedClip.maskGenID(), key);
 
     return result;
@@ -442,7 +442,9 @@
     create_clip_mask_key(reducedClip.maskGenID(), reducedClip.scissor(),
                          reducedClip.numAnalyticFPs(), &key);
 
-    sk_sp<GrTextureProxy> proxy(context->resourceProvider()->findOrCreateProxyByUniqueKey(
+    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
+
+    sk_sp<GrTextureProxy> proxy(proxyProvider->findOrCreateProxyByUniqueKey(
                                                                   key, kTopLeft_GrSurfaceOrigin));
     if (proxy) {
         return proxy;
@@ -462,7 +464,7 @@
         desc.fConfig = kAlpha_8_GrPixelConfig;
         // MDB TODO: We're going to fill this proxy with an ASAP upload (which is out of order wrt
         // to ops), so it can't have any pending IO.
-        proxy = GrSurfaceProxy::MakeDeferred(context->resourceProvider(), desc,
+        proxy = GrSurfaceProxy::MakeDeferred(proxyProvider, desc,
                                              SkBackingFit::kApprox, SkBudgeted::kYes,
                                              GrResourceProvider::kNoPendingIO_Flag);
 
@@ -496,7 +498,7 @@
     }
 
     SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
-    context->resourceProvider()->assignUniqueKeyToProxy(key, proxy.get());
+    proxyProvider->assignUniqueKeyToProxy(key, proxy.get());
     add_invalidate_on_pop_message(*fStack, reducedClip.maskGenID(), key);
     return proxy;
 }
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 9240d63..131ac45 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -12,6 +12,7 @@
 #include "GrContextPriv.h"
 #include "GrDrawingManager.h"
 #include "GrGpu.h"
+#include "GrProxyProvider.h"
 #include "GrRenderTargetContext.h"
 #include "GrRenderTargetProxy.h"
 #include "GrResourceCache.h"
@@ -198,6 +199,7 @@
         , fBackend(backend) {
     fResourceCache = nullptr;
     fResourceProvider = nullptr;
+    fProxyProvider = nullptr;
     fAtlasGlyphCache = nullptr;
 }
 
@@ -206,6 +208,7 @@
         , fBackend(proxy->fBackend) {
     fResourceCache = nullptr;
     fResourceProvider = nullptr;
+    fProxyProvider = nullptr;
     fAtlasGlyphCache = nullptr;
 }
 
@@ -214,6 +217,9 @@
     fCaps = fGpu->refCaps();
     fResourceCache = new GrResourceCache(fCaps.get(), fUniqueID);
     fResourceProvider = new GrResourceProvider(fGpu.get(), fResourceCache, &fSingleOwner);
+    fProxyProvider = new GrProxyProvider(fResourceProvider, fResourceCache, fCaps, &fSingleOwner);
+    fResourceCache->setProxyProvider(fProxyProvider);
+
     // DDL TODO: we need to think through how the task group & persistent cache
     // get passed on to/shared between all the DDLRecorders created with this context.
     fThreadSafeProxy.reset(new GrContextThreadSafeProxy(fCaps, this->uniqueID(), fBackend,
@@ -293,6 +299,7 @@
 
     delete fResourceProvider;
     delete fResourceCache;
+    delete fProxyProvider;
     delete fAtlasGlyphCache;
 }
 
@@ -303,6 +310,7 @@
 void GrContext::abandonContext() {
     ASSERT_SINGLE_OWNER
 
+    fProxyProvider->abandon();
     fResourceProvider->abandon();
 
     // Need to abandon the drawing manager first so all the render targets
@@ -322,6 +330,7 @@
 void GrContext::releaseResourcesAndAbandonContext() {
     ASSERT_SINGLE_OWNER
 
+    fProxyProvider->abandon();
     fResourceProvider->abandon();
 
     // Need to abandon the drawing manager first so all the render targets
@@ -521,7 +530,7 @@
 
     sk_sp<GrTextureProxy> tempProxy;
     if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
-        tempProxy = GrSurfaceProxy::MakeDeferred(fContext->resourceProvider(),
+        tempProxy = GrSurfaceProxy::MakeDeferred(this->proxyProvider(),
                                                  tempDrawInfo.fTempSurfaceDesc,
                                                  SkBackingFit::kApprox,
                                                  SkBudgeted::kYes);
@@ -812,11 +821,11 @@
 
     sk_sp<GrTextureProxy> proxy;
     if (GrMipMapped::kNo == mipMapped) {
-        proxy = GrSurfaceProxy::MakeDeferred(fContext->resourceProvider(), dstDesc, fit,
+        proxy = GrSurfaceProxy::MakeDeferred(this->proxyProvider(), dstDesc, fit,
                                              isDstBudgeted);
     } else {
         SkASSERT(SkBackingFit::kExact == fit);
-        proxy = GrSurfaceProxy::MakeDeferredMipMap(fContext->resourceProvider(), dstDesc,
+        proxy = GrSurfaceProxy::MakeDeferredMipMap(this->proxyProvider(), dstDesc,
                                                    isDstBudgeted);
     }
     if (!proxy) {
@@ -978,9 +987,9 @@
 
     sk_sp<GrTextureProxy> rtp;
     if (GrMipMapped::kNo == mipMapped) {
-        rtp = GrSurfaceProxy::MakeDeferred(this->resourceProvider(), desc, fit, budgeted);
+        rtp = GrSurfaceProxy::MakeDeferred(fProxyProvider, desc, fit, budgeted);
     } else {
-        rtp = GrSurfaceProxy::MakeDeferredMipMap(this->resourceProvider(), desc, budgeted);
+        rtp = GrSurfaceProxy::MakeDeferredMipMap(fProxyProvider, desc, budgeted);
     }
     if (!rtp) {
         return nullptr;
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index 2a286f2..2da8f34 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -167,6 +167,9 @@
 
     SkTaskGroup* getTaskGroup() { return fContext->fTaskGroup.get(); }
 
+    GrProxyProvider* proxyProvider() { return fContext->fProxyProvider; }
+    const GrProxyProvider* proxyProvider() const { return fContext->fProxyProvider; }
+
 private:
     explicit GrContextPriv(GrContext* context) : fContext(context) {}
     GrContextPriv(const GrContextPriv&); // unimpl
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 22afd03..420c43b 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -9,6 +9,7 @@
 
 #include "GrBackendSemaphore.h"
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrGpu.h"
 #include "GrOnFlushResourceProvider.h"
 #include "GrOpList.h"
@@ -377,7 +378,7 @@
     if (!pr && allowSW) {
         if (!fSoftwarePathRenderer) {
             fSoftwarePathRenderer =
-                    new GrSoftwarePathRenderer(fContext->resourceProvider(),
+                    new GrSoftwarePathRenderer(fContext->contextPriv().proxyProvider(),
                                                fOptionsForPathRendererChain.fAllowPathMaskCaching);
         }
         if (GrPathRenderer::CanDrawPath::kNo != fSoftwarePathRenderer->canDrawPath(args)) {
diff --git a/src/gpu/GrOnFlushResourceProvider.cpp b/src/gpu/GrOnFlushResourceProvider.cpp
index e3b5eeb..a93c9eb 100644
--- a/src/gpu/GrOnFlushResourceProvider.cpp
+++ b/src/gpu/GrOnFlushResourceProvider.cpp
@@ -7,6 +7,7 @@
 
 #include "GrOnFlushResourceProvider.h"
 
+#include "GrContextPriv.h"
 #include "GrDrawingManager.h"
 #include "GrSurfaceProxy.h"
 
@@ -21,11 +22,11 @@
     // will, when instantiated, have no pending IO.
     // TODO: fold the kNoPendingIO_Flag into GrSurfaceFlags?
     sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeDeferred(
-                                                    fDrawingMgr->getContext()->resourceProvider(),
-                                                    tmpDesc,
-                                                    SkBackingFit::kExact,
-                                                    SkBudgeted::kYes,
-                                                    GrResourceProvider::kNoPendingIO_Flag);
+                                        fDrawingMgr->getContext()->contextPriv().proxyProvider(),
+                                        tmpDesc,
+                                        SkBackingFit::kExact,
+                                        SkBudgeted::kYes,
+                                        GrResourceProvider::kNoPendingIO_Flag);
     if (!proxy->asRenderTargetProxy()) {
         return nullptr;
     }
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 8f8e797..96cbca4 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -7,6 +7,7 @@
 
 #include "GrProcessor.h"
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrGeometryProcessor.h"
 #include "GrMemoryPool.h"
 #include "GrSamplerState.h"
@@ -20,6 +21,10 @@
     return fContext->resourceProvider();
 }
 
+GrProxyProvider* GrProcessorTestData::proxyProvider() {
+    return fContext->contextPriv().proxyProvider();
+}
+
 const GrCaps* GrProcessorTestData::caps() {
     return fContext->caps();
 }
diff --git a/src/gpu/GrProcessorUnitTest.h b/src/gpu/GrProcessorUnitTest.h
index 739b2f0..731080e 100644
--- a/src/gpu/GrProcessorUnitTest.h
+++ b/src/gpu/GrProcessorUnitTest.h
@@ -19,6 +19,7 @@
 class SkMatrix;
 class GrCaps;
 class GrContext;
+class GrProxyProvider;
 class GrRenderTargetContext;
 struct GrProcessorTestData;
 class GrTexture;
@@ -63,6 +64,7 @@
 
     GrContext* context() { return fContext; }
     GrResourceProvider* resourceProvider();
+    GrProxyProvider* proxyProvider();
     const GrCaps* caps();
     sk_sp<GrTextureProxy> textureProxy(int index) { return fProxies[index]; }
 
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
new file mode 100644
index 0000000..d86f9bc
--- /dev/null
+++ b/src/gpu/GrProxyProvider.cpp
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrProxyProvider.h"
+
+#include "GrCaps.h"
+#include "GrResourceKey.h"
+#include "GrResourceProvider.h"
+#include "GrSurfaceProxy.h"
+#include "GrSurfaceProxyPriv.h"
+#include "GrTexture.h"
+#include "GrTextureProxyCacheAccess.h"
+#include "../private/GrSingleOwner.h"
+
+#define ASSERT_SINGLE_OWNER \
+    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
+
+GrProxyProvider::GrProxyProvider(GrResourceProvider* resourceProvider,
+                                 GrResourceCache* resourceCache,
+                                 sk_sp<const GrCaps> caps,
+                                 GrSingleOwner* owner)
+        : fResourceProvider(resourceProvider)
+        , fResourceCache(resourceCache)
+        , fCaps(caps)
+#ifdef SK_DEBUG
+        , fSingleOwner(owner)
+#endif
+{
+
+}
+
+GrProxyProvider::~GrProxyProvider() {
+    SkASSERT(!fUniquelyKeyedProxies.count());
+}
+
+void GrProxyProvider::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
+    ASSERT_SINGLE_OWNER
+    SkASSERT(key.isValid());
+    if (this->isAbandoned() || !proxy) {
+        return;
+    }
+
+    // If there is already a GrResource with this key then the caller has violated the normal
+    // usage pattern of uniquely keyed resources (e.g., they have created one w/o first seeing
+    // if it already existed in the cache).
+    SkASSERT(!fResourceCache->findAndRefUniqueResource(key));
+
+    // Uncached resources can never have a unique key, unless they're wrapped resources. Wrapped
+    // resources are a special case: the unique keys give us a weak ref so that we can reuse the
+    // same resource (rather than re-wrapping). When a wrapped resource is no longer referenced,
+    // it will always be released - it is never converted to a scratch resource.
+    if (SkBudgeted::kNo == proxy->isBudgeted() &&
+                    (!proxy->priv().isInstantiated() ||
+                     !proxy->priv().peekSurface()->resourcePriv().refsWrappedObjects())) {
+        return;
+    }
+
+    SkASSERT(!fUniquelyKeyedProxies.find(key));     // multiple proxies can't get the same key
+
+    proxy->cacheAccess().setUniqueKey(this, key);
+    SkASSERT(proxy->getUniqueKey() == key);
+    fUniquelyKeyedProxies.add(proxy);
+}
+
+void GrProxyProvider::adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface* surf) {
+    SkASSERT(surf->getUniqueKey().isValid());
+    proxy->cacheAccess().setUniqueKey(this, surf->getUniqueKey());
+    SkASSERT(proxy->getUniqueKey() == surf->getUniqueKey());
+    // multiple proxies can't get the same key
+    SkASSERT(!fUniquelyKeyedProxies.find(surf->getUniqueKey()));
+    fUniquelyKeyedProxies.add(proxy);
+}
+
+void GrProxyProvider::removeUniqueKeyFromProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
+    ASSERT_SINGLE_OWNER
+    if (this->isAbandoned() || !proxy) {
+        return;
+    }
+    this->processInvalidProxyUniqueKey(key, proxy, true);
+}
+
+sk_sp<GrTextureProxy> GrProxyProvider::findProxyByUniqueKey(const GrUniqueKey& key,
+                                                            GrSurfaceOrigin origin) {
+    ASSERT_SINGLE_OWNER
+
+    if (this->isAbandoned()) {
+        return nullptr;
+    }
+
+    sk_sp<GrTextureProxy> result = sk_ref_sp(fUniquelyKeyedProxies.find(key));
+    if (result) {
+        SkASSERT(result->origin() == origin);
+    }
+    return result;
+}
+
+sk_sp<GrTextureProxy> GrProxyProvider::findOrCreateProxyByUniqueKey(const GrUniqueKey& key,
+                                                                    GrSurfaceOrigin origin) {
+    ASSERT_SINGLE_OWNER
+
+    if (this->isAbandoned()) {
+        return nullptr;
+    }
+
+    sk_sp<GrTextureProxy> result = this->findProxyByUniqueKey(key, origin);
+    if (result) {
+        return result;
+    }
+
+    GrGpuResource* resource = fResourceCache->findAndRefUniqueResource(key);
+    if (!resource) {
+        return nullptr;
+    }
+
+    sk_sp<GrTexture> texture(static_cast<GrSurface*>(resource)->asTexture());
+    SkASSERT(texture);
+
+    result = GrSurfaceProxy::MakeWrapped(std::move(texture), origin);
+    SkASSERT(result->getUniqueKey() == key);
+    // MakeWrapped should've added this for us
+    SkASSERT(fUniquelyKeyedProxies.find(key));
+    return result;
+}
+
+sk_sp<GrTextureProxy> GrProxyProvider::createTextureProxy(const GrSurfaceDesc& desc,
+                                                          SkBudgeted budgeted,
+                                                          const GrMipLevel& mipLevel) {
+    ASSERT_SINGLE_OWNER
+
+    sk_sp<GrTexture> tex = fResourceProvider->createTexture(desc, budgeted, mipLevel);
+    if (!tex) {
+        return nullptr;
+    }
+
+    return GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
+}
+
+sk_sp<GrTextureProxy> GrProxyProvider::createTextureProxy(
+                                                    const GrSurfaceDesc& desc, SkBudgeted budgeted,
+                                                    const GrMipLevel texels[], int mipLevelCount,
+                                                    SkDestinationSurfaceColorMode mipColorMode) {
+    sk_sp<GrTexture> tex(fResourceProvider->createTexture(desc, budgeted,
+                                                          texels, mipLevelCount,
+                                                          mipColorMode));
+    if (!tex) {
+        return nullptr;
+    }
+
+    return GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
+}
+
+bool GrProxyProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) {
+    return proxy->priv().isExact() || (SkIsPow2(proxy->width()) && SkIsPow2(proxy->height()));
+}
+
+void GrProxyProvider::processInvalidProxyUniqueKey(const GrUniqueKey& key) {
+    // Note: this method is called for the whole variety of GrGpuResources so often 'key'
+    // will not be in 'fUniquelyKeyedProxies'.
+    GrTextureProxy* proxy = fUniquelyKeyedProxies.find(key);
+    if (proxy) {
+        this->processInvalidProxyUniqueKey(key, proxy, false);
+    }
+}
+
+void GrProxyProvider::processInvalidProxyUniqueKey(const GrUniqueKey& key, GrTextureProxy* proxy,
+                                                   bool invalidateSurface) {
+    SkASSERT(proxy);
+    SkASSERT(proxy->getUniqueKey().isValid());
+    SkASSERT(proxy->getUniqueKey() == key);
+
+    fUniquelyKeyedProxies.remove(key);
+    proxy->cacheAccess().clearUniqueKey();
+
+    if (invalidateSurface && proxy->priv().isInstantiated()) {
+        GrSurface* surface = proxy->priv().peekSurface();
+        if (surface) {
+            surface->resourcePriv().removeUniqueKey();
+        }
+    }
+}
+
+void GrProxyProvider::removeAllUniqueKeys() {
+    UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies);
+    for (UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies); !iter.done(); ++iter) {
+        GrTextureProxy& tmp = *iter;
+
+        this->processInvalidProxyUniqueKey(tmp.getUniqueKey(), &tmp, false);
+    }
+    SkASSERT(!fUniquelyKeyedProxies.count());
+}
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
new file mode 100644
index 0000000..404e020
--- /dev/null
+++ b/src/gpu/GrProxyProvider.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrProxyProvider_DEFINED
+#define GrProxyProvider_DEFINED
+
+#include "GrResourceKey.h"
+#include "GrTextureProxy.h"
+#include "GrTypes.h"
+#include "SkRefCnt.h"
+#include "SkTDynamicHash.h"
+
+class GrCaps;
+class GrResourceProvider;
+class GrSingleOwner;
+
+/*
+ * A factory for creating GrSurfaceProxy-derived objects.
+ */
+class GrProxyProvider {
+public:
+    GrProxyProvider(GrResourceProvider*, GrResourceCache*, sk_sp<const GrCaps>, GrSingleOwner*);
+
+    ~GrProxyProvider();
+
+    /*
+     * Assigns a unique key to a proxy. The proxy will be findable via this key using
+     * findProxyByUniqueKey(). It is an error if an existing proxy already has a key.
+     */
+    void assignUniqueKeyToProxy(const GrUniqueKey&, GrTextureProxy*);
+
+    /*
+     * Sets the unique key of the provided proxy to the unique key of the surface. The surface must
+     * have a valid unique key.
+     */
+    void adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface*);
+
+    /*
+     * Removes a unique key from a proxy. If the proxy has already been instantiated, it will
+     * also remove the unique key from the target GrSurface.
+     */
+    void removeUniqueKeyFromProxy(const GrUniqueKey&, GrTextureProxy*);
+
+    /*
+     * Finds a proxy by unique key.
+     */
+    sk_sp<GrTextureProxy> findProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin);
+
+    /*
+     * Finds a proxy by unique key or creates a new one that wraps a resource matching the unique
+     * key.
+     */
+    sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin);
+
+    /*
+     * Create an un-mipmapped texture proxy with data.
+     */
+    sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, SkBudgeted, const GrMipLevel&);
+
+    /*
+     * Create a mipmapped texture proxy with data.
+     */
+    sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, SkBudgeted,
+                                             const GrMipLevel texels[], int mipLevelCount,
+                                             SkDestinationSurfaceColorMode mipColorMode);
+
+    // 'proxy' is about to be used as a texture src or drawn to. This query can be used to
+    // determine if it is going to need a texture domain or a full clear.
+    static bool IsFunctionallyExact(GrSurfaceProxy* proxy);
+
+    /**
+     * Either the proxy attached to the unique key is being deleted (in which case we
+     * don't want it cluttering up the hash table) or the client has indicated that
+     * it will never refer to the unique key again. In either case, remove the key
+     * from the hash table.
+     * Note: this does not, by itself, alter unique key attached to the underlying GrTexture.
+     */
+    void processInvalidProxyUniqueKey(const GrUniqueKey&);
+
+    /**
+     * Same as above, but you must pass in a GrTextureProxy to save having to search for it. The
+     * GrUniqueKey of the proxy must be valid and it must match the passed in key. This function
+     * also gives the option to invalidate the GrUniqueKey on the underlying GrTexture.
+     */
+    void processInvalidProxyUniqueKey(const GrUniqueKey&, GrTextureProxy*, bool invalidateSurface);
+
+    const GrCaps* caps() const { return fCaps.get(); }
+
+    void abandon() {
+        fResourceCache = nullptr;
+        fResourceProvider = nullptr;
+    }
+
+    bool isAbandoned() const {
+        SkASSERT(SkToBool(fResourceCache) == SkToBool(fResourceProvider));
+        return !SkToBool(fResourceCache);
+    }
+
+    int numUniqueKeyProxies_TestOnly() const;
+
+    void removeAllUniqueKeys();
+
+private:
+    struct UniquelyKeyedProxyHashTraits {
+        static const GrUniqueKey& GetKey(const GrTextureProxy& p) { return p.getUniqueKey(); }
+
+        static uint32_t Hash(const GrUniqueKey& key) { return key.hash(); }
+    };
+    typedef SkTDynamicHash<GrTextureProxy, GrUniqueKey, UniquelyKeyedProxyHashTraits> UniquelyKeyedProxyHash;
+
+    // This holds the texture proxies that have unique keys. The resourceCache does not get a ref
+    // on these proxies but they must send a message to the resourceCache when they are deleted.
+    UniquelyKeyedProxyHash fUniquelyKeyedProxies;
+
+    GrResourceProvider*    fResourceProvider;
+    GrResourceCache*       fResourceCache;
+    sk_sp<const GrCaps>    fCaps;
+
+    // In debug builds we guard against improper thread handling
+    SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
+};
+
+#endif
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
index 20acf54..50b2e9a 100644
--- a/src/gpu/GrResourceCache.cpp
+++ b/src/gpu/GrResourceCache.cpp
@@ -10,6 +10,7 @@
 
 #include "GrCaps.h"
 #include "GrGpuResourceCacheAccess.h"
+#include "GrProxyProvider.h"
 #include "GrTexture.h"
 #include "GrTextureProxyCacheAccess.h"
 #include "GrTracing.h"
@@ -64,7 +65,8 @@
 
 
 GrResourceCache::GrResourceCache(const GrCaps* caps, uint32_t contextUniqueID)
-    : fTimestamp(0)
+    : fProxyProvider(nullptr)
+    , fTimestamp(0)
     , fMaxCount(kDefaultMaxCount)
     , fMaxBytes(kDefaultMaxSize)
     , fMaxUnusedFlushes(kDefaultMaxUnusedFlushes)
@@ -196,15 +198,10 @@
 
     this->processFreedGpuResources();
 
+    SkASSERT(fProxyProvider); // better have called setProxyProvider
     // We must remove the uniqueKeys from the proxies here. While they possess a uniqueKey
     // they also have a raw pointer back to this class (which is presumably going away)!
-    UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies);
-    for (UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies); !iter.done(); ++iter) {
-        GrTextureProxy& tmp = *iter;
-
-        this->processInvalidProxyUniqueKey(tmp.getUniqueKey(), &tmp, false);
-    }
-    SkASSERT(!fUniquelyKeyedProxies.count());
+    fProxyProvider->removeAllUniqueKeys();
 
     while(fNonpurgeableResources.count()) {
         GrGpuResource* back = *(fNonpurgeableResources.end() - 1);
@@ -588,9 +585,11 @@
 }
 
 void GrResourceCache::processInvalidUniqueKeys(
-    const SkTArray<GrUniqueKeyInvalidatedMessage>& msgs) {
+                                            const SkTArray<GrUniqueKeyInvalidatedMessage>& msgs) {
+    SkASSERT(fProxyProvider); // better have called setProxyProvider
+
     for (int i = 0; i < msgs.count(); ++i) {
-        this->processInvalidProxyUniqueKey(msgs[i].key());
+        fProxyProvider->processInvalidProxyUniqueKey(msgs[i].key());
 
         GrGpuResource* resource = this->findAndRefUniqueResource(msgs[i].key());
         if (resource) {
@@ -861,97 +860,3 @@
 }
 
 #endif
-
-void GrResourceCache::adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface* surf) {
-    SkASSERT(surf->getUniqueKey().isValid());
-    proxy->cacheAccess().setUniqueKey(this, surf->getUniqueKey());
-    SkASSERT(proxy->getUniqueKey() == surf->getUniqueKey());
-    // multiple proxies can't get the same key
-    SkASSERT(!fUniquelyKeyedProxies.find(surf->getUniqueKey()));
-    fUniquelyKeyedProxies.add(proxy);
-}
-
-void GrResourceCache::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
-    SkASSERT(key.isValid());
-    SkASSERT(proxy);
-
-    // If there is already a GrResource with this key then the caller has violated the normal
-    // usage pattern of uniquely keyed resources (e.g., they have created one w/o first seeing
-    // if it already existed in the cache).
-    SkASSERT(!this->findAndRefUniqueResource(key));
-
-    // Uncached resources can never have a unique key, unless they're wrapped resources. Wrapped
-    // resources are a special case: the unique keys give us a weak ref so that we can reuse the
-    // same resource (rather than re-wrapping). When a wrapped resource is no longer referenced,
-    // it will always be released - it is never converted to a scratch resource.
-    if (SkBudgeted::kNo == proxy->isBudgeted() &&
-                    (!proxy->priv().isInstantiated() ||
-                     !proxy->priv().peekSurface()->resourcePriv().refsWrappedObjects())) {
-        return;
-    }
-
-    SkASSERT(!fUniquelyKeyedProxies.find(key));     // multiple proxies can't get the same key
-
-    proxy->cacheAccess().setUniqueKey(this, key);
-    SkASSERT(proxy->getUniqueKey() == key);
-    fUniquelyKeyedProxies.add(proxy);
-}
-
-sk_sp<GrTextureProxy> GrResourceCache::findProxyByUniqueKey(const GrUniqueKey& key,
-                                                            GrSurfaceOrigin origin) {
-
-    sk_sp<GrTextureProxy> result = sk_ref_sp(fUniquelyKeyedProxies.find(key));
-    if (result) {
-        SkASSERT(result->origin() == origin);
-    }
-    return result;
-}
-
-sk_sp<GrTextureProxy> GrResourceCache::findOrCreateProxyByUniqueKey(const GrUniqueKey& key,
-                                                                    GrSurfaceOrigin origin) {
-    sk_sp<GrTextureProxy> result = this->findProxyByUniqueKey(key, origin);
-    if (result) {
-        return result;
-    }
-
-    GrGpuResource* resource = findAndRefUniqueResource(key);
-    if (!resource) {
-        return nullptr;
-    }
-
-    sk_sp<GrTexture> texture(static_cast<GrSurface*>(resource)->asTexture());
-    SkASSERT(texture);
-
-    result = GrSurfaceProxy::MakeWrapped(std::move(texture), origin);
-    SkASSERT(result->getUniqueKey() == key);
-    // MakeWrapped should've added this for us
-    SkASSERT(fUniquelyKeyedProxies.find(key));
-    return result;
-}
-
-void GrResourceCache::processInvalidProxyUniqueKey(const GrUniqueKey& key) {
-    // Note: this method is called for the whole variety of GrGpuResources so often 'key'
-    // will not be in 'fUniquelyKeyedProxies'.
-    GrTextureProxy* proxy = fUniquelyKeyedProxies.find(key);
-    if (proxy) {
-        this->processInvalidProxyUniqueKey(key, proxy, false);
-    }
-}
-
-void GrResourceCache::processInvalidProxyUniqueKey(const GrUniqueKey& key, GrTextureProxy* proxy,
-                                                   bool invalidateSurface) {
-    SkASSERT(proxy);
-    SkASSERT(proxy->getUniqueKey().isValid());
-    SkASSERT(proxy->getUniqueKey() == key);
-
-    fUniquelyKeyedProxies.remove(key);
-    proxy->cacheAccess().clearUniqueKey();
-
-    if (invalidateSurface && proxy->priv().isInstantiated()) {
-        GrSurface* surface = proxy->priv().peekSurface();
-        if (surface) {
-            surface->resourcePriv().removeUniqueKey();
-        }
-    }
-}
-
diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h
index 54be56d..6869e4e 100644
--- a/src/gpu/GrResourceCache.h
+++ b/src/gpu/GrResourceCache.h
@@ -13,7 +13,6 @@
 #include "GrGpuResourcePriv.h"
 #include "GrResourceCache.h"
 #include "GrResourceKey.h"
-#include "GrTextureProxy.h"
 #include "SkMessageBus.h"
 #include "SkRefCnt.h"
 #include "SkTArray.h"
@@ -22,6 +21,7 @@
 #include "SkTMultiMap.h"
 
 class GrCaps;
+class GrProxyProvider;
 class SkString;
 class SkTraceMemoryDump;
 
@@ -49,7 +49,7 @@
  */
 class GrResourceCache {
 public:
-    GrResourceCache(const GrCaps* caps, uint32_t contextUniqueID);
+    GrResourceCache(const GrCaps*, uint32_t contextUniqueID);
     ~GrResourceCache();
 
     // Default maximum number of budgeted resources in the cache.
@@ -157,78 +157,6 @@
         return resource;
     }
 
-    ///////////////////////////////////////////////////////////////////////////
-    // TextureProxies & GrUniqueKeys
-    //
-    // The four GrResourceCache methods assignUniqueKeyToProxy, adoptUniqueKeyFromSurface,
-    // findPorxyByUniqueKey, and findOrCreateProxyByUniqueKey drive the behavior of uniqueKeys on
-    // proxies.
-    //
-    // assignUniqueKeyToProxy does the following:
-    //    if the proxy is wrapped, it sets the texture & proxy keys & adds the proxy to the hash
-    //    if the proxy is deferred, it just set the unique key on the proxy & adds it to the hash
-    //
-    //    Note that when a deferred proxy with a unique key is instantiated, its unique key will be
-    //    pushed to the backing resource.
-    //
-    //    Futher note, a proxy can only receive a unique key once. It can be removed if Ganesh
-    //    determines that the key will never be used again but, in that case, the proxy should
-    //    never receive another key.
-    //
-    // adoptUniqueKeyFromSurface does the following:
-    //    takes in a GrSurface which must have a valid unique key. It sets the proxy's key to match
-    //    the surface and adds the proxy to the hash.
-    //
-    // findProxyByUniqueKey does the following:
-    //    looks in the UniqueKeyProxy hash table to see if there is already a proxy w/ the key and
-    //    returns the proxy. If it fails it will return null.
-    //
-    // findOrCreateProxyByUniqueKey does the following:
-    //    first calls findProxyByUniqueKey to see if a proxy already exists with the key
-    //    failing that it looks in the ResourceCache to see there is a texture with that key
-    //       if so, it will wrap the texture in a proxy, add the proxy to the hash and return it
-    //    failing that it will return null
-
-    /*
-     * Associate the provided proxy with the provided unique key.
-     */
-    void assignUniqueKeyToProxy(const GrUniqueKey&, GrTextureProxy*);
-
-    /*
-     * Sets the unique key of the provided proxy to the unique key of the surface. The surface must
-     * have a valid unique key.
-     */
-    void adoptUniqueKeyFromSurface(GrTextureProxy* proxy, const GrSurface*);
-
-    /**
-     * Find a texture proxy that is associated with the provided unique key. It will not look for a
-     * GrSurface that has the unique key.
-     */
-    sk_sp<GrTextureProxy> findProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin);
-
-    /**
-     * Find a texture proxy that is associated with the provided unique key. If not proxy is found,
-     * try to find a resources that is associated with the unique key and create a proxy that wraps
-     * it.
-     */
-    sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin);
-
-    /**
-     * Either the proxy attached to the unique key is being deleted (in which case we
-     * don't want it cluttering up the hash table) or the client has indicated that
-     * it will never refer to the unique key again. In either case, remove the key
-     * from the hash table.
-     * Note: this does not, by itself, alter unique key attached to the underlying GrTexture.
-     */
-    void processInvalidProxyUniqueKey(const GrUniqueKey&);
-
-    /**
-     * Same as above, but you must pass in a GrTextureProxy to save having to search for it. The
-     * GrUniqueKey of the proxy must be valid and it must match the passed in key. This function
-     * also gives the option to invalidate the GrUniqueKey on the underlying GrTexture.
-     */
-    void processInvalidProxyUniqueKey(const GrUniqueKey&, GrTextureProxy*, bool invalidateSurface);
-
     /**
      * Query whether a unique key exists in the cache.
      */
@@ -324,7 +252,7 @@
     // Enumerates all cached resources and dumps their details to traceMemoryDump.
     void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
 
-    int numUniqueKeyProxies_TestOnly() const;
+    void setProxyProvider(GrProxyProvider* proxyProvider) { fProxyProvider = proxyProvider; }
 
 private:
     ///////////////////////////////////////////////////////////////////////////
@@ -380,13 +308,6 @@
     };
     typedef SkTDynamicHash<GrGpuResource, GrUniqueKey, UniqueHashTraits> UniqueHash;
 
-    struct UniquelyKeyedProxyHashTraits {
-        static const GrUniqueKey& GetKey(const GrTextureProxy& p) { return p.getUniqueKey(); }
-
-        static uint32_t Hash(const GrUniqueKey& key) { return key.hash(); }
-    };
-    typedef SkTDynamicHash<GrTextureProxy, GrUniqueKey, UniquelyKeyedProxyHashTraits> UniquelyKeyedProxyHash;
-
     static bool CompareTimestamp(GrGpuResource* const& a, GrGpuResource* const& b) {
         return a->cacheAccess().timestamp() < b->cacheAccess().timestamp();
     }
@@ -400,6 +321,7 @@
     typedef SkTDPQueue<GrGpuResource*, CompareTimestamp, AccessResourceIndex> PurgeableQueue;
     typedef SkTDArray<GrGpuResource*> ResourceArray;
 
+    GrProxyProvider*                    fProxyProvider;
     // Whenever a resource is added to the cache or the result of a cache lookup, fTimestamp is
     // assigned as the resource's timestamp and then incremented. fPurgeableQueue orders the
     // purgeable resources by this value, and thus is used to purge resources in LRU order.
@@ -411,9 +333,6 @@
     ScratchMap                          fScratchMap;
     // This holds all resources that have unique keys.
     UniqueHash                          fUniqueHash;
-    // This holds the texture proxies that have unique keys. The resourceCache does not get a ref
-    // on these proxies but they must send a message to the resourceCache when they are deleted.
-    UniquelyKeyedProxyHash              fUniquelyKeyedProxies;
 
     // our budget, used in purgeAsNeeded()
     int                                 fMaxCount;
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 7fef350..0112b5c 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -20,7 +20,6 @@
 #include "GrResourceKey.h"
 #include "GrSemaphore.h"
 #include "GrStencilAttachment.h"
-#include "GrSurfaceProxyPriv.h"
 #include "GrTexturePriv.h"
 #include "../private/GrSingleOwner.h"
 #include "SkGr.h"
@@ -46,10 +45,6 @@
     fQuadIndexBufferKey = gQuadIndexBufferKey;
 }
 
-bool GrResourceProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) {
-    return proxy->priv().isExact() || (SkIsPow2(proxy->width()) && SkIsPow2(proxy->height()));
-}
-
 bool validate_desc(const GrSurfaceDesc& desc, const GrCaps& caps, int levelCount = 0) {
     if (desc.fWidth <= 0 || desc.fHeight <= 0) {
         return false;
@@ -115,9 +110,9 @@
     return true;
 }
 
-sk_sp<GrTextureProxy> GrResourceProvider::createTextureProxy(const GrSurfaceDesc& desc,
-                                                             SkBudgeted budgeted,
-                                                             const GrMipLevel& mipLevel) {
+sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc,
+                                                   SkBudgeted budgeted,
+                                                   const GrMipLevel& mipLevel) {
     ASSERT_SINGLE_OWNER
 
     if (this->isAbandoned()) {
@@ -138,20 +133,20 @@
 
     if (make_info(desc.fWidth, desc.fHeight, desc.fConfig, &srcInfo)) {
         sk_sp<GrTexture> tex = this->getExactScratch(desc, budgeted, 0);
-        sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
+        sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(tex, desc.fOrigin);
         if (proxy) {
             sk_sp<GrSurfaceContext> sContext =
                        context->contextPriv().makeWrappedSurfaceContext(std::move(proxy), nullptr);
             if (sContext) {
                 if (sContext->writePixels(srcInfo, mipLevel.fPixels, mipLevel.fRowBytes, 0, 0)) {
-                    return sContext->asTextureProxyRef();
+                    SkASSERT(sContext->asTextureProxy()->priv().peekTexture() == tex.get());
+                    return tex;
                 }
             }
         }
     }
 
-    sk_sp<GrTexture> tex(fGpu->createTexture(desc, budgeted, &mipLevel, 1));
-    return GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
+    return fGpu->createTexture(desc, budgeted, &mipLevel, 1);
 }
 
 sk_sp<GrTexture> GrResourceProvider::createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
@@ -276,42 +271,12 @@
     resource->resourcePriv().setUniqueKey(key);
 }
 
-void GrResourceProvider::removeUniqueKeyFromProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
-    ASSERT_SINGLE_OWNER
-    if (this->isAbandoned() || !proxy) {
-        return;
-    }
-    fCache->processInvalidProxyUniqueKey(key, proxy, true);
-}
-
 sk_sp<GrGpuResource> GrResourceProvider::findResourceByUniqueKey(const GrUniqueKey& key) {
     ASSERT_SINGLE_OWNER
     return this->isAbandoned() ? nullptr
                                : sk_sp<GrGpuResource>(fCache->findAndRefUniqueResource(key));
 }
 
-void GrResourceProvider::assignUniqueKeyToProxy(const GrUniqueKey& key, GrTextureProxy* proxy) {
-    ASSERT_SINGLE_OWNER
-    SkASSERT(key.isValid());
-    if (this->isAbandoned() || !proxy) {
-        return;
-    }
-
-    fCache->assignUniqueKeyToProxy(key, proxy);
-}
-
-sk_sp<GrTextureProxy> GrResourceProvider::findProxyByUniqueKey(const GrUniqueKey& key,
-                                                               GrSurfaceOrigin origin) {
-    ASSERT_SINGLE_OWNER
-    return this->isAbandoned() ? nullptr : fCache->findProxyByUniqueKey(key, origin);
-}
-
-sk_sp<GrTextureProxy> GrResourceProvider::findOrCreateProxyByUniqueKey(const GrUniqueKey& key,
-                                                                       GrSurfaceOrigin origin) {
-    ASSERT_SINGLE_OWNER
-    return this->isAbandoned() ? nullptr : fCache->findOrCreateProxyByUniqueKey(key, origin);
-}
-
 sk_sp<const GrBuffer> GrResourceProvider::findOrMakeStaticBuffer(GrBufferType intendedType,
                                                                  size_t size,
                                                                  const void* data,
diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h
index 64c9a8b..08da9ae 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -24,9 +24,7 @@
 class GrSemaphore;
 class GrSingleOwner;
 class GrStencilAttachment;
-class GrSurfaceProxy;
 class GrTexture;
-class GrTextureProxy;
 
 class GrStyle;
 class SkDescriptor;
@@ -53,29 +51,6 @@
         return sk_sp<T>(static_cast<T*>(this->findResourceByUniqueKey(key).release()));
     }
 
-    /*
-     * Assigns a unique key to a proxy. The proxy will be findable via this key using
-     * findProxyByUniqueKey(). It is an error if an existing proxy already has a key.
-     */
-    void assignUniqueKeyToProxy(const GrUniqueKey&, GrTextureProxy*);
-
-    /*
-     * Removes a unique key from a proxy. If the proxy has already been instantiated, it will
-     * also remove the unique key from the target GrSurface.
-     */
-    void removeUniqueKeyFromProxy(const GrUniqueKey&, GrTextureProxy*);
-
-    /*
-     * Finds a proxy by unique key.
-     */
-    sk_sp<GrTextureProxy> findProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin);
-
-    /*
-     * Finds a proxy by unique key or creates a new one that wraps a resource matching the unique
-     * key.
-     */
-    sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin);
-
     ///////////////////////////////////////////////////////////////////////////
     // Textures
 
@@ -95,7 +70,8 @@
                                    const GrMipLevel texels[], int mipLevelCount,
                                    SkDestinationSurfaceColorMode mipColorMode);
 
-    sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, SkBudgeted, const GrMipLevel&);
+    // Create a potentially loose fit texture with the provided data
+    sk_sp<GrTexture> createTexture(const GrSurfaceDesc&, SkBudgeted, const GrMipLevel&);
 
     ///////////////////////////////////////////////////////////////////////////
     // Wrapped Backend Surfaces
@@ -269,10 +245,6 @@
         fGpu = nullptr;
     }
 
-    // 'proxy' is about to be used as a texture src or drawn to. This query can be used to
-    // determine if it is going to need a texture domain or a full clear.
-    static bool IsFunctionallyExact(GrSurfaceProxy* proxy);
-
     const GrCaps* caps() const { return fCaps.get(); }
     bool overBudget() const { return fCache->overBudget(); }
 
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index ef7fa90..3fd5df4 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -13,7 +13,7 @@
 #include "GrGpuResourcePriv.h"
 #include "GrOpFlushState.h"
 #include "GrOpList.h"
-#include "GrResourceProvider.h"
+#include "GrProxyProvider.h"
 #include "GrSWMaskHelper.h"
 #include "SkMakeUnique.h"
 #include "SkSemaphore.h"
@@ -27,7 +27,7 @@
 GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
     // Pass on any style that applies. The caller will apply the style if a suitable renderer is
     // not found and try again with the new GrShape.
-    if (!args.fShape->style().applies() && SkToBool(fResourceProvider) &&
+    if (!args.fShape->style().applies() && SkToBool(fProxyProvider) &&
         (args.fAAType == GrAAType::kCoverage || args.fAAType == GrAAType::kNone)) {
         // This is the fallback renderer for when a path is too complicated for the GPU ones.
         return CanDrawPath::kAsBackup;
@@ -176,8 +176,8 @@
     desc.fConfig = kAlpha_8_GrPixelConfig;
     // MDB TODO: We're going to fill this proxy with an ASAP upload (which is out of order wrt to
     // ops), so it can't have any pending IO.
-    return GrSurfaceProxy::MakeDeferred(context->resourceProvider(), desc, fit, SkBudgeted::kYes,
-                                        GrResourceProvider::kNoPendingIO_Flag);
+    return GrSurfaceProxy::MakeDeferred(context->contextPriv().proxyProvider(), desc, fit,
+                                        SkBudgeted::kYes, GrResourceProvider::kNoPendingIO_Flag);
 }
 
 namespace {
@@ -227,7 +227,7 @@
 bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) {
     GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
                               "GrSoftwarePathRenderer::onDrawPath");
-    if (!fResourceProvider) {
+    if (!fProxyProvider) {
         return false;
     }
 
@@ -311,7 +311,7 @@
 
     sk_sp<GrTextureProxy> proxy;
     if (useCache) {
-        proxy = fResourceProvider->findOrCreateProxyByUniqueKey(maskKey, kTopLeft_GrSurfaceOrigin);
+        proxy = fProxyProvider->findOrCreateProxyByUniqueKey(maskKey, kTopLeft_GrSurfaceOrigin);
     }
     if (!proxy) {
         SkBackingFit fit = useCache ? SkBackingFit::kExact : SkBackingFit::kApprox;
@@ -358,7 +358,7 @@
         }
         if (useCache) {
             SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
-            fResourceProvider->assignUniqueKeyToProxy(maskKey, proxy.get());
+            fProxyProvider->assignUniqueKeyToProxy(maskKey, proxy.get());
             args.fShape->addGenIDChangeListener(new PathInvalidator(maskKey));
         }
     }
diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h
index d36b2f6..b399a18 100644
--- a/src/gpu/GrSoftwarePathRenderer.h
+++ b/src/gpu/GrSoftwarePathRenderer.h
@@ -10,7 +10,7 @@
 
 #include "GrPathRenderer.h"
 
-class GrResourceProvider;
+class GrProxyProvider;
 
 /**
  * This class uses the software side to render a path to an SkBitmap and
@@ -18,9 +18,11 @@
  */
 class GrSoftwarePathRenderer : public GrPathRenderer {
 public:
-    GrSoftwarePathRenderer(GrResourceProvider* resourceProvider, bool allowCaching)
-            : fResourceProvider(resourceProvider)
-            , fAllowCaching(allowCaching) {}
+    GrSoftwarePathRenderer(GrProxyProvider* proxyProvider, bool allowCaching)
+            : fProxyProvider(proxyProvider)
+            , fAllowCaching(allowCaching) {
+    }
+
 private:
     static void DrawNonAARect(GrRenderTargetContext* renderTargetContext,
                               GrPaint&& paint,
@@ -58,7 +60,7 @@
     bool onDrawPath(const DrawPathArgs&) override;
 
 private:
-    GrResourceProvider*    fResourceProvider;
+    GrProxyProvider*       fProxyProvider;
     bool                   fAllowCaching;
 
     typedef GrPathRenderer INHERITED;
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 8dd43de..1090d0d 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -13,7 +13,7 @@
 #include "GrContextPriv.h"
 #include "GrGpuResourcePriv.h"
 #include "GrOpList.h"
-#include "GrResourceProvider.h"
+#include "GrProxyProvider.h"
 #include "GrSurfaceContext.h"
 #include "GrTexturePriv.h"
 #include "GrTextureRenderTargetProxy.h"
@@ -202,7 +202,7 @@
     if (surf->getUniqueKey().isValid()) {
         // The proxy may already be in the hash. Thus we need to look for it first before creating
         // new one.
-        GrResourceProvider* provider = surf->getContext()->resourceProvider();
+        GrProxyProvider* provider = surf->getContext()->contextPriv().proxyProvider();
         sk_sp<GrSurfaceProxy> proxy = provider->findProxyByUniqueKey(surf->getUniqueKey(), origin);
         if (proxy) {
             return proxy;
@@ -231,7 +231,7 @@
     if (tex->getUniqueKey().isValid()) {
         // The proxy may already be in the hash. Thus we need to look for it first before creating
         // new one.
-        GrResourceProvider* provider = tex->getContext()->resourceProvider();
+        GrProxyProvider* provider = tex->getContext()->contextPriv().proxyProvider();
         sk_sp<GrTextureProxy> proxy = provider->findProxyByUniqueKey(tex->getUniqueKey(), origin);
         if (proxy) {
             return proxy;
@@ -245,14 +245,14 @@
     }
 }
 
-sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferred(GrResourceProvider* resourceProvider,
+sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferred(GrProxyProvider* proxyProvider,
                                                    const GrSurfaceDesc& desc,
                                                    SkBackingFit fit,
                                                    SkBudgeted budgeted,
                                                    uint32_t flags) {
     SkASSERT(0 == flags || GrResourceProvider::kNoPendingIO_Flag == flags);
 
-    const GrCaps* caps = resourceProvider->caps();
+    const GrCaps* caps = proxyProvider->caps();
 
     // TODO: move this logic into GrResourceProvider!
     // TODO: share this testing code with check_texture_creation_params
@@ -311,7 +311,7 @@
 #endif
 }
 
-sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferred(GrResourceProvider* resourceProvider,
+sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferred(GrProxyProvider* proxyProvider,
                                                    const GrSurfaceDesc& desc,
                                                    SkBudgeted budgeted,
                                                    const void* srcData,
@@ -319,13 +319,13 @@
     if (srcData) {
         GrMipLevel mipLevel = { srcData, rowBytes };
 
-        return resourceProvider->createTextureProxy(desc, budgeted, mipLevel);
+        return proxyProvider->createTextureProxy(desc, budgeted, mipLevel);
     }
 
-    return GrSurfaceProxy::MakeDeferred(resourceProvider, desc, SkBackingFit::kExact, budgeted);
+    return GrSurfaceProxy::MakeDeferred(proxyProvider, desc, SkBackingFit::kExact, budgeted);
 }
 
-sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferredMipMap(GrResourceProvider* resourceProvider,
+sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferredMipMap(GrProxyProvider* proxyProvider,
                                                          const GrSurfaceDesc& desc,
                                                          SkBudgeted budgeted) {
     // SkMipMap doesn't include the base level in the level count so we have to add 1
@@ -339,11 +339,11 @@
         texels[i].fRowBytes = 0;
     }
 
-    return MakeDeferredMipMap(resourceProvider, desc, budgeted, texels.get(), mipCount);
+    return MakeDeferredMipMap(proxyProvider, desc, budgeted, texels.get(), mipCount);
 }
 
 sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferredMipMap(
-                                                    GrResourceProvider* resourceProvider,
+                                                    GrProxyProvider* proxyProvider,
                                                     const GrSurfaceDesc& desc,
                                                     SkBudgeted budgeted,
                                                     const GrMipLevel texels[],
@@ -353,14 +353,14 @@
         if (texels) {
             return nullptr;
         }
-        return GrSurfaceProxy::MakeDeferred(resourceProvider, desc, budgeted, nullptr, 0);
+        return GrSurfaceProxy::MakeDeferred(proxyProvider, desc, budgeted, nullptr, 0);
     }
     if (!texels) {
         return nullptr;
     }
 
     if (1 == mipLevelCount) {
-        return resourceProvider->createTextureProxy(desc, budgeted, texels[0]);
+        return proxyProvider->createTextureProxy(desc, budgeted, texels[0]);
     }
 
 #ifdef SK_DEBUG
@@ -381,14 +381,7 @@
     SkASSERT((firstLevelHasData && allOtherLevelsHaveData) || allOtherLevelsLackData);
 #endif
 
-    sk_sp<GrTexture> tex(resourceProvider->createTexture(desc, budgeted,
-                                                         texels, mipLevelCount,
-                                                         mipColorMode));
-    if (!tex) {
-        return nullptr;
-    }
-
-    return GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
+    return proxyProvider->createTextureProxy(desc, budgeted, texels, mipLevelCount, mipColorMode);
 }
 
 sk_sp<GrTextureProxy> GrSurfaceProxy::MakeWrappedBackend(GrContext* context,
diff --git a/src/gpu/GrTextureAdjuster.cpp b/src/gpu/GrTextureAdjuster.cpp
index d8985fe..b307607 100644
--- a/src/gpu/GrTextureAdjuster.cpp
+++ b/src/gpu/GrTextureAdjuster.cpp
@@ -9,8 +9,9 @@
 
 #include "GrColorSpaceXform.h"
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrGpu.h"
-#include "GrResourceProvider.h"
+#include "GrProxyProvider.h"
 #include "SkGr.h"
 
 GrTextureAdjuster::GrTextureAdjuster(GrContext* context, sk_sp<GrTextureProxy> original,
@@ -39,12 +40,13 @@
 
 sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxyCopy(const CopyParams& copyParams,
                                                              bool willBeMipped) {
+    GrProxyProvider* proxyProvider = fContext->contextPriv().proxyProvider();
+
     GrUniqueKey key;
     this->makeCopyKey(copyParams, &key, nullptr);
     if (key.isValid()) {
         sk_sp<GrTextureProxy> cachedCopy =
-                fContext->resourceProvider()->findOrCreateProxyByUniqueKey(
-                                                             key, this->originalProxy()->origin());
+                proxyProvider->findOrCreateProxyByUniqueKey(key, this->originalProxy()->origin());
         if (cachedCopy) {
             return cachedCopy;
         }
@@ -56,7 +58,7 @@
     if (copy) {
         if (key.isValid()) {
             SkASSERT(copy->origin() == this->originalProxy()->origin());
-            fContext->resourceProvider()->assignUniqueKeyToProxy(key, copy.get());
+            proxyProvider->assignUniqueKeyToProxy(key, copy.get());
             this->didCacheCopy(key);
         }
     }
diff --git a/src/gpu/GrTextureMaker.cpp b/src/gpu/GrTextureMaker.cpp
index 6cb9832..1fc5f7a 100644
--- a/src/gpu/GrTextureMaker.cpp
+++ b/src/gpu/GrTextureMaker.cpp
@@ -9,8 +9,9 @@
 
 #include "GrColorSpaceXform.h"
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrGpu.h"
-#include "GrResourceProvider.h"
+#include "GrProxyProvider.h"
 
 sk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerState& params,
                                                                SkColorSpace* dstColorSpace,
@@ -42,14 +43,14 @@
         }
     }
 
-    GrSurfaceOrigin origOrigin = original ? original->origin()
-                                          : kTopLeft_GrSurfaceOrigin;
+    GrProxyProvider* proxyProvider = fContext->contextPriv().proxyProvider();
+
+    GrSurfaceOrigin origOrigin = original ? original->origin() : kTopLeft_GrSurfaceOrigin;
     GrUniqueKey copyKey;
     this->makeCopyKey(copyParams, &copyKey, dstColorSpace);
     sk_sp<GrTextureProxy> cachedProxy;
     if (copyKey.isValid()) {
-        cachedProxy = fContext->resourceProvider()->findOrCreateProxyByUniqueKey(copyKey,
-                                                                                 origOrigin);
+        cachedProxy = proxyProvider->findOrCreateProxyByUniqueKey(copyKey, origOrigin);
         if (cachedProxy && (!willBeMipped || GrMipMapped::kYes == cachedProxy->mipMapped())) {
             return cachedProxy;
         }
@@ -83,9 +84,9 @@
             // If we had a cachedProxy, that means there already is a proxy in the cache which
             // matches the key, but it does not have mip levels and we require them. Thus we must
             // remove the unique key from that proxy.
-            fContext->resourceProvider()->removeUniqueKeyFromProxy(copyKey, cachedProxy.get());
+            proxyProvider->removeUniqueKeyFromProxy(copyKey, cachedProxy.get());
         }
-        fContext->resourceProvider()->assignUniqueKeyToProxy(copyKey, result.get());
+        proxyProvider->assignUniqueKeyToProxy(copyKey, result.get());
         this->didCacheCopy(copyKey);
     }
     return result;
diff --git a/src/gpu/GrTextureProducer.cpp b/src/gpu/GrTextureProducer.cpp
index 1be75f9..c99ee08 100644
--- a/src/gpu/GrTextureProducer.cpp
+++ b/src/gpu/GrTextureProducer.cpp
@@ -7,8 +7,8 @@
 
 #include "GrTextureProducer.h"
 #include "GrClip.h"
+#include "GrProxyProvider.h"
 #include "GrRenderTargetContext.h"
-#include "GrResourceProvider.h"
 #include "GrTextureProxy.h"
 #include "effects/GrBicubicEffect.h"
 #include "effects/GrSimpleTextureEffect.h"
@@ -39,7 +39,7 @@
     if (copyParams.fFilter != GrSamplerState::Filter::kNearest) {
         bool resizing = localRect.width()  != dstRect.width() ||
                         localRect.height() != dstRect.height();
-        needsDomain = resizing && !GrResourceProvider::IsFunctionallyExact(inputProxy.get());
+        needsDomain = resizing && !GrProxyProvider::IsFunctionallyExact(inputProxy.get());
     }
 
     if (needsDomain) {
@@ -84,7 +84,7 @@
 
     SkASSERT(proxyBounds.contains(constraintRect));
 
-    const bool proxyIsExact = GrResourceProvider::IsFunctionallyExact(proxy);
+    const bool proxyIsExact = GrProxyProvider::IsFunctionallyExact(proxy);
 
     // If the constraint rectangle contains the whole proxy then no need for a domain.
     if (constraintRect.contains(proxyBounds) && proxyIsExact) {
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index 9b3dc9c..c42df8b 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -9,8 +9,9 @@
 #include "GrTextureProxyPriv.h"
 
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrDeferredProxyUploader.h"
-#include "GrResourceCache.h"
+#include "GrProxyProvider.h"
 #include "GrTexturePriv.h"
 
 // Deferred version
@@ -19,7 +20,7 @@
         : INHERITED(srcDesc, fit, budgeted, flags)
         , fMipMapped(GrMipMapped::kNo)
         , fMipColorMode(SkDestinationSurfaceColorMode::kLegacy)
-        , fCache(nullptr)
+        , fProxyProvider(nullptr)
         , fDeferredUploader(nullptr) {
     SkASSERT(!srcData);  // currently handled in Make()
 }
@@ -29,7 +30,7 @@
         : INHERITED(std::move(callback), config)
         , fMipMapped(GrMipMapped::kNo)
         , fMipColorMode(SkDestinationSurfaceColorMode::kLegacy)
-        , fCache(nullptr)
+        , fProxyProvider(nullptr)
         , fDeferredUploader(nullptr) {
 }
 
@@ -38,11 +39,11 @@
         : INHERITED(std::move(surf), origin, SkBackingFit::kExact)
         , fMipMapped(fTarget->asTexture()->texturePriv().mipMapped())
         , fMipColorMode(fTarget->asTexture()->texturePriv().mipColorMode())
-        , fCache(nullptr)
+        , fProxyProvider(nullptr)
         , fDeferredUploader(nullptr) {
     if (fTarget->getUniqueKey().isValid()) {
-        fCache = fTarget->asTexture()->getContext()->getResourceCache();
-        fCache->adoptUniqueKeyFromSurface(this, fTarget);
+        fProxyProvider = fTarget->asTexture()->getContext()->contextPriv().proxyProvider();
+        fProxyProvider->adoptUniqueKeyFromSurface(this, fTarget);
     }
 }
 
@@ -51,9 +52,9 @@
     // at this point. Zero out the pointer so the cache invalidation code doesn't try to use it.
     fTarget = nullptr;
     if (fUniqueKey.isValid()) {
-        fCache->processInvalidProxyUniqueKey(fUniqueKey, this, false);
+        fProxyProvider->processInvalidProxyUniqueKey(fUniqueKey, this, false);
     } else {
-        SkASSERT(!fCache);
+        SkASSERT(!fProxyProvider);
     }
 }
 
@@ -124,7 +125,7 @@
                                   this->mipMapped(), !this->priv().isExact());
 }
 
-void GrTextureProxy::setUniqueKey(GrResourceCache* cache, const GrUniqueKey& key) {
+void GrTextureProxy::setUniqueKey(GrProxyProvider* proxyProvider, const GrUniqueKey& key) {
     SkASSERT(key.isValid());
     SkASSERT(!fUniqueKey.isValid()); // proxies can only ever get one uniqueKey
 
@@ -134,12 +135,12 @@
     }
 
     fUniqueKey = key;
-    fCache = cache;
+    fProxyProvider = proxyProvider;
 }
 
 void GrTextureProxy::clearUniqueKey() {
     fUniqueKey.reset();
-    fCache = nullptr;
+    fProxyProvider = nullptr;
 }
 
 #ifdef SK_DEBUG
diff --git a/src/gpu/GrTextureProxyCacheAccess.h b/src/gpu/GrTextureProxyCacheAccess.h
index 79cf845..7db7150 100644
--- a/src/gpu/GrTextureProxyCacheAccess.h
+++ b/src/gpu/GrTextureProxyCacheAccess.h
@@ -15,8 +15,8 @@
  */
 class GrTextureProxy::CacheAccess {
 private:
-    void setUniqueKey(GrResourceCache* cache, const GrUniqueKey& key) {
-        fTextureProxy->setUniqueKey(cache, key);
+    void setUniqueKey(GrProxyProvider* proxyProvider, const GrUniqueKey& key) {
+        fTextureProxy->setUniqueKey(proxyProvider, key);
     }
 
     void clearUniqueKey() {
@@ -34,7 +34,7 @@
     GrTextureProxy* fTextureProxy;
 
     friend class GrTextureProxy;  // to construct/copy this type.
-    friend class GrResourceCache; // to use this type
+    friend class GrProxyProvider; // to use this type
 };
 
 inline GrTextureProxy::CacheAccess GrTextureProxy::cacheAccess() { return CacheAccess(this); }
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 47d67e1..a781e53 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -10,6 +10,7 @@
 #include "GrBlurUtils.h"
 #include "GrColorSpaceXform.h"
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrGpu.h"
 #include "GrImageTextureMaker.h"
 #include "GrRenderTargetContextPriv.h"
@@ -1190,7 +1191,8 @@
 sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkBitmap& bitmap) {
     // TODO: this makes a tight copy of 'bitmap' but it doesn't have to be (given SkSpecialImage's
     // semantics). Since this is cached we would have to bake the fit into the cache key though.
-    sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(fContext->resourceProvider(), bitmap);
+    sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(fContext->contextPriv().proxyProvider(),
+                                                          bitmap);
     if (!proxy) {
         return nullptr;
     }
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 89deb98..da57a04 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -13,7 +13,7 @@
 #include "GrContextPriv.h"
 #include "GrGpuResourcePriv.h"
 #include "GrPaint.h"
-#include "GrResourceProvider.h"
+#include "GrProxyProvider.h"
 #include "GrTextureProxy.h"
 #include "GrTypes.h"
 #include "GrXferProcessor.h"
@@ -65,7 +65,7 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
-sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrResourceProvider* resourceProvider,
+sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrProxyProvider* proxyProvider,
                                                    const SkBitmap& bitmap,
                                                    SkColorSpace* dstColorSpace) {
     if (!bitmap.readyToDraw()) {
@@ -75,10 +75,10 @@
     if (!bitmap.peekPixels(&pixmap)) {
         return nullptr;
     }
-    return GrUploadPixmapToTextureProxy(resourceProvider, pixmap, SkBudgeted::kYes, dstColorSpace);
+    return GrUploadPixmapToTextureProxy(proxyProvider, pixmap, SkBudgeted::kYes, dstColorSpace);
 }
 
-sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider* resourceProvider,
+sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrProxyProvider* proxyProvider,
                                                    const SkPixmap& pixmap,
                                                    SkBudgeted budgeted,
                                                    SkColorSpace* dstColorSpace) {
@@ -91,8 +91,8 @@
     }
 
     ATRACE_ANDROID_FRAMEWORK("Upload Texture [%ux%u]", pixmap.width(), pixmap.height());
-    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *resourceProvider->caps());
-    return GrSurfaceProxy::MakeDeferred(resourceProvider, desc, budgeted, pixmap.addr(),
+    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *proxyProvider->caps());
+    return GrSurfaceProxy::MakeDeferred(proxyProvider, desc, budgeted, pixmap.addr(),
                                         pixmap.rowBytes());
 }
 
@@ -151,7 +151,7 @@
         texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes();
     }
 
-    return GrSurfaceProxy::MakeDeferredMipMap(ctx->resourceProvider(),
+    return GrSurfaceProxy::MakeDeferredMipMap(ctx->contextPriv().proxyProvider(),
                                               desc,
                                               SkBudgeted::kYes,
                                               texels.get(),
@@ -175,7 +175,7 @@
     desc.fConfig = baseProxy->config();
     desc.fSampleCnt = 0;
 
-    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferredMipMap(ctx->resourceProvider(),
+    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferredMipMap(ctx->contextPriv().proxyProvider(),
                                                                      desc,
                                                                      SkBudgeted::kYes);
     if (!proxy) {
@@ -199,7 +199,7 @@
         return nullptr;
     }
 
-    return GrSurfaceProxy::MakeDeferredMipMap(ctx->resourceProvider(),
+    return GrSurfaceProxy::MakeDeferredMipMap(ctx->contextPriv().proxyProvider(),
                                               GrImageInfoToSurfaceDesc(info, *ctx->caps()),
                                               SkBudgeted::kYes, texels,
                                               mipLevelCount, colorMode);
@@ -214,7 +214,7 @@
                                                                       nullptr, scaleAdjust);
 }
 
-sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrResourceProvider* resourceProvider,
+sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider* proxyProvider,
                                               const SkBitmap& bitmap) {
     GrUniqueKey originalKey;
 
@@ -227,17 +227,16 @@
     sk_sp<GrTextureProxy> proxy;
 
     if (originalKey.isValid()) {
-        proxy = resourceProvider->findOrCreateProxyByUniqueKey(originalKey,
-                                                               kTopLeft_GrSurfaceOrigin);
+        proxy = proxyProvider->findOrCreateProxyByUniqueKey(originalKey, kTopLeft_GrSurfaceOrigin);
     }
     if (!proxy) {
         // Pass nullptr for |dstColorSpace|.  This is lenient - we allow a wider range of
         // color spaces in legacy mode.  Unfortunately, we have to be lenient here, since
         // we can't necessarily know the |dstColorSpace| at this time.
-        proxy = GrUploadBitmapToTextureProxy(resourceProvider, bitmap, nullptr);
+        proxy = GrUploadBitmapToTextureProxy(proxyProvider, bitmap, nullptr);
         if (proxy && originalKey.isValid()) {
             SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
-            resourceProvider->assignUniqueKeyToProxy(originalKey, proxy.get());
+            proxyProvider->assignUniqueKeyToProxy(originalKey, proxy.get());
             GrInstallBitmapUniqueKeyInvalidator(originalKey, bitmap.pixelRef());
         }
     }
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index 0b972b4..87b602e 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -205,7 +205,7 @@
  * The bitmap must have CPU-accessible pixels. Attempts to take advantage of faster paths for
  * yuv planes.
  */
-sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrResourceProvider*, const SkBitmap&,
+sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrProxyProvider*, const SkBitmap&,
                                                    SkColorSpace* dstColorSpace);
 
 sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext*, const SkBitmap&,
@@ -214,7 +214,7 @@
 /**
  * Creates a new texture for the pixmap.
  */
-sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider*,
+sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrProxyProvider*,
                                                    const SkPixmap&, SkBudgeted, SkColorSpace*);
 
 /**
@@ -242,7 +242,7 @@
 //    if (!texture) {
 //        return nullptr;
 //    }
-sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrResourceProvider*, const SkBitmap& bitmap);
+sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider*, const SkBitmap& bitmap);
 
 
 /**
diff --git a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h
index ff9f047..4a8f215 100644
--- a/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h
+++ b/src/gpu/effects/GrBlurredEdgeFragmentProcessor.h
@@ -16,7 +16,7 @@
 #include "GrCoordTransform.h"
 class GrBlurredEdgeFragmentProcessor : public GrFragmentProcessor {
 public:
-    enum class Mode { kSmoothStep = 1, kGaussian = 0 };
+    enum class Mode { kGaussian = 0, kSmoothStep = 1 };
     Mode mode() const { return fMode; }
     static std::unique_ptr<GrFragmentProcessor> Make(Mode mode) {
         return std::unique_ptr<GrFragmentProcessor>(new GrBlurredEdgeFragmentProcessor(mode));
diff --git a/src/gpu/effects/GrConfigConversionEffect.fp b/src/gpu/effects/GrConfigConversionEffect.fp
index 62b998d..a64ac43 100644
--- a/src/gpu/effects/GrConfigConversionEffect.fp
+++ b/src/gpu/effects/GrConfigConversionEffect.fp
@@ -46,7 +46,7 @@
         desc.fHeight = kSize;
         desc.fConfig = kConfig;
 
-        sk_sp<GrTextureProxy> dataProxy = GrSurfaceProxy::MakeDeferred(context->resourceProvider(),
+        sk_sp<GrTextureProxy> dataProxy = GrSurfaceProxy::MakeDeferred(context->proxyProvider(),
                                                                        desc,
                                                                        SkBudgeted::kYes, data, 0);
         if (!dataProxy) {
diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h
index cc02473..66e8db6 100644
--- a/src/gpu/effects/GrConfigConversionEffect.h
+++ b/src/gpu/effects/GrConfigConversionEffect.h
@@ -15,6 +15,7 @@
 
 #include "GrClip.h"
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrRenderTargetContext.h"
 #include "GrFragmentProcessor.h"
 #include "GrCoordTransform.h"
@@ -58,7 +59,7 @@
         desc.fConfig = kConfig;
 
         sk_sp<GrTextureProxy> dataProxy = GrSurfaceProxy::MakeDeferred(
-                context->resourceProvider(), desc, SkBudgeted::kYes, data, 0);
+                context->contextPriv().proxyProvider(), desc, SkBudgeted::kYes, data, 0);
         if (!dataProxy) {
             return false;
         }
diff --git a/src/gpu/effects/GrConstColorProcessor.h b/src/gpu/effects/GrConstColorProcessor.h
index 62a9a0c..830240b 100644
--- a/src/gpu/effects/GrConstColorProcessor.h
+++ b/src/gpu/effects/GrConstColorProcessor.h
@@ -16,7 +16,7 @@
 #include "GrCoordTransform.h"
 class GrConstColorProcessor : public GrFragmentProcessor {
 public:
-    enum class InputMode { kLast = 2, kModulateA = 2, kModulateRGBA = 1, kIgnore = 0 };
+    enum class InputMode { kLast = 2, kModulateA = 2, kIgnore = 0, kModulateRGBA = 1 };
 
     static const int kInputModeCnt = (int)InputMode::kLast + 1;
 
diff --git a/src/gpu/effects/GrRRectBlurEffect.fp b/src/gpu/effects/GrRRectBlurEffect.fp
index c920efd..c21c4f0 100644
--- a/src/gpu/effects/GrRRectBlurEffect.fp
+++ b/src/gpu/effects/GrRRectBlurEffect.fp
@@ -9,6 +9,7 @@
     #include "GrClip.h"
     #include "GrContext.h"
     #include "GrPaint.h"
+    #include "GrProxyProvider.h"
     #include "GrRenderTargetContext.h"
     #include "GrStyle.h"
     #include "SkBlurMaskFilter.h"
@@ -35,7 +36,7 @@
         }
         builder.finish();
 
-        sk_sp<GrTextureProxy> mask(context->resourceProvider()->findOrCreateProxyByUniqueKey(
+        sk_sp<GrTextureProxy> mask(context->proxyProvider()->findOrCreateProxyByUniqueKey(
                                                                  key, kBottomLeft_GrSurfaceOrigin));
         if (!mask) {
             // TODO: this could be approx but the texture coords will need to be updated
@@ -74,7 +75,7 @@
                 return nullptr;
             }
             SkASSERT(mask->origin() == kBottomLeft_GrSurfaceOrigin);
-            context->resourceProvider()->assignUniqueKeyToProxy(key, mask.get());
+            context->proxyProvider()->assignUniqueKeyToProxy(key, mask.get());
         }
 
         return mask;
diff --git a/src/gpu/effects/GrRRectBlurEffect.h b/src/gpu/effects/GrRRectBlurEffect.h
index def7244..b95f7b0 100644
--- a/src/gpu/effects/GrRRectBlurEffect.h
+++ b/src/gpu/effects/GrRRectBlurEffect.h
@@ -15,7 +15,9 @@
 
 #include "GrClip.h"
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrPaint.h"
+#include "GrProxyProvider.h"
 #include "GrRenderTargetContext.h"
 #include "GrStyle.h"
 #include "SkBlurMaskFilter.h"
@@ -43,7 +45,9 @@
         }
         builder.finish();
 
-        sk_sp<GrTextureProxy> mask(context->resourceProvider()->findOrCreateProxyByUniqueKey(
+        GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
+
+        sk_sp<GrTextureProxy> mask(proxyProvider->findOrCreateProxyByUniqueKey(
                 key, kBottomLeft_GrSurfaceOrigin));
         if (!mask) {
             // TODO: this could be approx but the texture coords will need to be updated
@@ -83,7 +87,7 @@
                 return nullptr;
             }
             SkASSERT(mask->origin() == kBottomLeft_GrSurfaceOrigin);
-            context->resourceProvider()->assignUniqueKeyToProxy(key, mask.get());
+            proxyProvider->assignUniqueKeyToProxy(key, mask.get());
         }
 
         return mask;
diff --git a/src/gpu/effects/GrRectBlurEffect.cpp b/src/gpu/effects/GrRectBlurEffect.cpp
index e018761..f886ae3 100644
--- a/src/gpu/effects/GrRectBlurEffect.cpp
+++ b/src/gpu/effects/GrRectBlurEffect.cpp
@@ -161,7 +161,7 @@
     float sigma = data->fRandom->nextRangeF(3, 8);
     float width = data->fRandom->nextRangeF(200, 300);
     float height = data->fRandom->nextRangeF(200, 300);
-    return GrRectBlurEffect::Make(data->resourceProvider(), SkRect::MakeWH(width, height), sigma);
+    return GrRectBlurEffect::Make(data->proxyProvider(), SkRect::MakeWH(width, height), sigma);
 }
 #endif
 #endif
diff --git a/src/gpu/effects/GrRectBlurEffect.fp b/src/gpu/effects/GrRectBlurEffect.fp
index d20f52b..29767e6 100644
--- a/src/gpu/effects/GrRectBlurEffect.fp
+++ b/src/gpu/effects/GrRectBlurEffect.fp
@@ -1,5 +1,5 @@
 @header {
-    #include "GrResourceProvider.h"
+    #include "GrProxyProvider.h"
     #include "../effects/SkBlurMask.h"
 }
 
@@ -32,7 +32,7 @@
 
 
 @class {
-    static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrResourceProvider* resourceProvider,
+    static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrProxyProvider* proxyProvider,
                                                           float sigma) {
         unsigned int profileSize = SkScalarCeilToInt(6 * sigma);
 
@@ -42,7 +42,7 @@
         builder[0] = profileSize;
         builder.finish();
 
-        sk_sp<GrTextureProxy> blurProfile(resourceProvider->findOrCreateProxyByUniqueKey(
+        sk_sp<GrTextureProxy> blurProfile(proxyProvider->findOrCreateProxyByUniqueKey(
                                                                     key, kTopLeft_GrSurfaceOrigin));
         if (!blurProfile) {
             GrSurfaceDesc texDesc;
@@ -53,14 +53,14 @@
 
             std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma));
 
-            blurProfile = GrSurfaceProxy::MakeDeferred(resourceProvider,
+            blurProfile = GrSurfaceProxy::MakeDeferred(proxyProvider,
                                                        texDesc, SkBudgeted::kYes, profile.get(), 0);
             if (!blurProfile) {
                 return nullptr;
             }
 
             SkASSERT(blurProfile->origin() == kTopLeft_GrSurfaceOrigin);
-            resourceProvider->assignUniqueKeyToProxy(key, blurProfile.get());
+            proxyProvider->assignUniqueKeyToProxy(key, blurProfile.get());
         }
 
         return blurProfile;
@@ -68,7 +68,7 @@
 }
 
 @make {
-     static std::unique_ptr<GrFragmentProcessor> Make(GrResourceProvider* resourceProvider,
+     static std::unique_ptr<GrFragmentProcessor> Make(GrProxyProvider* proxyProvider,
                                                       const SkRect& rect, float sigma) {
          int doubleProfileSize = SkScalarCeilToInt(12*sigma);
 
@@ -78,7 +78,7 @@
              return nullptr;
          }
 
-         sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(resourceProvider, sigma));
+         sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(proxyProvider, sigma));
          if (!blurProfile) {
             return nullptr;
          }
@@ -127,6 +127,5 @@
     float sigma = data->fRandom->nextRangeF(3,8);
     float width = data->fRandom->nextRangeF(200,300);
     float height = data->fRandom->nextRangeF(200,300);
-    return GrRectBlurEffect::Make(data->resourceProvider(),
-                                  SkRect::MakeWH(width, height), sigma);
+    return GrRectBlurEffect::Make(data->proxyProvider(), SkRect::MakeWH(width, height), sigma);
 }
diff --git a/src/gpu/effects/GrRectBlurEffect.h b/src/gpu/effects/GrRectBlurEffect.h
index 8c43eaf..4f9b971 100644
--- a/src/gpu/effects/GrRectBlurEffect.h
+++ b/src/gpu/effects/GrRectBlurEffect.h
@@ -13,13 +13,13 @@
 #include "SkTypes.h"
 #if SK_SUPPORT_GPU
 
-#include "GrResourceProvider.h"
+#include "GrProxyProvider.h"
 #include "../effects/SkBlurMask.h"
 #include "GrFragmentProcessor.h"
 #include "GrCoordTransform.h"
 class GrRectBlurEffect : public GrFragmentProcessor {
 public:
-    static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrResourceProvider* resourceProvider,
+    static sk_sp<GrTextureProxy> CreateBlurProfileTexture(GrProxyProvider* proxyProvider,
                                                           float sigma) {
         unsigned int profileSize = SkScalarCeilToInt(6 * sigma);
 
@@ -30,7 +30,7 @@
         builder.finish();
 
         sk_sp<GrTextureProxy> blurProfile(
-                resourceProvider->findOrCreateProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin));
+                proxyProvider->findOrCreateProxyByUniqueKey(key, kTopLeft_GrSurfaceOrigin));
         if (!blurProfile) {
             GrSurfaceDesc texDesc;
             texDesc.fOrigin = kTopLeft_GrSurfaceOrigin;
@@ -40,14 +40,14 @@
 
             std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma));
 
-            blurProfile = GrSurfaceProxy::MakeDeferred(resourceProvider, texDesc, SkBudgeted::kYes,
+            blurProfile = GrSurfaceProxy::MakeDeferred(proxyProvider, texDesc, SkBudgeted::kYes,
                                                        profile.get(), 0);
             if (!blurProfile) {
                 return nullptr;
             }
 
             SkASSERT(blurProfile->origin() == kTopLeft_GrSurfaceOrigin);
-            resourceProvider->assignUniqueKeyToProxy(key, blurProfile.get());
+            proxyProvider->assignUniqueKeyToProxy(key, blurProfile.get());
         }
 
         return blurProfile;
@@ -55,7 +55,7 @@
     SkRect rect() const { return fRect; }
     float sigma() const { return fSigma; }
 
-    static std::unique_ptr<GrFragmentProcessor> Make(GrResourceProvider* resourceProvider,
+    static std::unique_ptr<GrFragmentProcessor> Make(GrProxyProvider* proxyProvider,
                                                      const SkRect& rect, float sigma) {
         int doubleProfileSize = SkScalarCeilToInt(12 * sigma);
 
@@ -65,7 +65,7 @@
             return nullptr;
         }
 
-        sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(resourceProvider, sigma));
+        sk_sp<GrTextureProxy> blurProfile(CreateBlurProfileTexture(proxyProvider, sigma));
         if (!blurProfile) {
             return nullptr;
         }
diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp
index 02746cf..81e8da1 100644
--- a/src/gpu/effects/GrTextureDomain.cpp
+++ b/src/gpu/effects/GrTextureDomain.cpp
@@ -7,7 +7,7 @@
 
 #include "GrTextureDomain.h"
 
-#include "GrResourceProvider.h"
+#include "GrProxyProvider.h"
 #include "GrShaderCaps.h"
 #include "GrSimpleTextureEffect.h"
 #include "GrSurfaceProxyPriv.h"
@@ -20,7 +20,7 @@
 #include "glsl/GrGLSLUniformHandler.h"
 
 static bool can_ignore_rect(GrTextureProxy* proxy, const SkRect& domain) {
-    if (GrResourceProvider::IsFunctionallyExact(proxy)) {
+    if (GrProxyProvider::IsFunctionallyExact(proxy)) {
         const SkIRect kFullRect = SkIRect::MakeWH(proxy->width(), proxy->height());
 
         return domain.contains(kFullRect);
diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp
index a459b32..f39da2a 100644
--- a/src/gpu/effects/GrTextureStripAtlas.cpp
+++ b/src/gpu/effects/GrTextureStripAtlas.cpp
@@ -8,7 +8,7 @@
 #include "GrTextureStripAtlas.h"
 #include "GrContext.h"
 #include "GrContextPriv.h"
-#include "GrResourceProvider.h"
+#include "GrProxyProvider.h"
 #include "GrSurfaceContext.h"
 #include "SkGr.h"
 #include "SkPixelRef.h"
@@ -207,7 +207,9 @@
     builder[0] = static_cast<uint32_t>(fCacheKey);
     builder.finish();
 
-    sk_sp<GrTextureProxy> proxy = fDesc.fContext->resourceProvider()->findOrCreateProxyByUniqueKey(
+    GrProxyProvider* proxyProvider = fDesc.fContext->contextPriv().proxyProvider();
+
+    sk_sp<GrTextureProxy> proxy = proxyProvider->findOrCreateProxyByUniqueKey(
                                                                 key, kTopLeft_GrSurfaceOrigin);
     if (!proxy) {
         GrSurfaceDesc texDesc;
@@ -216,7 +218,7 @@
         texDesc.fHeight = fDesc.fHeight;
         texDesc.fConfig = fDesc.fConfig;
 
-        proxy = GrSurfaceProxy::MakeDeferred(fDesc.fContext->resourceProvider(),
+        proxy = GrSurfaceProxy::MakeDeferred(proxyProvider,
                                              texDesc, SkBackingFit::kExact,
                                              SkBudgeted::kYes,
                                              GrResourceProvider::kNoPendingIO_Flag);
@@ -225,7 +227,7 @@
         }
 
         SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
-        fDesc.fContext->resourceProvider()->assignUniqueKeyToProxy(key, proxy.get());
+        proxyProvider->assignUniqueKeyToProxy(key, proxy.get());
         // This is a new texture, so all of our cache info is now invalid
         this->initLRU();
         fKeyTable.rewind();
diff --git a/src/gpu/ops/GrClearOp.cpp b/src/gpu/ops/GrClearOp.cpp
index 702edcc..e54ca6e 100644
--- a/src/gpu/ops/GrClearOp.cpp
+++ b/src/gpu/ops/GrClearOp.cpp
@@ -9,7 +9,7 @@
 
 #include "GrGpuCommandBuffer.h"
 #include "GrOpFlushState.h"
-#include "GrResourceProvider.h"
+#include "GrProxyProvider.h"
 
 GrClearOp::GrClearOp(const GrFixedClip& clip, GrColor color, GrSurfaceProxy* proxy)
         : INHERITED(ClassID())
@@ -23,7 +23,7 @@
             fClip = GrFixedClip(SkIRect::MakeEmpty());
         }
 
-        if (GrResourceProvider::IsFunctionallyExact(proxy) && fClip.scissorRect() == rtRect) {
+        if (GrProxyProvider::IsFunctionallyExact(proxy) && fClip.scissorRect() == rtRect) {
             fClip.disableScissor();
         }
     }
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index 79a22d8..5ed02cc 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -615,6 +615,7 @@
 
 #if GR_TEST_UTILS
 #include "GrContext.h"
+#include "GrContextPriv.h"
 
 GR_DRAW_OP_TEST_DEFINE(TextureOp) {
     GrSurfaceDesc desc;
@@ -623,8 +624,9 @@
     desc.fWidth = random->nextULessThan(90) + 10;
     desc.fOrigin = random->nextBool() ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
     SkBackingFit fit = random->nextBool() ? SkBackingFit::kApprox : SkBackingFit::kExact;
-    auto proxy =
-            GrSurfaceProxy::MakeDeferred(context->resourceProvider(), desc, fit, SkBudgeted::kNo);
+    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferred(
+                                              context->contextPriv().proxyProvider(),
+                                              desc, fit, SkBudgeted::kNo);
     SkRect rect = GrTest::TestRect(random);
     SkRect srcRect;
     srcRect.fLeft = random->nextRangeScalar(0.f, proxy->width() / 2.f);