Funnel most proxy creation through GrProxyProvider

This is to provide a choke point for DDL to create Lazy Proxies.

Change-Id: If178da13bc6447b31b7601810236d34502d9efbd
Reviewed-on: https://skia-review.googlesource.com/93303
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Greg Daniel <egdaniel@google.com>
diff --git a/src/effects/GrCircleBlurFragmentProcessor.cpp b/src/effects/GrCircleBlurFragmentProcessor.cpp
index 55095e0..d414e66 100644
--- a/src/effects/GrCircleBlurFragmentProcessor.cpp
+++ b/src/effects/GrCircleBlurFragmentProcessor.cpp
@@ -227,8 +227,9 @@
                     create_circle_profile(sigma * scale, circleR * scale, kProfileTextureWidth));
         }
 
-        blurProfile = GrSurfaceProxy::MakeDeferred(proxyProvider, texDesc, SkBudgeted::kYes,
-                                                   profile.get(), 0);
+        // This will be an exact match texture
+        blurProfile = proxyProvider->createTextureProxy(texDesc, SkBudgeted::kYes,
+                                                        profile.get(), 0);
         if (!blurProfile) {
             return nullptr;
         }
diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp
index 064b1aa..7531bf6 100644
--- a/src/gpu/GrBitmapTextureMaker.cpp
+++ b/src/gpu/GrBitmapTextureMaker.cpp
@@ -49,8 +49,7 @@
 
     if (!proxy) {
         if (willBeMipped) {
-            proxy = GrGenerateMipMapsAndUploadToTextureProxy(this->context(), fBitmap,
-                                                             dstColorSpace);
+            proxy = GrGenerateMipMapsAndUploadToTextureProxy(proxyProvider, fBitmap, dstColorSpace);
         }
         if (!proxy) {
             proxy = GrUploadBitmapToTextureProxy(proxyProvider, fBitmap, dstColorSpace);
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index ce77369..35fd52d 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -464,9 +464,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.
-        proxy = GrSurfaceProxy::MakeDeferred(proxyProvider, desc,
-                                             SkBackingFit::kApprox, SkBudgeted::kYes,
-                                             GrResourceProvider::kNoPendingIO_Flag);
+        proxy = proxyProvider->createProxy(desc, SkBackingFit::kApprox, SkBudgeted::kYes,
+                                           GrResourceProvider::kNoPendingIO_Flag);
 
         auto uploader = skstd::make_unique<GrTDeferredProxyUploader<ClipMaskData>>(reducedClip);
         GrTDeferredProxyUploader<ClipMaskData>* uploaderRaw = uploader.get();
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 131ac45..95d2344 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -530,10 +530,9 @@
 
     sk_sp<GrTextureProxy> tempProxy;
     if (GrGpu::kNoDraw_DrawPreference != drawPreference) {
-        tempProxy = GrSurfaceProxy::MakeDeferred(this->proxyProvider(),
-                                                 tempDrawInfo.fTempSurfaceDesc,
-                                                 SkBackingFit::kApprox,
-                                                 SkBudgeted::kYes);
+        tempProxy = this->proxyProvider()->createProxy(tempDrawInfo.fTempSurfaceDesc,
+                                                       SkBackingFit::kApprox,
+                                                       SkBudgeted::kYes);
         if (!tempProxy && GrGpu::kRequireDraw_DrawPreference == drawPreference) {
             return false;
         }
@@ -821,12 +820,10 @@
 
     sk_sp<GrTextureProxy> proxy;
     if (GrMipMapped::kNo == mipMapped) {
-        proxy = GrSurfaceProxy::MakeDeferred(this->proxyProvider(), dstDesc, fit,
-                                             isDstBudgeted);
+        proxy = this->proxyProvider()->createProxy(dstDesc, fit, isDstBudgeted);
     } else {
         SkASSERT(SkBackingFit::kExact == fit);
-        proxy = GrSurfaceProxy::MakeDeferredMipMap(this->proxyProvider(), dstDesc,
-                                                   isDstBudgeted);
+        proxy = this->proxyProvider()->createMipMapProxy(dstDesc, isDstBudgeted);
     }
     if (!proxy) {
         return nullptr;
@@ -840,12 +837,7 @@
                                                                  sk_sp<SkColorSpace> colorSpace) {
     ASSERT_SINGLE_OWNER_PRIV
 
-    sk_sp<GrSurface> surface(fContext->resourceProvider()->wrapBackendTexture(tex));
-    if (!surface) {
-        return nullptr;
-    }
-
-    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(surface), origin));
+    sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->createWrappedTextureProxy(tex, origin);
     if (!proxy) {
         return nullptr;
     }
@@ -861,13 +853,8 @@
                                                                    const SkSurfaceProps* props) {
     ASSERT_SINGLE_OWNER_PRIV
 
-    sk_sp<GrSurface> surface(
-            fContext->resourceProvider()->wrapRenderableBackendTexture(tex, sampleCnt));
-    if (!surface) {
-        return nullptr;
-    }
-
-    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(surface), origin));
+    sk_sp<GrTextureProxy> proxy(this->proxyProvider()->createWrappedTextureProxy(tex, origin,
+                                                                                 sampleCnt));
     if (!proxy) {
         return nullptr;
     }
@@ -883,12 +870,8 @@
                                                 const SkSurfaceProps* surfaceProps) {
     ASSERT_SINGLE_OWNER_PRIV
 
-    sk_sp<GrRenderTarget> rt(fContext->resourceProvider()->wrapBackendRenderTarget(backendRT));
-    if (!rt) {
-        return nullptr;
-    }
-
-    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(rt), origin));
+    sk_sp<GrSurfaceProxy> proxy = this->proxyProvider()->createWrappedRenderTargetProxy(backendRT,
+                                                                                        origin);
     if (!proxy) {
         return nullptr;
     }
@@ -903,24 +886,18 @@
                                                      GrSurfaceOrigin origin,
                                                      int sampleCnt,
                                                      sk_sp<SkColorSpace> colorSpace,
