Add Gr*Proxy classes

This isn't wired in anywhere yet.

GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1937553002

Review-Url: https://codereview.chromium.org/1937553002
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index d004252..899083d 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -280,7 +280,7 @@
     paint.addColorFragmentProcessor(fp.get());
     paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
 
-    sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+    sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
                                                              bounds.width(), bounds.height(),
                                                              kRGBA_8888_GrPixelConfig));
     if (!drawContext) {
diff --git a/src/effects/SkAlphaThresholdFilter.cpp b/src/effects/SkAlphaThresholdFilter.cpp
index cec45ba..a4876c8 100644
--- a/src/effects/SkAlphaThresholdFilter.cpp
+++ b/src/effects/SkAlphaThresholdFilter.cpp
@@ -102,7 +102,7 @@
         config = kRGBA_8888_GrPixelConfig;
     }
 
-    sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+    sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
                                                              bounds.width(), bounds.height(),
                                                              config));
     if (!drawContext) {
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index cf9e2c3..befda79 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -335,7 +335,7 @@
         SkMatrix matrix;
         matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colorBounds.y()));
 
-        sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+        sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
                                                                  bounds.width(), bounds.height(),
                                                                  kSkia8888_GrPixelConfig));
         if (!drawContext) {
diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp
index 6efb0f6..d9b2936 100644
--- a/src/effects/SkLightingImageFilter.cpp
+++ b/src/effects/SkLightingImageFilter.cpp
@@ -407,7 +407,7 @@
     sk_sp<GrTexture> inputTexture(input->asTextureRef(context));
     SkASSERT(inputTexture);
 
-    sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+    sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
                                                              offsetBounds.width(),
                                                              offsetBounds.height(),
                                                              kRGBA_8888_GrPixelConfig));
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 2a0f078..121a7fd 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -487,7 +487,7 @@
     SkASSERT(radius.width() > 0 || radius.height() > 0);
 
     if (radius.fWidth > 0) {
-        sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+        sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(SkBackingFit::kApprox,
                                                                     rect.width(), rect.height(),
                                                                     kSkia8888_GrPixelConfig));
         if (!dstDrawContext) {
@@ -508,7 +508,7 @@
         srcRect = dstRect;
     }
     if (radius.fHeight > 0) {
-        sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+        sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(SkBackingFit::kApprox,
                                                                     rect.width(), rect.height(),
                                                                     kSkia8888_GrPixelConfig));
         if (!dstDrawContext) {
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index b1e19bb..99ce24f 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -238,7 +238,7 @@
 
     paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
 
-    sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+    sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
                                                              bounds.width(), bounds.height(),
                                                              kSkia8888_GrPixelConfig));
     if (!drawContext) {
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index f95bdff..59a3dfc 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -116,7 +116,7 @@
         config = kAlpha_8_GrPixelConfig;
     }
 
