Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Member Functions | Static Public Attributes | Private Member Functions | List of all members
GrResourceCache Class Referenceabstract

#include <GrResourceCache.h>

Classes

class  ResourceAccess
 
class  UnrefResourceMessage
 

Public Member Functions

 GrResourceCache (skgpu::SingleOwner *owner, GrDirectContext::DirectContextID owningContextID, uint32_t familyID)
 
 ~GrResourceCache ()
 
ResourceAccess resourceAccess ()
 
uint32_t contextUniqueID () const
 
void setLimit (size_t bytes)
 
int getResourceCount () const
 
int getBudgetedResourceCount () const
 
size_t getResourceBytes () const
 
size_t getPurgeableBytes () const
 
size_t getBudgetedResourceBytes () const
 
size_t getMaxResourceBytes () const
 
void abandonAll ()
 
void releaseAll ()
 
GrGpuResourcefindAndRefScratchResource (const skgpu::ScratchKey &scratchKey)
 
GrGpuResourcefindAndRefUniqueResource (const skgpu::UniqueKey &key)
 
bool hasUniqueKey (const skgpu::UniqueKey &key) const
 
void purgeAsNeeded ()
 
void purgeUnlockedResources (GrPurgeResourceOptions opts)
 
void purgeResourcesNotUsedSince (skgpu::StdSteadyClock::time_point purgeTime, GrPurgeResourceOptions opts)
 
bool purgeToMakeHeadroom (size_t desiredHeadroomBytes)
 
bool overBudget () const
 
void purgeUnlockedResources (size_t bytesToPurge, bool preferScratchResources)
 
bool requestsFlush () const
 
void dumpMemoryStatistics (SkTraceMemoryDump *traceMemoryDump) const
 
void setProxyProvider (GrProxyProvider *proxyProvider)
 
void setThreadSafeCache (GrThreadSafeCache *threadSafeCache)
 

Static Public Member Functions

template<typename T >
static std::enable_if_t< std::is_base_of_v< GrGpuResource, T >, void > ReturnResourceFromThread (sk_sp< T > &&resource, GrDirectContext::DirectContextID id)
 

Static Public Attributes

static const size_t kDefaultMaxSize = 256 * (1 << 20)
 

Private Member Functions

 SkDEBUGCODE (int fCount=0;) size_t fBytes=0
 
Methods accessible via ResourceAccess

/

Detailed Description

Manages the lifetime of all GrGpuResource instances.

Resources may have optionally have two types of keys: 1) A scratch key. This is for resources whose allocations are cached but not their contents. Multiple resources can share the same scratch key. This is so a caller can have two resource instances with the same properties (e.g. multipass rendering that ping-pongs between two temporary surfaces). The scratch key is set at resource creation time and should never change. Resources need not have a scratch key. 2) A unique key. This key's meaning is specific to the domain that created the key. Only one resource may have a given unique key. The unique key can be set, cleared, or changed anytime after resource creation.

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.

Definition at line 53 of file GrResourceCache.h.

Constructor & Destructor Documentation

◆ GrResourceCache()

GrResourceCache::GrResourceCache ( skgpu::SingleOwner owner,
GrDirectContext::DirectContextID  owningContextID,
uint32_t  familyID 
)

◆ ~GrResourceCache()

GrResourceCache::~GrResourceCache ( )

Definition at line 62 of file GrResourceCache.cpp.

62 {
63 this->releaseAll();
64}

Member Function Documentation

◆ abandonAll()

void GrResourceCache::abandonAll ( )

Abandons the backend API resources owned by all GrGpuResource objects and removes them from the cache.

Definition at line 136 of file GrResourceCache.cpp.