-                                                     const SkSurfaceProps* surfaceProps) {
+                                                     const SkSurfaceProps* props) {
     ASSERT_SINGLE_OWNER_PRIV
 
-    sk_sp<GrSurface> surface(fContext->resourceProvider()->wrapBackendTextureAsRenderTarget(
-                                                                                        tex,
-                                                                                        sampleCnt));
-    if (!surface) {
-        return nullptr;
-    }
-
-    sk_sp<GrSurfaceProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(surface), origin));
+    sk_sp<GrSurfaceProxy> proxy(this->proxyProvider()->createWrappedRenderTargetProxy(tex, origin,
+                                                                                      sampleCnt));
     if (!proxy) {
         return nullptr;
     }
 
     return this->drawingManager()->makeRenderTargetContext(std::move(proxy),
                                                            std::move(colorSpace),
-                                                           surfaceProps);
+                                                           props);
 }
 
 void GrContextPriv::addOnFlushCallbackObject(GrOnFlushCallbackObject* onFlushCBObject) {
@@ -987,9 +964,9 @@
 
     sk_sp<GrTextureProxy> rtp;
     if (GrMipMapped::kNo == mipMapped) {
-        rtp = GrSurfaceProxy::MakeDeferred(fProxyProvider, desc, fit, budgeted);
+        rtp = fProxyProvider->createProxy(desc, fit, budgeted);
     } else {
-        rtp = GrSurfaceProxy::MakeDeferredMipMap(fProxyProvider, desc, budgeted);
+        rtp = fProxyProvider->createMipMapProxy(desc, budgeted);
     }
     if (!rtp) {
         return nullptr;
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index c0358b7..0ba9dec 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -8,8 +8,10 @@
 #include "GrDrawOpAtlas.h"
 
 #include "GrContext.h"
+#include "GrContextPriv.h"
 #include "GrOpFlushState.h"
 #include "GrRectanizer.h"
+#include "GrProxyProvider.h"
 #include "GrResourceProvider.h"
 #include "GrTexture.h"
 #include "GrTracing.h"
@@ -452,6 +454,8 @@
         return false;
     }
 
+    GrProxyProvider* proxyProvider = fContext->contextPriv().proxyProvider();
+
     GrSurfaceDesc desc;
     desc.fFlags = kNone_GrSurfaceFlags;
     desc.fOrigin = kTopLeft_GrSurfaceOrigin;
@@ -463,16 +467,14 @@
     // guarantee we do not recieve a texture with pending IO
     // TODO: Determine how to avoid having to do this. (https://bug.skia.org/4156)
     static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag;
-    sk_sp<GrTexture> texture(fContext->resourceProvider()->createApproxTexture(desc, kFlags));
-    if (texture) {
-        // MDB TODO: for now, wrap an instantiated texture. Having the deferred instantiation
-        // possess the correct properties (e.g., no pendingIO) should fall out of the system but
-        // should receive special attention.
-        // Note: When switching over to the deferred proxy, use the kExact flag to create
-        // the atlas and assert that the width & height are powers of 2.
-        fProxies[fNumPages] = GrSurfaceProxy::MakeWrapped(std::move(texture),
-                                                          kTopLeft_GrSurfaceOrigin);
-    }
+    // MDB TODO: for now, wrap an instantiated texture. Having the deferred instantiation
+    // possess the correct properties (e.g., no pendingIO) should fall out of the system but
+    // should receive special attention.
+    // Note: When switching over to the deferred proxy, use the kExact flag to create
+    // the atlas and assert that the width & height are powers of 2.
+    // DDL TODO: remove this use of createInstantitateProxy & convert it to a testing-only method.
+    fProxies[fNumPages] = proxyProvider->createInstantiatedProxy(desc, SkBackingFit::kApprox,
+                                                                 SkBudgeted::kYes, kFlags);
     if (!fProxies[fNumPages]) {
         return false;
     }
diff --git a/src/gpu/GrOnFlushResourceProvider.cpp b/src/gpu/GrOnFlushResourceProvider.cpp
index a93c9eb..7fcd30f 100644
--- a/src/gpu/GrOnFlushResourceProvider.cpp
+++ b/src/gpu/GrOnFlushResourceProvider.cpp
@@ -9,6 +9,7 @@
 
 #include "GrContextPriv.h"
 #include "GrDrawingManager.h"
+#include "GrProxyProvider.h"
 #include "GrSurfaceProxy.h"
 
 sk_sp<GrRenderTargetContext> GrOnFlushResourceProvider::makeRenderTargetContext(
@@ -21,12 +22,10 @@
     // Because this is being allocated at the start of a flush we must ensure the proxy
     // will, when instantiated, have no pending IO.
     // TODO: fold the kNoPendingIO_Flag into GrSurfaceFlags?
-    sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeDeferred(
-                                        fDrawingMgr->getContext()->contextPriv().proxyProvider(),
-                                        tmpDesc,
-                                        SkBackingFit::kExact,
-                                        SkBudgeted::kYes,
-                                        GrResourceProvider::kNoPendingIO_Flag);
+    GrProxyProvider* proxyProvider = fDrawingMgr->getContext()->contextPriv().proxyProvider();
+    sk_sp<GrSurfaceProxy> proxy = proxyProvider->createProxy(tmpDesc, SkBackingFit::kExact,
+                                                             SkBudgeted::kYes,
+                                                             GrResourceProvider::kNoPendingIO_Flag);
     if (!proxy->asRenderTargetProxy()) {
         return nullptr;
     }
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index c9617ad..942d17f 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -8,13 +8,16 @@
 #include "GrProxyProvider.h"
 
 #include "GrCaps.h"
+#include "GrRenderTarget.h"
 #include "GrResourceKey.h"
 #include "GrResourceProvider.h"
 #include "GrSurfaceProxy.h"
 #include "GrSurfaceProxyPriv.h"
 #include "GrTexture.h"
 #include "GrTextureProxyCacheAccess.h"
+#include "GrTextureRenderTargetProxy.h"
 #include "../private/GrSingleOwner.h"
+#include "SkMipMap.h"
 
 #define ASSERT_SINGLE_OWNER \
     SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
@@ -126,24 +129,54 @@
     return result;
 }
 
+sk_sp<GrTextureProxy> GrProxyProvider::createInstantiatedProxy(const GrSurfaceDesc& desc,
+                                                               SkBackingFit fit,
+                                                               SkBudgeted budgeted,
+                                                               uint32_t flags) {
+    sk_sp<GrTexture> tex;
+
+    if (SkBackingFit::kApprox == fit) {
+        tex = fResourceProvider->createApproxTexture(desc, flags);
+    } else {
+        tex = fResourceProvider->createTexture(desc, budgeted, flags);
+    }
+    if (!tex) {
+        return nullptr;
+    }
+
+    SkASSERT(!tex->getUniqueKey().isValid());
+
+    if (tex->asRenderTarget()) {
+        return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(std::move(tex), desc.fOrigin));
+    }
+
+    return sk_sp<GrTextureProxy>(new GrTextureProxy(std::move(tex), desc.fOrigin));
+}
+
 sk_sp<GrTextureProxy> GrProxyProvider::createTextureProxy(const GrSurfaceDesc& desc,
                                                           SkBudgeted budgeted,
-                                                          const GrMipLevel& mipLevel) {
+                                                          const void* srcData, size_t rowBytes) {
     ASSERT_SINGLE_OWNER
 
     if (this->isAbandoned()) {
         return nullptr;
     }
 
-    sk_sp<GrTexture> tex = fResourceProvider->createTexture(desc, budgeted, mipLevel);
-    if (!tex) {
-        return nullptr;
+    if (srcData) {
+        GrMipLevel mipLevel = { srcData, rowBytes };
+
+        sk_sp<GrTexture> tex = fResourceProvider->createTexture(desc, budgeted, mipLevel);
+        if (!tex) {
+            return nullptr;
+        }
+
+        return GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
     }
 
-    return GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
+    return this->createProxy(desc, SkBackingFit::kExact, budgeted);
 }
 
-sk_sp<GrTextureProxy> GrProxyProvider::createTextureProxy(
+sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxy(
                                                     const GrSurfaceDesc& desc, SkBudgeted budgeted,
                                                     const GrMipLevel texels[], int mipLevelCount,
                                                     SkDestinationSurfaceColorMode mipColorMode) {
@@ -153,6 +186,38 @@
         return nullptr;
     }
 
+    if (!mipLevelCount) {
+        if (texels) {
+            return nullptr;
+        }
+        return this->createProxy(desc, SkBackingFit::kExact, budgeted);
+    }
+    if (!texels) {
+        return nullptr;
+    }
+
+    if (1 == mipLevelCount) {
+        return this->createTextureProxy(desc, budgeted, texels[0].fPixels, texels[0].fRowBytes);
+    }
+
+#ifdef SK_DEBUG
+    // There are only three states we want to be in when uploading data to a mipped surface.
+    // 1) We have data to upload to all layers
+    // 2) We are not uploading data to any layers
+    // 3) We are only uploading data to the base layer
+    // We check here to make sure we do not have any other state.
+    bool firstLevelHasData = SkToBool(texels[0].fPixels);
+    bool allOtherLevelsHaveData = true, allOtherLevelsLackData = true;
+    for  (int i = 1; i < mipLevelCount; ++i) {
+        if (texels[i].fPixels) {
+            allOtherLevelsLackData = false;
+        } else {
+            allOtherLevelsHaveData = false;
+        }
+    }
+    SkASSERT((firstLevelHasData && allOtherLevelsHaveData) || allOtherLevelsLackData);
+#endif
+
     sk_sp<GrTexture> tex(fResourceProvider->createTexture(desc, budgeted,
                                                           texels, mipLevelCount,
                                                           mipColorMode));
@@ -163,6 +228,137 @@
     return GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
 }
 
+sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxy(const GrSurfaceDesc& desc,
+                                                         SkBudgeted budgeted) {
+    // SkMipMap doesn't include the base level in the level count so we have to add 1
+    int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1;
+
+    std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipCount]);
+
+    // We don't want to upload any texel data
+    for (int i = 0; i < mipCount; i++) {
+        texels[i].fPixels = nullptr;
+        texels[i].fRowBytes = 0;
+    }
+
+    return this->createMipMapProxy(desc, budgeted, texels.get(), mipCount,
+                                   SkDestinationSurfaceColorMode::kLegacy);
+}
+
+sk_sp<GrTextureProxy> GrProxyProvider::createProxy(const GrSurfaceDesc& desc,
+                                                   SkBackingFit fit,
+                                                   SkBudgeted budgeted,
+                                                   uint32_t flags) {
+    SkASSERT(0 == flags || GrResourceProvider::kNoPendingIO_Flag == flags);
+
+    const GrCaps* caps = this->caps();
+
+    // TODO: move this logic into GrResourceProvider!
+    // TODO: share this testing code with check_texture_creation_params
+    if (!caps->isConfigTexturable(desc.fConfig)) {
+        return nullptr;
+    }
+
+    bool willBeRT = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
+    if (willBeRT && !caps->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
+        return nullptr;
+    }
+
+    // We currently do not support multisampled textures
+    if (!willBeRT && desc.fSampleCnt > 0) {
+        return nullptr;
+    }
+
+    int maxSize;
+    if (willBeRT) {
+        maxSize = caps->maxRenderTargetSize();
+    } else {
+        maxSize = caps->maxTextureSize();
+    }
+
+    if (desc.fWidth > maxSize || desc.fHeight > maxSize || desc.fWidth <= 0 || desc.fHeight <= 0) {
+        return nullptr;
+    }
+
+    GrSurfaceDesc copyDesc = desc;
+    copyDesc.fSampleCnt = caps->getSampleCount(desc.fSampleCnt, desc.fConfig);
+
+#ifdef SK_DISABLE_DEFERRED_PROXIES
+    // Temporarily force instantiation for crbug.com/769760 and crbug.com/769898
+    sk_sp<GrTexture> tex;
+
+    if (SkBackingFit::kApprox == fit) {
+        tex = resourceProvider->createApproxTexture(copyDesc, flags);
+    } else {
+        tex = resourceProvider->createTexture(copyDesc, budgeted, flags);
+    }
+
+    if (!tex) {
+        return nullptr;
+    }
+
+    return GrSurfaceProxy::MakeWrapped(std::move(tex), copyDesc.fOrigin);
+#else
+    if (willBeRT) {
+        // We know anything we instantiate later from this deferred path will be
+        // both texturable and renderable
+        return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(*caps, copyDesc, fit,
+                                                                    budgeted, flags));
+    }
+
+    return sk_sp<GrTextureProxy>(new GrTextureProxy(copyDesc, fit, budgeted, nullptr, 0, flags));
+#endif
+}
+
+sk_sp<GrTextureProxy> GrProxyProvider::createWrappedTextureProxy(const GrBackendTexture& backendTex,
+                                                                 GrSurfaceOrigin origin) {
+    sk_sp<GrTexture> texture(fResourceProvider->wrapBackendTexture(backendTex));
+    if (!texture) {
+        return nullptr;
+    }
+    SkASSERT(!texture->asRenderTarget());   // Strictly a GrTexture
+
+    return GrSurfaceProxy::MakeWrapped(std::move(texture), origin);
+}
+
+sk_sp<GrTextureProxy> GrProxyProvider::createWrappedTextureProxy(const GrBackendTexture& tex,
+                                                                 GrSurfaceOrigin origin,
+                                                                 int sampleCnt) {
+    sk_sp<GrTexture> texture(fResourceProvider->wrapRenderableBackendTexture(tex, sampleCnt));
+    if (!texture) {
+        return nullptr;
+    }
+    SkASSERT(texture->asRenderTarget());  // A GrTextureRenderTarget
+
+    return GrSurfaceProxy::MakeWrapped(std::move(texture), origin);
+}
+
+sk_sp<GrSurfaceProxy> GrProxyProvider::createWrappedRenderTargetProxy(
+                                                             const GrBackendRenderTarget& backendRT,
+                                                             GrSurfaceOrigin origin) {
+    sk_sp<GrRenderTarget> rt(fResourceProvider->wrapBackendRenderTarget(backendRT));
+    if (!rt) {
+        return nullptr;
+    }
+    SkASSERT(!rt->asTexture()); // Strictly a GrRenderTarget
+    SkASSERT(!rt->getUniqueKey().isValid());
+
+    return sk_sp<GrSurfaceProxy>(new GrRenderTargetProxy(std::move(rt), origin));
+}
+
+sk_sp<GrSurfaceProxy> GrProxyProvider::createWrappedRenderTargetProxy(const GrBackendTexture& tex,
+                                                                      GrSurfaceOrigin origin,
+                                                                      int sampleCnt) {
+    sk_sp<GrRenderTarget> rt(fResourceProvider->wrapBackendTextureAsRenderTarget(tex, sampleCnt));
+    if (!rt) {
+        return nullptr;
+    }
+    SkASSERT(!rt->asTexture()); // Strictly a GrRenderTarget
+    SkASSERT(!rt->getUniqueKey().isValid());
+
+    return sk_sp<GrSurfaceProxy>(new GrRenderTargetProxy(std::move(rt), origin));
+}
+
 bool GrProxyProvider::IsFunctionallyExact(GrSurfaceProxy* proxy) {
     return proxy->priv().isExact() || (SkIsPow2(proxy->width()) && SkIsPow2(proxy->height()));
 }
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index 404e020..1150c79 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -17,6 +17,7 @@
 class GrCaps;
 class GrResourceProvider;
 class GrSingleOwner;
