void SkResourceCache::purgeAsNeeded(bool forcePurge) { size_t byteLimit; int countLimit; if (fDiscardableFactory) { countLimit = SK_DISCARDABLEMEMORY_SCALEDIMAGECACHE_COUNT_LIMIT; byteLimit = SK_MaxU32; // no limit based on bytes } else { countLimit = SK_MaxS32; // no limit based on count byteLimit = fTotalByteLimit; } Rec* rec = fTail; while (rec) { if (!forcePurge && fTotalBytesUsed < byteLimit && fCount < countLimit) { break; } Rec* prev = rec->fPrev; if (rec->canBePurged()) { this->remove(rec); } rec = prev; } }
void SkResourceCache::add(Rec* rec, void* payload) { this->checkMessages(); SkASSERT(rec); // See if we already have this key (racy inserts, etc.) if (Rec** preexisting = fHash->find(rec->getKey())) { Rec* prev = *preexisting; if (prev->canBePurged()) { // if it can be purged, the install may fail, so we have to remove it this->remove(prev); } else { // if it cannot be purged, we reuse it and delete the new one prev->postAddInstall(payload); delete rec; return; } } this->addToHead(rec); fHash->set(rec); rec->postAddInstall(payload); if (gDumpCacheTransactions) { SkString bytesStr, totalStr; make_size_str(rec->bytesUsed(), &bytesStr); make_size_str(fTotalBytesUsed, &totalStr); SkDebugf("RC: add %5s %12p key %08x -- total %5s, count %d\n", bytesStr.c_str(), rec, rec->getHash(), totalStr.c_str(), fCount); } // since the new rec may push us over-budget, we perform a purge check now this->purgeAsNeeded(); }
void SkResourceCache::purgeSharedID(uint64_t sharedID) { if (0 == sharedID) { return; } #ifdef SK_TRACK_PURGE_SHAREDID_HITRATE gPurgeCallCounter += 1; bool found = false; #endif // go backwards, just like purgeAsNeeded, just to make the code similar. // could iterate either direction and still be correct. Rec* rec = fTail; while (rec) { Rec* prev = rec->fPrev; if (rec->getKey().getSharedID() == sharedID) { // even though the "src" is now dead, caches could still be in-flight, so // we have to check if it can be removed. if (rec->canBePurged()) { this->remove(rec); } #ifdef SK_TRACK_PURGE_SHAREDID_HITRATE found = true; #endif } rec = prev; } #ifdef SK_TRACK_PURGE_SHAREDID_HITRATE if (found) { gPurgeHitCounter += 1; } SkDebugf("PurgeShared calls=%d hits=%d rate=%g\n", gPurgeCallCounter, gPurgeHitCounter, gPurgeHitCounter * 100.0 / gPurgeCallCounter); #endif }