-    sk_sp<GrDrawContext> drawContext(context->newDrawContext(GrContext::kLoose_BackingFit,
+    sk_sp<GrDrawContext> drawContext(context->newDrawContext(SkBackingFit::kApprox,
                                                              SkScalarCeilToInt(maskRect->width()), 
                                                              SkScalarCeilToInt(maskRect->height()),
                                                              config,
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index a186bd8..31845f9 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -615,7 +615,7 @@
     return fDrawingManager->drawContext(std::move(rt), surfaceProps);
 }
 
-sk_sp<GrDrawContext> GrContext::newDrawContext(BackingFit fit,
+sk_sp<GrDrawContext> GrContext::newDrawContext(SkBackingFit fit,
                                                int width, int height,
                                                GrPixelConfig config,
                                                int sampleCnt,
@@ -629,7 +629,7 @@
     desc.fSampleCnt = sampleCnt;
 
     sk_sp<GrTexture> tex;
-    if (kTight_BackingFit == fit) {
+    if (SkBackingFit::kExact == fit) {
         tex.reset(this->textureProvider()->createTexture(desc, SkBudgeted::kYes));
     } else {
         tex.reset(this->textureProvider()->createApproxTexture(desc));
diff --git a/src/gpu/GrRenderTarget.cpp b/src/gpu/GrRenderTarget.cpp
index a673640..ebbfae9 100644
--- a/src/gpu/GrRenderTarget.cpp
+++ b/src/gpu/GrRenderTarget.cpp
@@ -109,3 +109,11 @@
 GrRenderTargetPriv::getMultisampleSpecs(const GrStencilSettings& stencil) const {
     return fRenderTarget->getGpu()->getMultisampleSpecs(fRenderTarget, stencil);
 }
+
+GrRenderTarget::SampleConfig GrRenderTarget::ComputeSampleConfig(const GrCaps& caps,
+                                                                 int sampleCnt) {
+    return (caps.usesMixedSamples() && sampleCnt > 0)
+                        ? GrRenderTarget::kStencil_SampleConfig
+                        : GrRenderTarget::kUnified_SampleConfig;
+}
+
diff --git a/src/gpu/GrRenderTargetPriv.h b/src/gpu/GrRenderTargetPriv.h
index e64ed57..24b7e88 100644
--- a/src/gpu/GrRenderTargetPriv.h
+++ b/src/gpu/GrRenderTargetPriv.h
@@ -32,6 +32,8 @@
 
     const GrGpu::MultisampleSpecs& getMultisampleSpecs(const GrStencilSettings& stencil) const;
 
+    GrRenderTarget::SampleConfig sampleConfig() const { return fRenderTarget->fSampleConfig; }
+
 private:
     explicit GrRenderTargetPriv(GrRenderTarget* renderTarget) : fRenderTarget(renderTarget) {}
     GrRenderTargetPriv(const GrRenderTargetPriv&) {} // unimpl
diff --git a/src/gpu/GrRenderTargetProxy.cpp b/src/gpu/GrRenderTargetProxy.cpp
new file mode 100644
index 0000000..8d821c3
--- /dev/null
+++ b/src/gpu/GrRenderTargetProxy.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrRenderTargetProxy.h"
+
+#include "GrDrawTarget.h"
+#include "GrGpuResourcePriv.h"
+#include "GrRenderTargetPriv.h"
+
+GrRenderTargetProxy::GrRenderTargetProxy(sk_sp<GrRenderTarget> rt)
+    : INHERITED(rt->desc(), SkBackingFit::kExact, rt->resourcePriv().isBudgeted())
+    , fTarget(std::move(rt))
+    , fSampleConfig(fTarget->renderTargetPriv().sampleConfig())
+    , fLastDrawTarget(nullptr) {
+}
+
+GrRenderTargetProxy::~GrRenderTargetProxy() {
+    if (fLastDrawTarget) {
+        fLastDrawTarget->clearRT();
+    }
+    SkSafeUnref(fLastDrawTarget);
+}
+
+GrRenderTarget* GrRenderTargetProxy::instantiate(GrTextureProvider* texProvider) {
+    if (fTarget) {
+        return fTarget.get();
+    }
+
+    // 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));
+    } else {
+        tex.reset(texProvider->createTexture(desc, fBudgeted));
+    }
+    if (!tex || !tex->asRenderTarget()) {
+        return nullptr;
+    }
+
+    fTarget.reset(tex->asRenderTarget());
+
+    // Check that our a priori computation matched the ultimate reality
+    SkASSERT(fSampleConfig == fTarget->renderTargetPriv().sampleConfig());
+
+    return fTarget.get();
+}
+
+void GrRenderTargetProxy::setLastDrawTarget(GrDrawTarget* dt) {
+    if (fLastDrawTarget) {
+        // The non-MDB world never closes so we can't check this condition
+#ifdef ENABLE_MDB
+        SkASSERT(fLastDrawTarget->isClosed());
+#endif
+        fLastDrawTarget->clearRT();
+    }
+
+    SkRefCnt_SafeAssign(fLastDrawTarget, dt);
+}
+
+sk_sp<GrRenderTargetProxy> GrRenderTargetProxy::Make(const GrCaps& caps,
+                                                     const GrSurfaceDesc& desc,
+                                                     SkBackingFit fit,
+                                                     SkBudgeted budgeted) {
+    return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(caps, desc, fit, budgeted));
+}
+
+sk_sp<GrRenderTargetProxy> GrRenderTargetProxy::Make(sk_sp<GrRenderTarget> rt) {
+    return sk_sp<GrRenderTargetProxy>(new GrRenderTargetProxy(rt));
+}
+
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
new file mode 100644
index 0000000..b8b5d75
--- /dev/null
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrSurfaceProxy.h"
+
+#include "SkAtomics.h"
+
+uint32_t GrSurfaceProxy::CreateUniqueID() {
+    static int32_t gUniqueID = SK_InvalidUniqueID;
+    uint32_t id;
+    do {
+        id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
+    } while (id == SK_InvalidUniqueID);
+    return id;
+}
diff --git a/src/gpu/GrTextureProxy.cpp b/src/gpu/GrTextureProxy.cpp
new file mode 100644
index 0000000..09c22e3
--- /dev/null
+++ b/src/gpu/GrTextureProxy.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrTextureProxy.h"
+
+#include "GrTextureProvider.h"
+#include "GrGpuResourcePriv.h"
+
+GrTextureProxy::GrTextureProxy(sk_sp<GrTexture> tex)
+    : INHERITED(tex->desc(), SkBackingFit::kExact, tex->resourcePriv().isBudgeted())
+    , fTexture(std::move(tex)) {
+}
+
+GrTexture* GrTextureProxy::instantiate(GrTextureProvider* texProvider) {
+    if (fTexture) {
+        return fTexture.get();
+    }
+
+    if (SkBackingFit::kApprox == fFit) {
+        fTexture.reset(texProvider->createApproxTexture(fDesc));
+    } else {
+        fTexture.reset(texProvider->createTexture(fDesc, fBudgeted));
+    }
+
+    return fTexture.get();
+}
+
+sk_sp<GrTextureProxy> GrTextureProxy::Make(const GrSurfaceDesc& desc,
+                                           SkBackingFit fit,
+                                           SkBudgeted budgeted,
+                                           const void* srcData,
+                                           size_t rowBytes) {
+    // TODO: handle 'srcData' (we could use the wrapped version if there is data)
+    SkASSERT(!srcData && !rowBytes);
+    return sk_sp<GrTextureProxy>(new GrTextureProxy(desc, fit, budgeted, srcData, rowBytes));
+}
+
+sk_sp<GrTextureProxy> GrTextureProxy::Make(sk_sp<GrTexture> tex) {
+    return sk_sp<GrTextureProxy>(new GrTextureProxy(tex));
+}
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 3372d42..d24734f 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1475,9 +1475,9 @@
     idDesc->fRTFBOID = 0;
     idDesc->fRTFBOOwnership = GrBackendObjectOwnership::kOwned;
     idDesc->fTexFBOID = 0;
-    idDesc->fSampleConfig = (GrGLCaps::kMixedSamples_MSFBOType == this->glCaps().msFBOType() &&
-                            desc.fSampleCnt > 0) ? GrRenderTarget::kStencil_SampleConfig :
-                                                   GrRenderTarget::kUnified_SampleConfig;
+    SkASSERT((GrGLCaps::kMixedSamples_MSFBOType == this->glCaps().msFBOType()) ==
+             this->caps()->usesMixedSamples());
+    idDesc->fSampleConfig = GrRenderTarget::ComputeSampleConfig(*this->caps(), desc.fSampleCnt);
 
     GrGLenum status;
 
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index eea7e2c..339dee7 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -253,7 +253,7 @@
     const int height = yuvSizes[0].fHeight;
 
     // Needs to be a render target in order to draw to it for the yuv->rgb conversion.
-    sk_sp<GrDrawContext> drawContext(ctx->newDrawContext(GrContext::kTight_BackingFit,
+    sk_sp<GrDrawContext> drawContext(ctx->newDrawContext(SkBackingFit::kExact,
                                                          width, height,
                                                          kRGBA_8888_GrPixelConfig,
                                                          0,