+class GrBackendRenderTarget;
 
 /*
  * A factory for creating GrSurfaceProxy-derived objects.
@@ -57,16 +58,75 @@
     sk_sp<GrTextureProxy> findOrCreateProxyByUniqueKey(const GrUniqueKey&, GrSurfaceOrigin);
 
     /*
-     * Create an un-mipmapped texture proxy with data.
+     * Create a texture proxy that is backed by an instantiated GrSurface. This is almost entirely
+     * used by Skia's testing code.
+     * DDL TODO: remove the remaining Skia-internal use of this method and make it truly
+     * testing-only.
      */
-    sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, SkBudgeted, const GrMipLevel&);
+    sk_sp<GrTextureProxy> createInstantiatedProxy(const GrSurfaceDesc&, SkBackingFit, SkBudgeted,
+                                                  uint32_t flags = 0);
+
+    /*
+     * Create an un-mipmapped texture proxy with data.
+     * DDL TODO: need to refine ownership semantics of 'srcData' if we're in completely
+     * deferred mode
+     */
+    sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, SkBudgeted,
+                                             const void* srcData, size_t rowBytes);
 
     /*
      * Create a mipmapped texture proxy with data.
+     *
+     * @param desc          Description of the texture properties.
+     * @param budgeted      Does the texture count against the resource cache budget?
+     * @param texels        A contiguous array of mipmap levels
+     * @param mipLevelCount The amount of elements in the texels array
      */
