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

Committed: https://skia.googlesource.com/skia/+/de5bf0cfeca908b81a28cc50065f7bc2da3d2fd1

Committed: https://skia.googlesource.com/skia/+/92605b35efa0155c44d24bd8415b4cc1db8831db

Review-Url: https://codereview.chromium.org/1937553002
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
index f9d0c53..f99bb01 100644
--- a/include/core/SkTypes.h
+++ b/include/core/SkTypes.h
@@ -442,6 +442,15 @@
     kYes = true
 };
 
+/**
+ * Indicates whether a backing store needs to be an exact match or can be larger
+ * than is strictly necessary
+ */
+enum class SkBackingFit {
+    kApprox,
+    kExact
+};
+
 ///////////////////////////////////////////////////////////////////////////////
 
 /** Use to combine multiple bits in a bitmask in a type safe way.
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index cb407aa..6f5ca98 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -194,16 +194,11 @@
      */
     sk_sp<GrDrawContext> drawContext(sk_sp<GrRenderTarget> rt, const SkSurfaceProps* = nullptr);
 
-    enum BackingFit {
-        kTight_BackingFit,
-        kLoose_BackingFit
-    };
-
     /**
      * Create both a GrRenderTarget and a matching GrDrawContext to wrap it.
      * The created GrRenderTarget will always be budgeted.
      */
