| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 | 9 |
| 10 | 10 |
| 11 #include "GrResourceCache.h" | 11 #include "GrResourceCache.h" |
| 12 #include "GrResource.h" | 12 #include "GrCacheable.h" |
| 13 | 13 |
| 14 DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage); | 14 DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage); |
| 15 | 15 |
| 16 GrResourceKey::ResourceType GrResourceKey::GenerateResourceType() { | 16 GrResourceKey::ResourceType GrResourceKey::GenerateResourceType() { |
| 17 static int32_t gNextType = 0; | 17 static int32_t gNextType = 0; |
| 18 | 18 |
| 19 int32_t type = sk_atomic_inc(&gNextType); | 19 int32_t type = sk_atomic_inc(&gNextType); |
| 20 if (type >= (1 << 8 * sizeof(ResourceType))) { | 20 if (type >= (1 << 8 * sizeof(ResourceType))) { |
| 21 SkFAIL("Too many Resource Types"); | 21 SkFAIL("Too many Resource Types"); |
| 22 } | 22 } |
| 23 | 23 |
| 24 return static_cast<ResourceType>(type); | 24 return static_cast<ResourceType>(type); |
| 25 } | 25 } |
| 26 | 26 |
| 27 /////////////////////////////////////////////////////////////////////////////// | 27 /////////////////////////////////////////////////////////////////////////////// |
| 28 | 28 |
| 29 GrResourceEntry::GrResourceEntry(const GrResourceKey& key, GrResource* resource) | 29 GrResourceCacheEntry::GrResourceCacheEntry(const GrResourceKey& key, GrCacheable
* resource) |
| 30 : fKey(key), fResource(resource) { | 30 : fKey(key), fResource(resource) { |
| 31 // we assume ownership of the resource, and will unref it when we die | 31 // we assume ownership of the resource, and will unref it when we die |
| 32 SkASSERT(resource); | 32 SkASSERT(resource); |
| 33 resource->ref(); | 33 resource->ref(); |
| 34 } | 34 } |
| 35 | 35 |
| 36 GrResourceEntry::~GrResourceEntry() { | 36 GrResourceCacheEntry::~GrResourceCacheEntry() { |
| 37 fResource->setCacheEntry(NULL); | 37 fResource->setCacheEntry(NULL); |
| 38 fResource->unref(); | 38 fResource->unref(); |
| 39 } | 39 } |
| 40 | 40 |
| 41 #ifdef SK_DEBUG | 41 #ifdef SK_DEBUG |
| 42 void GrResourceEntry::validate() const { | 42 void GrResourceCacheEntry::validate() const { |
| 43 SkASSERT(fResource); | 43 SkASSERT(fResource); |
| 44 SkASSERT(fResource->getCacheEntry() == this); | 44 SkASSERT(fResource->getCacheEntry() == this); |
| 45 fResource->validate(); | 45 fResource->validate(); |
| 46 } | 46 } |
| 47 #endif | 47 #endif |
| 48 | 48 |
| 49 /////////////////////////////////////////////////////////////////////////////// | 49 /////////////////////////////////////////////////////////////////////////////// |
| 50 | 50 |
| 51 GrResourceCache::GrResourceCache(int maxCount, size_t maxBytes) : | 51 GrResourceCache::GrResourceCache(int maxCount, size_t maxBytes) : |
| 52 fMaxCount(maxCount), | 52 fMaxCount(maxCount), |
| (...skipping 15 matching lines...) Expand all Loading... |
| 68 fOverbudgetCB = NULL; | 68 fOverbudgetCB = NULL; |
| 69 fOverbudgetData = NULL; | 69 fOverbudgetData = NULL; |
| 70 } | 70 } |
| 71 | 71 |
| 72 GrResourceCache::~GrResourceCache() { | 72 GrResourceCache::~GrResourceCache() { |
| 73 GrAutoResourceCacheValidate atcv(this); | 73 GrAutoResourceCacheValidate atcv(this); |
| 74 | 74 |
| 75 EntryList::Iter iter; | 75 EntryList::Iter iter; |
| 76 | 76 |
| 77 // Unlike the removeAll, here we really remove everything, including locked
resources. | 77 // Unlike the removeAll, here we really remove everything, including locked
resources. |
| 78 while (GrResourceEntry* entry = fList.head()) { | 78 while (GrResourceCacheEntry* entry = fList.head()) { |
| 79 GrAutoResourceCacheValidate atcv(this); | 79 GrAutoResourceCacheValidate atcv(this); |
| 80 | 80 |
| 81 // remove from our cache | 81 // remove from our cache |
| 82 fCache.remove(entry->fKey, entry); | 82 fCache.remove(entry->fKey, entry); |
| 83 | 83 |
| 84 // remove from our llist | 84 // remove from our llist |
| 85 this->internalDetach(entry); | 85 this->internalDetach(entry); |
| 86 | 86 |
| 87 delete entry; | 87 delete entry; |
| 88 } | 88 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 101 bool smaller = (maxResources < fMaxCount) || (maxResourceBytes < fMaxBytes); | 101 bool smaller = (maxResources < fMaxCount) || (maxResourceBytes < fMaxBytes); |
| 102 | 102 |
| 103 fMaxCount = maxResources; | 103 fMaxCount = maxResources; |
| 104 fMaxBytes = maxResourceBytes; | 104 fMaxBytes = maxResourceBytes; |
| 105 | 105 |
| 106 if (smaller) { | 106 if (smaller) { |
| 107 this->purgeAsNeeded(); | 107 this->purgeAsNeeded(); |
| 108 } | 108 } |
| 109 } | 109 } |
| 110 | 110 |
| 111 void GrResourceCache::internalDetach(GrResourceEntry* entry, | 111 void GrResourceCache::internalDetach(GrResourceCacheEntry* entry, |
| 112 BudgetBehaviors behavior) { | 112 BudgetBehaviors behavior) { |
| 113 fList.remove(entry); | 113 fList.remove(entry); |
| 114 | 114 |
| 115 // update our stats | 115 // update our stats |
| 116 if (kIgnore_BudgetBehavior == behavior) { | 116 if (kIgnore_BudgetBehavior == behavior) { |
| 117 fClientDetachedCount += 1; | 117 fClientDetachedCount += 1; |
| 118 fClientDetachedBytes += entry->resource()->sizeInBytes(); | 118 fClientDetachedBytes += entry->resource()->gpuMemorySize(); |
| 119 | 119 |
| 120 #if GR_CACHE_STATS | 120 #if GR_CACHE_STATS |
| 121 if (fHighWaterClientDetachedCount < fClientDetachedCount) { | 121 if (fHighWaterClientDetachedCount < fClientDetachedCount) { |
| 122 fHighWaterClientDetachedCount = fClientDetachedCount; | 122 fHighWaterClientDetachedCount = fClientDetachedCount; |
| 123 } | 123 } |
| 124 if (fHighWaterClientDetachedBytes < fClientDetachedBytes) { | 124 if (fHighWaterClientDetachedBytes < fClientDetachedBytes) { |
| 125 fHighWaterClientDetachedBytes = fClientDetachedBytes; | 125 fHighWaterClientDetachedBytes = fClientDetachedBytes; |
| 126 } | 126 } |
| 127 #endif | 127 #endif |
| 128 | 128 |
| 129 } else { | 129 } else { |
| 130 SkASSERT(kAccountFor_BudgetBehavior == behavior); | 130 SkASSERT(kAccountFor_BudgetBehavior == behavior); |
| 131 | 131 |
| 132 fEntryCount -= 1; | 132 fEntryCount -= 1; |
| 133 fEntryBytes -= entry->resource()->sizeInBytes(); | 133 fEntryBytes -= entry->resource()->gpuMemorySize(); |
| 134 } | 134 } |
| 135 } | 135 } |
| 136 | 136 |
| 137 void GrResourceCache::attachToHead(GrResourceEntry* entry, | 137 void GrResourceCache::attachToHead(GrResourceCacheEntry* entry, |
| 138 BudgetBehaviors behavior) { | 138 BudgetBehaviors behavior) { |
| 139 fList.addToHead(entry); | 139 fList.addToHead(entry); |
| 140 | 140 |
| 141 // update our stats | 141 // update our stats |
| 142 if (kIgnore_BudgetBehavior == behavior) { | 142 if (kIgnore_BudgetBehavior == behavior) { |
| 143 fClientDetachedCount -= 1; | 143 fClientDetachedCount -= 1; |
| 144 fClientDetachedBytes -= entry->resource()->sizeInBytes(); | 144 fClientDetachedBytes -= entry->resource()->gpuMemorySize(); |
| 145 } else { | 145 } else { |
| 146 SkASSERT(kAccountFor_BudgetBehavior == behavior); | 146 SkASSERT(kAccountFor_BudgetBehavior == behavior); |
| 147 | 147 |
| 148 fEntryCount += 1; | 148 fEntryCount += 1; |
| 149 fEntryBytes += entry->resource()->sizeInBytes(); | 149 fEntryBytes += entry->resource()->gpuMemorySize(); |
| 150 | 150 |
| 151 #if GR_CACHE_STATS | 151 #if GR_CACHE_STATS |
| 152 if (fHighWaterEntryCount < fEntryCount) { | 152 if (fHighWaterEntryCount < fEntryCount) { |
| 153 fHighWaterEntryCount = fEntryCount; | 153 fHighWaterEntryCount = fEntryCount; |
| 154 } | 154 } |
| 155 if (fHighWaterEntryBytes < fEntryBytes) { | 155 if (fHighWaterEntryBytes < fEntryBytes) { |
| 156 fHighWaterEntryBytes = fEntryBytes; | 156 fHighWaterEntryBytes = fEntryBytes; |
| 157 } | 157 } |
| 158 #endif | 158 #endif |
| 159 } | 159 } |
| 160 } | 160 } |
| 161 | 161 |
| 162 // This functor just searches for an entry with only a single ref (from | 162 // This functor just searches for an entry with only a single ref (from |
| 163 // the texture cache itself). Presumably in this situation no one else | 163 // the texture cache itself). Presumably in this situation no one else |
| 164 // is relying on the texture. | 164 // is relying on the texture. |
| 165 class GrTFindUnreffedFunctor { | 165 class GrTFindUnreffedFunctor { |
| 166 public: | 166 public: |
| 167 bool operator()(const GrResourceEntry* entry) const { | 167 bool operator()(const GrResourceCacheEntry* entry) const { |
| 168 return entry->resource()->unique(); | 168 return entry->resource()->unique(); |
| 169 } | 169 } |
| 170 }; | 170 }; |
| 171 | 171 |
| 172 GrResource* GrResourceCache::find(const GrResourceKey& key, uint32_t ownershipFl
ags) { | 172 GrCacheable* GrResourceCache::find(const GrResourceKey& key, uint32_t ownershipF
lags) { |
| 173 GrAutoResourceCacheValidate atcv(this); | 173 GrAutoResourceCacheValidate atcv(this); |
| 174 | 174 |
| 175 GrResourceEntry* entry = NULL; | 175 GrResourceCacheEntry* entry = NULL; |
| 176 | 176 |
| 177 if (ownershipFlags & kNoOtherOwners_OwnershipFlag) { | 177 if (ownershipFlags & kNoOtherOwners_OwnershipFlag) { |
| 178 GrTFindUnreffedFunctor functor; | 178 GrTFindUnreffedFunctor functor; |
| 179 | 179 |
| 180 entry = fCache.find<GrTFindUnreffedFunctor>(key, functor); | 180 entry = fCache.find<GrTFindUnreffedFunctor>(key, functor); |
| 181 } else { | 181 } else { |
| 182 entry = fCache.find(key); | 182 entry = fCache.find(key); |
| 183 } | 183 } |
| 184 | 184 |
| 185 if (NULL == entry) { | 185 if (NULL == entry) { |
| 186 return NULL; | 186 return NULL; |
| 187 } | 187 } |
| 188 | 188 |
| 189 if (ownershipFlags & kHide_OwnershipFlag) { | 189 if (ownershipFlags & kHide_OwnershipFlag) { |
| 190 this->makeExclusive(entry); | 190 this->makeExclusive(entry); |
| 191 } else { | 191 } else { |
| 192 // Make this resource MRU | 192 // Make this resource MRU |
| 193 this->internalDetach(entry); | 193 this->internalDetach(entry); |
| 194 this->attachToHead(entry); | 194 this->attachToHead(entry); |
| 195 } | 195 } |
| 196 | 196 |
| 197 return entry->fResource; | 197 return entry->fResource; |
| 198 } | 198 } |
| 199 | 199 |
| 200 void GrResourceCache::addResource(const GrResourceKey& key, | 200 void GrResourceCache::addResource(const GrResourceKey& key, |
| 201 GrResource* resource, | 201 GrCacheable* resource, |
| 202 uint32_t ownershipFlags) { | 202 uint32_t ownershipFlags) { |
| 203 SkASSERT(NULL == resource->getCacheEntry()); | 203 SkASSERT(NULL == resource->getCacheEntry()); |
| 204 // we don't expect to create new resources during a purge. In theory | 204 // we don't expect to create new resources during a purge. In theory |
| 205 // this could cause purgeAsNeeded() into an infinite loop (e.g. | 205 // this could cause purgeAsNeeded() into an infinite loop (e.g. |
| 206 // each resource destroyed creates and locks 2 resources and | 206 // each resource destroyed creates and locks 2 resources and |
| 207 // unlocks 1 thereby causing a new purge). | 207 // unlocks 1 thereby causing a new purge). |
| 208 SkASSERT(!fPurging); | 208 SkASSERT(!fPurging); |
| 209 GrAutoResourceCacheValidate atcv(this); | 209 GrAutoResourceCacheValidate atcv(this); |
| 210 | 210 |
| 211 GrResourceEntry* entry = SkNEW_ARGS(GrResourceEntry, (key, resource)); | 211 GrResourceCacheEntry* entry = SkNEW_ARGS(GrResourceCacheEntry, (key, resourc
e)); |
| 212 resource->setCacheEntry(entry); | 212 resource->setCacheEntry(entry); |
| 213 | 213 |
| 214 this->attachToHead(entry); | 214 this->attachToHead(entry); |
| 215 fCache.insert(key, entry); | 215 fCache.insert(key, entry); |
| 216 | 216 |
| 217 if (ownershipFlags & kHide_OwnershipFlag) { | 217 if (ownershipFlags & kHide_OwnershipFlag) { |
| 218 this->makeExclusive(entry); | 218 this->makeExclusive(entry); |
| 219 } | 219 } |
| 220 | 220 |
| 221 } | 221 } |
| 222 | 222 |
| 223 void GrResourceCache::makeExclusive(GrResourceEntry* entry) { | 223 void GrResourceCache::makeExclusive(GrResourceCacheEntry* entry) { |
| 224 GrAutoResourceCacheValidate atcv(this); | 224 GrAutoResourceCacheValidate atcv(this); |
| 225 | 225 |
| 226 // When scratch textures are detached (to hide them from future finds) they | 226 // When scratch textures are detached (to hide them from future finds) they |
| 227 // still count against the resource budget | 227 // still count against the resource budget |
| 228 this->internalDetach(entry, kIgnore_BudgetBehavior); | 228 this->internalDetach(entry, kIgnore_BudgetBehavior); |
| 229 fCache.remove(entry->key(), entry); | 229 fCache.remove(entry->key(), entry); |
| 230 | 230 |
| 231 #ifdef SK_DEBUG | 231 #ifdef SK_DEBUG |
| 232 fExclusiveList.addToHead(entry); | 232 fExclusiveList.addToHead(entry); |
| 233 #endif | 233 #endif |
| 234 } | 234 } |
| 235 | 235 |
| 236 void GrResourceCache::removeInvalidResource(GrResourceEntry* entry) { | 236 void GrResourceCache::removeInvalidResource(GrResourceCacheEntry* entry) { |
| 237 // If the resource went invalid while it was detached then purge it | 237 // If the resource went invalid while it was detached then purge it |
| 238 // This can happen when a 3D context was lost, | 238 // This can happen when a 3D context was lost, |
| 239 // the client called GrContext::contextDestroyed() to notify Gr, | 239 // the client called GrContext::contextDestroyed() to notify Gr, |
| 240 // and then later an SkGpuDevice's destructor releases its backing | 240 // and then later an SkGpuDevice's destructor releases its backing |
| 241 // texture (which was invalidated at contextDestroyed time). | 241 // texture (which was invalidated at contextDestroyed time). |
| 242 fClientDetachedCount -= 1; | 242 fClientDetachedCount -= 1; |
| 243 fEntryCount -= 1; | 243 fEntryCount -= 1; |
| 244 size_t size = entry->resource()->sizeInBytes(); | 244 size_t size = entry->resource()->gpuMemorySize(); |
| 245 fClientDetachedBytes -= size; | 245 fClientDetachedBytes -= size; |
| 246 fEntryBytes -= size; | 246 fEntryBytes -= size; |
| 247 } | 247 } |
| 248 | 248 |
| 249 void GrResourceCache::makeNonExclusive(GrResourceEntry* entry) { | 249 void GrResourceCache::makeNonExclusive(GrResourceCacheEntry* entry) { |
| 250 GrAutoResourceCacheValidate atcv(this); | 250 GrAutoResourceCacheValidate atcv(this); |
| 251 | 251 |
| 252 #ifdef SK_DEBUG | 252 #ifdef SK_DEBUG |
| 253 fExclusiveList.remove(entry); | 253 fExclusiveList.remove(entry); |
| 254 #endif | 254 #endif |
| 255 | 255 |
| 256 if (entry->resource()->isValid()) { | 256 if (entry->resource()->isValidOnGpu()) { |
| 257 // Since scratch textures still count against the cache budget even | 257 // Since scratch textures still count against the cache budget even |
| 258 // when they have been removed from the cache, re-adding them doesn't | 258 // when they have been removed from the cache, re-adding them doesn't |
| 259 // alter the budget information. | 259 // alter the budget information. |
| 260 attachToHead(entry, kIgnore_BudgetBehavior); | 260 attachToHead(entry, kIgnore_BudgetBehavior); |
| 261 fCache.insert(entry->key(), entry); | 261 fCache.insert(entry->key(), entry); |
| 262 } else { | 262 } else { |
| 263 this->removeInvalidResource(entry); | 263 this->removeInvalidResource(entry); |
| 264 } | 264 } |
| 265 } | 265 } |
| 266 | 266 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 fInvalidationInbox.poll(&invalidated); | 306 fInvalidationInbox.poll(&invalidated); |
| 307 | 307 |
| 308 for (int i = 0; i < invalidated.count(); i++) { | 308 for (int i = 0; i < invalidated.count(); i++) { |
| 309 // We're somewhat missing an opportunity here. We could use the | 309 // We're somewhat missing an opportunity here. We could use the |
| 310 // default find functor that gives us back resources whether we own | 310 // default find functor that gives us back resources whether we own |
| 311 // them exclusively or not, and when they're not exclusively owned mark | 311 // them exclusively or not, and when they're not exclusively owned mark |
| 312 // them for purging later when they do become exclusively owned. | 312 // them for purging later when they do become exclusively owned. |
| 313 // | 313 // |
| 314 // This is complicated and confusing. May try this in the future. For | 314 // This is complicated and confusing. May try this in the future. For |
| 315 // now, these resources are just LRU'd as if we never got the message. | 315 // now, these resources are just LRU'd as if we never got the message. |
| 316 while (GrResourceEntry* entry = fCache.find(invalidated[i].key, GrTFindU
nreffedFunctor())) { | 316 while (GrResourceCacheEntry* entry = fCache.find(invalidated[i].key, GrT
FindUnreffedFunctor())) { |
| 317 this->deleteResource(entry); | 317 this->deleteResource(entry); |
| 318 } | 318 } |
| 319 } | 319 } |
| 320 } | 320 } |
| 321 | 321 |
| 322 void GrResourceCache::deleteResource(GrResourceEntry* entry) { | 322 void GrResourceCache::deleteResource(GrResourceCacheEntry* entry) { |
| 323 SkASSERT(1 == entry->fResource->getRefCnt()); | 323 SkASSERT(1 == entry->fResource->getRefCnt()); |
| 324 | 324 |
| 325 // remove from our cache | 325 // remove from our cache |
| 326 fCache.remove(entry->key(), entry); | 326 fCache.remove(entry->key(), entry); |
| 327 | 327 |
| 328 // remove from our llist | 328 // remove from our llist |
| 329 this->internalDetach(entry); | 329 this->internalDetach(entry); |
| 330 delete entry; | 330 delete entry; |
| 331 } | 331 } |
| 332 | 332 |
| 333 void GrResourceCache::internalPurge(int extraCount, size_t extraBytes) { | 333 void GrResourceCache::internalPurge(int extraCount, size_t extraBytes) { |
| 334 SkASSERT(fPurging); | 334 SkASSERT(fPurging); |
| 335 | 335 |
| 336 bool withinBudget = false; | 336 bool withinBudget = false; |
| 337 bool changed = false; | 337 bool changed = false; |
| 338 | 338 |
| 339 // The purging process is repeated several times since one pass | 339 // The purging process is repeated several times since one pass |
| 340 // may free up other resources | 340 // may free up other resources |
| 341 do { | 341 do { |
| 342 EntryList::Iter iter; | 342 EntryList::Iter iter; |
| 343 | 343 |
| 344 changed = false; | 344 changed = false; |
| 345 | 345 |
| 346 // Note: the following code relies on the fact that the | 346 // Note: the following code relies on the fact that the |
| 347 // doubly linked list doesn't invalidate its data/pointers | 347 // doubly linked list doesn't invalidate its data/pointers |
| 348 // outside of the specific area where a deletion occurs (e.g., | 348 // outside of the specific area where a deletion occurs (e.g., |
| 349 // in internalDetach) | 349 // in internalDetach) |
| 350 GrResourceEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterSta
rt); | 350 GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_It
erStart); |
| 351 | 351 |
| 352 while (NULL != entry) { | 352 while (NULL != entry) { |
| 353 GrAutoResourceCacheValidate atcv(this); | 353 GrAutoResourceCacheValidate atcv(this); |
| 354 | 354 |
| 355 if ((fEntryCount+extraCount) <= fMaxCount && | 355 if ((fEntryCount+extraCount) <= fMaxCount && |
| 356 (fEntryBytes+extraBytes) <= fMaxBytes) { | 356 (fEntryBytes+extraBytes) <= fMaxBytes) { |
| 357 withinBudget = true; | 357 withinBudget = true; |
| 358 break; | 358 break; |
| 359 } | 359 } |
| 360 | 360 |
| 361 GrResourceEntry* prev = iter.prev(); | 361 GrResourceCacheEntry* prev = iter.prev(); |
| 362 if (entry->fResource->unique()) { | 362 if (entry->fResource->unique()) { |
| 363 changed = true; | 363 changed = true; |
| 364 this->deleteResource(entry); | 364 this->deleteResource(entry); |
| 365 } | 365 } |
| 366 entry = prev; | 366 entry = prev; |
| 367 } | 367 } |
| 368 } while (!withinBudget && changed); | 368 } while (!withinBudget && changed); |
| 369 } | 369 } |
| 370 | 370 |
| 371 void GrResourceCache::purgeAllUnlocked() { | 371 void GrResourceCache::purgeAllUnlocked() { |
| 372 GrAutoResourceCacheValidate atcv(this); | 372 GrAutoResourceCacheValidate atcv(this); |
| 373 | 373 |
| 374 // we can have one GrResource holding a lock on another | 374 // we can have one GrCacheable holding a lock on another |
| 375 // so we don't want to just do a simple loop kicking each | 375 // so we don't want to just do a simple loop kicking each |
| 376 // entry out. Instead change the budget and purge. | 376 // entry out. Instead change the budget and purge. |
| 377 | 377 |
| 378 size_t savedMaxBytes = fMaxBytes; | 378 size_t savedMaxBytes = fMaxBytes; |
| 379 int savedMaxCount = fMaxCount; | 379 int savedMaxCount = fMaxCount; |
| 380 fMaxBytes = (size_t) -1; | 380 fMaxBytes = (size_t) -1; |
| 381 fMaxCount = 0; | 381 fMaxCount = 0; |
| 382 this->purgeAsNeeded(); | 382 this->purgeAsNeeded(); |
| 383 | 383 |
| 384 #ifdef SK_DEBUG | 384 #ifdef SK_DEBUG |
| (...skipping 14 matching lines...) Expand all Loading... |
| 399 } | 399 } |
| 400 | 400 |
| 401 /////////////////////////////////////////////////////////////////////////////// | 401 /////////////////////////////////////////////////////////////////////////////// |
| 402 | 402 |
| 403 #ifdef SK_DEBUG | 403 #ifdef SK_DEBUG |
| 404 size_t GrResourceCache::countBytes(const EntryList& list) { | 404 size_t GrResourceCache::countBytes(const EntryList& list) { |
| 405 size_t bytes = 0; | 405 size_t bytes = 0; |
| 406 | 406 |
| 407 EntryList::Iter iter; | 407 EntryList::Iter iter; |
| 408 | 408 |
| 409 const GrResourceEntry* entry = iter.init(const_cast<EntryList&>(list), | 409 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(list), |
| 410 EntryList::Iter::kTail_IterStart); | 410 EntryList::Iter::kTail_IterSta
rt); |
| 411 | 411 |
| 412 for ( ; NULL != entry; entry = iter.prev()) { | 412 for ( ; NULL != entry; entry = iter.prev()) { |
| 413 bytes += entry->resource()->sizeInBytes(); | 413 bytes += entry->resource()->gpuMemorySize(); |
| 414 } | 414 } |
| 415 return bytes; | 415 return bytes; |
| 416 } | 416 } |
| 417 | 417 |
| 418 static bool both_zero_or_nonzero(int count, size_t bytes) { | 418 static bool both_zero_or_nonzero(int count, size_t bytes) { |
| 419 return (count == 0 && bytes == 0) || (count > 0 && bytes > 0); | 419 return (count == 0 && bytes == 0) || (count > 0 && bytes > 0); |
| 420 } | 420 } |
| 421 | 421 |
| 422 void GrResourceCache::validate() const { | 422 void GrResourceCache::validate() const { |
| 423 fList.validate(); | 423 fList.validate(); |
| 424 fExclusiveList.validate(); | 424 fExclusiveList.validate(); |
| 425 SkASSERT(both_zero_or_nonzero(fEntryCount, fEntryBytes)); | 425 SkASSERT(both_zero_or_nonzero(fEntryCount, fEntryBytes)); |
| 426 SkASSERT(both_zero_or_nonzero(fClientDetachedCount, fClientDetachedBytes)); | 426 SkASSERT(both_zero_or_nonzero(fClientDetachedCount, fClientDetachedBytes)); |
| 427 SkASSERT(fClientDetachedBytes <= fEntryBytes); | 427 SkASSERT(fClientDetachedBytes <= fEntryBytes); |
| 428 SkASSERT(fClientDetachedCount <= fEntryCount); | 428 SkASSERT(fClientDetachedCount <= fEntryCount); |
| 429 SkASSERT((fEntryCount - fClientDetachedCount) == fCache.count()); | 429 SkASSERT((fEntryCount - fClientDetachedCount) == fCache.count()); |
| 430 | 430 |
| 431 EntryList::Iter iter; | 431 EntryList::Iter iter; |
| 432 | 432 |
| 433 // check that the exclusively held entries are okay | 433 // check that the exclusively held entries are okay |
| 434 const GrResourceEntry* entry = iter.init(const_cast<EntryList&>(fExclusiveLi
st), | 434 const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fExclus
iveList), |
| 435 EntryList::Iter::kHead_IterStart); | 435 EntryList::Iter::kHead_IterSta
rt); |
| 436 | 436 |
| 437 for ( ; NULL != entry; entry = iter.next()) { | 437 for ( ; NULL != entry; entry = iter.next()) { |
| 438 entry->validate(); | 438 entry->validate(); |
| 439 } | 439 } |
| 440 | 440 |
| 441 // check that the shareable entries are okay | 441 // check that the shareable entries are okay |
| 442 entry = iter.init(const_cast<EntryList&>(fList), EntryList::Iter::kHead_Iter
Start); | 442 entry = iter.init(const_cast<EntryList&>(fList), EntryList::Iter::kHead_Iter
Start); |
| 443 | 443 |
| 444 int count = 0; | 444 int count = 0; |
| 445 for ( ; NULL != entry; entry = iter.next()) { | 445 for ( ; NULL != entry; entry = iter.next()) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 461 } | 461 } |
| 462 #endif // SK_DEBUG | 462 #endif // SK_DEBUG |
| 463 | 463 |
| 464 #if GR_CACHE_STATS | 464 #if GR_CACHE_STATS |
| 465 | 465 |
| 466 void GrResourceCache::printStats() { | 466 void GrResourceCache::printStats() { |
| 467 int locked = 0; | 467 int locked = 0; |
| 468 | 468 |
| 469 EntryList::Iter iter; | 469 EntryList::Iter iter; |
| 470 | 470 |
| 471 GrResourceEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterStart); | 471 GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterSt
art); |
| 472 | 472 |
| 473 for ( ; NULL != entry; entry = iter.prev()) { | 473 for ( ; NULL != entry; entry = iter.prev()) { |
| 474 if (entry->fResource->getRefCnt() > 1) { | 474 if (entry->fResource->getRefCnt() > 1) { |
| 475 ++locked; | 475 ++locked; |
| 476 } | 476 } |
| 477 } | 477 } |
| 478 | 478 |
| 479 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); | 479 SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes); |
| 480 SkDebugf("\t\tEntry Count: current %d (%d locked) high %d\n", | 480 SkDebugf("\t\tEntry Count: current %d (%d locked) high %d\n", |
| 481 fEntryCount, locked, fHighWaterEntryCount); | 481 fEntryCount, locked, fHighWaterEntryCount); |
| 482 SkDebugf("\t\tEntry Bytes: current %d high %d\n", | 482 SkDebugf("\t\tEntry Bytes: current %d high %d\n", |
| 483 fEntryBytes, fHighWaterEntryBytes); | 483 fEntryBytes, fHighWaterEntryBytes); |
| 484 SkDebugf("\t\tDetached Entry Count: current %d high %d\n", | 484 SkDebugf("\t\tDetached Entry Count: current %d high %d\n", |
| 485 fClientDetachedCount, fHighWaterClientDetachedCount); | 485 fClientDetachedCount, fHighWaterClientDetachedCount); |
| 486 SkDebugf("\t\tDetached Bytes: current %d high %d\n", | 486 SkDebugf("\t\tDetached Bytes: current %d high %d\n", |
| 487 fClientDetachedBytes, fHighWaterClientDetachedBytes); | 487 fClientDetachedBytes, fHighWaterClientDetachedBytes); |
| 488 } | 488 } |
| 489 | 489 |
| 490 #endif | 490 #endif |
| 491 | 491 |
| 492 /////////////////////////////////////////////////////////////////////////////// | 492 /////////////////////////////////////////////////////////////////////////////// |
| OLD | NEW |