Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | List of all members
SkResourceCache Class Reference

#include <SkResourceCache.h>

Classes

class  Hash
 
struct  Key
 
struct  PurgeSharedIDMessage
 
struct  Rec
 

Public Types

typedef const RecID
 
typedef bool(* FindVisitor) (const Rec &, void *context)
 
typedef SkDiscardableMemory *(* DiscardableFactory) (size_t bytes)
 
typedef void(* Visitor) (const Rec &, void *context)
 

Public Member Functions

 SkResourceCache (DiscardableFactory)
 
 SkResourceCache (size_t byteLimit)
 
 ~SkResourceCache ()
 
bool find (const Key &, FindVisitor, void *context)
 
void add (Rec *, void *payload=nullptr)
 
void visitAll (Visitor, void *context)
 
size_t getTotalBytesUsed () const
 
size_t getTotalByteLimit () const
 
size_t setSingleAllocationByteLimit (size_t maximumAllocationSize)
 
size_t getSingleAllocationByteLimit () const
 
size_t getEffectiveSingleAllocationByteLimit () const
 
size_t setTotalByteLimit (size_t newLimit)
 
void purgeSharedID (uint64_t sharedID)
 
void purgeAll ()
 
DiscardableFactory discardableFactory () const
 
SkCachedDatanewCachedData (size_t bytes)
 
void dump () const
 

Static Public Member Functions

static bool Find (const Key &key, FindVisitor, void *context)
 
static void Add (Rec *, void *payload=nullptr)
 
static void VisitAll (Visitor, void *context)
 
static size_t GetTotalBytesUsed ()
 
static size_t GetTotalByteLimit ()
 
static size_t SetTotalByteLimit (size_t newLimit)
 
static size_t SetSingleAllocationByteLimit (size_t)
 
static size_t GetSingleAllocationByteLimit ()
 
static size_t GetEffectiveSingleAllocationByteLimit ()
 
static void PurgeAll ()
 
static void CheckMessages ()
 
static void TestDumpMemoryStatistics ()
 
static void DumpMemoryStatistics (SkTraceMemoryDump *dump)
 
static DiscardableFactory GetDiscardableFactory ()
 
static SkCachedDataNewCachedData (size_t bytes)
 
static void PostPurgeSharedID (uint64_t sharedID)
 
static void Dump ()
 

Detailed Description

Cache object for bitmaps (with possible scale in X Y as part of the key).

Multiple caches can be instantiated, but each instance is not implicitly thread-safe, so if a given instance is to be shared across threads, the caller must manage the access itself (e.g. via a mutex).

As a convenience, a global instance is also defined, which can be safely access across threads via the static methods (e.g. FindAndLock, etc.).

Definition at line 30 of file SkResourceCache.h.

Member Typedef Documentation

◆ DiscardableFactory

typedef SkDiscardableMemory *(* SkResourceCache::DiscardableFactory) (size_t bytes)

Returns a locked/pinned SkDiscardableMemory instance for the specified number of bytes, or nullptr on failure.

Definition at line 137 of file SkResourceCache.h.

◆ FindVisitor

typedef bool(* SkResourceCache::FindVisitor) (const Rec &, void *context)

Callback function for find(). If called, the cache will have found a match for the specified Key, and will pass in the corresponding Rec, along with a caller-specified context. The function can read the data in Rec, and copy whatever it likes into context (casting context to whatever it really is).

The return value determines what the cache will do with the Rec. If the function returns true, then the Rec is considered "valid". If false is returned, the Rec will be considered "stale" and will be purged from the cache.

Definition at line 131 of file SkResourceCache.h.

◆ ID

typedef const Rec* SkResourceCache::ID

Definition at line 119 of file SkResourceCache.h.

◆ Visitor

typedef void(* SkResourceCache::Visitor) (const Rec &, void *context)

Definition at line 156 of file SkResourceCache.h.

Constructor & Destructor Documentation

◆ SkResourceCache() [1/2]

SkResourceCache::SkResourceCache ( DiscardableFactory  factory)

Construct the cache to call DiscardableFactory when it allocates memory for the pixels. In this mode, the cache has not explicit budget, and so methods like getTotalBytesUsed() and getTotalByteLimit() will return 0, and setTotalByteLimit will ignore its argument and return 0.

Definition at line 105 of file SkResourceCache.cpp.

106 : fPurgeSharedIDInbox(SK_InvalidUniqueID) {
107 this->init();
108 fDiscardableFactory = factory;
109}
static constexpr uint32_t SK_InvalidUniqueID
Definition SkTypes.h:196

◆ SkResourceCache() [2/2]

SkResourceCache::SkResourceCache ( size_t  byteLimit)
explicit

