Make GrDrawContext be GrRenderTargetProxy-backed

This is split out of https://codereview.chromium.org/2215323003/ (Start using RenderTargetProxy (omnibus))

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3841

CQ_INCLUDE_TRYBOTS=master.client.skia.android:Test-Android-Clang-Nexus5-GPU-Adreno330-arm-Debug-GN_Android-Trybot

Change-Id: I1a47f19ed1ac0c249e6ccac8db74095d7f456db4
Reviewed-on: https://skia-review.googlesource.com/3841
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index 4c66ac0..30003cd 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -195,6 +195,16 @@
                                                  const SkSurfaceProps* surfaceProps = nullptr,
                                                  SkBudgeted = SkBudgeted::kYes);
 
+    // Create a new draw context as above but have it backed by a deferred-style 
+    // GrRenderTargetProxy rather than one that is backed by an actual GrRenderTarget
+    sk_sp<GrRenderTargetContext> makeDeferredRenderTargetContext(SkBackingFit fit, 
+                                                 int width, int height,
+                                                 GrPixelConfig config,
+                                                 sk_sp<SkColorSpace> colorSpace,
+                                                 int sampleCnt = 0,
+                                                 GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin,
+                                                 const SkSurfaceProps* surfaceProps = nullptr,
+                                                 SkBudgeted = SkBudgeted::kYes);
     /*
      * This method will attempt to create a renderTargetContext that has, at least, the number of
      * channels and precision per channel as requested in 'config' (e.g., A8 and 888 can be
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index 445846f..dcbe8ea 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -143,6 +143,7 @@
     virtual bool completeStencilAttachment() = 0;
 
     friend class GrRenderTargetPriv;
+    friend class GrRenderTargetProxy; // for Flags
 
     GrStencilAttachment*  fStencilAttachment;
     uint8_t               fMultisampleSpecsID;
diff --git a/include/gpu/GrRenderTargetContext.h b/include/gpu/GrRenderTargetContext.h
index d1dc0c4..f728ef1 100644
--- a/include/gpu/GrRenderTargetContext.h
+++ b/include/gpu/GrRenderTargetContext.h
@@ -16,6 +16,7 @@
 #include "SkRegion.h"
 #include "SkSurfaceProps.h"
 #include "../private/GrInstancedPipelineInfo.h"
+#include "../private/GrRenderTargetProxy.h"
 #include "../private/GrSingleOwner.h"
 
 class GrAuditTrail;
@@ -314,21 +315,21 @@
                      int x, int y);
 
     bool isStencilBufferMultisampled() const {
-        return fRenderTarget->isStencilBufferMultisampled();
+        return fRenderTargetProxy->isStencilBufferMultisampled();
     }
-    bool isUnifiedMultisampled() const { return fRenderTarget->isUnifiedMultisampled(); }
-    bool hasMixedSamples() const { return fRenderTarget->isMixedSampled(); }
+    bool isUnifiedMultisampled() const { return fRenderTargetProxy->isUnifiedMultisampled(); }
+    bool hasMixedSamples() const { return fRenderTargetProxy->isMixedSampled(); }
 
     bool mustUseHWAA(const GrPaint& paint) const {
-        return paint.isAntiAlias() && fRenderTarget->isUnifiedMultisampled();
+        return paint.isAntiAlias() && fRenderTargetProxy->isUnifiedMultisampled();
     }
 
     const GrCaps* caps() const { return fContext->caps(); }
-    const GrSurfaceDesc& desc() const { return fRenderTarget->desc(); }
-    int width() const { return fRenderTarget->width(); }
-    int height() const { return fRenderTarget->height(); }
-    GrPixelConfig config() const { return fRenderTarget->config(); }
-    int numColorSamples() const { return fRenderTarget->numColorSamples(); }
+    const GrSurfaceDesc& desc() const { return fRenderTargetProxy->desc(); }
+    int width() const { return fRenderTargetProxy->width(); }
+    int height() const { return fRenderTargetProxy->height(); }
+    GrPixelConfig config() const { return fRenderTargetProxy->config(); }
+    int numColorSamples() const { return fRenderTargetProxy->numColorSamples(); }
     bool isGammaCorrect() const { return SkToBool(fColorSpace.get()); }
     SkSourceGammaTreatment sourceGammaTreatment() const {
         return this->isGammaCorrect() ? SkSourceGammaTreatment::kRespect
@@ -337,13 +338,23 @@
     const SkSurfaceProps& surfaceProps() const { return fSurfaceProps; }
     SkColorSpace* getColorSpace() const { return fColorSpace.get(); }
     GrColorSpaceXform* getColorXformFromSRGB() const { return fColorXformFromSRGB.get(); }
-    GrSurfaceOrigin origin() const { return fRenderTarget->origin(); }
+    GrSurfaceOrigin origin() const { return fRenderTargetProxy->origin(); }
 
     bool wasAbandoned() const;
 
-    GrRenderTarget* accessRenderTarget() { return fRenderTarget.get(); }
+    GrRenderTarget* accessRenderTarget() {
+        // TODO: usage of this entry point needs to be reduced and potentially eliminated
+        // since it ends the deferral of the GrRenderTarget's allocation
+        return fRenderTargetProxy->instantiate(fContext->textureProvider());
+    }
 
-    sk_sp<GrTexture> asTexture() { return sk_ref_sp(fRenderTarget->asTexture()); }
+    sk_sp<GrTexture> asTexture() {
+        // TODO: usage of this entry point needs to be reduced and potentially eliminated
+        // since it ends the deferral of the GrRenderTarget's allocation
+        // It's usage should migrate to the soon-to-be-added asDeferredTexture which
+        // returns a GrTextureProxy
+        return sk_ref_sp(this->accessRenderTarget()->asTexture());
+    }
 
     // Provides access to functions that aren't part of the public API.
     GrRenderTargetContextPriv priv();
@@ -352,8 +363,9 @@
     GrAuditTrail* auditTrail() { return fAuditTrail; }
 
 protected:
-    GrRenderTargetContext(GrContext*, GrDrawingManager*, sk_sp<GrRenderTarget>, sk_sp<SkColorSpace>,
-                          const SkSurfaceProps* surfaceProps, GrAuditTrail*, GrSingleOwner*);
+    GrRenderTargetContext(GrContext*, GrDrawingManager*, sk_sp<GrRenderTargetProxy>,
+                          sk_sp<SkColorSpace>, const SkSurfaceProps* surfaceProps, GrAuditTrail*,
+                          GrSingleOwner*);
 
     GrDrawingManager* drawingManager() { return fDrawingManager; }
 
@@ -418,7 +430,7 @@
     GrRenderTargetOpList* getOpList();
 
     GrDrawingManager*                 fDrawingManager;
-    sk_sp<GrRenderTarget>             fRenderTarget;
+    sk_sp<GrRenderTargetProxy>        fRenderTargetProxy;
 
     // In MDB-mode the GrOpList can be closed by some other renderTargetContext that has picked
     // it up. For this reason, the GrOpList should only ever be accessed via 'getOpList'.
diff --git a/include/private/GrInstancedPipelineInfo.h b/include/private/GrInstancedPipelineInfo.h
index 7e6482d..6f9c779 100644
--- a/include/private/GrInstancedPipelineInfo.h
+++ b/include/private/GrInstancedPipelineInfo.h
@@ -8,20 +8,20 @@
 #ifndef GrGrInstancedPipelineInfo_DEFINED
 #define GrGrInstancedPipelineInfo_DEFINED
 
-#include "GrRenderTarget.h"
+#include "GrRenderTargetProxy.h"
 
 /**
  * Provides info about the pipeline that GrInstancedRendering needs in order to select appropriate
  * drawing algorithms.
  */
 struct GrInstancedPipelineInfo {
-    GrInstancedPipelineInfo(const GrRenderTarget* rt)
-        : fIsMultisampled(rt->isStencilBufferMultisampled()),
-          fIsMixedSampled(rt->isMixedSampled()),
-          fIsRenderingToFloat(GrPixelConfigIsFloatingPoint(rt->desc().fConfig)),
-          fColorDisabled(false),
-          fDrawingShapeToStencil(false),
-          fCanDiscard(false) {
+    GrInstancedPipelineInfo(const GrRenderTargetProxy* rtp)
+        : fIsMultisampled(rtp->isStencilBufferMultisampled())
+        , fIsMixedSampled(rtp->isMixedSampled())
+        , fIsRenderingToFloat(GrPixelConfigIsFloatingPoint(rtp->desc().fConfig))
+        , fColorDisabled(false)
+        , fDrawingShapeToStencil(false)
+        , fCanDiscard(false) {
     }
 
     bool canUseCoverageAA() const {
diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h
index 59fed59..7d36bf6 100644
--- a/include/private/GrRenderTargetProxy.h
+++ b/include/private/GrRenderTargetProxy.h
@@ -9,7 +9,6 @@
 #define GrRenderTargetProxy_DEFINED
 
 #include "GrRenderTarget.h"
-#include "GrRenderTargetPriv.h"
 #include "GrSurfaceProxy.h"
 #include "GrTypes.h"
 
@@ -41,7 +40,7 @@
      * For our purposes, "Mixed Sampled" means the stencil buffer is multisampled but the color
      * buffer is not.
      */
-    bool isMixedSampled() const { return fFlags & GrRenderTargetPriv::Flags::kMixedSampled; }
+    bool isMixedSampled() const { return fFlags & GrRenderTarget::Flags::kMixedSampled; }
 
     /**
      * "Unified Sampled" means the stencil and color buffers are both multisampled.
@@ -58,7 +57,13 @@
      */
     int numColorSamples() const { return this->isMixedSampled() ? 0 : fDesc.fSampleCnt; }
 
-    GrRenderTargetPriv::Flags testingOnly_getFlags() const;
+    GrRenderTarget::Flags testingOnly_getFlags() const;
+
+    GrRenderTargetOpList* getLastRenderTargetOpList() {
+        return (GrRenderTargetOpList*) this->getLastOpList();
+    }
+
+    SkDEBUGCODE(void validate(GrContext*) const;)
 
 private:
     // Deferred version
@@ -67,16 +72,16 @@
     // Wrapped version
     GrRenderTargetProxy(const GrCaps&, sk_sp<GrRenderTarget> rt);
 
-    // For wrapped render targets we store it here.
-    // For deferred proxies we will fill this in when we need to instantiate the deferred resource
-    sk_sp<GrRenderTarget>       fTarget;
+    // For wrapped render targets the actual GrRenderTarget is stored in the GrIORefProxy class.
+    // For deferred proxies that pointer is filled in when we need to instantiate the
+    // deferred resource.
 
     // These don't usually get computed until the render target is instantiated, but the render
     // target proxy may need to answer queries about it before then. And since in the deferred case
     // we know the newly created render target will be internal, we are able to precompute what the
     // flags will ultimately end up being. In the wrapped case we just copy the wrapped
     // rendertarget's info here.
-    GrRenderTargetPriv::Flags   fFlags;
+    GrRenderTarget::Flags   fFlags;
 
     typedef GrSurfaceProxy INHERITED;
 };
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index 79d3450..d57c2f5 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -9,13 +9,70 @@
 #define GrSurfaceProxy_DEFINED
 
 #include "GrGpuResource.h"
+#include "GrSurface.h"
 #include "SkRect.h"
 
 class GrOpList;
 class GrTextureProxy;
 class GrRenderTargetProxy;
 
-class GrSurfaceProxy : public GrIORef<GrSurfaceProxy> {
+// This class replicates the functionality GrIORef<GrSurface> but tracks the
+// utilitization for later resource allocation (for the deferred case) and
+// forwards on the utilization in the wrapped case
+class GrIORefProxy : public SkNoncopyable {
+public:
+    void ref() const {
+        this->validate();
+
+        ++fRefCnt;
+        if (fTarget) {
+            fTarget->ref();
+        }
+    }
+
+    void unref() const {
+        this->validate();
+
+        if (fTarget) {
+            fTarget->unref();
+        }
+
+        if (!(--fRefCnt)) {
+            delete this;
+            return;
+        }
+
+        this->validate();
+    }
+
+    void validate() const {
+#ifdef SK_DEBUG    
+        SkASSERT(fRefCnt >= 0);
+#endif
+    }
+
+protected:
+    GrIORefProxy() : fRefCnt(1), fTarget(nullptr) {}
+    GrIORefProxy(sk_sp<GrSurface> surface) : fRefCnt(1) {
+        // Since we're manually forwarding on refs & unrefs we don't want sk_sp doing
+        // anything extra.
+        fTarget = surface.release();
+    }
+    virtual ~GrIORefProxy() {
+        // We don't unref 'fTarget' here since the 'unref' method will already
+        // have forwarded on the unref call that got use here.
+    }
+
+    // TODO: add the IO ref counts. Although if we can delay shader creation to flush time
+    // we may not even need to do that.
+    mutable int32_t fRefCnt;
+
+    // For deferred proxies this will be null. For wrapped proxies it will point to the
+    // wrapped resource.
+    GrSurface* fTarget;
+};
+
+class GrSurfaceProxy : public GrIORefProxy {
 public:
     const GrSurfaceDesc& desc() const { return fDesc; }
 
@@ -25,7 +82,7 @@
         return fDesc.fOrigin;
     }
     int width() const { return fDesc.fWidth; }
-    int height() const { return fDesc.fWidth; }
+    int height() const { return fDesc.fHeight; }
     GrPixelConfig config() const { return fDesc.fConfig; }
 
     uint32_t uniqueID() const { return fUniqueID; }
@@ -66,18 +123,10 @@
     }
 
     // Wrapped version
-    GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, 
-                   SkBudgeted budgeted, uint32_t uniqueID)
-        : fDesc(desc)
-        , fFit(fit)
-        , fBudgeted(budgeted)
-        , fUniqueID(uniqueID)
-        , fLastOpList(nullptr) {
-    }
+    GrSurfaceProxy(sk_sp<GrSurface> surface, SkBackingFit fit);
 
     virtual ~GrSurfaceProxy();
 
-
     // For wrapped resources, 'fDesc' will always be filled in from the wrapped resource.
     const GrSurfaceDesc fDesc;
     const SkBackingFit  fFit;      // always exact for wrapped resources
@@ -85,11 +134,6 @@
     const uint32_t      fUniqueID; // set from the backing resource for wrapped resources
 
 private:
-
-    // See comment in GrGpuResource.h.
-    void notifyAllCntsAreZero(CntType) const { delete this; }
-    bool notifyRefCountIsZero() const { return true; }
-
     // The last opList that wrote to or is currently going to write to this surface
     // The opList can be closed (e.g., no render target context is currently bound
     // to this renderTarget).
@@ -98,10 +142,7 @@
     // and the opList of a destination surface to which this one is being drawn or copied.
     GrOpList* fLastOpList;
 
-    typedef GrIORef<GrSurfaceProxy> INHERITED;
-
-    // to access notifyAllCntsAreZero and notifyRefCntIsZero.
-    friend class GrIORef<GrSurfaceProxy>;
+    typedef GrIORefProxy INHERITED;
 };
 
 #endif
diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h
index 63cb3c8..5b4eeef 100644
--- a/include/private/GrTextureProxy.h
+++ b/include/private/GrTextureProxy.h
@@ -36,9 +36,9 @@
     // Wrapped version
     GrTextureProxy(sk_sp<GrTexture> tex);
 
-    // For wrapped textures we store it here.
-    // For deferred proxies we will fill this in when we need to instantiate the deferred resource
-    sk_sp<GrTexture> fTexture;
+    // For wrapped proxies the GrTexture pointer is stored in GrIORefProxy.
+    // For deferred proxies that pointer will be filled n when we need to instantiate
+    // the deferred resource
 
     typedef GrSurfaceProxy INHERITED;
 };
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index d442b19..53ec06c 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -12,6 +12,7 @@
 #include "GrRenderTargetContext.h"
 #include "GrResourceCache.h"
 #include "GrResourceProvider.h"
+#include "GrRenderTargetProxy.h"
 #include "GrSoftwarePathRenderer.h"
 #include "GrSurfacePriv.h"
 
@@ -607,7 +608,11 @@
                                                                sk_sp<SkColorSpace> colorSpace,
                                                                const SkSurfaceProps* surfaceProps) {
     ASSERT_SINGLE_OWNER_PRIV
-    return this->drawingManager()->makeRenderTargetContext(std::move(rt), std::move(colorSpace),
+
+    sk_sp<GrRenderTargetProxy> rtp(GrRenderTargetProxy::Make(*fContext->caps(), std::move(rt)));
+
+    return this->drawingManager()->makeRenderTargetContext(std::move(rtp),
+                                                           std::move(colorSpace),
                                                            surfaceProps);
 }
 
@@ -624,7 +629,10 @@
         return nullptr;
     }
 
