commit-bot@chromium.org | 089a780 | 2014-05-02 21:38:22 +0000 | [diff] [blame] | 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 | */ |
| 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 | |
| 57 | void incDeferredRefCount() const { |
| 58 | SkASSERT(fDeferredRefCount >= 0); |
| 59 | ++fDeferredRefCount; |
| 60 | } |
| 61 | |
| 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 | |
| 71 | int getDeferredRefCount() const { return fDeferredRefCount; } |
| 72 | |
| 73 | void setNeedsDeferredUnref() { fFlags |= kDeferredUnref_FlagBit; } |
| 74 | |
| 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 | |
| 86 | GrGpu* getGpu() const { return fGpu; } |
| 87 | |
| 88 | // Derived classes should always call their parent class' onRelease |
| 89 | // and onAbandon methods in their overrides. |
| 90 | virtual void onRelease() {}; |
| 91 | virtual void onAbandon() {}; |
| 92 | |
| 93 | bool isWrapped() const { return kWrapped_FlagBit & fFlags; } |
| 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 |