-    sk_sp<GrTextureProxy> createTextureProxy(const GrSurfaceDesc&, SkBudgeted,
-                                             const GrMipLevel texels[], int mipLevelCount,
-                                             SkDestinationSurfaceColorMode mipColorMode);
+    sk_sp<GrTextureProxy> createMipMapProxy(const GrSurfaceDesc&, SkBudgeted,
+                                            const GrMipLevel texels[], int mipLevelCount,
+                                            SkDestinationSurfaceColorMode mipColorMode =
+                                                            SkDestinationSurfaceColorMode::kLegacy);
+
+
+    /*
+     * Create a mipmapped texture proxy without any data.
+     *
+     * Like the call above but there are no texels to upload. A texture proxy is returned that
+     * simply has space allocated for the mips. We will allocated the full amount of mip levels
+     * based on the width and height in the GrSurfaceDesc.
+     */
+    sk_sp<GrTextureProxy> createMipMapProxy(const GrSurfaceDesc&, SkBudgeted);
+
+    /*
+     * Create a GrSurfaceProxy without any data.
+     */
+    sk_sp<GrTextureProxy> createProxy(const GrSurfaceDesc&, SkBackingFit, SkBudgeted,
+                                      uint32_t flags = 0);
+
+    /*
+     * Create a texture proxy that wraps a (non-renderable) backend texture.
+     */
+    sk_sp<GrTextureProxy> createWrappedTextureProxy(const GrBackendTexture&, GrSurfaceOrigin);
+
+    /*
+     * Create a texture proxy that wraps a backend texture and is both texture-able and renderable
+     */
+    sk_sp<GrTextureProxy> createWrappedTextureProxy(const GrBackendTexture&,
+                                                    GrSurfaceOrigin,
+                                                    int sampleCnt);
+
+    /*
+     * Create a render target proxy that wraps a backend rendertarget
+     */
+    sk_sp<GrSurfaceProxy> createWrappedRenderTargetProxy(const GrBackendRenderTarget&,
+                                                         GrSurfaceOrigin);
+
+    /*
+     * Create a render target proxy that wraps a backend texture?
+     */
+    sk_sp<GrSurfaceProxy> createWrappedRenderTargetProxy(const GrBackendTexture& tex,
+                                                         GrSurfaceOrigin origin,
+                                                         int sampleCnt);
 
     // '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.
diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp
index 048b87f..33773a8 100644
--- a/src/gpu/GrResourceProvider.cpp
+++ b/src/gpu/GrResourceProvider.cpp
@@ -15,6 +15,7 @@
 #include "GrGpu.h"
 #include "GrPath.h"
 #include "GrPathRendering.h"
+#include "GrProxyProvider.h"
 #include "GrRenderTargetPriv.h"
 #include "GrResourceCache.h"
 #include "GrResourceKey.h"
@@ -128,19 +129,22 @@
     }
 
     GrContext* context = fGpu->getContext();
+    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
 
     SkImageInfo srcInfo;
 
     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(tex, desc.fOrigin);
+        // DDL TODO: remove this use of createInstantiatedProxy and convert it to a testing-only
+        // method.
+        sk_sp<GrTextureProxy> proxy = proxyProvider->createInstantiatedProxy(desc,
+                                                                             SkBackingFit::kExact,
+                                                                             budgeted);
         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)) {
-                    SkASSERT(sContext->asTextureProxy()->priv().peekTexture() == tex.get());
-                    return tex;
+                    return sk_ref_sp(sContext->asTextureProxy()->priv().peekTexture());
                 }
             }
         }
@@ -464,7 +468,7 @@
     if (this->isAbandoned()) {
         return nullptr;
     }
-    return this->gpu()->wrapBackendTextureAsRenderTarget(tex, sampleCnt);
+    return fGpu->wrapBackendTextureAsRenderTarget(tex, sampleCnt);
 }
 
 sk_sp<GrSemaphore> SK_WARN_UNUSED_RESULT GrResourceProvider::makeSemaphore(bool isOwned) {
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 3fd5df4..ff6a20f 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -169,15 +169,18 @@
 
 static sk_sp<GrTextureProxy> make_deferred_mask_texture_proxy(GrContext* context, SkBackingFit fit,
                                                               int width, int height) {
+    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
+
     GrSurfaceDesc desc;
     desc.fOrigin = kTopLeft_GrSurfaceOrigin;
     desc.fWidth = width;
     desc.fHeight = height;
     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->contextPriv().proxyProvider(), desc, fit,
-                                        SkBudgeted::kYes, GrResourceProvider::kNoPendingIO_Flag);
+    return proxyProvider->createProxy(desc, fit, SkBudgeted::kYes,
+                                      GrResourceProvider::kNoPendingIO_Flag);
 }
 
 namespace {
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index e505a9c..c9da6ce 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -223,35 +223,6 @@
     return fLastOpList ? fLastOpList->asTextureOpList() : nullptr;
 }
 
-sk_sp<GrSurfaceProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrSurface> surf, GrSurfaceOrigin origin) {
-    if (!surf) {
-        return nullptr;
-    }
-
-    if (surf->getUniqueKey().isValid()) {
-        // The proxy may already be in the hash. Thus we need to look for it first before creating
-        // new one.
-        GrProxyProvider* provider = surf->getContext()->contextPriv().proxyProvider();
-        sk_sp<GrSurfaceProxy> proxy = provider->findProxyByUniqueKey(surf->getUniqueKey(), origin);
-        if (proxy) {
-            return proxy;
-        }
-    }
-
-    if (surf->asTexture()) {
-        if (surf->asRenderTarget()) {
-            return sk_sp<GrSurfaceProxy>(new GrTextureRenderTargetProxy(std::move(surf), origin));
-        } else {
-            return sk_sp<GrSurfaceProxy>(new GrTextureProxy(std::move(surf), origin));
-        }
-    } else {
-        SkASSERT(surf->asRenderTarget());
-
-        // Not texturable
-        return sk_sp<GrSurfaceProxy>(new GrRenderTargetProxy(std::move(surf), origin));
-    }
-}
-
 sk_sp<GrTextureProxy> GrSurfaceProxy::MakeWrapped(sk_sp<GrTexture> tex, GrSurfaceOrigin origin) {
     if (!tex) {
         return nullptr;
@@ -274,152 +245,6 @@
     }
 }
 
