LCOV - code coverage report
Current view: top level - gfx/skia/skia/include/gpu - GrGpuResource.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 68 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 31 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2014 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 GrGpuResource_DEFINED
       9             : #define GrGpuResource_DEFINED
      10             : 
      11             : #include "GrResourceKey.h"
      12             : #include "GrTypesPriv.h"
      13             : 
      14             : class GrContext;
      15             : class GrGpu;
      16             : class GrResourceCache;
      17             : class SkTraceMemoryDump;
      18             : 
      19             : /**
      20             :  * Base class for GrGpuResource. Handles the various types of refs we need. Separated out as a base
      21             :  * class to isolate the ref-cnting behavior and provide friendship without exposing all of
      22             :  * GrGpuResource.
      23             :  *
      24             :  * Gpu resources can have three types of refs:
      25             :  *   1) Normal ref (+ by ref(), - by unref()): These are used by code that is issuing draw calls
      26             :  *      that read and write the resource via GrOpList and by any object that must own a
      27             :  *      GrGpuResource and is itself owned (directly or indirectly) by Skia-client code.
      28             :  *   2) Pending read (+ by addPendingRead(), - by completedRead()): GrContext has scheduled a read
      29             :  *      of the resource by the GPU as a result of a skia API call but hasn't executed it yet.
      30             :  *   3) Pending write (+ by addPendingWrite(), - by completedWrite()): GrContext has scheduled a
      31             :  *      write to the resource by the GPU as a result of a skia API call but hasn't executed it yet.
      32             :  *
      33             :  * The latter two ref types are private and intended only for Gr core code.
      34             :  *
      35             :  * When all the ref/io counts reach zero DERIVED::notifyAllCntsAreZero() will be called (static poly
      36             :  * morphism using CRTP). Similarly when the ref (but not necessarily pending read/write) count
      37             :  * reaches 0 DERIVED::notifyRefCountIsZero() will be called. In the case when an unref() causes both
      38             :  * the ref cnt to reach zero and the other counts are zero, notifyRefCountIsZero() will be called
      39             :  * before notifyIsPurgeable(). Moreover, if notifyRefCountIsZero() returns false then
      40             :  * notifyAllRefCntsAreZero() won't be called at all. notifyRefCountIsZero() must return false if the
      41             :  * object may be deleted after notifyRefCntIsZero() returns.
      42             :  *
      43             :  * GrIORef and GrGpuResource are separate classes for organizational reasons and to be
      44             :  * able to give access via friendship to only the functions related to pending IO operations.
      45             :  */
      46             : template <typename DERIVED> class GrIORef : public SkNoncopyable {
      47             : public:
      48             :     // Some of the signatures are written to mirror SkRefCnt so that GrGpuResource can work with
      49             :     // templated helper classes (e.g. sk_sp). However, we have different categories of
      50             :     // refs (e.g. pending reads). We also don't require thread safety as GrCacheable objects are
      51             :     // not intended to cross thread boundaries.
      52           0 :     void ref() const {
      53           0 :         this->validate();
      54           0 :         ++fRefCnt;
      55           0 :     }
      56             : 
      57           0 :     void unref() const {
      58           0 :         this->validate();
      59             : 
      60           0 :         if (!(--fRefCnt)) {
      61           0 :             if (!static_cast<const DERIVED*>(this)->notifyRefCountIsZero()) {
      62           0 :                 return;
      63             :             }
      64             :         }
      65             : 
      66           0 :         this->didRemoveRefOrPendingIO(kRef_CntType);
      67             :     }
      68             : 
      69           0 :     void validate() const {
      70             : #ifdef SK_DEBUG
      71           0 :         SkASSERT(fRefCnt >= 0);
      72           0 :         SkASSERT(fPendingReads >= 0);
      73           0 :         SkASSERT(fPendingWrites >= 0);
      74           0 :         SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 0);
      75             : #endif
      76           0 :     }
      77             : 
      78             : protected:
      79           0 :     GrIORef() : fRefCnt(1), fPendingReads(0), fPendingWrites(0) { }
      80             : 
      81             :     enum CntType {
      82             :         kRef_CntType,
      83             :         kPendingRead_CntType,
      84             :         kPendingWrite_CntType,
      85             :     };
      86             : 
      87           0 :     bool isPurgeable() const { return !this->internalHasRef() && !this->internalHasPendingIO(); }
      88             : 
      89           0 :     bool internalHasPendingRead() const { return SkToBool(fPendingReads); }
      90           0 :     bool internalHasPendingWrite() const { return SkToBool(fPendingWrites); }
      91           0 :     bool internalHasPendingIO() const { return SkToBool(fPendingWrites | fPendingReads); }
      92             : 
      93           0 :     bool internalHasRef() const { return SkToBool(fRefCnt); }
      94             : 
      95             : private:
      96             :     friend class GrIORefProxy; // needs to forward on wrapped IO calls
      97             :     // This is for a unit test.
      98             :     template <typename T>
      99             :     friend void testingOnly_getIORefCnts(const T*, int* refCnt, int* readCnt, int* writeCnt);
     100             : 
     101           0 :     void addPendingRead() const {
     102           0 :         this->validate();
     103           0 :         ++fPendingReads;
     104           0 :     }
     105             : 
     106           0 :     void completedRead() const {
     107           0 :         this->validate();
     108           0 :         --fPendingReads;
     109           0 :         this->didRemoveRefOrPendingIO(kPendingRead_CntType);
     110           0 :     }
     111             : 
     112           0 :     void addPendingWrite() const {
     113           0 :         this->validate();
     114           0 :         ++fPendingWrites;
     115           0 :     }
     116             : 
     117           0 :     void completedWrite() const {
     118           0 :         this->validate();
     119           0 :         --fPendingWrites;
     120           0 :         this->didRemoveRefOrPendingIO(kPendingWrite_CntType);
     121           0 :     }
     122             : 
     123             : private:
     124           0 :     void didRemoveRefOrPendingIO(CntType cntTypeRemoved) const {
     125           0 :         if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) {
     126           0 :             static_cast<const DERIVED*>(this)->notifyAllCntsAreZero(cntTypeRemoved);
     127             :         }
     128           0 :     }
     129             : 
     130             :     mutable int32_t fRefCnt;
     131             :     mutable int32_t fPendingReads;
     132             :     mutable int32_t fPendingWrites;
     133             : 
     134             :     // This class is used to manage conversion of refs to pending reads/writes.
     135             :     friend class GrGpuResourceRef;
     136             :     friend class GrResourceCache; // to check IO ref counts.
     137             : 
     138             :     template <typename, GrIOType> friend class GrPendingIOResource;
     139             : };
     140             : 
     141             : /**
     142             :  * Base class for objects that can be kept in the GrResourceCache.
     143             :  */
     144             : class SK_API GrGpuResource : public GrIORef<GrGpuResource> {
     145             : public:
     146             : 
     147             :     /**
     148             :      * Tests whether a object has been abandoned or released. All objects will
     149             :      * be in this state after their creating GrContext is destroyed or has
     150             :      * contextLost called. It's up to the client to test wasDestroyed() before
     151             :      * attempting to use an object if it holds refs on objects across
     152             :      * ~GrContext, freeResources with the force flag, or contextLost.
     153             :      *
     154             :      * @return true if the object has been released or abandoned,
     155             :      *         false otherwise.
     156             :      */
     157           0 :     bool wasDestroyed() const { return NULL == fGpu; }
     158             : 
     159             :     /**
     160             :      * Retrieves the context that owns the object. Note that it is possible for
     161             :      * this to return NULL. When objects have been release()ed or abandon()ed
     162             :      * they no longer have an owning context. Destroying a GrContext
     163             :      * automatically releases all its resources.
     164             :      */
     165             :     const GrContext* getContext() const;
     166             :     GrContext* getContext();
     167             : 
     168             :     /**
     169             :      * Retrieves the amount of GPU memory used by this resource in bytes. It is
     170             :      * approximate since we aren't aware of additional padding or copies made
     171             :      * by the driver.
     172             :      *
     173             :      * @return the amount of GPU memory used in bytes
     174             :      */
     175           0 :     size_t gpuMemorySize() const {
     176           0 :         if (kInvalidGpuMemorySize == fGpuMemorySize) {
     177           0 :             fGpuMemorySize = this->onGpuMemorySize();
     178           0 :             SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
     179             :         }
     180           0 :         return fGpuMemorySize;
     181             :     }
     182             : 
     183             :     class UniqueID {
     184             :     public:
     185           0 :         static UniqueID InvalidID() {
     186           0 :             return UniqueID(uint32_t(SK_InvalidUniqueID));
     187             :         }
     188             : 
     189           0 :         UniqueID() {}
     190             : 
     191           0 :         explicit UniqueID(uint32_t id) : fID(id) {}
     192             : 
     193           0 :         uint32_t asUInt() const { return fID; }
     194             : 
     195           0 :         bool operator==(const UniqueID& other) const {
     196           0 :             return fID == other.fID;
     197             :         }
     198           0 :         bool operator!=(const UniqueID& other) const {
     199           0 :             return !(*this == other);
     200             :         }
     201             : 
     202           0 :         void makeInvalid() { fID = SK_InvalidUniqueID; }
     203           0 :         bool isInvalid() const { return SK_InvalidUniqueID == fID; }
     204             : 
     205             :     protected:
     206             :         uint32_t fID;
     207             :     };
     208             : 
     209             :     /**
     210             :      * Gets an id that is unique for this GrGpuResource object. It is static in that it does
     211             :      * not change when the content of the GrGpuResource object changes. This will never return
     212             :      * 0.
     213             :      */
     214           0 :     UniqueID uniqueID() const { return fUniqueID; }
     215             : 
     216             :     /** Returns the current unique key for the resource. It will be invalid if the resource has no
     217             :         associated unique key. */
     218           0 :     const GrUniqueKey& getUniqueKey() const { return fUniqueKey; }
     219             : 
     220             :     /**
     221             :      * Internal-only helper class used for manipulations of the resource by the cache.
     222             :      */
     223             :     class CacheAccess;
     224             :     inline CacheAccess cacheAccess();
     225             :     inline const CacheAccess cacheAccess() const;
     226             : 
     227             :     /**
     228             :      * Internal-only helper class used for manipulations of the resource by internal code.
     229             :      */
     230             :     class ResourcePriv;
     231             :     inline ResourcePriv resourcePriv();
     232             :     inline const ResourcePriv resourcePriv() const;
     233             : 
     234             :     /**
     235             :      * Removes references to objects in the underlying 3D API without freeing them.
     236             :      * Called by CacheAccess.
     237             :      * In general this method should not be called outside of skia. It was
     238             :      * made by public for a special case where it needs to be called in Blink
     239             :      * when a texture becomes unsafe to use after having been shared through
     240             :      * a texture mailbox.
     241             :      */
     242             :     void abandon();
     243             : 
     244             :     /**
     245             :      * Dumps memory usage information for this GrGpuResource to traceMemoryDump.
     246             :      * Typically, subclasses should not need to override this, and should only
     247             :      * need to override setMemoryBacking.
     248             :      **/
     249             :     virtual void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
     250             : 
     251             :     static uint32_t CreateUniqueID();
     252             : 
     253             : protected:
     254             :     // This must be called by every non-wrapped GrGpuObject. It should be called once the object is
     255             :     // fully initialized (i.e. only from the constructors of the final class).
     256             :     void registerWithCache(SkBudgeted);
     257             : 
     258             :     // This must be called by every GrGpuObject that references any wrapped backend objects. It
     259             :     // should be called once the object is fully initialized (i.e. only from the constructors of the
     260             :     // final class).
     261             :     void registerWithCacheWrapped();
     262             : 
     263             :     // This is only called by resources that are being exported from Ganesh to client code. It
     264             :     // ensures that the cache can no longer reach this resource, and that it no longer counts
     265             :     // against the budget.
     266             :     void detachFromCache();
     267             : 
     268             :     GrGpuResource(GrGpu*);
     269             :     virtual ~GrGpuResource();
     270             : 
     271           0 :     GrGpu* getGpu() const { return fGpu; }
     272             : 
     273             :     /** Overridden to free GPU resources in the backend API. */
     274           0 :     virtual void onRelease() { }
     275             :     /** Overridden to abandon any internal handles, ptrs, etc to backend API resources.
     276             :         This may be called when the underlying 3D context is no longer valid and so no
     277             :         backend API calls should be made. */
     278           0 :     virtual void onAbandon() { }
     279             : 
     280             :     /**
     281             :      * This entry point should be called whenever gpuMemorySize() should report a different size.
     282             :      * The cache will call gpuMemorySize() to update the current size of the resource.
     283             :      */
     284             :     void didChangeGpuMemorySize() const;
     285             : 
     286             :     /**
     287             :      * Allows subclasses to add additional backing information to the SkTraceMemoryDump. Called by
     288             :      * onMemoryDump. The default implementation adds no backing information.
     289             :      **/
     290           0 :     virtual void setMemoryBacking(SkTraceMemoryDump*, const SkString&) const {}
     291             : 
     292             : private:
     293             :     /**
     294             :      * Called by the registerWithCache if the resource is available to be used as scratch.
     295             :      * Resource subclasses should override this if the instances should be recycled as scratch
     296             :      * resources and populate the scratchKey with the key.
     297             :      * By default resources are not recycled as scratch.
     298             :      **/
     299           0 :     virtual void computeScratchKey(GrScratchKey*) const { }
     300             : 
     301             :     /**
     302             :      * Frees the object in the underlying 3D API. Called by CacheAccess.
     303             :      */
     304             :     void release();
     305             : 
     306             :     virtual size_t onGpuMemorySize() const = 0;
     307             : 
     308             :     // See comments in CacheAccess and ResourcePriv.
     309             :     void setUniqueKey(const GrUniqueKey&);
     310             :     void removeUniqueKey();
     311             :     void notifyAllCntsAreZero(CntType) const;
     312             :     bool notifyRefCountIsZero() const;
     313             :     void removeScratchKey();
     314             :     void makeBudgeted();
     315             :     void makeUnbudgeted();
     316             : 
     317             : #ifdef SK_DEBUG
     318             :     friend class GrGpu;  // for assert in GrGpu to access getGpu
     319             : #endif
     320             : 
     321             :     // An index into a heap when this resource is purgeable or an array when not. This is maintained
     322             :     // by the cache.
     323             :     int fCacheArrayIndex;
     324             :     // This value reflects how recently this resource was accessed in the cache. This is maintained
     325             :     // by the cache.
     326             :     uint32_t fTimestamp;
     327             :     uint32_t fExternalFlushCntWhenBecamePurgeable;
     328             :     GrStdSteadyClock::time_point fTimeWhenBecamePurgeable;
     329             : 
     330             :     static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
     331             :     GrScratchKey fScratchKey;
     332             :     GrUniqueKey fUniqueKey;
     333             : 
     334             :     // This is not ref'ed but abandon() or release() will be called before the GrGpu object
     335             :     // is destroyed. Those calls set will this to NULL.
     336             :     GrGpu* fGpu;
     337             :     mutable size_t fGpuMemorySize;
     338             : 
     339             :     SkBudgeted fBudgeted;
     340             :     bool fRefsWrappedObjects;
     341             :     const UniqueID fUniqueID;
     342             : 
     343             :     typedef GrIORef<GrGpuResource> INHERITED;
     344             :     friend class GrIORef<GrGpuResource>; // to access notifyAllCntsAreZero and notifyRefCntIsZero.
     345             : };
     346             : 
     347             : #endif

Generated by: LCOV version 1.13