Back SkSpecialImage_Gpu with a GrTextureProxy

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

The addition of the gpuMemorySize methods is for the SkSpecialImage cache.

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

Change-Id: Ia9b9d42fb2a0caf61bbfa3ebcc84308c56f541fc
Reviewed-on: https://skia-review.googlesource.com/4227
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
index 50d79f4..3809848 100644
--- a/src/gpu/GrRenderTargetProxy.cpp
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -53,6 +53,12 @@
         return nullptr;
     }
 
+#ifdef SK_DEBUG
+    if (kInvalidGpuMemorySize != fGpuMemorySize) {
+        SkASSERT(fTarget->gpuMemorySize() <= fGpuMemorySize);    
+    }
+#endif
+
     // Check that our a priori computation matched the ultimate reality
     SkASSERT(fFlags == fTarget->asRenderTarget()->renderTargetPriv().flags());
 
@@ -70,6 +76,20 @@
 }
 #endif
 
+size_t GrRenderTargetProxy::onGpuMemorySize() const {
+    if (fTarget) {
+        return fTarget->gpuMemorySize();
+    }
+
+    SkASSERT(kUnknown_GrPixelConfig != fDesc.fConfig);
+    SkASSERT(!GrPixelConfigIsCompressed(fDesc.fConfig));
+    size_t colorBytes = GrBytesPerPixel(fDesc.fConfig);
+    SkASSERT(colorBytes > 0);
+
+    // TODO: do we have enough information to improve this worst case estimate?
+    return (fDesc.fSampleCnt + 1) * fDesc.fWidth * fDesc.fHeight * colorBytes;
+}
+
 sk_sp<GrRenderTargetProxy> GrRenderTargetProxy::Make(const GrCaps& caps,
                                                      const GrSurfaceDesc& desc,
                                                      SkBackingFit fit,