Move proxyProvider and singleOwner to GrImageContext

This starts to beef up the capabilities of the GrImageContext in preparation for its future responsibilities (i.e., creating promise images w/o a recordingContext).

Note that the proxyProvider still has different behavior if it has a full context vs. a reduced context. I intend to just let this behavior remain as is.

Change-Id: Idb9d99a548ef928fc1b9dc1e5a34f74343bb0b4b
Reviewed-on: https://skia-review.googlesource.com/c/189490
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 3aeab96..290e959 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -13,7 +13,6 @@
 #include "SkTypes.h"
 #include "../private/GrAuditTrail.h"
 #include "../private/GrRecordingContext.h"
-#include "../private/GrSingleOwner.h"
 #include "GrContextOptions.h"
 
 // We shouldn't need this but currently Android is relying on this being include transitively.
@@ -33,7 +32,6 @@
 struct GrMockOptions;
 class GrOpMemoryPool;
 class GrPath;
-class GrProxyProvider;
 class GrRenderTargetContext;
 class GrResourceCache;
 class GrResourceProvider;
@@ -280,7 +278,9 @@
     void storeVkPipelineCacheData();
 
 protected:
-    GrContext(GrBackendApi, const GrContextOptions& options, int32_t id = SK_InvalidGenID);
+    GrContext(GrBackendApi, const GrContextOptions&, int32_t contextID = SK_InvalidGenID);
+
+    GrContext* asDirectContext() override { return this; }
 
     bool init(sk_sp<const GrCaps>, sk_sp<GrSkSLFPFactoryCache>) override;
 
@@ -297,7 +297,6 @@
     sk_sp<GrGpu>                            fGpu;
     GrResourceCache*                        fResourceCache;
     GrResourceProvider*                     fResourceProvider;
-    GrProxyProvider*                        fProxyProvider;
 
     // All the GrOp-derived classes use this pool.
     sk_sp<GrOpMemoryPool>                   fOpMemoryPool;
@@ -309,11 +308,6 @@
     // true if the PM/UPM conversion succeeded; false otherwise
     bool                                    fPMUPMConversionsRoundTrip;
 
-    // In debug builds we guard against improper thread handling
-    // This guard is passed to the GrDrawingManager and, from there to all the
-    // GrRenderTargetContexts.  It is also passed to the GrResourceProvider and SkGpuDevice.
-    mutable GrSingleOwner                   fSingleOwner;
-
     std::unique_ptr<GrDrawingManager>       fDrawingManager;
 
     GrAuditTrail                            fAuditTrail;
diff --git a/include/private/GrContext_Base.h b/include/private/GrContext_Base.h
index aa22385..bc18ac0 100644
--- a/include/private/GrContext_Base.h
+++ b/include/private/GrContext_Base.h
@@ -35,7 +35,7 @@
 protected:
     friend class GrBaseContextPriv; // for hidden functions
 
-    GrContext_Base(GrBackendApi backend, const GrContextOptions& options, uint32_t uniqueID);
+    GrContext_Base(GrBackendApi backend, const GrContextOptions& options, uint32_t contextID);
 
     /**
      * An identifier for this context. The id is used by all compatible contexts. For example,
@@ -60,7 +60,6 @@
 
     sk_sp<GrSkSLFPFactoryCache> fpFactoryCache();
 
-    GrContext_Base* asBaseContext() { return this; }
     virtual GrImageContext* asImageContext() { return nullptr; }
     virtual GrRecordingContext* asRecordingContext() { return nullptr; }
     virtual GrContext* asDirectContext() { return nullptr; }
diff --git a/include/private/GrImageContext.h b/include/private/GrImageContext.h
index bc2be9a..018479c 100644
--- a/include/private/GrImageContext.h
+++ b/include/private/GrImageContext.h
@@ -9,8 +9,10 @@
 #define GrImageContext_DEFINED
 
 #include "GrContext_Base.h"
+#include "../private/GrSingleOwner.h"
 
 class GrImageContextPriv;
+class GrProxyProvider;
 
 class SK_API GrImageContext : public GrContext_Base {
 public:
@@ -23,11 +25,24 @@
 protected:
     friend class GrImageContextPriv; // for hidden functions
 
-    GrImageContext(GrBackendApi, const GrContextOptions&, uint32_t uniqueID);
+    GrImageContext(GrBackendApi, const GrContextOptions&, uint32_t contextID);
+
+    GrProxyProvider* proxyProvider() { return fProxyProvider.get(); }
+    const GrProxyProvider* proxyProvider() const { return fProxyProvider.get(); }
+
+    /** This is only useful for debug purposes */
+    GrSingleOwner* singleOwner() const { return &fSingleOwner; }
 
     GrImageContext* asImageContext() override { return this; }
 
 private:
+    std::unique_ptr<GrProxyProvider> fProxyProvider;
+
+    // In debug builds we guard against improper thread handling
+    // This guard is passed to the GrDrawingManager and, from there to all the
+    // GrRenderTargetContexts.  It is also passed to the GrResourceProvider and SkGpuDevice.
+    mutable GrSingleOwner           fSingleOwner;
+
     typedef GrContext_Base INHERITED;
 };
 
diff --git a/include/private/GrRecordingContext.h b/include/private/GrRecordingContext.h
index b7e035b..e75c450 100644
--- a/include/private/GrRecordingContext.h
+++ b/include/private/GrRecordingContext.h
@@ -23,7 +23,7 @@
 protected:
     friend class GrRecordingContextPriv; // for hidden functions
 
-    GrRecordingContext(GrBackendApi, const GrContextOptions&, uint32_t uniqueID);
+    GrRecordingContext(GrBackendApi, const GrContextOptions&, uint32_t contextID);
 
     GrRecordingContext* asRecordingContext() override { return this; }
 
diff --git a/src/gpu/GrBaseContextPriv.h b/src/gpu/GrBaseContextPriv.h
index 4857829..61d4a30 100644
--- a/src/gpu/GrBaseContextPriv.h
+++ b/src/gpu/GrBaseContextPriv.h
@@ -23,9 +23,13 @@
     const GrContextOptions& options() const { return fContext->options(); }
 
     const GrCaps* caps() const { return fContext->caps(); }
-    sk_sp<const GrCaps> refCaps() const { return fContext->refCaps(); }
+    sk_sp<const GrCaps> refCaps() const;
 
-    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache() { return fContext->fpFactoryCache(); }
+    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache();
+
+    GrImageContext* asImageContext() { return fContext->asImageContext(); }
+    GrRecordingContext* asRecordingContext() { return fContext->asRecordingContext(); }
+    GrContext* asDirectContext() { return fContext->asDirectContext(); }
 
 private:
     explicit GrBaseContextPriv(GrContext_Base* context) : fContext(context) {}
diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp
index 95f1c84..89a3702 100644
--- a/src/gpu/GrBitmapTextureMaker.cpp
+++ b/src/gpu/GrBitmapTextureMaker.cpp
@@ -61,7 +61,7 @@
                 SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
                 if (fOriginalKey.isValid()) {
                     GrInstallBitmapUniqueKeyInvalidator(
-                            fOriginalKey, proxyProvider->contextUniqueID(), fBitmap.pixelRef());
+                            fOriginalKey, proxyProvider->contextID(), fBitmap.pixelRef());
                 }
                 return proxy;
             }
@@ -86,7 +86,7 @@
                 SkASSERT(proxy->getUniqueKey() == fOriginalKey);
                 proxyProvider->removeUniqueKeyFromProxy(proxy.get());
                 proxyProvider->assignUniqueKeyToProxy(fOriginalKey, mippedProxy.get());
-                GrInstallBitmapUniqueKeyInvalidator(fOriginalKey, proxyProvider->contextUniqueID(),
+                GrInstallBitmapUniqueKeyInvalidator(fOriginalKey, proxyProvider->contextID(),
                                                     fBitmap.pixelRef());
             }
             return mippedProxy;
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 9bf044d..8d7f945 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -38,24 +38,24 @@
 
 #define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
 #define ASSERT_SINGLE_OWNER \
-    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fSingleOwner);)
+    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(this->singleOwner());)
 #define RETURN_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return; }
 #define RETURN_FALSE_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return false; }
 #define RETURN_NULL_IF_ABANDONED if (fDrawingManager->wasAbandoned()) { return nullptr; }
 
 ////////////////////////////////////////////////////////////////////////////////
 
-GrContext::GrContext(GrBackendApi backend, const GrContextOptions& options, int32_t id)
-        : INHERITED(backend, options, id) {
+GrContext::GrContext(GrBackendApi backend, const GrContextOptions& options, int32_t contextID)
+        : INHERITED(backend, options, contextID) {
     fResourceCache = nullptr;
     fResourceProvider = nullptr;
-    fProxyProvider = nullptr;
     fGlyphCache = nullptr;
 }
 
 bool GrContext::init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) {
     ASSERT_SINGLE_OWNER
     SkASSERT(fThreadSafeProxy); // needs to have been initialized by derived classes
+    SkASSERT(this->proxyProvider());
 
     if (!INHERITED::init(std::move(caps), std::move(FPFactoryCache))) {
         return false;
@@ -64,17 +64,13 @@
     SkASSERT(this->caps());
 
     if (fGpu) {
-        fResourceCache = new GrResourceCache(this->caps(), &fSingleOwner, this->contextID());
-        fResourceProvider = new GrResourceProvider(fGpu.get(), fResourceCache, &fSingleOwner,
+        fResourceCache = new GrResourceCache(this->caps(), this->singleOwner(), this->contextID());
+        fResourceProvider = new GrResourceProvider(fGpu.get(), fResourceCache, this->singleOwner(),
                                                    this->options().fExplicitlyAllocateGPUResources);
-        fProxyProvider = new GrProxyProvider(fResourceProvider, fResourceCache,
-                                             this->refCaps(), &fSingleOwner);
-    } else {
-        fProxyProvider = new GrProxyProvider(this->contextID(), this->refCaps(), &fSingleOwner);
     }
 
     if (fResourceCache) {
-        fResourceCache->setProxyProvider(fProxyProvider);
+        fResourceCache->setProxyProvider(this->proxyProvider());
     }
 
     fDidTestPMConversions = false;
@@ -113,7 +109,7 @@
                                             ? fResourceProvider->explicitlyAllocateGPUResources()
                                             : false;
     fDrawingManager.reset(new GrDrawingManager(this, prcOptions, textContextOptions,
-                                               &fSingleOwner, explicitlyAllocatingResources,
+                                               this->singleOwner(), explicitlyAllocatingResources,
                                                this->options().fSortRenderTargets,
                                                this->options().fReduceOpListSplitting));
 
@@ -140,7 +136,6 @@
     }
     delete fResourceProvider;
     delete fResourceCache;
-    delete fProxyProvider;
     delete fGlyphCache;
 }
 
@@ -153,7 +148,7 @@
 void GrContext::abandonContext() {
     ASSERT_SINGLE_OWNER
 
-    fProxyProvider->abandon();
+    this->proxyProvider()->abandon();
     fResourceProvider->abandon();
 
     // Need to abandon the drawing manager first so all the render targets
@@ -182,7 +177,7 @@
     if (this->abandoned()) {
         return;
     }
-    fProxyProvider->abandon();
+    this->proxyProvider()->abandon();
     fResourceProvider->abandon();
 
     // Need to abandon the drawing manager first so all the render targets
@@ -229,7 +224,7 @@
     fResourceCache->purgeResourcesNotUsedSince(purgeTime);
 
     if (auto ccpr = fDrawingManager->getCoverageCountingPathRenderer()) {
-        ccpr->purgeCacheEntriesOlderThan(fProxyProvider, purgeTime);
+        ccpr->purgeCacheEntriesOlderThan(this->proxyProvider(), purgeTime);
     }
 
     fTextBlobCache->purgeStaleBlobs();
diff --git a/src/gpu/GrContextPriv.cpp b/src/gpu/GrContextPriv.cpp
index c12ba76..5dbbe30 100644
--- a/src/gpu/GrContextPriv.cpp
+++ b/src/gpu/GrContextPriv.cpp
@@ -27,10 +27,14 @@
 #define ASSERT_OWNED_PROXY_PRIV(P) \
     SkASSERT(!(P) || !((P)->peekTexture()) || (P)->peekTexture()->getContext() == fContext)
 #define ASSERT_SINGLE_OWNER_PRIV \
-    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(&fContext->fSingleOwner);)
+    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fContext->singleOwner());)
 #define RETURN_IF_ABANDONED_PRIV if (fContext->fDrawingManager->wasAbandoned()) { return; }
 #define RETURN_FALSE_IF_ABANDONED_PRIV if (fContext->fDrawingManager->wasAbandoned()) { return false; }
 
+sk_sp<const GrCaps> GrContextPriv::refCaps() const {
+    return fContext->refCaps();
+}
+
 sk_sp<GrSkSLFPFactoryCache> GrContextPriv::fpFactoryCache() {
     return fContext->fpFactoryCache();
 }
@@ -702,9 +706,9 @@
 
     sk_sp<GrTextureProxy> rtp;
     if (GrMipMapped::kNo == mipMapped) {
-        rtp = fContext->fProxyProvider->createProxy(format, desc, origin, fit, budgeted);
+        rtp = fContext->proxyProvider()->createProxy(format, desc, origin, fit, budgeted);
     } else {
-        rtp = fContext->fProxyProvider->createMipMapProxy(format, desc, origin, budgeted);
+        rtp = fContext->proxyProvider()->createMipMapProxy(format, desc, origin, budgeted);
     }
     if (!rtp) {
         return nullptr;
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index f01ef8b..9db268b 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -37,11 +37,20 @@
     const GrContextOptions& options() const { return fContext->options(); }
 
     const GrCaps* caps() const { return fContext->caps(); }
-    sk_sp<const GrCaps> refCaps() const { return fContext->refCaps(); }
+    sk_sp<const GrCaps> refCaps() const;
 
     sk_sp<GrSkSLFPFactoryCache> fpFactoryCache();
 
+    GrImageContext* asImageContext() { return fContext->asImageContext(); }
+    GrRecordingContext* asRecordingContext() { return fContext->asRecordingContext(); }
+    GrContext* asDirectContext() { return fContext->asDirectContext(); }
+
     // from GrImageContext
+    GrProxyProvider* proxyProvider() { return fContext->proxyProvider(); }
+    const GrProxyProvider* proxyProvider() const { return fContext->proxyProvider(); }
+
+    /** This is only useful for debug purposes */
+    SkDEBUGCODE(GrSingleOwner* singleOwner() const { return fContext->singleOwner(); } )
 
     // from GrRecordingContext
 
@@ -202,9 +211,6 @@
 
     SkTaskGroup* getTaskGroup() { return fContext->fTaskGroup.get(); }
 
-    GrProxyProvider* proxyProvider() { return fContext->fProxyProvider; }
-    const GrProxyProvider* proxyProvider() const { return fContext->fProxyProvider; }
-
     GrResourceProvider* resourceProvider() { return fContext->fResourceProvider; }
     const GrResourceProvider* resourceProvider() const { return fContext->fResourceProvider; }
 
@@ -262,9 +268,6 @@
 
     GrContextOptions::PersistentCache* getPersistentCache() { return fContext->fPersistentCache; }
 
-    /** This is only useful for debug purposes */
-    SkDEBUGCODE(GrSingleOwner* debugSingleOwner() const { return &fContext->fSingleOwner; } )
-
 #ifdef SK_ENABLE_DUMP_GPU
     /** Returns a string with detailed information about the context & GPU, in JSON format. */
     SkString dump() const;
diff --git a/src/gpu/GrContext_Base.cpp b/src/gpu/GrContext_Base.cpp
index 7f71df5..122a281 100644
--- a/src/gpu/GrContext_Base.cpp
+++ b/src/gpu/GrContext_Base.cpp
@@ -7,6 +7,7 @@
 
 #include "GrContext_Base.h"
 
+#include "GrBaseContextPriv.h"
 #include "GrCaps.h"
 #include "GrSkSLFPFactoryCache.h"
 
@@ -42,3 +43,11 @@
     return true;
 }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+sk_sp<const GrCaps> GrBaseContextPriv::refCaps() const {
+    return fContext->refCaps();
+}
+
+sk_sp<GrSkSLFPFactoryCache> GrBaseContextPriv::fpFactoryCache() {
+    return fContext->fpFactoryCache();
+}
diff --git a/src/gpu/GrDDLContext.cpp b/src/gpu/GrDDLContext.cpp
index 6b72e4e..1373e43 100644
--- a/src/gpu/GrDDLContext.cpp
+++ b/src/gpu/GrDDLContext.cpp
@@ -40,6 +40,10 @@
     }
 
 protected:
+    // TODO: Here we're pretending this isn't derived from GrContext. Switch this to be derived from
+    // GrRecordingContext!
+    GrContext* asDirectContext() override { return nullptr; }
+
     bool init(sk_sp<const GrCaps> caps, sk_sp<GrSkSLFPFactoryCache> FPFactoryCache) override {
         SkASSERT(caps && FPFactoryCache);
         SkASSERT(fThreadSafeProxy); // should've been set in the ctor
diff --git a/src/gpu/GrImageContext.cpp b/src/gpu/GrImageContext.cpp
index 6adf700..0d38379 100644
--- a/src/gpu/GrImageContext.cpp
+++ b/src/gpu/GrImageContext.cpp
@@ -7,10 +7,25 @@
 
 #include "GrImageContext.h"
 
+#include "GrCaps.h"
+#include "GrImageContextPriv.h"
+#include "GrProxyProvider.h"
+#include "GrSkSLFPFactoryCache.h"
+
 GrImageContext::GrImageContext(GrBackendApi backend,
                                const GrContextOptions& options,
-                               uint32_t uniqueID)
-            : INHERITED(backend, options, uniqueID) {
+                               uint32_t contextID)
+            : INHERITED(backend, options, contextID) {
+    fProxyProvider.reset(new GrProxyProvider(this));
 }
 
 GrImageContext::~GrImageContext() {}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+sk_sp<const GrCaps> GrImageContextPriv::refCaps() const {
+    return fContext->refCaps();
+}
+
+sk_sp<GrSkSLFPFactoryCache> GrImageContextPriv::fpFactoryCache() {
+    return fContext->fpFactoryCache();
+}
diff --git a/src/gpu/GrImageContextPriv.h b/src/gpu/GrImageContextPriv.h
index 4de9e9a..b499ed7 100644
--- a/src/gpu/GrImageContextPriv.h
+++ b/src/gpu/GrImageContextPriv.h
@@ -23,11 +23,20 @@
     const GrContextOptions& options() const { return fContext->options(); }
 
     const GrCaps* caps() const { return fContext->caps(); }
-    sk_sp<const GrCaps> refCaps() const { return fContext->refCaps(); }
+    sk_sp<const GrCaps> refCaps() const;
 
-    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache() { return fContext->fpFactoryCache(); }
+    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache();
+
+    GrImageContext* asImageContext() { return fContext->asImageContext(); }
+    GrRecordingContext* asRecordingContext() { return fContext->asRecordingContext(); }
+    GrContext* asDirectContext() { return fContext->asDirectContext(); }
 
     // from GrImageContext
+    GrProxyProvider* proxyProvider() { return fContext->proxyProvider(); }
+    const GrProxyProvider* proxyProvider() const { return fContext->proxyProvider(); }
+
+    /** This is only useful for debug purposes */
+    SkDEBUGCODE(GrSingleOwner* singleOwner() const { return fContext->singleOwner(); } )
 
 private:
     explicit GrImageContextPriv(GrImageContext* context) : fContext(context) {}
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 5afd87d..a108569 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -8,6 +8,10 @@
 #include "GrProxyProvider.h"
 
 #include "GrCaps.h"
+#include "GrContext.h"
+#include "GrContextPriv.h"
+#include "GrImageContext.h"
+#include "GrImageContextPriv.h"
 #include "GrRenderTarget.h"
 #include "GrResourceKey.h"
 #include "GrResourceProvider.h"
@@ -28,46 +32,15 @@
 #include "SkTraceEvent.h"
 
 #define ASSERT_SINGLE_OWNER \
-    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fSingleOwner);)
+    SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fImageContext->priv().singleOwner());)
 