-    return this->drawingManager()->makeRenderTargetContext(sk_ref_sp(surface->asRenderTarget()),
+    sk_sp<GrRenderTargetProxy> rtp(GrRenderTargetProxy::Make(*fContext->caps(),
+                                                            sk_ref_sp(surface->asRenderTarget())));
+
+    return this->drawingManager()->makeRenderTargetContext(std::move(rtp),
                                                            std::move(colorSpace), props);
 }
 
@@ -639,7 +647,10 @@
         return nullptr;
     }
 
-    return this->drawingManager()->makeRenderTargetContext(std::move(rt), std::move(colorSpace),
+    sk_sp<GrRenderTargetProxy> rtp(GrRenderTargetProxy::Make(*fContext->caps(), std::move(rt)));
+
+    return this->drawingManager()->makeRenderTargetContext(std::move(rtp),
+                                                           std::move(colorSpace),
                                                            surfaceProps);
 }
 
@@ -655,8 +666,12 @@
         return nullptr;
     }
 
-    return this->drawingManager()->makeRenderTargetContext(sk_ref_sp(surface->asRenderTarget()),
-                                                           std::move(colorSpace), surfaceProps);
+    sk_sp<GrRenderTargetProxy> rtp(GrRenderTargetProxy::Make(*fContext->caps(),
+                                                             sk_ref_sp(surface->asRenderTarget())));
+
+    return this->drawingManager()->makeRenderTargetContext(std::move(rtp),
+                                                           std::move(colorSpace),
+                                                           surfaceProps);
 }
 
 static inline GrPixelConfig GrPixelConfigFallback(GrPixelConfig config) {
@@ -756,6 +771,30 @@
     return renderTargetContext;
 }
 
