LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/gpu - GrResourceCache.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 43 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 25 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 GrResourceCache_DEFINED
       9             : #define GrResourceCache_DEFINED
      10             : 
      11             : #include "GrGpuResource.h"
      12             : #include "GrGpuResourceCacheAccess.h"
      13             : #include "GrGpuResourcePriv.h"
      14             : #include "GrResourceCache.h"
      15             : #include "GrResourceKey.h"
      16             : #include "SkMessageBus.h"
      17             : #include "SkRefCnt.h"
      18             : #include "SkTArray.h"
      19             : #include "SkTDPQueue.h"
      20             : #include "SkTInternalLList.h"
      21             : #include "SkTMultiMap.h"
      22             : 
      23             : class GrCaps;
      24             : class SkString;
      25             : class SkTraceMemoryDump;
      26             : 
      27             : /**
      28             :  * Manages the lifetime of all GrGpuResource instances.
      29             :  *
      30             :  * Resources may have optionally have two types of keys:
      31             :  *      1) A scratch key. This is for resources whose allocations are cached but not their contents.
      32             :  *         Multiple resources can share the same scratch key. This is so a caller can have two
      33             :  *         resource instances with the same properties (e.g. multipass rendering that ping-pongs
      34             :  *         between two temporary surfaces). The scratch key is set at resource creation time and
      35             :  *         should never change. Resources need not have a scratch key.
      36             :  *      2) A unique key. This key's meaning is specific to the domain that created the key. Only one
      37             :  *         resource may have a given unique key. The unique key can be set, cleared, or changed
      38             :  *         anytime after resource creation.
      39             :  *
      40             :  * A unique key always takes precedence over a scratch key when a resource has both types of keys.
      41             :  * If a resource has neither key type then it will be deleted as soon as the last reference to it
      42             :  * is dropped.
      43             :  */
      44             : class GrResourceCache {
      45             : public:
      46             :     GrResourceCache(const GrCaps* caps);
      47             :     ~GrResourceCache();
      48             : 
      49             :     // Default maximum number of budgeted resources in the cache.
      50             :     static const int    kDefaultMaxCount            = 2 * (1 << 12);
      51             :     // Default maximum number of bytes of gpu memory of budgeted resources in the cache.
      52             :     static const size_t kDefaultMaxSize             = 96 * (1 << 20);
      53             :     // Default number of external flushes a budgeted resources can go unused in the cache before it
      54             :     // is purged. Using a value <= 0 disables this feature. This will be removed once Chrome
      55             :     // starts using time-based purging.
      56             :     static const int    kDefaultMaxUnusedFlushes =
      57             :             1  * /* flushes per frame */
      58             :             60 * /* fps */
      59             :             30;  /* seconds */
      60             : 
      61             :     /** Used to access functionality needed by GrGpuResource for lifetime management. */
      62             :     class ResourceAccess;
      63             :     ResourceAccess resourceAccess();
      64             : 
      65             :     /**
      66             :      * Sets the cache limits in terms of number of resources, max gpu memory byte size, and number
      67             :      * of external GrContext flushes that a resource can be unused before it is evicted. The latter
      68             :      * value is a suggestion and there is no promise that a resource will be purged immediately
      69             :      * after it hasn't been used in maxUnusedFlushes flushes.
      70             :      */
      71             :     void setLimits(int count, size_t bytes, int maxUnusedFlushes = kDefaultMaxUnusedFlushes);
      72             : 
      73             :     /**
      74             :      * Returns the number of resources.
      75             :      */
      76           0 :     int getResourceCount() const {
      77           0 :         return fPurgeableQueue.count() + fNonpurgeableResources.count();
      78             :     }
      79             : 
      80             :     /**
      81             :      * Returns the number of resources that count against the budget.
      82             :      */
      83           0 :     int getBudgetedResourceCount() const { return fBudgetedCount; }
      84             : 
      85             :     /**
      86             :      * Returns the number of bytes consumed by resources.
      87             :      */
      88             :     size_t getResourceBytes() const { return fBytes; }
      89             : 
      90             :     /**
      91             :      * Returns the number of bytes consumed by budgeted resources.
      92             :      */
      93           0 :     size_t getBudgetedResourceBytes() const { return fBudgetedBytes; }
      94             : 
      95             :     /**
      96             :      * Returns the cached resources count budget.
      97             :      */
      98           0 :     int getMaxResourceCount() const { return fMaxCount; }
      99             : 
     100             :     /**
     101             :      * Returns the number of bytes consumed by cached resources.
     102             :      */
     103           0 :     size_t getMaxResourceBytes() const { return fMaxBytes; }
     104             : 
     105             :     /**
     106             :      * Abandons the backend API resources owned by all GrGpuResource objects and removes them from
     107             :      * the cache.
     108             :      */
     109             :     void abandonAll();
     110             : 
     111             :     /**
     112             :      * Releases the backend API resources owned by all GrGpuResource objects and removes them from
     113             :      * the cache.
     114             :      */
     115             :     void releaseAll();
     116             : 
     117             :     enum {
     118             :         /** Preferentially returns scratch resources with no pending IO. */
     119             :         kPreferNoPendingIO_ScratchFlag = 0x1,
     120             :         /** Will not return any resources that match but have pending IO. */
     121             :         kRequireNoPendingIO_ScratchFlag = 0x2,
     122             :     };
     123             : 
     124             :     /**
     125             :      * Find a resource that matches a scratch key.
     126             :      */
     127             :     GrGpuResource* findAndRefScratchResource(const GrScratchKey& scratchKey,
     128             :                                              size_t resourceSize,
     129             :                                              uint32_t flags);
     130             : 
     131             : #ifdef SK_DEBUG
     132             :     // This is not particularly fast and only used for validation, so debug only.
     133             :     int countScratchEntriesForKey(const GrScratchKey& scratchKey) const {
     134             :         return fScratchMap.countForKey(scratchKey);
     135             :     }
     136             : #endif
     137             : 
     138             :     /**
     139             :      * Find a resource that matches a unique key.
     140             :      */
     141           0 :     GrGpuResource* findAndRefUniqueResource(const GrUniqueKey& key) {
     142           0 :         GrGpuResource* resource = fUniqueHash.find(key);
     143           0 :         if (resource) {
     144           0 :             this->refAndMakeResourceMRU(resource);
     145             :         }
     146           0 :         return resource;
     147             :     }
     148             : 
     149             :     /**
     150             :      * Query whether a unique key exists in the cache.
     151             :      */
     152             :     bool hasUniqueKey(const GrUniqueKey& key) const {
     153             :         return SkToBool(fUniqueHash.find(key));
     154             :     }
     155             : 
     156             :     /** Purges resources to become under budget and processes resources with invalidated unique
     157             :         keys. */
     158             :     void purgeAsNeeded();
     159             : 
     160             :     /** Purges all resources that don't have external owners. */
     161             :     void purgeAllUnlocked();
     162             : 
     163             :     /** Purge all resources not used since the passed in time. */
     164             :     void purgeResourcesNotUsedSince(GrStdSteadyClock::time_point);
     165             : 
     166             :     /** Returns true if the cache would like a flush to occur in order to make more resources
     167             :         purgeable. */
     168           0 :     bool requestsFlush() const { return fRequestFlush; }
     169             : 
     170             :     enum FlushType {
     171             :         kExternal,
     172             :         kImmediateMode,
     173             :         kCacheRequested,
     174             :     };
     175             :     void notifyFlushOccurred(FlushType);
     176             : 
     177             : #if GR_CACHE_STATS
     178             :     struct Stats {
     179             :         int fTotal;
     180             :         int fNumPurgeable;
     181             :         int fNumNonPurgeable;
     182             : 
     183             :         int fScratch;
     184             :         int fWrapped;
     185             :         size_t fUnbudgetedSize;
     186             : 
     187             :         Stats() { this->reset(); }
     188             : 
     189             :         void reset() {
     190             :             fTotal = 0;
     191             :             fNumPurgeable = 0;
     192             :             fNumNonPurgeable = 0;
     193             :             fScratch = 0;
     194             :             fWrapped = 0;
     195             :             fUnbudgetedSize = 0;
     196             :         }
     197             : 
     198             :         void update(GrGpuResource* resource) {
     199             :             if (resource->cacheAccess().isScratch()) {
     200             :                 ++fScratch;
     201             :             }
     202             :             if (resource->resourcePriv().refsWrappedObjects()) {
     203             :                 ++fWrapped;
     204             :             }
     205             :             if (SkBudgeted::kNo  == resource->resourcePriv().isBudgeted()) {
     206             :                 fUnbudgetedSize += resource->gpuMemorySize();
     207             :             }
     208             :         }
     209             :     };
     210             : 
     211             :     void getStats(Stats*) const;
     212             : 
     213             :     void dumpStats(SkString*) const;
     214             : 
     215             :     void dumpStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* value) const;
     216             : #endif
     217             : 
     218             : #ifdef SK_DEBUG
     219             :     int countUniqueKeysWithTag(const char* tag) const;
     220             : #endif
     221             : 
     222             :     // This function is for unit testing and is only defined in test tools.
     223             :     void changeTimestamp(uint32_t newTimestamp);
     224             : 
     225             :     // Enumerates all cached resources and dumps their details to traceMemoryDump.
     226             :     void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
     227             : 
     228             : private:
     229             :     ///////////////////////////////////////////////////////////////////////////
     230             :     /// @name Methods accessible via ResourceAccess
     231             :     ////
     232             :     void insertResource(GrGpuResource*);
     233             :     void removeResource(GrGpuResource*);
     234             :     void notifyCntReachedZero(GrGpuResource*, uint32_t flags);
     235             :     void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize);
     236             :     void changeUniqueKey(GrGpuResource*, const GrUniqueKey&);
     237             :     void removeUniqueKey(GrGpuResource*);
     238             :     void willRemoveScratchKey(const GrGpuResource*);
     239             :     void didChangeBudgetStatus(GrGpuResource*);
     240             :     void refAndMakeResourceMRU(GrGpuResource*);
     241             :     /// @}
     242             : 
     243             :     void processInvalidUniqueKeys(const SkTArray<GrUniqueKeyInvalidatedMessage>&);
     244             :     void addToNonpurgeableArray(GrGpuResource*);
     245             :     void removeFromNonpurgeableArray(GrGpuResource*);
     246           0 :     bool overBudget() const { return fBudgetedBytes > fMaxBytes || fBudgetedCount > fMaxCount; }
     247             : 
     248           0 :     bool wouldFit(size_t bytes) {
     249           0 :         return fBudgetedBytes+bytes <= fMaxBytes && fBudgetedCount+1 <= fMaxCount;
     250             :     }
     251             : 
     252             :     uint32_t getNextTimestamp();
     253             : 
     254             : #ifdef SK_DEBUG
     255             :     bool isInCache(const GrGpuResource* r) const;
     256             :     void validate() const;
     257             : #else
     258             :     void validate() const {}
     259             : #endif
     260             : 
     261             :     class AutoValidate;
     262             : 
     263             :     class AvailableForScratchUse;
     264             : 
     265             :     struct ScratchMapTraits {
     266           0 :         static const GrScratchKey& GetKey(const GrGpuResource& r) {
     267           0 :             return r.resourcePriv().getScratchKey();
     268             :         }
     269             : 
     270           0 :         static uint32_t Hash(const GrScratchKey& key) { return key.hash(); }
     271             :     };
     272             :     typedef SkTMultiMap<GrGpuResource, GrScratchKey, ScratchMapTraits> ScratchMap;
     273             : 
     274             :     struct UniqueHashTraits {
     275           0 :         static const GrUniqueKey& GetKey(const GrGpuResource& r) { return r.getUniqueKey(); }
     276             : 
     277           0 :         static uint32_t Hash(const GrUniqueKey& key) { return key.hash(); }
     278             :     };
     279             :     typedef SkTDynamicHash<GrGpuResource, GrUniqueKey, UniqueHashTraits> UniqueHash;
     280             : 
     281           0 :     static bool CompareTimestamp(GrGpuResource* const& a, GrGpuResource* const& b) {
     282           0 :         return a->cacheAccess().timestamp() < b->cacheAccess().timestamp();
     283             :     }
     284             : 
     285           0 :     static int* AccessResourceIndex(GrGpuResource* const& res) {
     286           0 :         return res->cacheAccess().accessCacheIndex();
     287             :     }
     288             : 
     289             :     typedef SkMessageBus<GrUniqueKeyInvalidatedMessage>::Inbox InvalidUniqueKeyInbox;
     290             :     typedef SkTDPQueue<GrGpuResource*, CompareTimestamp, AccessResourceIndex> PurgeableQueue;
     291             :     typedef SkTDArray<GrGpuResource*> ResourceArray;
     292             : 
     293             :     // Whenever a resource is added to the cache or the result of a cache lookup, fTimestamp is
     294             :     // assigned as the resource's timestamp and then incremented. fPurgeableQueue orders the
     295             :     // purgeable resources by this value, and thus is used to purge resources in LRU order.
     296             :     uint32_t                            fTimestamp;
     297             :     PurgeableQueue                      fPurgeableQueue;
     298             :     ResourceArray                       fNonpurgeableResources;
     299             : 
     300             :     // This map holds all resources that can be used as scratch resources.
     301             :     ScratchMap                          fScratchMap;
     302             :     // This holds all resources that have unique keys.
     303             :     UniqueHash                          fUniqueHash;
     304             : 
     305             :     // our budget, used in purgeAsNeeded()
     306             :     int                                 fMaxCount;
     307             :     size_t                              fMaxBytes;
     308             :     int                                 fMaxUnusedFlushes;
     309             : 
     310             : #if GR_CACHE_STATS
     311             :     int                                 fHighWaterCount;
     312             :     size_t                              fHighWaterBytes;
     313             :     int                                 fBudgetedHighWaterCount;
     314             :     size_t                              fBudgetedHighWaterBytes;
     315             : #endif
     316             : 
     317             :     // our current stats for all resources
     318             :     SkDEBUGCODE(int                     fCount;)
     319             :     size_t                              fBytes;
     320             : 
     321             :     // our current stats for resources that count against the budget
     322             :     int                                 fBudgetedCount;
     323             :     size_t                              fBudgetedBytes;
     324             : 
     325             :     bool                                fRequestFlush;
     326             :     uint32_t                            fExternalFlushCnt;
     327             : 
     328             :     InvalidUniqueKeyInbox               fInvalidUniqueKeyInbox;
     329             : 
     330             :     // This resource is allowed to be in the nonpurgeable array for the sake of validate() because
     331             :     // we're in the midst of converting it to purgeable status.
     332             :     SkDEBUGCODE(GrGpuResource*          fNewlyPurgeableResourceForValidation;)
     333             : 
     334             :     bool                                fPreferVRAMUseOverFlushes;
     335             : };
     336             : 
     337             : class GrResourceCache::ResourceAccess {
     338             : private:
     339           0 :     ResourceAccess(GrResourceCache* cache) : fCache(cache) { }
     340             :     ResourceAccess(const ResourceAccess& that) : fCache(that.fCache) { }
     341             :     ResourceAccess& operator=(const ResourceAccess&); // unimpl
     342             : 
     343             :     /**
     344             :      * Insert a resource into the cache.
     345             :      */
     346           0 :     void insertResource(GrGpuResource* resource) { fCache->insertResource(resource); }
     347             : 
     348             :     /**
     349             :      * Removes a resource from the cache.
     350             :      */
     351           0 :     void removeResource(GrGpuResource* resource) { fCache->removeResource(resource); }
     352             : 
     353             :     /**
     354             :      * Notifications that should be sent to the cache when the ref/io cnt status of resources
     355             :      * changes.
     356             :      */
     357             :     enum RefNotificationFlags {
     358             :         /** All types of refs on the resource have reached zero. */
     359             :         kAllCntsReachedZero_RefNotificationFlag = 0x1,
     360             :         /** The normal (not pending IO type) ref cnt has reached zero. */
     361             :         kRefCntReachedZero_RefNotificationFlag  = 0x2,
     362             :     };
     363             :     /**
     364             :      * Called by GrGpuResources when they detect that their ref/io cnts have reached zero. When the
     365             :      * normal ref cnt reaches zero the flags that are set should be:
     366             :      *     a) kRefCntReachedZero if a pending IO cnt is still non-zero.
     367             :      *     b) (kRefCntReachedZero | kAllCntsReachedZero) when all pending IO cnts are also zero.
     368             :      * kAllCntsReachedZero is set by itself if a pending IO cnt is decremented to zero and all the
     369             :      * the other cnts are already zero.
     370             :      */
     371           0 :     void notifyCntReachedZero(GrGpuResource* resource, uint32_t flags) {
     372           0 :         fCache->notifyCntReachedZero(resource, flags);
     373           0 :     }
     374             : 
     375             :     /**
     376             :      * Called by GrGpuResources when their sizes change.
     377             :      */
     378           0 :     void didChangeGpuMemorySize(const GrGpuResource* resource, size_t oldSize) {
     379           0 :         fCache->didChangeGpuMemorySize(resource, oldSize);
     380           0 :     }
     381             : 
     382             :     /**
     383             :      * Called by GrGpuResources to change their unique keys.
     384             :      */
     385           0 :     void changeUniqueKey(GrGpuResource* resource, const GrUniqueKey& newKey) {
     386           0 :          fCache->changeUniqueKey(resource, newKey);
     387           0 :     }
     388             : 
     389             :     /**
     390             :      * Called by a GrGpuResource to remove its unique key.
     391             :      */
     392           0 :     void removeUniqueKey(GrGpuResource* resource) { fCache->removeUniqueKey(resource); }
     393             : 
     394             :     /**
     395             :      * Called by a GrGpuResource when it removes its scratch key.
     396             :      */
     397           0 :     void willRemoveScratchKey(const GrGpuResource* resource) {
     398           0 :         fCache->willRemoveScratchKey(resource);
     399           0 :     }
     400             : 
     401             :     /**
     402             :      * Called by GrGpuResources when they change from budgeted to unbudgeted or vice versa.
     403             :      */
     404           0 :     void didChangeBudgetStatus(GrGpuResource* resource) { fCache->didChangeBudgetStatus(resource); }
     405             : 
     406             :     // No taking addresses of this type.
     407             :     const ResourceAccess* operator&() const;
     408             :     ResourceAccess* operator&();
     409             : 
     410             :     GrResourceCache* fCache;
     411             : 
     412             :     friend class GrGpuResource; // To access all the proxy inline methods.
     413             :     friend class GrResourceCache; // To create this type.
     414             : };
     415             : 
     416           0 : inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() {
     417           0 :     return ResourceAccess(this);
     418             : }
     419             : 
     420             : #endif

Generated by: LCOV version 1.13