136 {
137 AutoValidate av(this);
138
139 while (!fNonpurgeableResources.empty()) {
140 GrGpuResource* back = *(fNonpurgeableResources.end() - 1);
141 SkASSERT(!back->wasDestroyed());
142 back->cacheAccess().abandon();
143 }
144
145 while (fPurgeableQueue.count()) {
146 GrGpuResource* top = fPurgeableQueue.peek();
147 SkASSERT(!top->wasDestroyed());
148 top->cacheAccess().abandon();
149 }
150
151 fThreadSafeCache->dropAllRefs();
152
153 SkASSERT(!fScratchMap.count());
154 SkASSERT(!fUniqueHash.count());
155 SkASSERT(!fCount);
156 SkASSERT(!this->getResourceCount());
157 SkASSERT(!fBytes);
158 SkASSERT(!fBudgetedCount);
159 SkASSERT(!fBudgetedBytes);
160 SkASSERT(!fPurgeableBytes);
161}
#define SkASSERT(cond)
Definition SkAssert.h:116
bool wasDestroyed() const
int getResourceCount() const
void dropAllRefs() SK_EXCLUDES(fSpinLock)
T * end()
Definition SkTDArray.h:152
bool empty() const
Definition SkTDArray.h:135
const T & peek() const
Definition SkTDPQueue.h:48
int count() const
Definition SkTDPQueue.h:45
int count() const
int count() const

◆ contextUniqueID()

uint32_t GrResourceCache::contextUniqueID ( ) const
inline

Unique ID of the owning GrContext.

Definition at line 87 of file GrResourceCache.h.

87{ return fContextUniqueID; }

◆ dumpMemoryStatistics()

void GrResourceCache::dumpMemoryStatistics ( SkTraceMemoryDump traceMemoryDump) const

Definition at line 723 of file GrResourceCache.cpp.

723 {
724 for (int i = 0; i < fNonpurgeableResources.size(); ++i) {
725 fNonpurgeableResources[i]->dumpMemoryStatistics(traceMemoryDump);
726 }
727 for (int i = 0; i < fPurgeableQueue.count(); ++i) {
728 fPurgeableQueue.at(i)->dumpMemoryStatistics(traceMemoryDump);
729 }
730}
virtual void dumpMemoryStatistics(SkTraceMemoryDump *traceMemoryDump) const
int size() const
Definition SkTDArray.h:138
T at(int i) const
Definition SkTDPQueue.h:110

◆ findAndRefScratchResource()

GrGpuResource * GrResourceCache::findAndRefScratchResource ( const skgpu::ScratchKey scratchKey)

Find a resource that matches a scratch key.

Definition at line 210 of file GrResourceCache.cpp.

210 {
211 SkASSERT(scratchKey.isValid());
212
213 GrGpuResource* resource = fScratchMap.find(scratchKey);
214 if (resource) {
215 fScratchMap.remove(scratchKey, resource);
216 this->refAndMakeResourceMRU(resource);
217 this->validate();
218 }
219 return resource;
220}
T * find(const Key &key) const
Definition SkTMultiMap.h:94
void remove(const Key &key, const T *value)
Definition SkTMultiMap.h:66
bool isValid() const
Definition ResourceKey.h:55

◆ findAndRefUniqueResource()

GrGpuResource * GrResourceCache::findAndRefUniqueResource ( const skgpu::UniqueKey key)
inline

Find a resource that matches a unique key.

Definition at line 151 of file GrResourceCache.h.

151 {
152 GrGpuResource* resource = fUniqueHash.find(key);
153 if (resource) {
154 this->refAndMakeResourceMRU(resource);
155 }
156 return resource;
157 }
T * find(const Key &key) const

◆ getBudgetedResourceBytes()

size_t GrResourceCache::getBudgetedResourceBytes ( ) const
inline

Returns the number of bytes consumed by budgeted resources.

Definition at line 117 of file GrResourceCache.h.

117{ return fBudgetedBytes; }

◆ getBudgetedResourceCount()

int GrResourceCache::getBudgetedResourceCount ( ) const
inline

Returns the number of resources that count against the budget.

Definition at line 102 of file GrResourceCache.h.

102{ return fBudgetedCount; }

◆ getMaxResourceBytes()

size_t GrResourceCache::getMaxResourceBytes ( ) const
inline

Returns the number of bytes consumed by cached resources.

Definition at line 122 of file GrResourceCache.h.

122{ return fMaxBytes; }

◆ getPurgeableBytes()

size_t GrResourceCache::getPurgeableBytes ( ) const
inline

Returns the number of bytes held by unlocked resources which are available for purging.

Definition at line 112 of file GrResourceCache.h.

112{ return fPurgeableBytes; }

◆ getResourceBytes()