-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 = proxyProvider->caps();
-
-    // TODO: move this logic into GrResourceProvider!
-    // TODO: share this testing code with check_texture_creation_params
-    if (!caps->isConfigTexturable(desc.fConfig)) {
-        return nullptr;
-    }
-
-    bool willBeRT = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
-    if (willBeRT && !caps->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
-        return nullptr;
-    }
-
-    // We currently do not support multisampled textures
-    if (!willBeRT && desc.fSampleCnt > 0) {
-        return nullptr;
-    }
-
-    int maxSize;
-    if (willBeRT) {
-        maxSize = caps->maxRenderTargetSize();
-    } else {
-        maxSize = caps->maxTextureSize();
-    }
-
-    if (desc.fWidth > maxSize || desc.fHeight > maxSize || desc.fWidth <= 0 || desc.fHeight <= 0) {
-        return nullptr;
-    }
-
-    GrSurfaceDesc copyDesc = desc;
-    copyDesc.fSampleCnt = caps->getSampleCount(desc.fSampleCnt, desc.fConfig);
-
-#ifdef SK_DISABLE_DEFERRED_PROXIES
-    // Temporarily force instantiation for crbug.com/769760 and crbug.com/769898
-    sk_sp<GrTexture> tex;
-
-    if (SkBackingFit::kApprox == fit) {
-        tex = resourceProvider->createApproxTexture(copyDesc, flags);
-    } else {
-        tex = resourceProvider->createTexture(copyDesc, budgeted, flags);
-    }
-
-    if (!tex) {
-        return nullptr;
-    }
-
-    return GrSurfaceProxy::MakeWrapped(std::move(tex), copyDesc.fOrigin);
-#else
-    if (willBeRT) {
-        // We know anything we instantiate later from this deferred path will be
-        // both texturable and renderable
-        return sk_sp<GrTextureProxy>(new GrTextureRenderTargetProxy(*caps, copyDesc, fit,
-                                                                    budgeted, flags));
-    }
-
-    return sk_sp<GrTextureProxy>(new GrTextureProxy(copyDesc, fit, budgeted, nullptr, 0, flags));
-#endif
-}
-
-sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferred(GrProxyProvider* proxyProvider,
-                                                   const GrSurfaceDesc& desc,
-                                                   SkBudgeted budgeted,
-                                                   const void* srcData,
-                                                   size_t rowBytes) {
-    if (srcData) {
-        GrMipLevel mipLevel = { srcData, rowBytes };
-
-        return proxyProvider->createTextureProxy(desc, budgeted, mipLevel);
-    }
-
-    return GrSurfaceProxy::MakeDeferred(proxyProvider, desc, SkBackingFit::kExact, budgeted);
-}
-
-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
-    int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1;
-
-    std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipCount]);
-
-    // We don't want to upload any texel data
-    for (int i = 0; i < mipCount; i++) {
-        texels[i].fPixels = nullptr;
-        texels[i].fRowBytes = 0;
-    }
-
-    return MakeDeferredMipMap(proxyProvider, desc, budgeted, texels.get(), mipCount);
-}
-
-sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferredMipMap(
-                                                    GrProxyProvider* proxyProvider,
-                                                    const GrSurfaceDesc& desc,
-                                                    SkBudgeted budgeted,
-                                                    const GrMipLevel texels[],
-                                                    int mipLevelCount,
-                                                    SkDestinationSurfaceColorMode mipColorMode) {
-    if (!mipLevelCount) {
-        if (texels) {
-            return nullptr;
-        }
-        return GrSurfaceProxy::MakeDeferred(proxyProvider, desc, budgeted, nullptr, 0);
-    }
-    if (!texels) {
-        return nullptr;
-    }
-
-    if (1 == mipLevelCount) {
-        return proxyProvider->createTextureProxy(desc, budgeted, texels[0]);
-    }
-
-#ifdef SK_DEBUG
-    // There are only three states we want to be in when uploading data to a mipped surface.
-    // 1) We have data to upload to all layers
-    // 2) We are not uploading data to any layers
-    // 3) We are only uploading data to the base layer
-    // We check here to make sure we do not have any other state.
-    bool firstLevelHasData = SkToBool(texels[0].fPixels);
-    bool allOtherLevelsHaveData = true, allOtherLevelsLackData = true;
-    for  (int i = 1; i < mipLevelCount; ++i) {
-        if (texels[i].fPixels) {
-            allOtherLevelsLackData = false;
-        } else {
-            allOtherLevelsHaveData = false;
-        }
-    }
-    SkASSERT((firstLevelHasData && allOtherLevelsHaveData) || allOtherLevelsLackData);
-#endif
-
-    return proxyProvider->createTextureProxy(desc, budgeted, texels, mipLevelCount, mipColorMode);
-}
-
-sk_sp<GrTextureProxy> GrSurfaceProxy::MakeWrappedBackend(GrContext* context,
-                                                         const GrBackendTexture& backendTex,
-                                                         GrSurfaceOrigin origin) {
-    sk_sp<GrTexture> tex(context->resourceProvider()->wrapBackendTexture(backendTex));
-    return GrSurfaceProxy::MakeWrapped(std::move(tex), origin);
-}
-
 sk_sp<GrTextureProxy> GrSurfaceProxy::MakeLazy(LazyInstantiateCallback&& callback,
                                                const GrSurfaceDesc& desc,
                                                GrMipMapped mipMapped,
diff --git a/src/gpu/GrTextureRenderTargetProxy.h b/src/gpu/GrTextureRenderTargetProxy.h
index 739f797..63cc487 100644
--- a/src/gpu/GrTextureRenderTargetProxy.h
+++ b/src/gpu/GrTextureRenderTargetProxy.h
@@ -23,7 +23,9 @@
 // the uniqueID of the RenderTarget/Texture it represents!
 class GrTextureRenderTargetProxy : public GrTextureProxy, public GrRenderTargetProxy {
 private:
+    // DDL TODO: rm the GrSurfaceProxy friending
     friend class GrSurfaceProxy; // for ctors
+    friend class GrProxyProvider; // for ctors
 
     // Deferred version
     GrTextureRenderTargetProxy(const GrCaps&, const GrSurfaceDesc&,
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index da57a04..8faa9d4 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -92,8 +92,8 @@
 
     ATRACE_ANDROID_FRAMEWORK("Upload Texture [%ux%u]", pixmap.width(), pixmap.height());
     GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *proxyProvider->caps());
-    return GrSurfaceProxy::MakeDeferred(proxyProvider, desc, budgeted, pixmap.addr(),
-                                        pixmap.rowBytes());
+
+    return proxyProvider->createTextureProxy(desc, budgeted, pixmap.addr(), pixmap.rowBytes());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -111,7 +111,7 @@
     pixelRef->addGenIDChangeListener(new Invalidator(key));
 }
 
-sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext* ctx,
+sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrProxyProvider* proxyProvider,
                                                                const SkBitmap& bitmap,
                                                                SkColorSpace* dstColorSpace) {
     SkDestinationSurfaceColorMode colorMode = dstColorSpace
@@ -128,7 +128,7 @@
     }
 
     ATRACE_ANDROID_FRAMEWORK("Upload MipMap Texture [%ux%u]", pixmap.width(), pixmap.height());
