• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef GrGpuObject_DEFINED
9 #define GrGpuObject_DEFINED
10 
11 #include "GrCacheable.h"
12 #include "SkTInternalLList.h"
13 
14 class GrGpu;
15 class GrContext;
16 
17 /**
18  * Base class for the GPU objects created by a GrContext.
19  */
20 class GrGpuObject : public GrCacheable {
21 public:
22     SK_DECLARE_INST_COUNT(GrGpuObject)
23 
24     /**
25      * Frees the object in the underlying 3D API. It must be safe to call this
26      * when the object has been previously abandoned.
27      */
28     void release();
29 
30     /**
31      * Removes references to objects in the underlying 3D API without freeing
32      * them. Used when the API context has been torn down before the GrContext.
33      */
34     void abandon();
35 
36     /**
37      * Tests whether a object has been abandoned or released. All objects will
38      * be in this state after their creating GrContext is destroyed or has
39      * contextLost called. It's up to the client to test wasDestroyed() before
40      * attempting to use an object if it holds refs on objects across
41      * ~GrContext, freeResources with the force flag, or contextLost.
42      *
43      * @return true if the object has been released or abandoned,
44      *         false otherwise.
45      */
wasDestroyed()46     bool wasDestroyed() const { return NULL == fGpu; }
47 
48     /**
49      * Retrieves the context that owns the object. Note that it is possible for
50      * this to return NULL. When objects have been release()ed or abandon()ed
51      * they no longer have an owning context. Destroying a GrContext
52      * automatically releases all its resources.
53      */
54     const GrContext* getContext() const;
55     GrContext* getContext();
56 
incDeferredRefCount()57     void incDeferredRefCount() const {
58         SkASSERT(fDeferredRefCount >= 0);
59         ++fDeferredRefCount;
60     }
61 
decDeferredRefCount()62     void decDeferredRefCount() const {
63         SkASSERT(fDeferredRefCount > 0);
64         --fDeferredRefCount;
65         if (0 == fDeferredRefCount && this->needsDeferredUnref()) {
66             SkASSERT(this->getRefCnt() > 1);
67             this->unref();
68         }
69     }
70 
getDeferredRefCount()71     int getDeferredRefCount() const { return fDeferredRefCount; }
72 
setNeedsDeferredUnref()73     void setNeedsDeferredUnref() { fFlags |= kDeferredUnref_FlagBit; }
74 
isValidOnGpu()75     virtual bool isValidOnGpu() const SK_OVERRIDE { return !this->wasDestroyed(); }
76 
77 protected:
78     /**
79      * isWrapped indicates we have wrapped a client-created backend object in a GrGpuObject. If it
80      * is true then the client is responsible for the lifetime of the underlying backend object.
81      * Otherwise, our onRelease() should free the object.
82      */
83     GrGpuObject(GrGpu* gpu, bool isWrapped);
84     virtual ~GrGpuObject();
85 
getGpu()86     GrGpu* getGpu() const { return fGpu; }
87 
88     // Derived classes should always call their parent class' onRelease
89     // and onAbandon methods in their overrides.
onRelease()90     virtual void onRelease() {};
onAbandon()91     virtual void onAbandon() {};
92 
isWrapped()93     bool isWrapped() const { return kWrapped_FlagBit & fFlags; }
needsDeferredUnref()94     bool needsDeferredUnref() const { return SkToBool(kDeferredUnref_FlagBit & fFlags); }
95 
96 private:
97 #ifdef SK_DEBUG
98     friend class GrGpu; // for assert in GrGpu to access getGpu
99 #endif
100 
101     // We're in an internal doubly linked list
102     SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrGpuObject);
103 
104     GrGpu*              fGpu;               // not reffed. The GrGpu can be deleted while there
105                                             // are still live GrGpuObjects. It will call
106                                             // release() on all such objects in its destructor.
107     mutable int         fDeferredRefCount;  // How many references in deferred drawing buffers.
108 
109     enum Flags {
110         /**
111          * This object wraps a GPU object given to us by the user.
112          * Lifetime management is left up to the user (i.e., we will not
113          * free it).
114          */
115         kWrapped_FlagBit         = 0x1,
116 
117         /**
118          * This texture should be de-refed when the deferred ref count goes
119          * to zero. An object gets into this state when the resource cache
120          * is holding a ref-of-obligation (i.e., someone needs to own it but
121          * no one else wants to) but doesn't really want to keep it around.
122          */
123         kDeferredUnref_FlagBit  = 0x2,
124     };
125     uint32_t         fFlags;
126 
127     typedef GrCacheable INHERITED;
128 };
129 
130 #endif
131