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 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      */
     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 
     66     void setCacheEntry(GrResourceEntry* cacheEntry) { fCacheEntry = cacheEntry; }
     67     GrResourceEntry* getCacheEntry() { return fCacheEntry; }
     68 
     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 
     83     int getDeferredRefCount() const { return fDeferredRefCount; }
     84 
     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 
     96     GrGpu* getGpu() const { return fGpu; }
     97 
     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() {};
    102 
    103     bool isInCache() const { return NULL != fCacheEntry; }
    104     bool isWrapped() const { return kWrapped_FlagBit & fFlags; }
    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