+sk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContext(
+                                                        SkBackingFit fit,
+                                                        int width, int height,
+                                                        GrPixelConfig config,
+                                                        sk_sp<SkColorSpace> colorSpace,
+                                                        int sampleCnt,
+                                                        GrSurfaceOrigin origin,
+                                                        const SkSurfaceProps* surfaceProps,
+                                                        SkBudgeted budgeted) {
+    GrSurfaceDesc desc;
+    desc.fFlags = kRenderTarget_GrSurfaceFlag;
+    desc.fOrigin = origin;
+    desc.fWidth = width;
+    desc.fHeight = height;
+    desc.fConfig = config;
+    desc.fSampleCnt = sampleCnt;
+
+    sk_sp<GrRenderTargetProxy> rtp = GrRenderTargetProxy::Make(*this->caps(), desc, fit, budgeted);
+
+    return fDrawingManager->makeRenderTargetContext(std::move(rtp),
+                                                    std::move(colorSpace),
+                                                    surfaceProps);
+}
+
 bool GrContext::abandoned() const {
     ASSERT_SINGLE_OWNER
     return fDrawingManager->wasAbandoned();
diff --git a/src/gpu/GrDrawingManager.cpp b/src/gpu/GrDrawingManager.cpp
index 0198f2f..af6a511 100644
--- a/src/gpu/GrDrawingManager.cpp
+++ b/src/gpu/GrDrawingManager.cpp
@@ -10,6 +10,7 @@
 #include "GrContext.h"
 #include "GrRenderTargetContext.h"
 #include "GrPathRenderingRenderTargetContext.h"
+#include "GrRenderTargetProxy.h"
 #include "GrResourceProvider.h"
 #include "GrSoftwarePathRenderer.h"
 #include "GrSurfacePriv.h"
@@ -142,7 +143,7 @@
     }
 }
 
