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