size_t GrResourceCache::getResourceBytes ( ) const
inline

Returns the number of bytes consumed by resources.

Definition at line 107 of file GrResourceCache.h.

107{ return fBytes; }

◆ getResourceCount()

int GrResourceCache::getResourceCount ( ) const
inline

Returns the number of resources.

Definition at line 95 of file GrResourceCache.h.

95 {
96 return fPurgeableQueue.count() + fNonpurgeableResources.size();
97 }

◆ hasUniqueKey()

bool GrResourceCache::hasUniqueKey ( const skgpu::UniqueKey key) const
inline

Query whether a unique key exists in the cache.

Definition at line 162 of file GrResourceCache.h.

162 {
163 return SkToBool(fUniqueHash.find(key));
164 }
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35

◆ overBudget()

bool GrResourceCache::overBudget ( ) const
inline

Definition at line 190 of file GrResourceCache.h.

190{ return fBudgetedBytes > fMaxBytes; }

◆ purgeAsNeeded()

void GrResourceCache::purgeAsNeeded ( )

Purges resources to become under budget and processes resources with invalidated unique keys.

Definition at line 441 of file GrResourceCache.cpp.

441 {
443 fInvalidUniqueKeyInbox.poll(&invalidKeyMsgs);
444 if (!invalidKeyMsgs.empty()) {
445 SkASSERT(fProxyProvider);
446
447 for (int i = 0; i < invalidKeyMsgs.size(); ++i) {
448 if (invalidKeyMsgs[i].inThreadSafeCache()) {
449 fThreadSafeCache->remove(invalidKeyMsgs[i].key());
450 SkASSERT(!fThreadSafeCache->has(invalidKeyMsgs[i].key()));
451 } else {
452 fProxyProvider->processInvalidUniqueKey(
453 invalidKeyMsgs[i].key(), nullptr,
455 SkASSERT(!this->findAndRefUniqueResource(invalidKeyMsgs[i].key()));
456 }
457 }
458 }
459
460 this->processFreedGpuResources();
461
462 bool stillOverbudget = this->overBudget();
463 while (stillOverbudget && fPurgeableQueue.count()) {
464 GrGpuResource* resource = fPurgeableQueue.peek();
465 SkASSERT(resource->resourcePriv().isPurgeable());
466 resource->cacheAccess().release();
467 stillOverbudget = this->overBudget();
468 }
469
470 if (stillOverbudget) {
471 fThreadSafeCache->dropUniqueRefs(this);
472
473 stillOverbudget = this->overBudget();
474 while (stillOverbudget && fPurgeableQueue.count()) {
475 GrGpuResource* resource = fPurgeableQueue.peek();
476 SkASSERT(resource->resourcePriv().isPurgeable());
477 resource->cacheAccess().release();
478 stillOverbudget = this->overBudget();
479 }
480 }
481
482 this->validate();
483}
ResourcePriv resourcePriv()
void processInvalidUniqueKey(const skgpu::UniqueKey &, GrTextureProxy *, InvalidateGPUResource)
bool overBudget() const
GrGpuResource * findAndRefUniqueResource(const skgpu::UniqueKey &key)
void remove(const skgpu::UniqueKey &) SK_EXCLUDES(fSpinLock)
void dropUniqueRefs(GrResourceCache *resourceCache) SK_EXCLUDES(fSpinLock)
bool empty() const
Definition SkTArray.h:194
int size() const
Definition SkTArray.h:416

◆ purgeResourcesNotUsedSince()

void GrResourceCache::purgeResourcesNotUsedSince ( skgpu::StdSteadyClock::time_point  purgeTime,
GrPurgeResourceOptions  opts 
)
inline

Definition at line 180 of file GrResourceCache.h.

181 {
182 this->purgeUnlockedResources(&purgeTime, opts);
183 }
void purgeUnlockedResources(GrPurgeResourceOptions opts)

◆ purgeToMakeHeadroom()

bool GrResourceCache::purgeToMakeHeadroom ( size_t  desiredHeadroomBytes)

If it's possible to purge enough resources to get the provided amount of budget headroom, do so and return true. If it's not possible, do nothing and return false.

Definition at line 552 of file GrResourceCache.cpp.

552 {
553 AutoValidate av(this);
554 if (desiredHeadroomBytes > fMaxBytes) {
555 return false;
556 }
557 if (this->wouldFit(desiredHeadroomBytes)) {
558 return true;
559 }
560 fPurgeableQueue.sort();
561
562 size_t projectedBudget = fBudgetedBytes;
563 int purgeCnt = 0;
564 for (int i = 0; i < fPurgeableQueue.count(); i++) {
565 GrGpuResource* resource = fPurgeableQueue.at(i);
567 projectedBudget -= resource->gpuMemorySize();
568 }
569 if (projectedBudget + desiredHeadroomBytes <= fMaxBytes) {
570 purgeCnt = i + 1;
571 break;
572 }
573 }
574 if (purgeCnt == 0) {
575 return false;
576 }
577
578 // Success! Release the resources.
579 // Copy to array first so we don't mess with the queue.
580 std::vector<GrGpuResource*> resources;
581 resources.reserve(purgeCnt);
582 for (int i = 0; i < purgeCnt; i++) {
583 resources.push_back(fPurgeableQueue.at(i));
584 }
585 for (GrGpuResource* resource : resources) {
586 resource->cacheAccess().release();
587 }
588 return true;
589}
GrBudgetedType budgetedType() const
size_t gpuMemorySize() const
void sort()
Definition SkTDPQueue.h:115