-GrRenderTargetOpList* GrDrawingManager::newOpList(GrRenderTarget* rt) {
+GrRenderTargetOpList* GrDrawingManager::newOpList(GrRenderTargetProxy* rtp) {
     SkASSERT(fContext);
 
 #ifndef ENABLE_MDB
@@ -151,7 +152,7 @@
         SkASSERT(fOpLists.count() == 1);
         // In the non-MDB-world the same GrOpList gets reused for multiple render targets.
         // Update this pointer so all the asserts are happy
-        rt->setLastOpList(fOpLists[0]);
+        rtp->setLastOpList(fOpLists[0]);
         // DrawingManager gets the creation ref - this ref is for the caller
 
         // TODO: although this is true right now it isn't cool
@@ -159,7 +160,7 @@
     }
 #endif
 
-    GrRenderTargetOpList* opList = new GrRenderTargetOpList(rt,
+    GrRenderTargetOpList* opList = new GrRenderTargetOpList(rtp,
                                                             fContext->getGpu(),
                                                             fContext->resourceProvider(),
                                                             fContext->getAuditTrail(),
@@ -208,9 +209,9 @@
 }
 
 sk_sp<GrRenderTargetContext> GrDrawingManager::makeRenderTargetContext(
-                                                               sk_sp<GrRenderTarget> rt,
-                                                               sk_sp<SkColorSpace> colorSpace,
-                                                               const SkSurfaceProps* surfaceProps) {
+                                                            sk_sp<GrRenderTargetProxy> rtp,
+                                                            sk_sp<SkColorSpace> colorSpace,
+                                                            const SkSurfaceProps* surfaceProps) {
     if (this->wasAbandoned()) {
         return nullptr;
     }
@@ -218,7 +219,7 @@
     // SkSurface catches bad color space usage at creation. This check handles anything that slips
     // by, including internal usage. We allow a null color space here, for read/write pixels and
     // other special code paths. If a color space is provided, though, enforce all other rules.
-    if (colorSpace && !SkSurface_Gpu::Valid(fContext, rt->config(), colorSpace.get())) {
+    if (colorSpace && !SkSurface_Gpu::Valid(fContext, rtp->config(), colorSpace.get())) {
         SkDEBUGFAIL("Invalid config and colorspace combination");
         return nullptr;
     }
@@ -229,17 +230,19 @@
     }
 
     if (useDIF && fContext->caps()->shaderCaps()->pathRenderingSupport() &&
-        rt->isStencilBufferMultisampled()) {
+        rtp->isStencilBufferMultisampled()) {
+        // TODO: defer stencil buffer attachment for PathRenderingDrawContext
+        sk_sp<GrRenderTarget> rt(sk_ref_sp(rtp->instantiate(fContext->textureProvider())));
         GrStencilAttachment* sb = fContext->resourceProvider()->attachStencilAttachment(rt.get());
         if (sb) {
             return sk_sp<GrRenderTargetContext>(new GrPathRenderingRenderTargetContext(
-                                                        fContext, this, std::move(rt),
+                                                        fContext, this, std::move(rtp),
                                                         std::move(colorSpace), surfaceProps,
                                                         fContext->getAuditTrail(), fSingleOwner));
         }
     }
 
-    return sk_sp<GrRenderTargetContext>(new GrRenderTargetContext(fContext, this, std::move(rt),
+    return sk_sp<GrRenderTargetContext>(new GrRenderTargetContext(fContext, this, std::move(rtp),
                                                                   std::move(colorSpace),
                                                                   surfaceProps,
                                                                   fContext->getAuditTrail(),
diff --git a/src/gpu/GrDrawingManager.h b/src/gpu/GrDrawingManager.h
index 6b50266..3945fe5 100644
--- a/src/gpu/GrDrawingManager.h
+++ b/src/gpu/GrDrawingManager.h
@@ -19,6 +19,7 @@
 
 class GrContext;
 class GrRenderTargetContext;
+class GrRenderTargetProxy;
 class GrSingleOWner;
 class GrSoftwarePathRenderer;
 
@@ -34,13 +35,13 @@
     bool wasAbandoned() const { return fAbandoned; }
     void freeGpuResources();
 
-    sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrRenderTarget> rt,
+    sk_sp<GrRenderTargetContext> makeRenderTargetContext(sk_sp<GrRenderTargetProxy> rtp,
                                                          sk_sp<SkColorSpace>,
                                                          const SkSurfaceProps*);
 
     // The caller automatically gets a ref on the returned opList. It must
     // be balanced by an unref call.
-    GrRenderTargetOpList* newOpList(GrRenderTarget* rt);
+    GrRenderTargetOpList* newOpList(GrRenderTargetProxy* rtp);
 
     GrContext* getContext() { return fContext; }
 
diff --git a/src/gpu/GrOpList.cpp b/src/gpu/GrOpList.cpp
index 2010e65..baecbd6 100644
--- a/src/gpu/GrOpList.cpp
+++ b/src/gpu/GrOpList.cpp
@@ -7,16 +7,16 @@
 
 #include "GrOpList.h"
 
-#include "GrRenderTarget.h"
 #include "GrRenderTargetOpList.h"
 #include "GrSurface.h"
+#include "GrSurfaceProxy.h"
 
-GrOpList::GrOpList(GrSurface* surface, GrAuditTrail* auditTrail) 
+GrOpList::GrOpList(GrSurfaceProxy* surfaceProxy, GrAuditTrail* auditTrail) 
     : fFlags(0)
-    , fTarget(surface)
+    , fTarget(surfaceProxy)
     , fAuditTrail(auditTrail) {
 
-    surface->setLastOpList(this);
+    surfaceProxy->setLastOpList(this);
 
 #ifdef SK_DEBUG
     static int debugID = 0;
diff --git a/src/gpu/GrOpList.h b/src/gpu/GrOpList.h
index 16d8a2b..0435568 100644
--- a/src/gpu/GrOpList.h
+++ b/src/gpu/GrOpList.h
@@ -16,10 +16,11 @@
 class GrAuditTrail;
 class GrBatchFlushState;
 class GrSurface;
+class GrSurfaceProxy;
 
 class GrOpList : public SkRefCnt {
 public:
-    GrOpList(GrSurface* surface, GrAuditTrail* auditTrail);
+    GrOpList(GrSurfaceProxy* surfaceProxy, GrAuditTrail* auditTrail);
     ~GrOpList() override;
 
     virtual void prepareBatches(GrBatchFlushState* flushState) = 0;
@@ -114,7 +115,7 @@
 
     SkDEBUGCODE(int                                 fDebugID;)
     uint32_t                                        fFlags;
-    GrSurface*                                      fTarget;
+    GrSurfaceProxy*                                 fTarget;
 
     // 'this' GrOpList relies on the output of the GrOpLists in 'fDependencies'
     SkTDArray<GrOpList*>                            fDependencies;
diff --git a/src/gpu/GrPathRenderingRenderTargetContext.h b/src/gpu/GrPathRenderingRenderTargetContext.h
index b19876e..a4353e1 100644
--- a/src/gpu/GrPathRenderingRenderTargetContext.h
+++ b/src/gpu/GrPathRenderingRenderTargetContext.h
@@ -27,10 +27,11 @@
                       SkDrawFilter*, const SkIRect& clipBounds) override;
 protected:
     GrPathRenderingRenderTargetContext(GrContext* ctx, GrDrawingManager* mgr,
-                                       sk_sp<GrRenderTarget> rt, sk_sp<SkColorSpace> colorSpace,
+                                       sk_sp<GrRenderTargetProxy> rtp,
+                                       sk_sp<SkColorSpace> colorSpace,
                                        const SkSurfaceProps* surfaceProps, GrAuditTrail* at,
                                        GrSingleOwner* so)
-        : INHERITED(ctx, mgr, std::move(rt), std::move(colorSpace), surfaceProps, at, so) {}
+        : INHERITED(ctx, mgr, std::move(rtp), std::move(colorSpace), surfaceProps, at, so) {}
 
 private:
     SkAutoTDelete<GrStencilAndCoverTextContext> fStencilAndCoverTextContext;
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index a746e80..937910f 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -75,16 +75,16 @@
 // when the renderTargetContext attempts to use it (via getOpList).
 GrRenderTargetContext::GrRenderTargetContext(GrContext* context,
                                              GrDrawingManager* drawingMgr,
-                                             sk_sp<GrRenderTarget> rt,
+                                             sk_sp<GrRenderTargetProxy> rtp,
                                              sk_sp<SkColorSpace> colorSpace,
                                              const SkSurfaceProps* surfaceProps,
                                              GrAuditTrail* auditTrail,
                                              GrSingleOwner* singleOwner)
     : fDrawingManager(drawingMgr)
-    , fRenderTarget(std::move(rt))
-    , fOpList(SkSafeRef(fRenderTarget->getLastRenderTargetOpList()))
+    , fRenderTargetProxy(std::move(rtp))
+    , fOpList(SkSafeRef(fRenderTargetProxy->getLastRenderTargetOpList()))
     , fContext(context)
-    , fInstancedPipelineInfo(fRenderTarget.get())
+    , fInstancedPipelineInfo(fRenderTargetProxy.get())
     , fColorSpace(std::move(colorSpace))
     , fColorXformFromSRGB(nullptr)
     , fSurfaceProps(SkSurfacePropsCopyOrDefault(surfaceProps))
@@ -103,11 +103,11 @@
 
 #ifdef SK_DEBUG
 void GrRenderTargetContext::validate() const {
-    SkASSERT(fRenderTarget);
-    ASSERT_OWNED_RESOURCE(fRenderTarget);
+    SkASSERT(fRenderTargetProxy);
+    fRenderTargetProxy->validate(fContext);
 
     if (fOpList && !fOpList->isClosed()) {
-        SkASSERT(fRenderTarget->getLastOpList() == fOpList);
+        SkASSERT(fRenderTargetProxy->getLastOpList() == fOpList);
     }
 }
 #endif
@@ -122,7 +122,7 @@
     SkDEBUGCODE(this->validate();)
 
     if (!fOpList || fOpList->isClosed()) {
-        fOpList = fDrawingManager->newOpList(fRenderTarget.get());
+        fOpList = fDrawingManager->newOpList(fRenderTargetProxy.get());
     }
 
     return fOpList;
@@ -135,7 +135,11 @@
     SkDEBUGCODE(this->validate();)
     GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::copySurface");
 
-    return this->getOpList()->copySurface(fRenderTarget.get(), src, srcRect, dstPoint);
+    // TODO: this needs to be fixed up since it ends the deferrable of the GrRenderTarget
+    sk_sp<GrRenderTarget> rt(
+                        sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
+
+    return this->getOpList()->copySurface(rt.get(), src, srcRect, dstPoint);
 }
 
 void GrRenderTargetContext::drawText(const GrClip& clip, const GrPaint& grPaint,
@@ -192,7 +196,12 @@
     GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::discard");
 
     AutoCheckFlush acf(fDrawingManager);
-    this->getOpList()->discard(fRenderTarget.get());
+
+    // TODO: this needs to be fixed up since it ends the deferrable of the GrRenderTarget
+    sk_sp<GrRenderTarget> rt(
+                        sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
+
+    this->getOpList()->discard(rt.get());
 }
 
 void GrRenderTargetContext::clear(const SkIRect* rect,
@@ -268,7 +277,7 @@
     // set rect to be big enough to fill the space, but not super-huge, so we
     // don't overflow fixed-point implementations
 
-    SkRect r = fRenderTarget->getBoundsRect();
+    SkRect r = fRenderTargetProxy->getBoundsRect();
     SkTCopyOnFirstWrite<GrPaint> paint(origPaint);
 
     SkRRect rrect;
@@ -324,7 +333,7 @@
     return viewMatrix.preservesRightAngles();
 }
 
-static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTarget* rt,
+static bool should_apply_coverage_aa(const GrPaint& paint, GrRenderTargetProxy* rtp,
                                      bool* useHWAA = nullptr) {
     if (!paint.isAntiAlias()) {
         if (useHWAA) {
@@ -333,9 +342,9 @@
         return false;
     } else {
         if (useHWAA) {
-            *useHWAA = rt->isUnifiedMultisampled();
+            *useHWAA = rtp->isUnifiedMultisampled();
         }
-        return !rt->isUnifiedMultisampled();
+        return !rtp->isUnifiedMultisampled();
     }
 }
 
@@ -412,7 +421,7 @@
         }
     }
 
-    if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA)) {
+    if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
         // The fill path can handle rotation but not skew.
         if (view_matrix_ok_for_aa_fill_rect(viewMatrix)) {
             SkRect devBoundRect;
@@ -462,7 +471,7 @@
         if (!fContext->caps()->useDrawInsteadOfClear()) {
             // Check if this is a full RT draw and can be replaced with a clear. We don't bother
             // checking cases where the RT is fully inside a stroke.
-            SkRect rtRect = fRenderTarget->getBoundsRect();
+            SkRect rtRect = fRenderTargetProxy->getBoundsRect();
             // Does the clip contain the entire RT?
             if (clip.quickContains(rtRect)) {
                 SkMatrix invM;
@@ -528,7 +537,7 @@
         SkAutoTUnref<GrDrawBatch> batch;
 
         GrColor color = paint.getColor();
-        if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA)) {
+        if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
             // The stroke path needs the rect to remain axis aligned (no rotation or skew).
             if (viewMatrix.rectStaysRect()) {
                 batch.reset(GrRectBatchFactory::CreateAAStroke(color, viewMatrix, rect, stroke));
@@ -538,7 +547,7 @@
             // hairline rects. We jam all the vertices to pixel centers to avoid this, but not
             // when MSAA is enabled because it can cause ugly artifacts.
             snapToPixelCenters = stroke.getStyle() == SkStrokeRec::kHairline_Style &&
-                                 !fRenderTarget->isUnifiedMultisampled();
+                                 !fRenderTargetProxy->isUnifiedMultisampled();
             batch.reset(GrRectBatchFactory::CreateNonAAStroke(color, viewMatrix, rect,
                                                               stroke, snapToPixelCenters));
         }
@@ -664,7 +673,7 @@
         }
     }
 
-    if (!should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA)) {
+    if (!should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
         this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, &croppedLocalRect,
                                   nullptr, nullptr, useHWAA);
         return;
@@ -723,7 +732,7 @@
         }
     }
 
-    if (!should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA)) {
+    if (!should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
         this->drawNonAAFilledRect(clip, paint, viewMatrix, croppedRect, nullptr,
                                   &localMatrix, nullptr, useHWAA);
         return;
@@ -856,7 +865,7 @@
         }
     }
 
-    if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA)) {
+    if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
         GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
         SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateRRectBatch(
                                                                 paint.getColor(),
@@ -899,7 +908,7 @@
         }
     }
 
-    bool applyAA = paintIn.isAntiAlias() && !fRenderTarget->isUnifiedMultisampled();
+    bool applyAA = paintIn.isAntiAlias() && !fRenderTargetProxy->isUnifiedMultisampled();
 
     GrPrimitiveEdgeType innerEdgeType = applyAA ? kInverseFillAA_GrProcessorEdgeType :
                                                   kInverseFillBW_GrProcessorEdgeType;
@@ -1040,7 +1049,7 @@
         }
     }
 
-    if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA)) {
+    if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
         GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
         SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateOvalBatch(paint.getColor(),
                                                                         viewMatrix,
@@ -1069,7 +1078,7 @@
                                     bool useCenter,
                                     const GrStyle& style) {
     bool useHWAA;
-    if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA)) {
+    if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA)) {
         GrShaderCaps* shaderCaps = fContext->caps()->shaderCaps();
         SkAutoTUnref<GrDrawBatch> batch(GrOvalRenderer::CreateArcBatch(paint.getColor(),
                                                                        viewMatrix,
@@ -1120,9 +1129,13 @@
     SkDEBUGCODE(this->validate();)
     GR_AUDIT_TRAIL_AUTO_FRAME(fAuditTrail, "GrRenderTargetContext::prepareForExternalIO");
 
-    ASSERT_OWNED_RESOURCE(fRenderTarget);
+    // Deferral of the VRAM resources must end in this instance anyway
+    sk_sp<GrRenderTarget> rt(
+                        sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
 
-    fDrawingManager->prepareSurfaceForExternalIO(fRenderTarget.get());
+    ASSERT_OWNED_RESOURCE(rt);
+
+    fDrawingManager->prepareSurfaceForExternalIO(rt.get());
 }
 
 void GrRenderTargetContext::drawNonAAFilledRect(const GrClip& clip,
@@ -1157,8 +1170,12 @@
         flags = GrContext::kUnpremul_PixelOpsFlag;
     }
 
-    return fRenderTarget->readPixels(x, y, dstInfo.width(), dstInfo.height(),
-                                     config, dstBuffer, dstRowBytes, flags);
+    // Deferral of the VRAM resources must end in this instance anyway
+    sk_sp<GrRenderTarget> rt(
+                        sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
+
+    return rt->readPixels(x, y, dstInfo.width(), dstInfo.height(),
+                          config, dstBuffer, dstRowBytes, flags);
 }
 
 bool GrRenderTargetContext::writePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
@@ -1173,8 +1190,12 @@
         flags = GrContext::kUnpremul_PixelOpsFlag;
     }
 
-    return fRenderTarget->writePixels(x, y, srcInfo.width(), srcInfo.height(),
-                                      config, srcBuffer, srcRowBytes, flags);
+    // Deferral of the VRAM resources must end in this instance anyway
+    sk_sp<GrRenderTarget> rt(
+                        sk_ref_sp(fRenderTargetProxy->instantiate(fContext->textureProvider())));
+
+    return rt->writePixels(x, y, srcInfo.width(), srcInfo.height(),
+                           config, srcBuffer, srcRowBytes, flags);
 }
 
 // Can 'path' be drawn as a pair of filled nested rectangles?
@@ -1243,7 +1264,8 @@
     AutoCheckFlush acf(fDrawingManager);
 
     bool useHWAA;
-    if (should_apply_coverage_aa(paint, fRenderTarget.get(), &useHWAA) && !style.pathEffect()) {
+    if (should_apply_coverage_aa(paint, fRenderTargetProxy.get(), &useHWAA) &&
+                                                                            !style.pathEffect()) {
         if (style.isSimpleFill() && !path.isConvex()) {
             // Concave AA paths are expensive - try to avoid them for special cases
             SkRect rects[2];
@@ -1361,7 +1383,7 @@
 
     SkDEBUGCODE(fRenderTargetContext->validate();)
 
-    return fRenderTargetContext->fRenderTarget->resourcePriv().isBudgeted();
+    return fRenderTargetContext->fRenderTargetProxy->isBudgeted();
 }
 
 void GrRenderTargetContext::internalDrawPath(const GrClip& clip,
@@ -1373,7 +1395,7 @@
     RETURN_IF_ABANDONED
     SkASSERT(!path.isEmpty());
 
-    bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTarget.get());
+    bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTargetProxy.get());
     constexpr bool kHasUserStencilSettings = false;
     bool isStencilBufferMSAA = this->isStencilBufferMultisampled();
 
diff --git a/src/gpu/GrRenderTargetOpList.cpp b/src/gpu/GrRenderTargetOpList.cpp
index 9f50d5d..33a8608 100644
--- a/src/gpu/GrRenderTargetOpList.cpp
+++ b/src/gpu/GrRenderTargetOpList.cpp
@@ -46,10 +46,10 @@
 static const int kDefaultMaxBatchLookback  = 10;
 static const int kDefaultMaxBatchLookahead = 10;
 
-GrRenderTargetOpList::GrRenderTargetOpList(GrRenderTarget* rt, GrGpu* gpu,
+GrRenderTargetOpList::GrRenderTargetOpList(GrRenderTargetProxy* rtp, GrGpu* gpu,
                                            GrResourceProvider* resourceProvider,
                                            GrAuditTrail* auditTrail, const Options& options)
-    : INHERITED(rt, auditTrail)
+    : INHERITED(rtp, auditTrail)
     , fLastFullClearBatch(nullptr)
     , fGpu(SkRef(gpu))
     , fResourceProvider(resourceProvider) {
diff --git a/src/gpu/GrRenderTargetOpList.h b/src/gpu/GrRenderTargetOpList.h
index e379c35..2a7f1a1 100644
--- a/src/gpu/GrRenderTargetOpList.h
+++ b/src/gpu/GrRenderTargetOpList.h
@@ -36,6 +36,7 @@
 class GrPath;
 class GrDrawPathBatchBase;
 class GrPipelineBuilder;
+class GrRenderTargetProxy;
 
 class GrRenderTargetOpList final : public GrOpList {
 public:
@@ -52,7 +53,7 @@
         int  fMaxBatchLookahead;
     };
 
-    GrRenderTargetOpList(GrRenderTarget*, GrGpu*, GrResourceProvider*,
+    GrRenderTargetOpList(GrRenderTargetProxy*, GrGpu*, GrResourceProvider*,
                          GrAuditTrail*, const Options&);
 
     ~GrRenderTargetOpList() override;
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
index 5ea43d6..50d79f4 100644
--- a/src/gpu/GrRenderTargetProxy.cpp
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -8,8 +8,8 @@
 #include "GrRenderTargetProxy.h"
 
 #include "GrCaps.h"
-#include "GrGpuResourcePriv.h"
 #include "GrRenderTargetOpList.h"
+#include "GrRenderTargetPriv.h"
 #include "GrTextureProvider.h"
 
 // Deferred version
@@ -18,53 +18,58 @@
 GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc,
                                          SkBackingFit fit, SkBudgeted budgeted)
     : INHERITED(desc, fit, budgeted)
-    , fTarget(nullptr)
-    , fFlags(GrRenderTargetPriv::Flags::kNone) {
+    , fFlags(GrRenderTarget::Flags::kNone) {
     // Since we know the newly created render target will be internal, we are able to precompute
     // what the flags will ultimately end up being.
     if (caps.usesMixedSamples() && fDesc.fSampleCnt > 0) {
-        fFlags |= GrRenderTargetPriv::Flags::kMixedSampled;
+        fFlags |= GrRenderTarget::Flags::kMixedSampled;
     }
     if (caps.maxWindowRectangles() > 0) {
-        fFlags |= GrRenderTargetPriv::Flags::kWindowRectsSupport;
+        fFlags |= GrRenderTarget::Flags::kWindowRectsSupport;
     }
 }
 
 // Wrapped version
 GrRenderTargetProxy::GrRenderTargetProxy(const GrCaps& caps, sk_sp<GrRenderTarget> rt)
-    : INHERITED(rt->desc(), SkBackingFit::kExact,
-                rt->resourcePriv().isBudgeted(), rt->uniqueID())
-    , fTarget(std::move(rt))
-    , fFlags(fTarget->renderTargetPriv().flags()) {
+    : INHERITED(std::move(rt), SkBackingFit::kExact)
+    , fFlags(fTarget->asRenderTarget()->renderTargetPriv().flags()) {
 }
 
 GrRenderTarget* GrRenderTargetProxy::instantiate(GrTextureProvider* texProvider) {
     if (fTarget) {
-        return fTarget.get();
+        return fTarget->asRenderTarget();
     }
 
     // TODO: it would be nice to not have to copy the desc here
     GrSurfaceDesc desc = fDesc;
     desc.fFlags |= GrSurfaceFlags::kRenderTarget_GrSurfaceFlag;
 
-    sk_sp<GrTexture> tex;
     if (SkBackingFit::kApprox == fFit) {
-        tex.reset(texProvider->createApproxTexture(desc));
+        fTarget = texProvider->createApproxTexture(desc);
     } else {
-        tex.reset(texProvider->createTexture(desc, fBudgeted));
+        fTarget = texProvider->createTexture(desc, fBudgeted);
     }
-    if (!tex || !tex->asRenderTarget()) {
+    if (!fTarget) {
         return nullptr;
     }
 
-    fTarget = sk_ref_sp(tex->asRenderTarget());
-
     // Check that our a priori computation matched the ultimate reality
-    SkASSERT(fFlags == fTarget->renderTargetPriv().flags());
+    SkASSERT(fFlags == fTarget->asRenderTarget()->renderTargetPriv().flags());
 
-    return fTarget.get();
+    return fTarget->asRenderTarget();
 }
 
+
+#ifdef SK_DEBUG
+void GrRenderTargetProxy::validate(GrContext* context) const {
+    if (fTarget) {
+        SkASSERT(fTarget->getContext() == context);
+    }
+
+    INHERITED::validate();
+}
+#endif
+
 sk_sp<GrRenderTargetProxy> GrRenderTargetProxy::Make(const GrCaps& caps,
                                                      const GrSurfaceDesc& desc,
                                                      SkBackingFit fit,
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 9cd84ed..094eaa3 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -7,8 +7,18 @@
 
 #include "GrSurfaceProxy.h"
 
+#include "GrGpuResourcePriv.h"
 #include "GrOpList.h"
 
+GrSurfaceProxy::GrSurfaceProxy(sk_sp<GrSurface> surface, SkBackingFit fit)
+    : INHERITED(std::move(surface))
+    , fDesc(fTarget->desc())
+    , fFit(fit)
+    , fBudgeted(fTarget->resourcePriv().isBudgeted())
+    , fUniqueID(fTarget->uniqueID())
+    , fLastOpList(nullptr) {
+}
+
 GrSurfaceProxy::~GrSurfaceProxy() {
     if (fLastOpList) {
         fLastOpList->clearTarget();
diff --git a/src/gpu/GrTextureOpList.cpp b/src/gpu/GrTextureOpList.cpp
index 43c2ece..974ee9b 100644
--- a/src/gpu/GrTextureOpList.cpp
+++ b/src/gpu/GrTextureOpList.cpp
@@ -9,13 +9,13 @@
 
 #include "GrAuditTrail.h"
 #include "GrGpu.h"
-#include "GrTexture.h"
+#include "GrTextureProxy.h"
 
 #include "batches/GrCopySurfaceBatch.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 
-GrTextureOpList::GrTextureOpList(GrTexture* tex, GrGpu* gpu, GrAuditTrail* auditTrail)
+GrTextureOpList::GrTextureOpList(GrTextureProxy* tex, GrGpu* gpu, GrAuditTrail* auditTrail)
     : INHERITED(tex, auditTrail)
     , fGpu(SkRef(gpu)) {
 }
diff --git a/src/gpu/GrTextureOpList.h b/src/gpu/GrTextureOpList.h
index 5b700dc..33ca656 100644
--- a/src/gpu/GrTextureOpList.h
+++ b/src/gpu/GrTextureOpList.h
@@ -15,13 +15,13 @@
 class GrAuditTrail;
 class GrBatch;
 class GrGpu;
-class GrTexture;
+class GrTextureProxy;
 struct SkIPoint;
 struct SkIRect;
 
 class GrTextureOpList final : public GrOpList {
 public:
-    GrTextureOpList(GrTexture*, GrGpu*, GrAuditTrail*);
+    GrTextureOpList(GrTextureProxy*, GrGpu*, GrAuditTrail*);
 
     ~GrTextureOpList() override;
 
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
index 205dfdd..41775b1 100644
--- a/src/gpu/GrTextureProxy.cpp
+++ b/src/gpu/GrTextureProxy.cpp
@@ -8,7 +8,6 @@
 #include "GrTextureProxy.h"
 
 #include "GrTextureProvider.h"
-#include "GrGpuResourcePriv.h"
 
 GrTextureProxy::GrTextureProxy(const GrSurfaceDesc& srcDesc, SkBackingFit fit, SkBudgeted budgeted,
                                const void* /*srcData*/, size_t /*rowBytes*/)
@@ -17,23 +16,21 @@
 }
 
 GrTextureProxy::GrTextureProxy(sk_sp<GrTexture> tex)
-    : INHERITED(tex->desc(), SkBackingFit::kExact,
-                tex->resourcePriv().isBudgeted(), tex->uniqueID())
-    , fTexture(std::move(tex)) {
+    : INHERITED(std::move(tex), SkBackingFit::kExact) {
 }
 
 GrTexture* GrTextureProxy::instantiate(GrTextureProvider* texProvider) {
-    if (fTexture) {
-        return fTexture.get();
+    if (fTarget) {
+        return fTarget->asTexture();
     }
 
     if (SkBackingFit::kApprox == fFit) {
-        fTexture.reset(texProvider->createApproxTexture(fDesc));
+        fTarget = texProvider->createApproxTexture(fDesc);
     } else {
-        fTexture.reset(texProvider->createTexture(fDesc, fBudgeted));
+        fTarget = texProvider->createTexture(fDesc, fBudgeted);
     }
 
-    return fTexture.get();
+    return fTarget->asTexture();
 }
 
 sk_sp<GrTextureProxy> GrTextureProxy::Make(const GrSurfaceDesc& desc,
diff --git a/tests/ProxyTest.cpp b/tests/ProxyTest.cpp
index 367dee4..9a7697c 100644
--- a/tests/ProxyTest.cpp
+++ b/tests/ProxyTest.cpp
@@ -13,6 +13,7 @@
 #include "GrGpu.h"
 #include "GrSurfaceProxy.h"
 #include "GrTextureProxy.h"
+#include "GrRenderTargetPriv.h"
 #include "GrRenderTargetProxy.h"
 
 // Check that the surface proxy's member vars are set as expected
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index e844ce5..90751f0 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -262,7 +262,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-GrRenderTargetPriv::Flags GrRenderTargetProxy::testingOnly_getFlags() const {
+GrRenderTarget::Flags GrRenderTargetProxy::testingOnly_getFlags() const {
     return fFlags;
 }