Construct the cache, allocating memory with malloc, and respect the byteLimit, purging automatically when a new image is added to the cache that pushes the total bytesUsed over the limit. Note: The limit can be changed at runtime with setTotalByteLimit.

Definition at line 111 of file SkResourceCache.cpp.

112 : fPurgeSharedIDInbox(SK_InvalidUniqueID) {
113 this->init();
114 fTotalByteLimit = byteLimit;
115}

◆ ~SkResourceCache()

SkResourceCache::~SkResourceCache ( )

Definition at line 117 of file SkResourceCache.cpp.

117 {
118 Rec* rec = fHead;
119 while (rec) {
120 Rec* next = rec->fNext;
121 delete rec;
122 rec = next;
123 }
124 delete fHash;
125}
static float next(float f)

Member Function Documentation

◆ Add()

void SkResourceCache::Add ( Rec rec,
void *  payload = nullptr 
)
static

Definition at line 546 of file SkResourceCache.cpp.

546 {
548 get_cache()->add(rec, payload);
549}
static SkMutex & resource_cache_mutex()
static SkResourceCache * get_cache()
void add(Rec *, void *payload=nullptr)

◆ add()

void SkResourceCache::add ( Rec rec,
void *  payload = nullptr 
)

Definition at line 157 of file SkResourceCache.cpp.

157 {
158 this->checkMessages();
159
160 SkASSERT(rec);
161 // See if we already have this key (racy inserts, etc.)
162 if (Rec** preexisting = fHash->find(rec->getKey())) {
163 Rec* prev = *preexisting;
164 if (prev->canBePurged()) {
165 // if it can be purged, the install may fail, so we have to remove it
166 this->remove(prev);
167 } else {
168 // if it cannot be purged, we reuse it and delete the new one
169 prev->postAddInstall(payload);
170 delete rec;
171 return;
172 }
173 }
174
175 this->addToHead(rec);
176 fHash->set(rec);
177 rec->postAddInstall(payload);
178
180 SkString bytesStr, totalStr;
181 make_size_str(rec->bytesUsed(), &bytesStr);
182 make_size_str(fTotalBytesUsed, &totalStr);
183 SkDebugf("RC: add %5s %12p key %08x -- total %5s, count %d\n",
184 bytesStr.c_str(), rec, rec->getHash(), totalStr.c_str(), fCount);
185 }
186
187 // since the new rec may push us over-budget, we perform a purge check now
188 this->purgeAsNeeded();
189}
static float prev(float f)
#define SkASSERT(cond)
Definition SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static void make_size_str(size_t size, SkString *str)
static bool gDumpCacheTransactions
const char * c_str() const
Definition SkString.h:133
T * find(const K &key) const
Definition SkTHash.h:96
virtual void postAddInstall(void *)

◆ CheckMessages()

void SkResourceCache::CheckMessages ( )
static

Definition at line 536 of file SkResourceCache.cpp.

536 {
538 return get_cache()->checkMessages();
539}

◆ discardableFactory()

DiscardableFactory SkResourceCache::discardableFactory ( ) const
inline

Definition at line 252 of file SkResourceCache.h.

252{ return fDiscardableFactory; }

◆ Dump()

void SkResourceCache::Dump ( )
static

Call SkDebugf() with diagnostic information about the state of the cache

Definition at line 511 of file SkResourceCache.cpp.

511 {
513 get_cache()->dump();
514}

◆ dump()

void SkResourceCache::dump ( ) const

Call SkDebugf() with diagnostic information about the state of the cache

Definition at line 423 of file SkResourceCache.cpp.

423 {
424 this->validate();
425
426 SkDebugf("SkResourceCache: count=%d bytes=%zu %s\n",
427 fCount, fTotalBytesUsed, fDiscardableFactory ? "discardable" : "malloc");
428}

◆ DumpMemoryStatistics()

void SkResourceCache::DumpMemoryStatistics ( SkTraceMemoryDump dump)
static

Dump memory usage statistics of every Rec in the cache using the SkTraceMemoryDump interface.

Definition at line 616 of file SkResourceCache.cpp.

616 {
617 // Since resource could be backed by malloc or discardable, the cache always dumps detailed
618 // stats to be accurate.
620}
static void sk_trace_dump_visitor(const SkResourceCache::Rec &rec, void *context)
static void VisitAll(Visitor, void *context)

◆ find()

bool SkResourceCache::find ( const Key key,
FindVisitor  visitor,
void *  context 
)

Returns true if the visitor was called on a matching Key, and the visitor returned true.

find() will search the cache for the specified Key. If no match is found, return false and do not call the FindVisitor. If a match is found, return whatever the visitor returns. Its return value is interpreted to mean: true : Rec is valid false : Rec is "stale" – the cache will purge it.

Definition at line 129 of file SkResourceCache.cpp.