-    sk_sp<GrDrawContext> newDrawContext(BackingFit fit, 
+    sk_sp<GrDrawContext> newDrawContext(SkBackingFit fit, 
                                         int width, int height,
                                         GrPixelConfig config,
                                         int sampleCnt = 0,
diff --git a/include/gpu/GrRenderTarget.h b/include/gpu/GrRenderTarget.h
index eb9f142..ff75af3 100644
--- a/include/gpu/GrRenderTarget.h
+++ b/include/gpu/GrRenderTarget.h
@@ -11,6 +11,7 @@
 #include "GrSurface.h"
 #include "SkRect.h"
 
+class GrCaps;
 class GrDrawTarget;
 class GrStencilAttachment;
 class GrRenderTargetPriv;
@@ -155,6 +156,8 @@
     void setLastDrawTarget(GrDrawTarget* dt);
     GrDrawTarget* getLastDrawTarget() { return fLastDrawTarget; }
 
+    static SampleConfig ComputeSampleConfig(const GrCaps& caps, int sampleCnt);
+
 protected:
     GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc,
                    SampleConfig sampleConfig, GrStencilAttachment* stencil = nullptr)
diff --git a/include/private/GrRenderTargetProxy.h b/include/private/GrRenderTargetProxy.h
new file mode 100644
index 0000000..287aa01
--- /dev/null
+++ b/include/private/GrRenderTargetProxy.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrRenderTargetProxy_DEFINED
+#define GrRenderTargetProxy_DEFINED
+
+#include "GrRenderTarget.h"
+#include "GrSurfaceProxy.h"
+#include "GrTypes.h"
+
+class GrTextureProvider;
+
+// This class delays the acquisition of RenderTargets until they are actually
+// required
+// Beware: the uniqueID of the RenderTargetProxy will usually be different than
+// the uniqueID of the RenderTarget it represents!
+class GrRenderTargetProxy : public GrSurfaceProxy {
+public:
+    /**
+     * The caller gets the creation ref.
+     */
+    static sk_sp<GrRenderTargetProxy> Make(const GrCaps&, const GrSurfaceDesc&,
+                                           SkBackingFit, SkBudgeted);
+    static sk_sp<GrRenderTargetProxy> Make(sk_sp<GrRenderTarget> rt);
+
+    ~GrRenderTargetProxy() override;
+
+    // TODO: add asTextureProxy variants
+    GrRenderTargetProxy* asRenderTargetProxy() override { return this; }
+    const GrRenderTargetProxy* asRenderTargetProxy() const override { return this; }
+
+    // Actually instantiate the backing rendertarget, if necessary.
+    GrRenderTarget* instantiate(GrTextureProvider* texProvider);
+
+    /**
+     * @return true  if the surface is multisampled in all buffers,
+     *         false otherwise
+     */
+    bool isUnifiedMultisampled() const {
+        if (fSampleConfig != GrRenderTarget::kUnified_SampleConfig) {
+            return false;
+        }
+        return 0 != fDesc.fSampleCnt;
+    }
+
+    /**
+     * @return true if the surface is multisampled in the stencil buffer,
+     *         false otherwise
+     */
+    bool isStencilBufferMultisampled() const {
+        return 0 != fDesc.fSampleCnt;
+    }
+
+    /**
+     * @return the number of color samples-per-pixel, or zero if non-MSAA or
+     *         multisampled in the stencil buffer only.
+     */
+    int numColorSamples() const {
+        if (fSampleConfig == GrRenderTarget::kUnified_SampleConfig) {
+            return fDesc.fSampleCnt;
+        }
+        return 0;
+    }
+
+    /**
+     * @return the number of stencil samples-per-pixel, or zero if non-MSAA.
+     */
+    int numStencilSamples() const {
+        return fDesc.fSampleCnt;
+    }
+
+    /**
+     * @return true if the surface is mixed sampled, false otherwise.
+     */
+    bool hasMixedSamples() const {
+        SkASSERT(GrRenderTarget::kStencil_SampleConfig != fSampleConfig ||
+                 this->isStencilBufferMultisampled());
+        return GrRenderTarget::kStencil_SampleConfig == fSampleConfig;
+    }
+
+    void setLastDrawTarget(GrDrawTarget* dt);
+    GrDrawTarget* getLastDrawTarget() { return fLastDrawTarget; }
+
+private:
+    // TODO: we can probably munge the 'desc' in both the wrapped and deferred 
+    // cases to make the sampleConfig/numSamples stuff more rational.
+    GrRenderTargetProxy(const GrCaps& caps, const GrSurfaceDesc& desc,
+                        SkBackingFit fit, SkBudgeted budgeted)
+        : INHERITED(desc, fit, budgeted)
+        , fTarget(nullptr)
+        , fSampleConfig(GrRenderTarget::ComputeSampleConfig(caps, desc.fSampleCnt))
+        , fLastDrawTarget(nullptr) {
+    }
+
+    // Wrapped version
+    GrRenderTargetProxy(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;
+
+    // The sample config doesn't usually get computed until the render target is instantiated but
+    // the render target proxy may need to answer queries about it before then. For this reason
+    // we precompute it in the deferred case. In the wrapped case we just copy the wrapped
+    // rendertarget's info here.
+    GrRenderTarget::SampleConfig fSampleConfig;
+
+    // The last drawTarget that wrote to or is currently going to write to this renderTarget
+    // The drawTarget can be closed (e.g., no draw context is currently bound
+    // to this renderTarget).
+    // This back-pointer is required so that we can add a dependancy between
+    // the drawTarget used to create the current contents of this renderTarget
+    // and the drawTarget of a destination renderTarget to which this one is being drawn.
+    GrDrawTarget* fLastDrawTarget;
+
+    typedef GrSurfaceProxy INHERITED;
+};
+
+#endif
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
new file mode 100644
index 0000000..01c5267
--- /dev/null
+++ b/include/private/GrSurfaceProxy.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrSurfaceProxy_DEFINED
+#define GrSurfaceProxy_DEFINED
+
+#include "GrGpuResource.h"
+
+class GrTextureProxy;
+class GrRenderTargetProxy;
+
+class GrSurfaceProxy : public GrIORef<GrSurfaceProxy> {
+public:
+    const GrSurfaceDesc& desc() const { return fDesc; }
+
+    GrSurfaceOrigin origin() const {
+        SkASSERT(kTopLeft_GrSurfaceOrigin == fDesc.fOrigin ||
+                 kBottomLeft_GrSurfaceOrigin == fDesc.fOrigin);
+        return fDesc.fOrigin;
+    }
+    int width() const { return fDesc.fWidth; }
+    int height() const { return fDesc.fWidth; }
+    GrPixelConfig config() const { return fDesc.fConfig; }
+
+    uint32_t uniqueID() const { return fUniqueID; }
+
+    /**
+     * @return the texture proxy associated with the surface proxy, may be NULL.
+     */
+    virtual GrTextureProxy* asTextureProxy() { return nullptr; }
+    virtual const GrTextureProxy* asTextureProxy() const { return nullptr; }
+
+    /**
+     * @return the render target proxy associated with the surface proxy, may be NULL.
+     */
+    virtual GrRenderTargetProxy* asRenderTargetProxy() { return nullptr; }
+    virtual const GrRenderTargetProxy* asRenderTargetProxy() const { return nullptr; }
+
+protected:
+    GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted)
+        : fDesc(desc)
+        , fFit(fit)
+        , fBudgeted(budgeted)
+        , fUniqueID(CreateUniqueID()) {
+    }
+
+    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
+    const SkBudgeted    fBudgeted; // set from the backing resource for wrapped resources
+    const uint32_t      fUniqueID;
+
+private:
+    static uint32_t CreateUniqueID();
+
+    // See comment in GrGpuResource.h.
+    void notifyAllCntsAreZero(CntType) const { delete this; }
+    bool notifyRefCountIsZero() const { return true; }
+
+    typedef GrIORef<GrSurfaceProxy> INHERITED;
+
+    // to access notifyAllCntsAreZero and notifyRefCntIsZero.
+    friend class GrIORef<GrSurfaceProxy>;
+};
+
+#endif
diff --git a/include/private/GrTextureProxy.h b/include/private/GrTextureProxy.h
new file mode 100644
index 0000000..eb82ca7
--- /dev/null
+++ b/include/private/GrTextureProxy.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrTextureProxy_DEFINED
+#define GrTextureProxy_DEFINED
+
+#include "GrSurfaceProxy.h"
+#include "GrTexture.h"
+
+class GrTextureProvider;
+
+// This class delays the acquisition of textures until they are actually required
+class GrTextureProxy : public GrSurfaceProxy {
+public:
+    // TODO: need to refine ownership semantics of 'srcData' if we're in completely
+    // deferred mode
+    static sk_sp<GrTextureProxy> Make(const GrSurfaceDesc&, SkBackingFit, SkBudgeted,
+                                      const void* srcData = nullptr, size_t rowBytes = 0);
+    static sk_sp<GrTextureProxy> Make(sk_sp<GrTexture>);
+
+    // TODO: add asRenderTargetProxy variants
+    GrTextureProxy* asTextureProxy() override { return this; }
+    const GrTextureProxy* asTextureProxy() const override { return this; }
+
+    // Actually instantiate the backing texture, if necessary
+    GrTexture* instantiate(GrTextureProvider* texProvider);
+
+private:
+    GrTextureProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted,
+                   const void* /*srcData*/, size_t /*rowBytes*/)
+        : INHERITED(desc, fit, budgeted) {
+        // TODO: Handle 'srcData' here
+    }
+
+    // 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;
+
+    typedef GrSurfaceProxy INHERITED;
+};
+
+#endif