| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 1 | /* | 
| epoger@google.com | ec3ed6a | 2011-07-28 14:26:00 +0000 | [diff] [blame] | 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. | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 6 |  */ | 
 | 7 |  | 
 | 8 | #ifndef GrResource_DEFINED | 
 | 9 | #define GrResource_DEFINED | 
 | 10 |  | 
| commit-bot@chromium.org | a4de8c2 | 2013-09-09 13:38:37 +0000 | [diff] [blame] | 11 | #include "SkRefCnt.h" | 
| bsalomon@google.com | 42619d8 | 2012-12-03 14:54:59 +0000 | [diff] [blame] | 12 | #include "SkTInternalLList.h" | 
| robertphillips@google.com | 9474ed0 | 2012-09-04 13:34:32 +0000 | [diff] [blame] | 13 |  | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 14 | class GrGpu; | 
| bsalomon@google.com | f7b5c1e | 2011-11-15 19:42:07 +0000 | [diff] [blame] | 15 | class GrContext; | 
| robertphillips@google.com | 1f47f4f | 2012-08-16 14:49:16 +0000 | [diff] [blame] | 16 | class GrResourceEntry; | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 17 |  | 
| bsalomon@google.com | 76b7fcc | 2012-04-27 17:24:09 +0000 | [diff] [blame] | 18 | /** | 
 | 19 |  * Base class for the GPU resources created by a GrContext. | 
 | 20 |  */ | 
| commit-bot@chromium.org | a4de8c2 | 2013-09-09 13:38:37 +0000 | [diff] [blame] | 21 | class GrResource : public SkRefCnt { | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 22 | public: | 
| robertphillips@google.com | 4d73ac2 | 2012-06-13 18:54:08 +0000 | [diff] [blame] | 23 |     SK_DECLARE_INST_COUNT(GrResource) | 
| robertphillips@google.com | 977b9c8 | 2012-06-05 19:35:09 +0000 | [diff] [blame] | 24 |  | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 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 |      */ | 
 | 47 |     bool isValid() const { return NULL != fGpu; } | 
 | 48 |  | 
| bsalomon@google.com | cee661a | 2011-07-26 12:32:36 +0000 | [diff] [blame] | 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 |      */ | 
| robertphillips@google.com | 1f47f4f | 2012-08-16 14:49:16 +0000 | [diff] [blame] | 55 |     virtual size_t sizeInBytes() const = 0; | 
| bsalomon@google.com | cee661a | 2011-07-26 12:32:36 +0000 | [diff] [blame] | 56 |  | 
| bsalomon@google.com | 838f6e1 | 2013-01-23 21:37:01 +0000 | [diff] [blame] | 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 |      */ | 
| robertphillips@google.com | 1f47f4f | 2012-08-16 14:49:16 +0000 | [diff] [blame] | 63 |     const GrContext* getContext() const; | 
 | 64 |     GrContext* getContext(); | 
 | 65 |  | 
 | 66 |     void setCacheEntry(GrResourceEntry* cacheEntry) { fCacheEntry = cacheEntry; } | 
 | 67 |     GrResourceEntry* getCacheEntry() { return fCacheEntry; } | 
| bsalomon@google.com | f7b5c1e | 2011-11-15 19:42:07 +0000 | [diff] [blame] | 68 |  | 
| robertphillips@google.com | 9ef0426 | 2013-10-29 14:06:15 +0000 | [diff] [blame^] | 69 |     void incDeferredRefCount() const {  | 
 | 70 |         SkASSERT(fDeferredRefCount >= 0);  | 
 | 71 |         ++fDeferredRefCount;  | 
 | 72 |     } | 
 | 73 |  | 
 | 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 |  | 
| robertphillips@google.com | 0255a5d | 2013-10-24 14:03:01 +0000 | [diff] [blame] | 83 |     int getDeferredRefCount() const { return fDeferredRefCount; } | 
| bsalomon@google.com | 838f6e1 | 2013-01-23 21:37:01 +0000 | [diff] [blame] | 84 |  | 
| robertphillips@google.com | 9ef0426 | 2013-10-29 14:06:15 +0000 | [diff] [blame^] | 85 |     void setNeedsDeferredUnref() { fFlags |= kDeferredUnref_FlagBit; } | 
 | 86 |  | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 87 | protected: | 
| bsalomon@google.com | 7283022 | 2013-01-23 20:25:22 +0000 | [diff] [blame] | 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); | 
| bsalomon@google.com | 76b7fcc | 2012-04-27 17:24:09 +0000 | [diff] [blame] | 94 |     virtual ~GrResource(); | 
 | 95 |  | 
 | 96 |     GrGpu* getGpu() const { return fGpu; } | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 97 |  | 
| robertphillips@google.com | d364554 | 2012-09-05 18:37:39 +0000 | [diff] [blame] | 98 |     // Derived classes should always call their parent class' onRelease | 
 | 99 |     // and onAbandon methods in their overrides. | 
 | 100 |     virtual void onRelease() {}; | 
 | 101 |     virtual void onAbandon() {}; | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 102 |  | 
| bsalomon@google.com | a292112 | 2012-08-28 12:34:17 +0000 | [diff] [blame] | 103 |     bool isInCache() const { return NULL != fCacheEntry; } | 
| robertphillips@google.com | 9ef0426 | 2013-10-29 14:06:15 +0000 | [diff] [blame^] | 104 |     bool isWrapped() const { return kWrapped_FlagBit & fFlags; } | 
 | 105 |     bool needsDeferredUnref() const { return SkToBool(kDeferredUnref_FlagBit & fFlags); } | 
| bsalomon@google.com | a292112 | 2012-08-28 12:34:17 +0000 | [diff] [blame] | 106 |  | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 107 | private: | 
| commit-bot@chromium.org | 515dcd3 | 2013-08-28 14:17:03 +0000 | [diff] [blame] | 108 | #ifdef SK_DEBUG | 
| robertphillips@google.com | 9474ed0 | 2012-09-04 13:34:32 +0000 | [diff] [blame] | 109 |     friend class GrGpu; // for assert in GrGpu to access getGpu | 
 | 110 | #endif | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 111 |  | 
| bsalomon@google.com | 42619d8 | 2012-12-03 14:54:59 +0000 | [diff] [blame] | 112 |     // We're in an internal doubly linked list | 
 | 113 |     SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrResource); | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 114 |  | 
| bsalomon@google.com | 838f6e1 | 2013-01-23 21:37:01 +0000 | [diff] [blame] | 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. | 
| robertphillips@google.com | 1f47f4f | 2012-08-16 14:49:16 +0000 | [diff] [blame] | 121 |  | 
| bsalomon@google.com | 7283022 | 2013-01-23 20:25:22 +0000 | [diff] [blame] | 122 |     enum Flags { | 
| robertphillips@google.com | 9ef0426 | 2013-10-29 14:06:15 +0000 | [diff] [blame^] | 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, | 
| bsalomon@google.com | 7283022 | 2013-01-23 20:25:22 +0000 | [diff] [blame] | 137 |     }; | 
 | 138 |     uint32_t         fFlags; | 
 | 139 |  | 
| commit-bot@chromium.org | a4de8c2 | 2013-09-09 13:38:37 +0000 | [diff] [blame] | 140 |     typedef SkRefCnt INHERITED; | 
| bsalomon@google.com | 8fe7247 | 2011-03-30 21:26:44 +0000 | [diff] [blame] | 141 | }; | 
 | 142 |  | 
 | 143 | #endif |