180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2010 Google Inc. 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrResourceCache.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrResource.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 15d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek SollenbergerGrResourceKey::ResourceType GrResourceKey::GenerateResourceType() { 16d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger static int32_t gNextType = 0; 17d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 18d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger int32_t type = sk_atomic_inc(&gNextType); 19d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger if (type >= (1 << 8 * sizeof(ResourceType))) { 20d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger GrCrash("Too many Resource Types"); 21d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger } 22d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 23d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger return static_cast<ResourceType>(type); 24d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger} 25d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 26d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger/////////////////////////////////////////////////////////////////////////////// 27d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrResourceEntry::GrResourceEntry(const GrResourceKey& key, GrResource* resource) 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru : fKey(key), fResource(resource) { 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we assume ownership of the resource, and will unref it when we die 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(resource); 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru resource->ref(); 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrResourceEntry::~GrResourceEntry() { 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fResource->setCacheEntry(NULL); 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fResource->unref(); 3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrResourceEntry::validate() const { 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fResource); 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fResource->getCacheEntry() == this); 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fResource->validate(); 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrResourceCache::GrResourceCache(int maxCount, size_t maxBytes) : 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMaxCount(maxCount), 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMaxBytes(maxBytes) { 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_CACHE_STATS 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHighWaterEntryCount = 0; 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHighWaterEntryBytes = 0; 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHighWaterClientDetachedCount = 0; 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHighWaterClientDetachedBytes = 0; 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEntryCount = 0; 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEntryBytes = 0; 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClientDetachedCount = 0; 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClientDetachedBytes = 0; 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 6558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fPurging = false; 6658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 6758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fOverbudgetCB = NULL; 6858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fOverbudgetData = NULL; 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruGrResourceCache::~GrResourceCache() { 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoResourceCacheValidate atcv(this); 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru EntryList::Iter iter; 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Unlike the removeAll, here we really remove everything, including locked resources. 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru while (GrResourceEntry* entry = fList.head()) { 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoResourceCacheValidate atcv(this); 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // remove from our cache 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCache.remove(entry->fKey, entry); 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // remove from our llist 84363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->internalDetach(entry); 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru delete entry; 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrResourceCache::getLimits(int* maxResources, size_t* maxResourceBytes) const{ 9158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (NULL != maxResources) { 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *maxResources = fMaxCount; 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (NULL != maxResourceBytes) { 9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *maxResourceBytes = fMaxBytes; 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrResourceCache::setLimits(int maxResources, size_t maxResourceBytes) { 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool smaller = (maxResources < fMaxCount) || (maxResourceBytes < fMaxBytes); 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMaxCount = maxResources; 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMaxBytes = maxResourceBytes; 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (smaller) { 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->purgeAsNeeded(); 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrResourceCache::internalDetach(GrResourceEntry* entry, 111363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger BudgetBehaviors behavior) { 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fList.remove(entry); 11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // update our stats 115363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (kIgnore_BudgetBehavior == behavior) { 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClientDetachedCount += 1; 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClientDetachedBytes += entry->resource()->sizeInBytes(); 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_CACHE_STATS 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fHighWaterClientDetachedCount < fClientDetachedCount) { 12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHighWaterClientDetachedCount = fClientDetachedCount; 12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fHighWaterClientDetachedBytes < fClientDetachedBytes) { 12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHighWaterClientDetachedBytes = fClientDetachedBytes; 12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 129363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrAssert(kAccountFor_BudgetBehavior == behavior); 130363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEntryCount -= 1; 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEntryBytes -= entry->resource()->sizeInBytes(); 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrResourceCache::attachToHead(GrResourceEntry* entry, 137363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger BudgetBehaviors behavior) { 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fList.addToHead(entry); 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // update our stats 141363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (kIgnore_BudgetBehavior == behavior) { 14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClientDetachedCount -= 1; 14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClientDetachedBytes -= entry->resource()->sizeInBytes(); 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 145363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrAssert(kAccountFor_BudgetBehavior == behavior); 146363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEntryCount += 1; 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEntryBytes += entry->resource()->sizeInBytes(); 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_CACHE_STATS 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fHighWaterEntryCount < fEntryCount) { 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHighWaterEntryCount = fEntryCount; 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (fHighWaterEntryBytes < fEntryBytes) { 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fHighWaterEntryBytes = fEntryBytes; 15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 161363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// This functor just searches for an entry with only a single ref (from 162363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// the texture cache itself). Presumably in this situation no one else 163363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger// is relying on the texture. 164363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerclass GrTFindUnreffedFunctor { 165363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerpublic: 166363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bool operator()(const GrResourceEntry* entry) const { 16758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return entry->resource()->unique(); 168363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 169363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger}; 170363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 171363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerGrResource* GrResourceCache::find(const GrResourceKey& key, uint32_t ownershipFlags) { 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoResourceCacheValidate atcv(this); 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 174363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrResourceEntry* entry = NULL; 175363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 176363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (ownershipFlags & kNoOtherOwners_OwnershipFlag) { 177363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrTFindUnreffedFunctor functor; 178363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 179363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger entry = fCache.find<GrTFindUnreffedFunctor>(key, functor); 180363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 181363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger entry = fCache.find(key); 182363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 183363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (NULL == entry) { 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return NULL; 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 188363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (ownershipFlags & kHide_OwnershipFlag) { 189363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->makeExclusive(entry); 190363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } else { 191363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Make this resource MRU 192363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->internalDetach(entry); 193363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->attachToHead(entry); 194363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return entry->fResource; 19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 199363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid GrResourceCache::addResource(const GrResourceKey& key, 200363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger GrResource* resource, 201363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger uint32_t ownershipFlags) { 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(NULL == resource->getCacheEntry()); 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we don't expect to create new resources during a purge. In theory 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // this could cause purgeAsNeeded() into an infinite loop (e.g. 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // each resource destroyed creates and locks 2 resources and 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // unlocks 1 thereby causing a new purge). 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(!fPurging); 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoResourceCacheValidate atcv(this); 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResourceEntry* entry = SkNEW_ARGS(GrResourceEntry, (key, resource)); 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru resource->setCacheEntry(entry); 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 213363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->attachToHead(entry); 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCache.insert(key, entry); 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 216363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger if (ownershipFlags & kHide_OwnershipFlag) { 217363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->makeExclusive(entry); 218363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 219363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrResourceCache::makeExclusive(GrResourceEntry* entry) { 22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoResourceCacheValidate atcv(this); 22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 225363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // When scratch textures are detached (to hide them from future finds) they 226363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // still count against the resource budget 227363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger this->internalDetach(entry, kIgnore_BudgetBehavior); 22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCache.remove(entry->key(), entry); 22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fExclusiveList.addToHead(entry); 23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrResourceCache::removeInvalidResource(GrResourceEntry* entry) { 23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // If the resource went invalid while it was detached then purge it 23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // This can happen when a 3D context was lost, 23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // the client called GrContext::contextDestroyed() to notify Gr, 23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // and then later an SkGpuDevice's destructor releases its backing 24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // texture (which was invalidated at contextDestroyed time). 24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClientDetachedCount -= 1; 24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEntryCount -= 1; 24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t size = entry->resource()->sizeInBytes(); 24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClientDetachedBytes -= size; 24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEntryBytes -= size; 24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrResourceCache::makeNonExclusive(GrResourceEntry* entry) { 24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoResourceCacheValidate atcv(this); 25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fExclusiveList.remove(entry); 25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (entry->resource()->isValid()) { 256363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // Since scratch textures still count against the cache budget even 257363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // when they have been removed from the cache, re-adding them doesn't 258363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger // alter the budget information. 259363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger attachToHead(entry, kIgnore_BudgetBehavior); 26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCache.insert(entry->key(), entry); 26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } else { 26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->removeInvalidResource(entry); 26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Destroying a resource may potentially trigger the unlock of additional 26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * resources which in turn will trigger a nested purge. We block the nested 26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * purge using the fPurging variable. However, the initial purge will keep 27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * looping until either all resources in the cache are unlocked or we've met 27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * the budget. There is an assertion in createAndLock to check against a 27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * resource's destructor inserting new resources into the cache. If these 27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * new resources were unlocked before purgeAsNeeded completed it could 27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * potentially make purgeAsNeeded loop infinitely. 27558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * 27658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * extraCount and extraBytes are added to the current resource totals to account 27758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * for incoming resources (e.g., GrContext is about to add 10MB split between 27858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger * 10 textures). 27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 28058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergervoid GrResourceCache::purgeAsNeeded(int extraCount, size_t extraBytes) { 28158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (fPurging) { 28258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger return; 28380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 28458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 28558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fPurging = true; 28658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 28758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger this->internalPurge(extraCount, extraBytes); 28858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (((fEntryCount+extraCount) > fMaxCount || 28958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger (fEntryBytes+extraBytes) > fMaxBytes) && 29058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger NULL != fOverbudgetCB) { 29158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Despite the purge we're still over budget. See if Ganesh can 29258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // release some resources and purge again. 29358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if ((*fOverbudgetCB)(fOverbudgetData)) { 29458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger this->internalPurge(extraCount, extraBytes); 29558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 29658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 29758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 29858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fPurging = false; 29958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 30058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 30158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergervoid GrResourceCache::deleteResource(GrResourceEntry* entry) { 30258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrAssert(1 == entry->fResource->getRefCnt()); 30358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 30458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // remove from our cache 30558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger fCache.remove(entry->key(), entry); 30658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 30758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // remove from our llist 30858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger this->internalDetach(entry); 30958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger delete entry; 31058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger} 31158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 31258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergervoid GrResourceCache::internalPurge(int extraCount, size_t extraBytes) { 31358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger SkASSERT(fPurging); 31458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 31558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger bool withinBudget = false; 31658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger bool changed = false; 31758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 31858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // The purging process is repeated several times since one pass 31958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // may free up other resources 32058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger do { 32158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger EntryList::Iter iter; 32258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 32358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger changed = false; 32458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 32558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // Note: the following code relies on the fact that the 32658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // doubly linked list doesn't invalidate its data/pointers 32758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // outside of the specific area where a deletion occurs (e.g., 32858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger // in internalDetach) 32958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrResourceEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterStart); 33058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 33158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger while (NULL != entry) { 33258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrAutoResourceCacheValidate atcv(this); 33358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 33458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if ((fEntryCount+extraCount) <= fMaxCount && 33558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger (fEntryBytes+extraBytes) <= fMaxBytes) { 33658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger withinBudget = true; 33758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger break; 33858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 33958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger 34058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger GrResourceEntry* prev = iter.prev(); 34158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger if (entry->fResource->unique()) { 34258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger changed = true; 34358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger this->deleteResource(entry); 34458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 34558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger entry = prev; 34658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } 34758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger } while (!withinBudget && changed); 34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrResourceCache::purgeAllUnlocked() { 35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAutoResourceCacheValidate atcv(this); 35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // we can have one GrResource holding a lock on another 35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // so we don't want to just do a simple loop kicking each 35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // entry out. Instead change the budget and purge. 35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int savedMaxBytes = fMaxBytes; 35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int savedMaxCount = fMaxCount; 35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMaxBytes = (size_t) -1; 36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMaxCount = 0; 36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru this->purgeAsNeeded(); 36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fExclusiveList.countEntries() == fClientDetachedCount); 36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(countBytes(fExclusiveList) == fClientDetachedBytes); 36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (!fCache.count()) { 36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // Items may have been detached from the cache (such as the backing 36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // texture for an SkGpuDevice). The above purge would not have removed 36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // them. 37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fEntryCount == fClientDetachedCount); 37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fEntryBytes == fClientDetachedBytes); 37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fList.isEmpty()); 37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMaxBytes = savedMaxBytes; 37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fMaxCount = savedMaxCount; 37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_DEBUG 38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querusize_t GrResourceCache::countBytes(const EntryList& list) { 38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t bytes = 0; 38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru EntryList::Iter iter; 38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrResourceEntry* entry = iter.init(const_cast<EntryList&>(list), 38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru EntryList::Iter::kTail_IterStart); 39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for ( ; NULL != entry; entry = iter.prev()) { 39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bytes += entry->resource()->sizeInBytes(); 39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return bytes; 39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool both_zero_or_nonzero(int count, size_t bytes) { 39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return (count == 0 && bytes == 0) || (count > 0 && bytes > 0); 39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrResourceCache::validate() const { 40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fList.validate(); 40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fExclusiveList.validate(); 40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(both_zero_or_nonzero(fEntryCount, fEntryBytes)); 40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(both_zero_or_nonzero(fClientDetachedCount, fClientDetachedBytes)); 40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fClientDetachedBytes <= fEntryBytes); 40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fClientDetachedCount <= fEntryCount); 40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert((fEntryCount - fClientDetachedCount) == fCache.count()); 40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fCache.validate(); 41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru EntryList::Iter iter; 41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // check that the exclusively held entries are okay 41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const GrResourceEntry* entry = iter.init(const_cast<EntryList&>(fExclusiveList), 41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru EntryList::Iter::kHead_IterStart); 41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for ( ; NULL != entry; entry = iter.next()) { 42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru entry->validate(); 42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru // check that the shareable entries are okay 42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru entry = iter.init(const_cast<EntryList&>(fList), EntryList::Iter::kHead_IterStart); 42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int count = 0; 42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for ( ; NULL != entry; entry = iter.next()) { 42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru entry->validate(); 42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fCache.find(entry->key())); 43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru count += 1; 43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(count == fEntryCount - fClientDetachedCount); 43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru size_t bytes = countBytes(fList); 43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(bytes == fEntryBytes - fClientDetachedBytes); 43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bytes = countBytes(fExclusiveList); 43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(bytes == fClientDetachedBytes); 43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fList.countEntries() == fEntryCount - fClientDetachedCount); 44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrAssert(fExclusiveList.countEntries() == fClientDetachedCount); 44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif // GR_DEBUG 44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if GR_CACHE_STATS 44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrResourceCache::printStats() { 44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru int locked = 0; 45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru EntryList::Iter iter; 45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru GrResourceEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterStart); 45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for ( ; NULL != entry; entry = iter.prev()) { 45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru if (entry->fResource->getRefCnt() > 1) { 45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ++locked; 45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); 46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\t\tEntry Count: current %d (%d locked) high %d\n", 46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEntryCount, locked, fHighWaterEntryCount); 46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\t\tEntry Bytes: current %d high %d\n", 46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fEntryBytes, fHighWaterEntryBytes); 46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\t\tDetached Entry Count: current %d high %d\n", 46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClientDetachedCount, fHighWaterClientDetachedCount); 46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkDebugf("\t\tDetached Bytes: current %d high %d\n", 46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru fClientDetachedBytes, fHighWaterClientDetachedBytes); 47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////// 475