◆ purgeUnlockedResources() [1/2]

void GrResourceCache::purgeUnlockedResources ( GrPurgeResourceOptions  opts)
inline

Definition at line 173 of file GrResourceCache.h.

173 {
174 this->purgeUnlockedResources(/*purgeTime=*/nullptr, opts);
175 }

◆ purgeUnlockedResources() [2/2]

void GrResourceCache::purgeUnlockedResources ( size_t  bytesToPurge,
bool  preferScratchResources 
)

Purge unlocked resources from the cache until the the provided byte count has been reached or we have purged all unlocked resources. The default policy is to purge in LRU order, but can be overridden to prefer purging scratch resources (in LRU order) prior to purging other resource types.

Parameters
maxBytesToPurgethe desired number of bytes to be purged.
preferScratchResourcesIf true scratch resources will be purged prior to other resource types.

Definition at line 591 of file GrResourceCache.cpp.

591 {
592
593 const size_t tmpByteBudget = std::max((size_t)0, fBytes - bytesToPurge);
594 bool stillOverbudget = tmpByteBudget < fBytes;
595
596 if (preferScratchResources && bytesToPurge < fPurgeableBytes) {
597 // Sort the queue
598 fPurgeableQueue.sort();
599
600 // Make a list of the scratch resources to delete
601 SkTDArray<GrGpuResource*> scratchResources;
602 size_t scratchByteCount = 0;
603 for (int i = 0; i < fPurgeableQueue.count() && stillOverbudget; i++) {
604 GrGpuResource* resource = fPurgeableQueue.at(i);
605 SkASSERT(resource->resourcePriv().isPurgeable());
606 if (!resource->getUniqueKey().isValid()) {
607 *scratchResources.append() = resource;
608 scratchByteCount += resource->gpuMemorySize();
609 stillOverbudget = tmpByteBudget < fBytes - scratchByteCount;
610 }
611 }
612
613 // Delete the scratch resources. This must be done as a separate pass
614 // to avoid messing up the sorted order of the queue
615 for (int i = 0; i < scratchResources.size(); i++) {
616 scratchResources[i]->cacheAccess().release();
617 }
618 stillOverbudget = tmpByteBudget < fBytes;
619
620 this->validate();
621 }
622
623 // Purge any remaining resources in LRU order
624 if (stillOverbudget) {
625 const size_t cachedByteCount = fMaxBytes;
626 fMaxBytes = tmpByteBudget;
627 this->purgeAsNeeded();
628 fMaxBytes = cachedByteCount;
629 }
630}
const skgpu::UniqueKey & getUniqueKey() const
T * append()
Definition SkTDArray.h:191

◆ releaseAll()

void GrResourceCache::releaseAll ( )

Releases the backend API resources owned by all GrGpuResource objects and removes them from the cache.

Definition at line 163 of file GrResourceCache.cpp.