-GrProxyProvider::GrProxyProvider(GrResourceProvider* resourceProvider,
-                                 GrResourceCache* resourceCache,
-                                 sk_sp<const GrCaps> caps,
-                                 GrSingleOwner* owner)
-        : fResourceProvider(resourceProvider)
-        , fResourceCache(resourceCache)
-        , fAbandoned(false)
-        , fCaps(caps)
-        , fContextUniqueID(resourceCache->contextUniqueID())
-#ifdef SK_DEBUG
-        , fSingleOwner(owner)
-#endif
-{
-    SkASSERT(fResourceProvider);
-    SkASSERT(fResourceCache);
-    SkASSERT(fCaps);
-    SkASSERT(fSingleOwner);
-}
-
-GrProxyProvider::GrProxyProvider(uint32_t contextUniqueID,
-                                 sk_sp<const GrCaps> caps,
-                                 GrSingleOwner* owner)
-        : fResourceProvider(nullptr)
-        , fResourceCache(nullptr)
-        , fAbandoned(false)
-        , fCaps(caps)
-        , fContextUniqueID(contextUniqueID)
-#ifdef SK_DEBUG
-        , fSingleOwner(owner)
-#endif
-{
-    SkASSERT(fContextUniqueID != SK_InvalidUniqueID);
-    SkASSERT(fCaps);
-    SkASSERT(fSingleOwner);
+GrProxyProvider::GrProxyProvider(GrImageContext* imageContext)
+        : fImageContext(imageContext)
+        , fAbandoned(false) {
 }
 
 GrProxyProvider::~GrProxyProvider() {
-    if (fResourceCache) {
+    if (this->renderingDirectly()) {
         // In DDL-mode a proxy provider can still have extant uniquely keyed proxies (since
         // they need their unique keys to, potentially, find a cached resource when the
         // DDL is played) but, in non-DDL-mode they should all have been cleaned up by this point.
@@ -82,10 +55,18 @@
         return false;
     }
 
-    // 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 || !fResourceCache->findAndRefUniqueResource(key));
+#ifdef SK_DEBUG
+    {
+        GrContext* direct = fImageContext->priv().asDirectContext();
+        if (direct) {
+            GrResourceCache* resourceCache = direct->priv().getResourceCache();
+            // 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(!resourceCache->findAndRefUniqueResource(key));
+        }
+    }
+#endif
 
     SkASSERT(!fUniquelyKeyedProxies.find(key));     // multiple proxies can't get the same key
 
@@ -131,6 +112,37 @@
     return result;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_TEST_UTILS
+sk_sp<GrTextureProxy> GrProxyProvider::testingOnly_createInstantiatedProxy(
+        const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit, SkBudgeted budgeted) {
+    GrContext* direct = fImageContext->priv().asDirectContext();
+    if (!direct) {
+        return nullptr;
+    }
+
+    GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
+    sk_sp<GrTexture> tex;
+
+    if (SkBackingFit::kApprox == fit) {
+        tex = resourceProvider->createApproxTexture(desc, GrResourceProvider::Flags::kNone);
+    } else {
+        tex = resourceProvider->createTexture(desc, budgeted, GrResourceProvider::Flags::kNone);
+    }
+    if (!tex) {
+        return nullptr;
+    }
+
+    return this->createWrapped(std::move(tex), origin);
+}
+
+sk_sp<GrTextureProxy> GrProxyProvider::testingOnly_createWrapped(sk_sp<GrTexture> tex,
+                                                                 GrSurfaceOrigin origin) {
+    return this->createWrapped(std::move(tex), origin);
+}
+#endif
+
 sk_sp<GrTextureProxy> GrProxyProvider::createWrapped(sk_sp<GrTexture> tex, GrSurfaceOrigin origin) {
 #ifdef SK_DEBUG
     if (tex->getUniqueKey().isValid()) {
@@ -158,11 +170,14 @@
         return result;
     }
 
-    if (!fResourceCache) {
+    GrContext* direct = fImageContext->priv().asDirectContext();
+    if (!direct) {
         return nullptr;
     }
 
-    GrGpuResource* resource = fResourceCache->findAndRefUniqueResource(key);
+    GrResourceCache* resourceCache = direct->priv().getResourceCache();
+
+    GrGpuResource* resource = resourceCache->findAndRefUniqueResource(key);
     if (!resource) {
         return nullptr;
     }
@@ -197,7 +212,7 @@
         return nullptr;
     }
 
-    GrBackendFormat format = fCaps->getBackendFormatFromColorType(info.colorType());
+    GrBackendFormat format = this->caps()->getBackendFormatFromColorType(info.colorType());
     if (!format.isValid()) {
         return nullptr;
     }
@@ -221,7 +236,7 @@
     }
 
     if (SkToBool(descFlags & kRenderTarget_GrSurfaceFlag)) {
-        if (fCaps->usesMixedSamples() && sampleCnt > 1) {
+        if (this->caps()->usesMixedSamples() && sampleCnt > 1) {
             surfaceFlags |= GrInternalSurfaceFlags::kMixedSampled;
         }
     }
@@ -257,10 +272,13 @@
         return nullptr;
     }
 
-    if (fResourceProvider) {
+    GrContext* direct = fImageContext->priv().asDirectContext();
+    if (direct) {
+        GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
+
         // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however
         // we're better off instantiating the proxy immediately here.
-        if (!proxy->priv().doLazyInstantiation(fResourceProvider)) {
+        if (!proxy->priv().doLazyInstantiation(resourceProvider)) {
             return nullptr;
         }
     }
@@ -300,8 +318,8 @@
     // In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap
     // even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the
     // upload of the data to the gpu can happen at anytime and the bitmap may change by then.
-    SkCopyPixelsMode copyMode = this->recordingDDL() ? kIfMutable_SkCopyPixelsMode
-                                                     : kNever_SkCopyPixelsMode;
+    SkCopyPixelsMode copyMode = this->renderingDirectly() ? kNever_SkCopyPixelsMode
+                                                          : kIfMutable_SkCopyPixelsMode;
     sk_sp<SkImage> baseLevel = SkMakeImageFromRasterBitmap(bitmap, copyMode);
     if (!baseLevel) {
         return nullptr;
@@ -313,7 +331,8 @@
                                         SkBackingFit::kExact);
     }
 
-    const GrBackendFormat format = fCaps->getBackendFormatFromColorType(bitmap.info().colorType());
+    const GrBackendFormat format =
+                            this->caps()->getBackendFormatFromColorType(bitmap.info().colorType());
     if (!format.isValid()) {
         return nullptr;
     }
@@ -372,10 +391,12 @@
         return nullptr;
     }
 
-    if (fResourceProvider) {
+    GrContext* direct = fImageContext->priv().asDirectContext();
+    if (direct) {
+        GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
         // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however
         // we're better off instantiating the proxy immediately here.
-        if (!proxy->priv().doLazyInstantiation(fResourceProvider)) {
+        if (!proxy->priv().doLazyInstantiation(resourceProvider)) {
             return nullptr;
         }
     }
@@ -424,7 +445,8 @@
     }
 
     const GrColorType ct = GrPixelConfigToColorType(desc.fConfig);
-    const GrBackendFormat format = fCaps->getBackendFormatFromGrColorType(ct, GrSRGBEncoded::kNo);
+    const GrBackendFormat format =
+                            this->caps()->getBackendFormatFromGrColorType(ct, GrSRGBEncoded::kNo);
 
     sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
         [desc, data](GrResourceProvider* resourceProvider) {
@@ -444,10 +466,12 @@
         return nullptr;
     }
 
-    if (fResourceProvider) {
+    GrContext* direct = fImageContext->priv().asDirectContext();
+    if (direct) {
+        GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
         // In order to reuse code we always create a lazy proxy. When we aren't in DDL mode however
         // we're better off instantiating the proxy immediately here.
-        if (!proxy->priv().doLazyInstantiation(fResourceProvider)) {
+        if (!proxy->priv().doLazyInstantiation(resourceProvider)) {
             return nullptr;
         }
     }
@@ -467,12 +491,15 @@
     }
 
     // This is only supported on a direct GrContext.
-    if (!fResourceProvider) {
+    GrContext* direct = fImageContext->priv().asDirectContext();
+    if (!direct) {
         return nullptr;
     }
 
+    GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
+
     sk_sp<GrTexture> tex =
-            fResourceProvider->wrapBackendTexture(backendTex, ownership, cacheable, ioType);
+            resourceProvider->wrapBackendTexture(backendTex, ownership, cacheable, ioType);
     if (!tex) {
         return nullptr;
     }
@@ -500,17 +527,20 @@
     }
 
     // This is only supported on a direct GrContext.
-    if (!fResourceProvider) {
+    GrContext* direct = fImageContext->priv().asDirectContext();
+    if (!direct) {
         return nullptr;
     }
 
+    GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
+
     sampleCnt = this->caps()->getRenderTargetSampleCount(sampleCnt, backendTex.config());
     if (!sampleCnt) {
         return nullptr;
     }
 
-    sk_sp<GrTexture> tex = fResourceProvider->wrapRenderableBackendTexture(backendTex, sampleCnt,
-                                                                           ownership, cacheable);
+    sk_sp<GrTexture> tex = resourceProvider->wrapRenderableBackendTexture(backendTex, sampleCnt,
+                                                                          ownership, cacheable);
     if (!tex) {
         return nullptr;
     }
@@ -537,11 +567,14 @@
     }
 
     // This is only supported on a direct GrContext.
-    if (!fResourceProvider) {
+    GrContext* direct = fImageContext->priv().asDirectContext();
+    if (!direct) {
         return nullptr;
     }
 
-    sk_sp<GrRenderTarget> rt = fResourceProvider->wrapBackendRenderTarget(backendRT);
+    GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
+
+    sk_sp<GrRenderTarget> rt = resourceProvider->wrapBackendRenderTarget(backendRT);
     if (!rt) {
         return nullptr;
     }
@@ -568,12 +601,15 @@
     }
 
     // This is only supported on a direct GrContext.
-    if (!fResourceProvider) {
+    GrContext* direct = fImageContext->priv().asDirectContext();
+    if (!direct) {
         return nullptr;
     }
 
+    GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
+
     sk_sp<GrRenderTarget> rt =
-            fResourceProvider->wrapBackendTextureAsRenderTarget(backendTex, sampleCnt);
+            resourceProvider->wrapBackendTextureAsRenderTarget(backendTex, sampleCnt);
     if (!rt) {
         return nullptr;
     }
@@ -592,16 +628,19 @@
     }
 
     // This is only supported on a direct GrContext.
-    if (!fResourceProvider) {
+    GrContext* direct = fImageContext->priv().asDirectContext();
+    if (!direct) {
         return nullptr;
     }
 
-    sk_sp<GrRenderTarget> rt = fResourceProvider->wrapVulkanSecondaryCBAsRenderTarget(imageInfo,
-                                                                                      vkInfo);
+    GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
 
+    sk_sp<GrRenderTarget> rt = resourceProvider->wrapVulkanSecondaryCBAsRenderTarget(imageInfo,
+                                                                                     vkInfo);
     if (!rt) {
         return nullptr;
     }
+
     SkASSERT(!rt->asTexture());  // A GrRenderTarget that's not textureable
     SkASSERT(!rt->getUniqueKey().isValid());
     // This proxy should be unbudgeted because we're just wrapping an external resource
@@ -634,8 +673,8 @@
                                                        SkBackingFit fit,
                                                        SkBudgeted budgeted) {
     // For non-ddl draws always make lazy proxy's single use.
-    LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse
-                                                       : LazyInstantiationType::kMultipleUse;
+    LazyInstantiationType lazyType = this->renderingDirectly() ? LazyInstantiationType::kSingleUse
+                                                               : LazyInstantiationType::kMultipleUse;
     return this->createLazyProxy(std::move(callback), format, desc, origin, mipMapped, surfaceFlags,
                                  fit, budgeted, lazyType);
 }
@@ -652,7 +691,8 @@
     SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
              (desc.fWidth > 0 && desc.fHeight > 0));
 
-    if (desc.fWidth > fCaps->maxTextureSize() || desc.fHeight > fCaps->maxTextureSize()) {
+    if (desc.fWidth > this->caps()->maxTextureSize() ||
+        desc.fHeight > this->caps()->maxTextureSize()) {
         return nullptr;
     }
 
@@ -660,7 +700,7 @@
 #ifdef SK_DEBUG
     if (SkToBool(kRenderTarget_GrSurfaceFlag & desc.fFlags)) {
         if (SkToBool(surfaceFlags & GrInternalSurfaceFlags::kMixedSampled)) {
-            SkASSERT(fCaps->usesMixedSamples() && desc.fSampleCnt > 1);
+            SkASSERT(this->caps()->usesMixedSamples() && desc.fSampleCnt > 1);
         }
     }
 #endif
@@ -680,7 +720,8 @@
     SkASSERT((desc.fWidth <= 0 && desc.fHeight <= 0) ||
              (desc.fWidth > 0 && desc.fHeight > 0));
 
-    if (desc.fWidth > fCaps->maxRenderTargetSize() || desc.fHeight > fCaps->maxRenderTargetSize()) {
+    if (desc.fWidth > this->caps()->maxRenderTargetSize() ||
+        desc.fHeight > this->caps()->maxRenderTargetSize()) {
         return nullptr;
     }
 
@@ -688,14 +729,14 @@
 
 #ifdef SK_DEBUG
     if (SkToBool(surfaceFlags & GrInternalSurfaceFlags::kMixedSampled)) {
-        SkASSERT(fCaps->usesMixedSamples() && desc.fSampleCnt > 1);
+        SkASSERT(this->caps()->usesMixedSamples() && desc.fSampleCnt > 1);
     }
 #endif
 
     using LazyInstantiationType = GrSurfaceProxy::LazyInstantiationType;
     // For non-ddl draws always make lazy proxy's single use.
-    LazyInstantiationType lazyType = fResourceProvider ? LazyInstantiationType::kSingleUse
-                                                       : LazyInstantiationType::kMultipleUse;
+    LazyInstantiationType lazyType = this->renderingDirectly() ? LazyInstantiationType::kSingleUse
+                                                               : LazyInstantiationType::kMultipleUse;
 
     if (textureInfo) {
         return sk_sp<GrRenderTargetProxy>(new GrTextureRenderTargetProxy(
@@ -762,8 +803,12 @@
         if (proxy && proxy->isInstantiated()) {
             invalidGpuResource = sk_ref_sp(proxy->peekSurface());
         }
-        if (!invalidGpuResource && fResourceProvider) {
-            invalidGpuResource = fResourceProvider->findByUniqueKey<GrGpuResource>(key);
+        if (!invalidGpuResource) {
+            GrContext* direct = fImageContext->priv().asDirectContext();
+            if (direct) {
+                GrResourceProvider* resourceProvider = direct->priv().resourceProvider();
+                invalidGpuResource = resourceProvider->findByUniqueKey<GrGpuResource>(key);
+            }
         }
         SkASSERT(!invalidGpuResource || invalidGpuResource->getUniqueKey() == key);
     }
@@ -780,6 +825,18 @@
     }
 }
 
+uint32_t GrProxyProvider::contextID() const {
+    return fImageContext->priv().contextID();
+}
+
+const GrCaps* GrProxyProvider::caps() const {
+    return fImageContext->priv().caps();
+}
+
+sk_sp<const GrCaps> GrProxyProvider::refCaps() const {
+    return fImageContext->priv().refCaps();
+}
+
 void GrProxyProvider::orphanAllUniqueKeys() {
     UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies);
     for (UniquelyKeyedProxyHash::Iter iter(&fUniquelyKeyedProxies); !iter.done(); ++iter) {
@@ -798,3 +855,7 @@
     }
     SkASSERT(!fUniquelyKeyedProxies.count());
 }
+
+bool GrProxyProvider::renderingDirectly() const {
+    return fImageContext->priv().asDirectContext();
+}
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index f7481e5..385d055 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -8,15 +8,12 @@
 #ifndef GrProxyProvider_DEFINED
 #define GrProxyProvider_DEFINED
 
-#include "GrCaps.h"
 #include "GrResourceKey.h"
 #include "GrTextureProxy.h"
 #include "GrTypes.h"
-#include "SkRefCnt.h"
 #include "SkTDynamicHash.h"
 
-class GrResourceProvider;
-class GrSingleOwner;
+class GrImageContext;
 class GrBackendRenderTarget;
 class SkBitmap;
 class SkImage;
@@ -26,8 +23,7 @@
  */
 class GrProxyProvider {
 public:
-    GrProxyProvider(GrResourceProvider*, GrResourceCache*, sk_sp<const GrCaps>, GrSingleOwner*);
-    GrProxyProvider(uint32_t contextUniqueID, sk_sp<const GrCaps>, GrSingleOwner*);
+    GrProxyProvider(GrImageContext*);
 
     ~GrProxyProvider();
 
@@ -215,24 +211,16 @@
      */
     void processInvalidUniqueKey(const GrUniqueKey&, GrTextureProxy*, InvalidateGPUResource);
 
-    uint32_t contextUniqueID() const { return fContextUniqueID; }
-    const GrCaps* caps() const { return fCaps.get(); }
-    sk_sp<const GrCaps> refCaps() const { return fCaps; }
+    // TODO: remove these entry points - it is a bit sloppy to be getting context info from here
+    uint32_t contextID() const;
+    const GrCaps* caps() const;
+    sk_sp<const GrCaps> refCaps() const;
 
     void abandon() {
-        fResourceCache = nullptr;
-        fResourceProvider = nullptr;
         fAbandoned = true;
     }
 
-    bool isAbandoned() const {
-#ifdef SK_DEBUG
-        if (fAbandoned) {
-            SkASSERT(!fResourceCache && !fResourceProvider);
-        }
-#endif
-        return fAbandoned;
-    }
+    bool isAbandoned() const { return fAbandoned; }
 
     int numUniqueKeyProxies_TestOnly() const;
 
@@ -244,16 +232,19 @@
     void removeAllUniqueKeys();
 
     /**
-     * Are we currently recording a DDL?
+     * Does the proxy provider have access to a GrDirectContext? If so, proxies will be
+     * instantiated immediately.
      */
-    bool recordingDDL() const { return !SkToBool(fResourceProvider); }
+    bool renderingDirectly() const;
 
+#if GR_TEST_UTILS
     /*
      * Create a texture proxy that is backed by an instantiated GrSurface.
      */
     sk_sp<GrTextureProxy> testingOnly_createInstantiatedProxy(const GrSurfaceDesc&, GrSurfaceOrigin,
                                                               SkBackingFit, SkBudgeted);
     sk_sp<GrTextureProxy> testingOnly_createWrapped(sk_sp<GrTexture>, GrSurfaceOrigin);
+#endif
 
 private:
     friend class GrAHardwareBufferImageGenerator; // for createWrapped
@@ -272,15 +263,8 @@
     // on these proxies but they must send a message to the resourceCache when they are deleted.
     UniquelyKeyedProxyHash fUniquelyKeyedProxies;
 
-    GrResourceProvider*    fResourceProvider;
-    GrResourceCache*       fResourceCache;
+    GrImageContext*        fImageContext;
     bool                   fAbandoned;
-    sk_sp<const GrCaps>    fCaps;
-    // If this provider is owned by a DDLContext then this is the DirectContext's ID.
-    uint32_t               fContextUniqueID;
-
-    // In debug builds we guard against improper thread handling
-    SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
 };
 
 #endif
diff --git a/src/gpu/GrRecordingContext.cpp b/src/gpu/GrRecordingContext.cpp
index ca19782..1067950 100644
--- a/src/gpu/GrRecordingContext.cpp
+++ b/src/gpu/GrRecordingContext.cpp
@@ -7,11 +7,23 @@
 
 #include "GrRecordingContext.h"
 
+#include "GrCaps.h"
+#include "GrRecordingContextPriv.h"
+#include "GrSkSLFPFactoryCache.h"
+
 GrRecordingContext::GrRecordingContext(GrBackendApi backend,
                                        const GrContextOptions& options,
-                                       uint32_t uniqueID)
-        : INHERITED(backend, options, uniqueID) {
+                                       uint32_t contextID)
+        : INHERITED(backend, options, contextID) {
 }
 
 GrRecordingContext::~GrRecordingContext() { }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+sk_sp<const GrCaps> GrRecordingContextPriv::refCaps() const {
+    return fContext->refCaps();
+}
+
+sk_sp<GrSkSLFPFactoryCache> GrRecordingContextPriv::fpFactoryCache() {
+    return fContext->fpFactoryCache();
+}
diff --git a/src/gpu/GrRecordingContextPriv.h b/src/gpu/GrRecordingContextPriv.h
index 9233789..92eadb0 100644
--- a/src/gpu/GrRecordingContextPriv.h
+++ b/src/gpu/GrRecordingContextPriv.h
@@ -23,11 +23,20 @@
     const GrContextOptions& options() const { return fContext->options(); }
 
     const GrCaps* caps() const { return fContext->caps(); }
-    sk_sp<const GrCaps> refCaps() const { return fContext->refCaps(); }
+    sk_sp<const GrCaps> refCaps() const;
 
-    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache(); // { return fContext->getFPFactoryCache(); }
+    sk_sp<GrSkSLFPFactoryCache> fpFactoryCache();
+
+    GrImageContext* asImageContext() { return fContext->asImageContext(); }
+    GrRecordingContext* asRecordingContext() { return fContext->asRecordingContext(); }
+    GrContext* asDirectContext() { return fContext->asDirectContext(); }
 
     // from GrImageContext
+    GrProxyProvider* proxyProvider() { return fContext->proxyProvider(); }
+    const GrProxyProvider* proxyProvider() const { return fContext->proxyProvider(); }
+
+    /** This is only useful for debug purposes */
+    SkDEBUGCODE(GrSingleOwner* singleOwner() const { return fContext->singleOwner(); } )
 
     // from GrRecordingContext
 
diff --git a/src/gpu/GrTextureAdjuster.cpp b/src/gpu/GrTextureAdjuster.cpp
index 1544398..8295998 100644
--- a/src/gpu/GrTextureAdjuster.cpp
+++ b/src/gpu/GrTextureAdjuster.cpp
@@ -66,7 +66,7 @@
                 proxyProvider->removeUniqueKeyFromProxy(cachedCopy.get());
             }
             proxyProvider->assignUniqueKeyToProxy(key, copy.get());
-            this->didCacheCopy(key, proxyProvider->contextUniqueID());
+            this->didCacheCopy(key, proxyProvider->contextID());
         }
     }
     return copy;
diff --git a/src/gpu/GrTextureMaker.cpp b/src/gpu/GrTextureMaker.cpp
index afbfbf0..bf71a70 100644
--- a/src/gpu/GrTextureMaker.cpp
+++ b/src/gpu/GrTextureMaker.cpp
@@ -98,7 +98,7 @@
             proxyProvider->removeUniqueKeyFromProxy(cachedProxy.get());
         }
         proxyProvider->assignUniqueKeyToProxy(copyKey, result.get());
-        this->didCacheCopy(copyKey, proxyProvider->contextUniqueID());
+        this->didCacheCopy(copyKey, proxyProvider->contextID());
     }
     return result;
 }
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index dc7aeea..0a745ca 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -56,7 +56,7 @@
 #include "text/GrTextTarget.h"
 
 #define ASSERT_SINGLE_OWNER \
-SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fContext->priv().debugSingleOwner());)
+SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fContext->priv().singleOwner());)
 
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index fffbe42..dd18074 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -119,8 +119,8 @@
     // In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap
     // even if it's mutable. In ddl, if the bitmap is mutable then we must make a copy since the
     // upload of the data to the gpu can happen at anytime and the bitmap may change by then.
-    SkCopyPixelsMode cpyMode = proxyProvider->recordingDDL() ? kIfMutable_SkCopyPixelsMode
-                                                             : kNever_SkCopyPixelsMode;
+    SkCopyPixelsMode cpyMode = proxyProvider->renderingDirectly() ? kNever_SkCopyPixelsMode
+                                                                  : kIfMutable_SkCopyPixelsMode;
     sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, cpyMode);
 
     return proxyProvider->createTextureProxy(std::move(image), kNone_GrSurfaceFlags, 1,
@@ -196,8 +196,8 @@
     // In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap
     // even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the
     // upload of the data to the gpu can happen at anytime and the bitmap may change by then.
-    SkCopyPixelsMode cpyMode = proxyProvider->recordingDDL() ? kIfMutable_SkCopyPixelsMode
-                                                             : kNever_SkCopyPixelsMode;
+    SkCopyPixelsMode cpyMode = proxyProvider->renderingDirectly() ? kNever_SkCopyPixelsMode
+                                                                  : kIfMutable_SkCopyPixelsMode;
     sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, cpyMode);
 
     if (!image) {
@@ -244,8 +244,8 @@
             const SkBitmap* bm = as_IB(srcImage.get())->onPeekBitmap();
             // When recording DDLs we do not want to install change listeners because doing
             // so isn't threadsafe.
-            if (bm && !proxyProvider->recordingDDL()) {
-                GrInstallBitmapUniqueKeyInvalidator(originalKey, proxyProvider->contextUniqueID(),
+            if (bm && proxyProvider->renderingDirectly()) {
+                GrInstallBitmapUniqueKeyInvalidator(originalKey, proxyProvider->contextID(),
                                                     bm->pixelRef());
             }
         }
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index aadf734..b2bad56 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -221,7 +221,7 @@
 
 /** Call this after installing a GrUniqueKey on texture. It will cause the texture's key to be
     removed should the bitmap's contents change or be destroyed. */
-void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, uint32_t contextUniqueID,
+void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, uint32_t contextID,
                                          SkPixelRef* pixelRef);
 
 #endif
diff --git a/src/gpu/effects/GrRectBlurEffect.fp b/src/gpu/effects/GrRectBlurEffect.fp
index 5fda20c..50f833c 100644
--- a/src/gpu/effects/GrRectBlurEffect.fp
+++ b/src/gpu/effects/GrRectBlurEffect.fp
@@ -7,6 +7,7 @@
 
 @header {
     #include "GrProxyProvider.h"
+    #include "GrShaderCaps.h"
     #include "SkBlurMask.h"
     #include "SkScalar.h"
 }
diff --git a/src/gpu/effects/GrRectBlurEffect.h b/src/gpu/effects/GrRectBlurEffect.h
index bad6be1..017bbbe 100644
--- a/src/gpu/effects/GrRectBlurEffect.h
+++ b/src/gpu/effects/GrRectBlurEffect.h
@@ -13,6 +13,7 @@
 #include "SkTypes.h"
 
 #include "GrProxyProvider.h"
+#include "GrShaderCaps.h"
 #include "SkBlurMask.h"
 #include "SkScalar.h"
 #include "GrFragmentProcessor.h"
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index 7a0cbfe..a4e621c 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -65,29 +65,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-sk_sp<GrTextureProxy> GrProxyProvider::testingOnly_createInstantiatedProxy(
-        const GrSurfaceDesc& desc, GrSurfaceOrigin origin, SkBackingFit fit, SkBudgeted budgeted) {
-    sk_sp<GrTexture> tex;
-
-    if (SkBackingFit::kApprox == fit) {
-        tex = fResourceProvider->createApproxTexture(desc, GrResourceProvider::Flags::kNone);
-    } else {
-        tex = fResourceProvider->createTexture(desc, budgeted, GrResourceProvider::Flags::kNone);
-    }
-    if (!tex) {
-        return nullptr;
-    }
-
-    return this->createWrapped(std::move(tex), origin);
-}
-
-sk_sp<GrTextureProxy> GrProxyProvider::testingOnly_createWrapped(sk_sp<GrTexture> tex,
-                                                                 GrSurfaceOrigin origin) {
-    return this->createWrapped(std::move(tex), origin);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
 #define ASSERT_SINGLE_OWNER \
     SkDEBUGCODE(GrSingleOwner::AutoEnforce debug_SingleOwner(fRenderTargetContext->singleOwner());)