129 {
130 this->checkMessages();
131
132 if (auto found = fHash->find(key)) {
133 Rec* rec = *found;
134 if (visitor(*rec, context)) {
135 this->moveToHead(rec); // for our LRU
136 return true;
137 } else {
138 this->remove(rec); // stale
139 return false;
140 }
141 }
142 return false;
143}

◆ Find()

bool SkResourceCache::Find ( const Key key,
FindVisitor  visitor,
void *  context 
)
static

Returns true if the visitor was called on a matching Key, and the visitor returned true.

Find() will search the cache for the specified Key. If no match is found, return false and do not call the FindVisitor. If a match is found, return whatever the visitor returns. Its return value is interpreted to mean: true : Rec is valid false : Rec is "stale" – the cache will purge it.

Definition at line 541 of file SkResourceCache.cpp.

541 {
543 return get_cache()->find(key, visitor, context);
544}
bool find(const Key &, FindVisitor, void *context)

◆ GetDiscardableFactory()

SkResourceCache::DiscardableFactory SkResourceCache::GetDiscardableFactory ( )
static

Returns the DiscardableFactory used by the global cache, or nullptr.

Definition at line 501 of file SkResourceCache.cpp.

501 {
503 return get_cache()->discardableFactory();
504}
DiscardableFactory discardableFactory() const

◆ GetEffectiveSingleAllocationByteLimit()

size_t SkResourceCache::GetEffectiveSingleAllocationByteLimit ( )
static

Definition at line 526 of file SkResourceCache.cpp.

◆ getEffectiveSingleAllocationByteLimit()

size_t SkResourceCache::getEffectiveSingleAllocationByteLimit ( ) const

Definition at line 440 of file SkResourceCache.cpp.

440 {
441 // fSingleAllocationByteLimit == 0 means the caller is asking for our default
442 size_t limit = fSingleAllocationByteLimit;
443
444 // if we're not discardable (i.e. we are fixed-budget) then cap the single-limit
445 // to our budget.
446 if (nullptr == fDiscardableFactory) {
447 if (0 == limit) {
448 limit = fTotalByteLimit;
449 } else {
450 limit = std::min(limit, fTotalByteLimit);
451 }
452 }
453 return limit;
454}

◆ GetSingleAllocationByteLimit()

size_t SkResourceCache::GetSingleAllocationByteLimit ( )
static

Definition at line 521 of file SkResourceCache.cpp.

521 {
524}
size_t getSingleAllocationByteLimit() const

◆ getSingleAllocationByteLimit()

size_t SkResourceCache::getSingleAllocationByteLimit ( ) const

Definition at line 436 of file SkResourceCache.cpp.

436 {
437 return fSingleAllocationByteLimit;
438}

◆ GetTotalByteLimit()

size_t SkResourceCache::GetTotalByteLimit ( )
static

Definition at line 491 of file SkResourceCache.cpp.

491 {
493 return get_cache()->getTotalByteLimit();
494}
size_t getTotalByteLimit() const

◆ getTotalByteLimit()

size_t SkResourceCache::getTotalByteLimit ( ) const
inline

Definition at line 226 of file SkResourceCache.h.

226{ return fTotalByteLimit; }

◆ GetTotalBytesUsed()

size_t SkResourceCache::GetTotalBytesUsed ( )
static

Definition at line 486 of file SkResourceCache.cpp.

486 {
488 return get_cache()->getTotalBytesUsed();
489}
size_t getTotalBytesUsed() const

◆ getTotalBytesUsed()

size_t SkResourceCache::getTotalBytesUsed ( ) const
inline

Definition at line 225 of file SkResourceCache.h.

225{ return fTotalBytesUsed; }

◆ NewCachedData()

SkCachedData * SkResourceCache::NewCachedData ( size_t  bytes)
static

Definition at line 506 of file SkResourceCache.cpp.

506 {
508 return get_cache()->newCachedData(bytes);
509}
SkCachedData * newCachedData(size_t bytes)

◆ newCachedData()

SkCachedData * SkResourceCache::newCachedData ( size_t  bytes)

Definition at line 306 of file SkResourceCache.cpp.

306 {
307 this->checkMessages();
308
309 if (fDiscardableFactory) {
310 SkDiscardableMemory* dm = fDiscardableFactory(bytes);
311 return dm ? new SkCachedData(bytes, dm) : nullptr;
312 } else {
313 return new SkCachedData(sk_malloc_throw(bytes), bytes);
314 }
315}
static void * sk_malloc_throw(size_t size)
Definition SkMalloc.h:67

◆ PostPurgeSharedID()

void SkResourceCache::PostPurgeSharedID ( uint64_t  sharedID)
static

Definition at line 556 of file SkResourceCache.cpp.