-    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *ctx->resourceProvider()->caps());
+    GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info(), *proxyProvider->caps());
     std::unique_ptr<SkMipMap> mipmaps(SkMipMap::Build(pixmap, colorMode, nullptr));
     if (!mipmaps) {
         return nullptr;
@@ -151,22 +151,18 @@
         texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes();
     }
 
-    return GrSurfaceProxy::MakeDeferredMipMap(ctx->contextPriv().proxyProvider(),
-                                              desc,
-                                              SkBudgeted::kYes,
-                                              texels.get(),
-                                              mipLevelCount,
-                                              colorMode);
+    return proxyProvider->createMipMapProxy(desc, SkBudgeted::kYes, texels.get(), mipLevelCount,
+                                            colorMode);
 }
 
-sk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrContext* ctx,
-                                                     GrTextureProxy* baseProxy) {
+sk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrContext* ctx, GrTextureProxy* baseProxy) {
     SkASSERT(baseProxy);
 
     if (!ctx->caps()->isConfigCopyable(baseProxy->config())) {
         return nullptr;
     }
 
+    GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
     GrSurfaceDesc desc;
     desc.fFlags = kNone_GrSurfaceFlags;
     desc.fOrigin = baseProxy->origin();
@@ -175,9 +171,7 @@
     desc.fConfig = baseProxy->config();
     desc.fSampleCnt = 0;
 
-    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferredMipMap(ctx->contextPriv().proxyProvider(),
-                                                                     desc,
-                                                                     SkBudgeted::kYes);
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createMipMapProxy(desc, SkBudgeted::kYes);
     if (!proxy) {
         return nullptr;
     }
@@ -191,7 +185,8 @@
 }
 
 
-sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext* ctx, const SkImageInfo& info,
+sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrProxyProvider* proxyProvider,
+                                                   const SkImageInfo& info,
                                                    const GrMipLevel texels[],
                                                    int mipLevelCount,
                                                    SkDestinationSurfaceColorMode colorMode) {
@@ -199,10 +194,10 @@
         return nullptr;
     }
 
-    return GrSurfaceProxy::MakeDeferredMipMap(ctx->contextPriv().proxyProvider(),
-                                              GrImageInfoToSurfaceDesc(info, *ctx->caps()),
-                                              SkBudgeted::kYes, texels,
-                                              mipLevelCount, colorMode);
+    GrSurfaceDesc desc(GrImageInfoToSurfaceDesc(info, *proxyProvider->caps()));
+
+    return proxyProvider->createMipMapProxy(desc, SkBudgeted::kYes,
+                                            texels, mipLevelCount, colorMode);
 }
 
 sk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrContext* ctx,
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index 87b602e..3bf3ba9 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -208,7 +208,7 @@
 sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrProxyProvider*, const SkBitmap&,
                                                    SkColorSpace* dstColorSpace);
 
-sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext*, const SkBitmap&,
+sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrProxyProvider*, const SkBitmap&,
                                                                SkColorSpace* dstColorSpace);
 
 /**
@@ -226,7 +226,7 @@
 /**
  * Creates a new texture populated with the mipmap levels.
  */
-sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext*, const SkImageInfo&,
+sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrProxyProvider*, const SkImageInfo&,
                                                    const GrMipLevel texels[],
                                                    int mipLevelCount,
                                                    SkDestinationSurfaceColorMode colorMode);
diff --git a/src/gpu/effects/GrConfigConversionEffect.h b/src/gpu/effects/GrConfigConversionEffect.h
index 9656c7f..46964f5 100644
--- a/src/gpu/effects/GrConfigConversionEffect.h
+++ b/src/gpu/effects/GrConfigConversionEffect.h
@@ -16,6 +16,7 @@
 #include "GrClip.h"
 #include "GrContext.h"
 #include "GrContextPriv.h"
+#include "GrProxyProvider.h"
 #include "GrRenderTargetContext.h"
 #include "GrFragmentProcessor.h"
 #include "GrCoordTransform.h"
@@ -60,8 +61,8 @@
 
         GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
 
-        sk_sp<GrTextureProxy> dataProxy =
-                GrSurfaceProxy::MakeDeferred(proxyProvider, desc, SkBudgeted::kYes, data, 0);
+        sk_sp<GrTextureProxy> dataProxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
+                                                                            data, 0);
         if (!dataProxy) {
             return false;
         }
diff --git a/src/gpu/effects/GrRectBlurEffect.h b/src/gpu/effects/GrRectBlurEffect.h
index 4f9b971..acc38b3 100644
--- a/src/gpu/effects/GrRectBlurEffect.h
+++ b/src/gpu/effects/GrRectBlurEffect.h
@@ -40,8 +40,8 @@
 
             std::unique_ptr<uint8_t[]> profile(SkBlurMask::ComputeBlurProfile(sigma));
 
-            blurProfile = GrSurfaceProxy::MakeDeferred(proxyProvider, texDesc, SkBudgeted::kYes,
-                                                       profile.get(), 0);
+            blurProfile = proxyProvider->createTextureProxy(texDesc, SkBudgeted::kYes,
+                                                            profile.get(), 0);
             if (!blurProfile) {
                 return nullptr;
             }
diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp
index f39da2a..ab02b6d 100644
--- a/src/gpu/effects/GrTextureStripAtlas.cpp
+++ b/src/gpu/effects/GrTextureStripAtlas.cpp
@@ -218,10 +218,8 @@
         texDesc.fHeight = fDesc.fHeight;
         texDesc.fConfig = fDesc.fConfig;
 
-        proxy = GrSurfaceProxy::MakeDeferred(proxyProvider,
-                                             texDesc, SkBackingFit::kExact,
-                                             SkBudgeted::kYes,
-                                             GrResourceProvider::kNoPendingIO_Flag);
+        proxy = proxyProvider->createProxy(texDesc, SkBackingFit::kExact, SkBudgeted::kYes,
+                                           GrResourceProvider::kNoPendingIO_Flag);
         if (!proxy) {
             return;
         }
