Split GrResource into GrCacheable/GrGpuObject

Before this change, an object needed to inherit from GrResource (and
thus be a GPU object) in order to live in the GrResourceCache. That
was a problem for caching items that weren't GPU objects themselves,
but owned GPU objects.

This change splits GrResource into two classes:

  1. GrCacheable: The base class for objects that can live in the
     GrResourceCache.

  2. GrGpuObject, which inherits from GrCacheable: The base class for
     objects that get tracked by GrGpu.

This change is purely a refactor; there is no change in functionality.

Change-Id: I3e8daeb1f123041f414aa306c1366e959ae9e39e

BUG=skia:
R=bsalomon@google.com

Author: cdalton@nvidia.com

Review URL: https://codereview.chromium.org/251013002

git-svn-id: http://skia.googlecode.com/svn/trunk@14553 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/gpu/GrGpuObject.h b/include/gpu/GrGpuObject.h
new file mode 100644
index 0000000..72d2f89
--- /dev/null
+++ b/include/gpu/GrGpuObject.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGpuObject_DEFINED
+#define GrGpuObject_DEFINED
+
+#include "GrCacheable.h"
+#include "SkTInternalLList.h"
+
+class GrGpu;
+class GrContext;
+
+/**
+ * Base class for the GPU objects created by a GrContext.
+ */
+class GrGpuObject : public GrCacheable {
+public:
+    SK_DECLARE_INST_COUNT(GrGpuObject)
+
+    /**
+     * Frees the object in the underlying 3D API. It must be safe to call this
+     * when the object has been previously abandoned.
+     */
+    void release();
+
+    /**
+     * Removes references to objects in the underlying 3D API without freeing
+     * them. Used when the API context has been torn down before the GrContext.
+     */
+    void abandon();
+
+    /**
+     * Tests whether a object has been abandoned or released. All objects will
+     * be in this state after their creating GrContext is destroyed or has
+     * contextLost called. It's up to the client to test wasDestroyed() before
+     * attempting to use an object if it holds refs on objects across
+     * ~GrContext, freeResources with the force flag, or contextLost.
+     *
+     * @return true if the object has been released or abandoned,
+     *         false otherwise.
+     */
+    bool wasDestroyed() const { return NULL == fGpu; }
+
+    /**
+     * Retrieves the context that owns the object. Note that it is possible for
+     * this to return NULL. When objects have been release()ed or abandon()ed
+     * they no longer have an owning context. Destroying a GrContext
+     * automatically releases all its resources.
+     */
+    const GrContext* getContext() const;
+    GrContext* getContext();
+
+    void incDeferredRefCount() const {
+        SkASSERT(fDeferredRefCount >= 0);
+        ++fDeferredRefCount;
+    }
+
+    void decDeferredRefCount() const {
+        SkASSERT(fDeferredRefCount > 0);
+        --fDeferredRefCount;
+        if (0 == fDeferredRefCount && this->needsDeferredUnref()) {
+            SkASSERT(this->getRefCnt() > 1);
+            this->unref();
+        }
+    }
+
+    int getDeferredRefCount() const { return fDeferredRefCount; }
+
+    void setNeedsDeferredUnref() { fFlags |= kDeferredUnref_FlagBit; }
+
+    virtual bool isValidOnGpu() const SK_OVERRIDE { return !this->wasDestroyed(); }
+
+protected:
+    /**
+     * isWrapped indicates we have wrapped a client-created backend object in a GrGpuObject. If it
+     * is true then the client is responsible for the lifetime of the underlying backend object.
+     * Otherwise, our onRelease() should free the object.
+     */
+    GrGpuObject(GrGpu* gpu, bool isWrapped);
+    virtual ~GrGpuObject();
+
+    GrGpu* getGpu() const { return fGpu; }
+
+    // Derived classes should always call their parent class' onRelease
+    // and onAbandon methods in their overrides.
+    virtual void onRelease() {};
+    virtual void onAbandon() {};
+
+    bool isWrapped() const { return kWrapped_FlagBit & fFlags; }
+    bool needsDeferredUnref() const { return SkToBool(kDeferredUnref_FlagBit & fFlags); }
+
+private:
+#ifdef SK_DEBUG
+    friend class GrGpu; // for assert in GrGpu to access getGpu
+#endif
+
+    // We're in an internal doubly linked list
+    SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrGpuObject);
+
+    GrGpu*              fGpu;               // not reffed. The GrGpu can be deleted while there
+                                            // are still live GrGpuObjects. It will call
+                                            // release() on all such objects in its destructor.
+    mutable int         fDeferredRefCount;  // How many references in deferred drawing buffers.
+
+    enum Flags {
+        /**
+         * This object wraps a GPU object given to us by the user.
+         * Lifetime management is left up to the user (i.e., we will not
+         * free it).
+         */
+        kWrapped_FlagBit         = 0x1,
+
+        /**
+         * This texture should be de-refed when the deferred ref count goes
+         * to zero. An object gets into this state when the resource cache
+         * is holding a ref-of-obligation (i.e., someone needs to own it but
+         * no one else wants to) but doesn't really want to keep it around.
+         */
+        kDeferredUnref_FlagBit  = 0x2,
+    };
+    uint32_t         fFlags;
+
+    typedef GrCacheable INHERITED;
+};
+
+#endif