556 {
557 if (sharedID) {
558 SkMessageBus<PurgeSharedIDMessage, uint32_t>::Post(PurgeSharedIDMessage(sharedID));
559 }
560}
static void Post(Message m)

◆ PurgeAll()

void SkResourceCache::PurgeAll ( )
static

Definition at line 531 of file SkResourceCache.cpp.

531 {
533 return get_cache()->purgeAll();
534}

◆ purgeAll()

void SkResourceCache::purgeAll ( )
inline

Definition at line 248 of file SkResourceCache.h.

248 {
249 this->purgeAsNeeded(true);
250 }

◆ purgeSharedID()

void SkResourceCache::purgeSharedID ( uint64_t  sharedID)

Definition at line 248 of file SkResourceCache.cpp.

248 {
249 if (0 == sharedID) {
250 return;
251 }
252
253#ifdef SK_TRACK_PURGE_SHAREDID_HITRATE
254 gPurgeCallCounter += 1;
255 bool found = false;
256#endif
257 // go backwards, just like purgeAsNeeded, just to make the code similar.
258 // could iterate either direction and still be correct.
259 Rec* rec = fTail;
260 while (rec) {
261 Rec* prev = rec->fPrev;
262 if (rec->getKey().getSharedID() == sharedID) {
263 // even though the "src" is now dead, caches could still be in-flight, so
264 // we have to check if it can be removed.
265 if (rec->canBePurged()) {
266 this->remove(rec);
267 }
268#ifdef SK_TRACK_PURGE_SHAREDID_HITRATE
269 found = true;
270#endif
271 }
272 rec = prev;
273 }
274
275#ifdef SK_TRACK_PURGE_SHAREDID_HITRATE
276 if (found) {
277 gPurgeHitCounter += 1;
278 }
279
280 SkDebugf("PurgeShared calls=%d hits=%d rate=%g\n", gPurgeCallCounter, gPurgeHitCounter,
281 gPurgeHitCounter * 100.0 / gPurgeCallCounter);
282#endif
283}

◆ setSingleAllocationByteLimit()

size_t SkResourceCache::setSingleAllocationByteLimit ( size_t  maximumAllocationSize)

This is respected by SkBitmapProcState::possiblyScaleImage. 0 is no maximum at all; this is the default. setSingleAllocationByteLimit() returns the previous value.

Definition at line 430 of file SkResourceCache.cpp.

430 {
431 size_t oldLimit = fSingleAllocationByteLimit;
432 fSingleAllocationByteLimit = newLimit;
433 return oldLimit;
434}

◆ SetSingleAllocationByteLimit()

size_t SkResourceCache::SetSingleAllocationByteLimit ( size_t  size)
static

Definition at line 516 of file SkResourceCache.cpp.

516 {
519}
size_t setSingleAllocationByteLimit(size_t maximumAllocationSize)

◆ SetTotalByteLimit()

size_t SkResourceCache::SetTotalByteLimit ( size_t  newLimit)
static

Definition at line 496 of file SkResourceCache.cpp.

496 {
498 return get_cache()->setTotalByteLimit(newLimit);
499}
size_t setTotalByteLimit(size_t newLimit)

◆ setTotalByteLimit()

size_t SkResourceCache::setTotalByteLimit ( size_t  newLimit)

Set the maximum number of bytes available to this cache. If the current cache exceeds this new value, it will be purged to try to fit within this new limit.

Definition at line 297 of file SkResourceCache.cpp.

297 {
298 size_t prevLimit = fTotalByteLimit;
299 fTotalByteLimit = newLimit;
300 if (newLimit < prevLimit) {
301 this->purgeAsNeeded();
302 }
303 return prevLimit;
304}

◆ TestDumpMemoryStatistics()

void SkResourceCache::TestDumpMemoryStatistics ( )
static

Definition at line 596 of file SkResourceCache.cpp.

596 {
597 VisitAll(dump_visitor, nullptr);
598}
static void dump_visitor(const SkResourceCache::Rec &rec, void *)

◆ VisitAll()

void SkResourceCache::VisitAll ( Visitor  visitor,
void *  context 
)
static

Definition at line 551 of file SkResourceCache.cpp.

551 {
553 get_cache()->visitAll(visitor, context);
554}
void visitAll(Visitor, void *context)

◆ visitAll()

void SkResourceCache::visitAll ( Visitor  visitor,
void *  context 
)

Definition at line 285 of file SkResourceCache.cpp.

285 {
286 // go backwards, just like purgeAsNeeded, just to make the code similar.
287 // could iterate either direction and still be correct.
288 Rec* rec = fTail;
289 while (rec) {
290 visitor(*rec, context);
291 rec = rec->fPrev;
292 }
293}

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