diff --git a/src/gpu/ops/GrTextureOp.cpp b/src/gpu/ops/GrTextureOp.cpp
index 6d735f5..6e2e430 100644
--- a/src/gpu/ops/GrTextureOp.cpp
+++ b/src/gpu/ops/GrTextureOp.cpp
@@ -793,6 +793,7 @@
 #if GR_TEST_UTILS
 #include "GrContext.h"
 #include "GrContextPriv.h"
+#include "GrProxyProvider.h"
 
 GR_DRAW_OP_TEST_DEFINE(TextureOp) {
     GrSurfaceDesc desc;
@@ -801,9 +802,10 @@
     desc.fWidth = random->nextULessThan(90) + 10;
     desc.fOrigin = random->nextBool() ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin;
     SkBackingFit fit = random->nextBool() ? SkBackingFit::kApprox : SkBackingFit::kExact;
-    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferred(
-                                              context->contextPriv().proxyProvider(),
-                                              desc, fit, SkBudgeted::kNo);
+
+    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
+    sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(desc, fit, SkBudgeted::kNo);
+
     SkRect rect = GrTest::TestRect(random);
     SkRect srcRect;
     srcRect.fLeft = random->nextRangeScalar(0.f, proxy->width() / 2.f);
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index e70ba05..20e8349 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -19,6 +19,7 @@
 #include "GrContextPriv.h"
 #include "GrGpu.h"
 #include "GrImageTextureMaker.h"
+#include "GrProxyProvider.h"
 #include "GrRenderTargetContext.h"
 #include "GrResourceProvider.h"
 #include "GrSemaphore.h"
@@ -291,10 +292,10 @@
         tex->setRelease(releaseProc, releaseCtx);
     }
 
-    const SkBudgeted budgeted = SkBudgeted::kNo;
     sk_sp<GrTextureProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(tex), origin));
+
     return sk_make_sp<SkImage_Gpu>(ctx, kNeedNewImageUniqueID,
-                                   at, std::move(proxy), std::move(colorSpace), budgeted);
+                                   at, std::move(proxy), std::move(colorSpace), SkBudgeted::kNo);
 }
 
 sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx,
@@ -394,20 +395,22 @@
                                                   const SkISize yuvSizes[],
                                                   GrSurfaceOrigin origin,
                                                   sk_sp<SkColorSpace> imageColorSpace) {
+    GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
+
     if (!are_yuv_sizes_valid(yuvSizes, nv12)) {
         return nullptr;
     }
 
-    sk_sp<GrTextureProxy> yProxy = GrSurfaceProxy::MakeWrappedBackend(ctx, yuvBackendTextures[0],
-                                                                      origin);
-    sk_sp<GrTextureProxy> uProxy = GrSurfaceProxy::MakeWrappedBackend(ctx, yuvBackendTextures[1],
-                                                                      origin);
+    sk_sp<GrTextureProxy> yProxy = proxyProvider->createWrappedTextureProxy(yuvBackendTextures[0],
+                                                                            origin);
+    sk_sp<GrTextureProxy> uProxy = proxyProvider->createWrappedTextureProxy(yuvBackendTextures[1],
+                                                                            origin);
     sk_sp<GrTextureProxy> vProxy;
 
     if (nv12) {
         vProxy = uProxy;
     } else {
-        vProxy = GrSurfaceProxy::MakeWrappedBackend(ctx, yuvBackendTextures[2], origin);
+        vProxy = proxyProvider->createWrappedTextureProxy(yuvBackendTextures[2], origin);
     }
     if (!yProxy || !uProxy || !vProxy) {
         return nullptr;
@@ -605,15 +608,16 @@
         return SkImage::MakeRasterCopy(pixmap);
     }
 
+    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
     // Turn the pixmap into a GrTextureProxy
     sk_sp<GrTextureProxy> proxy;
     if (buildMips) {
         SkBitmap bmp;
         bmp.installPixels(pixmap);
-        proxy = GrGenerateMipMapsAndUploadToTextureProxy(context, bmp, dstColorSpace);
+        proxy = GrGenerateMipMapsAndUploadToTextureProxy(proxyProvider, bmp, dstColorSpace);
     } else {
-        proxy = GrUploadPixmapToTextureProxy(context->contextPriv().proxyProvider(),
-                                             pixmap, SkBudgeted::kYes, dstColorSpace);
+        proxy = GrUploadPixmapToTextureProxy(proxyProvider, pixmap, SkBudgeted::kYes,
+                                             dstColorSpace);
     }
 
     if (!proxy) {
@@ -1089,6 +1093,8 @@
     if (!ctx) {
         return nullptr;
     }
+    GrProxyProvider* proxyProvider = ctx->contextPriv().proxyProvider();
+
     // For images where the client is passing the mip data we require that all the mip levels have
     // valid data.
     for (int i = 0; i < mipLevelCount; ++i) {
@@ -1096,8 +1102,8 @@
             return nullptr;
         }
     }
-    sk_sp<GrTextureProxy> proxy(GrUploadMipMapToTextureProxy(ctx, info, texels, mipLevelCount,
-                                                             colorMode));
+    sk_sp<GrTextureProxy> proxy(GrUploadMipMapToTextureProxy(proxyProvider, info,
+                                                             texels, mipLevelCount, colorMode));
     if (!proxy) {
         return nullptr;
     }
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
index ae4dfd6..53ebc0c 100644
--- a/src/image/SkImage_Lazy.cpp
+++ b/src/image/SkImage_Lazy.cpp
@@ -829,7 +829,7 @@
     SkBitmap bitmap;
     if (!proxy && this->lockAsBitmap(&bitmap, chint, format, genPixelsInfo, behavior)) {
         if (willBeMipped) {
-            proxy = GrGenerateMipMapsAndUploadToTextureProxy(ctx, bitmap, dstColorSpace);
+            proxy = GrGenerateMipMapsAndUploadToTextureProxy(proxyProvider, bitmap, dstColorSpace);
         }
         if (!proxy) {
             proxy = GrUploadBitmapToTextureProxy(proxyProvider, bitmap, dstColorSpace);