Home | History | Annotate | Download | only in gpu
      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
    131