| Index: src/gpu/GrResourceCache.h
|
| diff --git a/src/gpu/GrResourceCache.h b/src/gpu/GrResourceCache.h
|
| index 8331bf5d1642b44e82b813d5ab2a800719076732..9880d69f6e6832200d83d6c17dab8832e089cd05 100644
|
| --- a/src/gpu/GrResourceCache.h
|
| +++ b/src/gpu/GrResourceCache.h
|
| @@ -38,20 +38,39 @@ class SkString;
|
| * A unique key always takes precedence over a scratch key when a resource has both types of keys.
|
| * If a resource has neither key type then it will be deleted as soon as the last reference to it
|
| * is dropped.
|
| + *
|
| + * When proactive purging is enabled, on every flush, the timestamp of that flush is stored in a
|
| + * n-sized ring buffer. When purging occurs each purgeable resource's timestamp is compared to the
|
| + * timestamp of the n-th prior flush. If the resource's last use timestamp is older than the old
|
| + * flush then the resource is proactively purged even when the cache is under budget. By default
|
| + * this feature is disabled, though it can be enabled by calling GrResourceCache::setLimits.
|
| */
|
| class GrResourceCache {
|
| public:
|
| GrResourceCache();
|
| ~GrResourceCache();
|
|
|
| + // Default maximum number of budgeted resources in the cache.
|
| + static const int kDefaultMaxCount = 2 * (1 << 12);
|
| + // Default maximum number of bytes of gpu memory of budgeted resources in the cache.
|
| + static const size_t kDefaultMaxSize = 96 * (1 << 20);
|
| + // Default number of flushes a budgeted resources can go unused in the cache before it is
|
| + // purged. Large values disable the feature (as the ring buffer of flush timestamps would be
|
| + // large). This is currently the default until we decide to enable this feature
|
| + // of the cache by default.
|
| + static const int kDefaultMaxUnusedFlushes = 1024;
|
| +
|
| /** Used to access functionality needed by GrGpuResource for lifetime management. */
|
| class ResourceAccess;
|
| ResourceAccess resourceAccess();
|
|
|
| /**
|
| - * Sets the cache limits in terms of number of resources and max gpu memory byte size.
|
| + * Sets the cache limits in terms of number of resources, max gpu memory byte size, and number
|
| + * of GrContext flushes that a resource can be unused before it is evicted. The latter value is
|
| + * a suggestion and there is no promise that a resource will be purged immediately after it
|
| + * hasn't been used in maxUnusedFlushes flushes.
|
| */
|
| - void setLimits(int count, size_t bytes);
|
| + void setLimits(int count, size_t bytes, int maxUnusedFlushes = kDefaultMaxUnusedFlushes);
|
|
|
| /**
|
| * Returns the number of resources.
|
| @@ -136,17 +155,7 @@ public:
|
|
|
| /** Purges resources to become under budget and processes resources with invalidated unique
|
| keys. */
|
| - void purgeAsNeeded() {
|
| - SkTArray<GrUniqueKeyInvalidatedMessage> invalidKeyMsgs;
|
| - fInvalidUniqueKeyInbox.poll(&invalidKeyMsgs);
|
| - if (invalidKeyMsgs.count()) {
|
| - this->processInvalidUniqueKeys(invalidKeyMsgs);
|
| - }
|
| - if (fBudgetedCount <= fMaxCount && fBudgetedBytes <= fMaxBytes) {
|
| - return;
|
| - }
|
| - this->internalPurgeAsNeeded();
|
| - }
|
| + void purgeAsNeeded();
|
|
|
| /** Purges all resources that don't have external owners. */
|
| void purgeAllUnlocked();
|
| @@ -166,6 +175,8 @@ public:
|
| fOverBudgetCB = overBudgetCB;
|
| fOverBudgetData = data;
|
| }
|
| +
|
| + void notifyFlushOccurred();
|
|
|
| #if GR_GPU_STATS
|
| void dumpStats(SkString*) const;
|
| @@ -180,7 +191,7 @@ private:
|
| ////
|
| void insertResource(GrGpuResource*);
|
| void removeResource(GrGpuResource*);
|
| - void notifyPurgeable(GrGpuResource*);
|
| + void notifyCntReachedZero(GrGpuResource*, uint32_t flags);
|
| void didChangeGpuMemorySize(const GrGpuResource*, size_t oldSize);
|
| void changeUniqueKey(GrGpuResource*, const GrUniqueKey&);
|
| void removeUniqueKey(GrGpuResource*);
|
| @@ -189,7 +200,7 @@ private:
|
| void refAndMakeResourceMRU(GrGpuResource*);
|
| /// @}
|
|
|
| - void internalPurgeAsNeeded();
|
| + void resetFlushTimestamps();
|
| void processInvalidUniqueKeys(const SkTArray<GrUniqueKeyInvalidatedMessage>&);
|
| void addToNonpurgeableArray(GrGpuResource*);
|
| void removeFromNonpurgeableArray(GrGpuResource*);
|
| @@ -251,6 +262,7 @@ private:
|
| // our budget, used in purgeAsNeeded()
|
| int fMaxCount;
|
| size_t fMaxBytes;
|
| + int fMaxUnusedFlushes;
|
|
|
| #if GR_CACHE_STATS
|
| int fHighWaterCount;
|
| @@ -270,7 +282,16 @@ private:
|
| PFOverBudgetCB fOverBudgetCB;
|
| void* fOverBudgetData;
|
|
|
| + // We keep track of the "timestamps" of the last n flushes. If a resource hasn't been used in
|
| + // that time then we well preemptively purge it to reduce memory usage.
|
| + uint32_t* fFlushTimestamps;
|
| + int fLastFlushTimestampIndex;
|
| +
|
| InvalidUniqueKeyInbox fInvalidUniqueKeyInbox;
|
| +
|
| + // This resource is allowed to be in the nonpurgeable array for the sake of validate() because
|
| + // we're in the midst of converting it to purgeable status.
|
| + SkDEBUGCODE(GrGpuResource* fNewlyPurgeableResourceForValidation;)
|
| };
|
|
|
| class GrResourceCache::ResourceAccess {
|
| @@ -290,9 +311,26 @@ private:
|
| void removeResource(GrGpuResource* resource) { fCache->removeResource(resource); }
|
|
|
| /**
|
| - * Called by GrGpuResources when they detects that they are newly purgeable.
|
| + * Notifications that should be sent to the cache when the ref/io cnt status of resources
|
| + * changes.
|
| + */
|
| + enum RefNotificationFlags {
|
| + /** All types of refs on the resource have reached zero. */
|
| + kAllCntsReachedZero_RefNotificationFlag = 0x1,
|
| + /** The normal (not pending IO type) ref cnt has reached zero. */
|
| + kRefCntReachedZero_RefNotificationFlag = 0x2,
|
| + };
|
| + /**
|
| + * Called by GrGpuResources when they detect that their ref/io cnts have reached zero. When the
|
| + * normal ref cnt reaches zero the flags that are set should be:
|
| + * a) kRefCntReachedZero if a pending IO cnt is still non-zero.
|
| + * b) (kRefCntReachedZero | kAllCntsReachedZero) when all pending IO cnts are also zero.
|
| + * kAllCntsReachedZero is set by itself if a pending IO cnt is decremented to zero and all the
|
| + * the other cnts are already zero.
|
| */
|
| - void notifyPurgeable(GrGpuResource* resource) { fCache->notifyPurgeable(resource); }
|
| + void notifyCntReachedZero(GrGpuResource* resource, uint32_t flags) {
|
| + fCache->notifyCntReachedZero(resource, flags);
|
| + }
|
|
|
| /**
|
| * Called by GrGpuResources when their sizes change.
|
|
|