163 {
164 AutoValidate av(this);
165
166 fThreadSafeCache->dropAllRefs();
167
168 this->processFreedGpuResources();
169
170 SkASSERT(fProxyProvider); // better have called setProxyProvider
171 SkASSERT(fThreadSafeCache); // better have called setThreadSafeCache too
172
173 // We must remove the uniqueKeys from the proxies here. While they possess a uniqueKey
174 // they also have a raw pointer back to this class (which is presumably going away)!
175 fProxyProvider->removeAllUniqueKeys();
176
177 while (!fNonpurgeableResources.empty()) {
178 GrGpuResource* back = *(fNonpurgeableResources.end() - 1);
179 SkASSERT(!back->wasDestroyed());
180 back->cacheAccess().release();
181 }
182
183 while (fPurgeableQueue.count()) {
184 GrGpuResource* top = fPurgeableQueue.peek();
185 SkASSERT(!top->wasDestroyed());
186 top->cacheAccess().release();
187 }
188
189 SkASSERT(!fScratchMap.count());
190 SkASSERT(!fUniqueHash.count());
191 SkASSERT(!fCount);
192 SkASSERT(!this->getResourceCount());
193 SkASSERT(!fBytes);
194 SkASSERT(!fBudgetedCount);
195 SkASSERT(!fBudgetedBytes);
196 SkASSERT(!fPurgeableBytes);
197}

◆ requestsFlush()

bool GrResourceCache::requestsFlush ( ) const

Returns true if the cache would like a flush to occur in order to make more resources purgeable.

Definition at line 632 of file GrResourceCache.cpp.

632 {
633 return this->overBudget() && !fPurgeableQueue.count() &&
634 fNumBudgetedResourcesFlushWillMakePurgeable > 0;
635}

◆ resourceAccess()

GrResourceCache::ResourceAccess GrResourceCache::resourceAccess ( )
inline

Definition at line 487 of file GrResourceCache.h.

487 {
488 return ResourceAccess(this);
489}

◆ ReturnResourceFromThread()

template<typename T >
static std::enable_if_t< std::is_base_of_v< GrGpuResource, T >, void > GrResourceCache::ReturnResourceFromThread ( sk_sp< T > &&  resource,
GrDirectContext::DirectContextID  id 
)
inlinestatic

This is used to safely return a resource to the cache when the owner may be on another thread from GrDirectContext. If the context still exists then using this method ensures that the resource is received by the cache for processing (recycling or destruction) on the context's thread.

This is templated as it is rather than simply taking sk_sp<GrGpuResource> in order to enforce that the caller passes an rvalue. If the caller doesn't move its ref into this function then it will retain ownership, defeating the purpose. (Note that sk_sp<GrGpuResource>&& doesn't work either because calling with sk_sp<GrSpecificResource> will create a temporary sk_sp<GrGpuResource> which is an rvalue).

Definition at line 74 of file GrResourceCache.h.

74 {
75 UnrefResourceMessage msg(std::move(resource), id);
76 UnrefResourceMessage::Bus::Post(std::move(msg));
77 }
static void Post(Message m)

◆ setLimit()

void GrResourceCache::setLimit ( size_t  bytes)

Sets the max gpu memory byte size of the cache.

Definition at line 66 of file GrResourceCache.cpp.

66 {
67 fMaxBytes = bytes;
68 this->purgeAsNeeded();
69}

◆ setProxyProvider()

void GrResourceCache::setProxyProvider ( GrProxyProvider proxyProvider)
inline

Definition at line 264 of file GrResourceCache.h.

264{ fProxyProvider = proxyProvider; }

◆ setThreadSafeCache()

void GrResourceCache::setThreadSafeCache ( GrThreadSafeCache threadSafeCache)
inline

Definition at line 265 of file GrResourceCache.h.

265 {
266 fThreadSafeCache = threadSafeCache;
267 }

◆ SkDEBUGCODE()

GrResourceCache::SkDEBUGCODE ( int  fCount = 0;)
privatepure virtual

Member Data Documentation

◆ kDefaultMaxSize

const size_t GrResourceCache::kDefaultMaxSize = 256 * (1 << 20)
static

Definition at line 80 of file GrResourceCache.h.


The documentation for this class was generated from the following files: