| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2014 Google Inc. | 3 * Copyright 2014 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 #include "GrResourceCache.h" | 10 #include "GrResourceCache.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 GrResourceCache::GrResourceCache() | 60 GrResourceCache::GrResourceCache() |
| 61 : fTimestamp(0) | 61 : fTimestamp(0) |
| 62 , fMaxCount(kDefaultMaxCount) | 62 , fMaxCount(kDefaultMaxCount) |
| 63 , fMaxBytes(kDefaultMaxSize) | 63 , fMaxBytes(kDefaultMaxSize) |
| 64 #if GR_CACHE_STATS | 64 #if GR_CACHE_STATS |
| 65 , fHighWaterCount(0) | 65 , fHighWaterCount(0) |
| 66 , fHighWaterBytes(0) | 66 , fHighWaterBytes(0) |
| 67 , fBudgetedHighWaterCount(0) | 67 , fBudgetedHighWaterCount(0) |
| 68 , fBudgetedHighWaterBytes(0) | 68 , fBudgetedHighWaterBytes(0) |
| 69 #endif | 69 #endif |
| 70 , fCount(0) | |
| 71 , fBytes(0) | 70 , fBytes(0) |
| 72 , fBudgetedCount(0) | 71 , fBudgetedCount(0) |
| 73 , fBudgetedBytes(0) | 72 , fBudgetedBytes(0) |
| 74 , fOverBudgetCB(NULL) | 73 , fOverBudgetCB(NULL) |
| 75 , fOverBudgetData(NULL) { | 74 , fOverBudgetData(NULL) { |
| 75 SkDEBUGCODE(fCount = 0;) |
| 76 } | 76 } |
| 77 | 77 |
| 78 GrResourceCache::~GrResourceCache() { | 78 GrResourceCache::~GrResourceCache() { |
| 79 this->releaseAll(); | 79 this->releaseAll(); |
| 80 } | 80 } |
| 81 | 81 |
| 82 void GrResourceCache::setLimits(int count, size_t bytes) { | 82 void GrResourceCache::setLimits(int count, size_t bytes) { |
| 83 fMaxCount = count; | 83 fMaxCount = count; |
| 84 fMaxBytes = bytes; | 84 fMaxBytes = bytes; |
| 85 this->purgeAsNeeded(); | 85 this->purgeAsNeeded(); |
| 86 } | 86 } |
| 87 | 87 |
| 88 void GrResourceCache::insertResource(GrGpuResource* resource) { | 88 void GrResourceCache::insertResource(GrGpuResource* resource) { |
| 89 SkASSERT(resource); | 89 SkASSERT(resource); |
| 90 SkASSERT(!this->isInCache(resource)); |
| 90 SkASSERT(!resource->wasDestroyed()); | 91 SkASSERT(!resource->wasDestroyed()); |
| 91 SkASSERT(!this->isInCache(resource)); | 92 SkASSERT(!resource->isPurgeable()); |
| 92 fResources.addToHead(resource); | 93 this->addToNonpurgeableArray(resource); |
| 93 | 94 |
| 94 size_t size = resource->gpuMemorySize(); | 95 size_t size = resource->gpuMemorySize(); |
| 95 ++fCount; | 96 SkDEBUGCODE(++fCount;) |
| 96 fBytes += size; | 97 fBytes += size; |
| 97 #if GR_CACHE_STATS | 98 #if GR_CACHE_STATS |
| 98 fHighWaterCount = SkTMax(fCount, fHighWaterCount); | 99 fHighWaterCount = SkTMax(this->getResourceCount(), fHighWaterCount); |
| 99 fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes); | 100 fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes); |
| 100 #endif | 101 #endif |
| 101 if (resource->resourcePriv().isBudgeted()) { | 102 if (resource->resourcePriv().isBudgeted()) { |
| 102 ++fBudgetedCount; | 103 ++fBudgetedCount; |
| 103 fBudgetedBytes += size; | 104 fBudgetedBytes += size; |
| 104 #if GR_CACHE_STATS | 105 #if GR_CACHE_STATS |
| 105 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount
); | 106 fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount
); |
| 106 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); | 107 fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes
); |
| 107 #endif | 108 #endif |
| 108 } | 109 } |
| 109 if (resource->resourcePriv().getScratchKey().isValid()) { | 110 if (resource->resourcePriv().getScratchKey().isValid()) { |
| 110 SkASSERT(!resource->cacheAccess().isWrapped()); | 111 SkASSERT(!resource->cacheAccess().isWrapped()); |
| 111 fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); | 112 fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); |
| 112 } | 113 } |
| 113 | 114 |
| 114 resource->cacheAccess().setTimestamp(fTimestamp++); | 115 resource->cacheAccess().setTimestamp(fTimestamp++); |
| 115 | 116 |
| 116 this->purgeAsNeeded(); | 117 this->purgeAsNeeded(); |
| 117 } | 118 } |
| 118 | 119 |
| 119 void GrResourceCache::removeResource(GrGpuResource* resource) { | 120 void GrResourceCache::removeResource(GrGpuResource* resource) { |
| 120 this->validate(); | 121 this->validate(); |
| 121 SkASSERT(this->isInCache(resource)); | 122 SkASSERT(this->isInCache(resource)); |
| 122 | 123 |
| 123 if (resource->isPurgeable()) { | 124 if (resource->isPurgeable()) { |
| 124 fPurgeableQueue.remove(resource); | 125 fPurgeableQueue.remove(resource); |
| 126 } else { |
| 127 this->removeFromNonpurgeableArray(resource); |
| 125 } | 128 } |
| 126 | 129 |
| 127 size_t size = resource->gpuMemorySize(); | 130 size_t size = resource->gpuMemorySize(); |
| 128 --fCount; | 131 SkDEBUGCODE(--fCount;) |
| 129 fBytes -= size; | 132 fBytes -= size; |
| 130 if (resource->resourcePriv().isBudgeted()) { | 133 if (resource->resourcePriv().isBudgeted()) { |
| 131 --fBudgetedCount; | 134 --fBudgetedCount; |
| 132 fBudgetedBytes -= size; | 135 fBudgetedBytes -= size; |
| 133 } | 136 } |
| 134 | 137 |
| 135 fResources.remove(resource); | |
| 136 if (resource->resourcePriv().getScratchKey().isValid()) { | 138 if (resource->resourcePriv().getScratchKey().isValid()) { |
| 137 fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); | 139 fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); |
| 138 } | 140 } |
| 139 if (resource->getContentKey().isValid()) { | 141 if (resource->getContentKey().isValid()) { |
| 140 fContentHash.remove(resource->getContentKey()); | 142 fContentHash.remove(resource->getContentKey()); |
| 141 } | 143 } |
| 142 this->validate(); | 144 this->validate(); |
| 143 } | 145 } |
| 144 | 146 |
| 145 void GrResourceCache::abandonAll() { | 147 void GrResourceCache::abandonAll() { |
| 146 AutoValidate av(this); | 148 AutoValidate av(this); |
| 147 | 149 |
| 148 while (GrGpuResource* head = fResources.head()) { | 150 while (fNonpurgeableResources.count()) { |
| 149 SkASSERT(!head->wasDestroyed()); | 151 GrGpuResource* back = *(fNonpurgeableResources.end() - 1); |
| 150 head->cacheAccess().abandon(); | 152 SkASSERT(!back->wasDestroyed()); |
| 151 // abandon should have already removed this from the list. | 153 back->cacheAccess().abandon(); |
| 152 SkASSERT(head != fResources.head()); | |
| 153 } | 154 } |
| 155 |
| 156 while (fPurgeableQueue.count()) { |
| 157 GrGpuResource* top = fPurgeableQueue.peek(); |
| 158 SkASSERT(!top->wasDestroyed()); |
| 159 top->cacheAccess().abandon(); |
| 160 } |
| 161 |
| 154 SkASSERT(!fScratchMap.count()); | 162 SkASSERT(!fScratchMap.count()); |
| 155 SkASSERT(!fContentHash.count()); | 163 SkASSERT(!fContentHash.count()); |
| 156 SkASSERT(!fCount); | 164 SkASSERT(!fCount); |
| 165 SkASSERT(!this->getResourceCount()); |
| 157 SkASSERT(!fBytes); | 166 SkASSERT(!fBytes); |
| 158 SkASSERT(!fBudgetedCount); | 167 SkASSERT(!fBudgetedCount); |
| 159 SkASSERT(!fBudgetedBytes); | 168 SkASSERT(!fBudgetedBytes); |
| 160 } | 169 } |
| 161 | 170 |
| 162 void GrResourceCache::releaseAll() { | 171 void GrResourceCache::releaseAll() { |
| 163 AutoValidate av(this); | 172 AutoValidate av(this); |
| 164 | 173 |
| 165 while (GrGpuResource* head = fResources.head()) { | 174 while(fNonpurgeableResources.count()) { |
| 166 SkASSERT(!head->wasDestroyed()); | 175 GrGpuResource* back = *(fNonpurgeableResources.end() - 1); |
| 167 head->cacheAccess().release(); | 176 SkASSERT(!back->wasDestroyed()); |
| 168 // release should have already removed this from the list. | 177 back->cacheAccess().release(); |
| 169 SkASSERT(head != fResources.head()); | |
| 170 } | 178 } |
| 179 |
| 180 while (fPurgeableQueue.count()) { |
| 181 GrGpuResource* top = fPurgeableQueue.peek(); |
| 182 SkASSERT(!top->wasDestroyed()); |
| 183 top->cacheAccess().release(); |
| 184 } |
| 185 |
| 171 SkASSERT(!fScratchMap.count()); | 186 SkASSERT(!fScratchMap.count()); |
| 187 SkASSERT(!fContentHash.count()); |
| 172 SkASSERT(!fCount); | 188 SkASSERT(!fCount); |
| 189 SkASSERT(!this->getResourceCount()); |
| 173 SkASSERT(!fBytes); | 190 SkASSERT(!fBytes); |
| 174 SkASSERT(!fBudgetedCount); | 191 SkASSERT(!fBudgetedCount); |
| 175 SkASSERT(!fBudgetedBytes); | 192 SkASSERT(!fBudgetedBytes); |
| 176 } | 193 } |
| 177 | 194 |
| 178 class GrResourceCache::AvailableForScratchUse { | 195 class GrResourceCache::AvailableForScratchUse { |
| 179 public: | 196 public: |
| 180 AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendin
gIO) { } | 197 AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendin
gIO) { } |
| 181 | 198 |
| 182 bool operator()(const GrGpuResource* resource) const { | 199 bool operator()(const GrGpuResource* resource) const { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 this->validate(); | 258 this->validate(); |
| 242 return true; | 259 return true; |
| 243 } | 260 } |
| 244 | 261 |
| 245 void GrResourceCache::refAndMakeResourceMRU(GrGpuResource* resource) { | 262 void GrResourceCache::refAndMakeResourceMRU(GrGpuResource* resource) { |
| 246 SkASSERT(resource); | 263 SkASSERT(resource); |
| 247 SkASSERT(this->isInCache(resource)); | 264 SkASSERT(this->isInCache(resource)); |
| 248 if (resource->isPurgeable()) { | 265 if (resource->isPurgeable()) { |
| 249 // It's about to become unpurgeable. | 266 // It's about to become unpurgeable. |
| 250 fPurgeableQueue.remove(resource); | 267 fPurgeableQueue.remove(resource); |
| 268 this->addToNonpurgeableArray(resource); |
| 251 } | 269 } |
| 252 resource->ref(); | 270 resource->ref(); |
| 253 resource->cacheAccess().setTimestamp(fTimestamp++); | 271 resource->cacheAccess().setTimestamp(fTimestamp++); |
| 254 SkASSERT(!resource->isPurgeable()); | 272 this->validate(); |
| 255 } | 273 } |
| 256 | 274 |
| 257 void GrResourceCache::notifyPurgeable(GrGpuResource* resource) { | 275 void GrResourceCache::notifyPurgeable(GrGpuResource* resource) { |
| 258 SkASSERT(resource); | 276 SkASSERT(resource); |
| 259 SkASSERT(this->isInCache(resource)); | 277 SkASSERT(this->isInCache(resource)); |
| 260 SkASSERT(resource->isPurgeable()); | 278 SkASSERT(resource->isPurgeable()); |
| 261 | 279 |
| 262 SkASSERT(-1 == *resource->cacheAccess().accessCacheIndex()); | 280 this->removeFromNonpurgeableArray(resource); |
| 263 fPurgeableQueue.insert(resource); | 281 fPurgeableQueue.insert(resource); |
| 264 | 282 |
| 265 if (!resource->resourcePriv().isBudgeted()) { | 283 if (!resource->resourcePriv().isBudgeted()) { |
| 266 // Check whether this resource could still be used as a scratch resource
. | 284 // Check whether this resource could still be used as a scratch resource
. |
| 267 if (!resource->cacheAccess().isWrapped() && | 285 if (!resource->cacheAccess().isWrapped() && |
| 268 resource->resourcePriv().getScratchKey().isValid()) { | 286 resource->resourcePriv().getScratchKey().isValid()) { |
| 269 // We won't purge an existing resource to make room for this one. | 287 // We won't purge an existing resource to make room for this one. |
| 270 bool underBudget = fBudgetedCount < fMaxCount && | 288 if (fBudgetedCount < fMaxCount && |
| 271 fBudgetedBytes + resource->gpuMemorySize() <= fMa
xBytes; | 289 fBudgetedBytes + resource->gpuMemorySize() <= fMaxBytes) { |
| 272 if (underBudget) { | |
| 273 resource->resourcePriv().makeBudgeted(); | 290 resource->resourcePriv().makeBudgeted(); |
| 274 return; | 291 return; |
| 275 } | 292 } |
| 276 } | 293 } |
| 277 } else { | 294 } else { |
| 278 // Purge the resource immediately if we're over budget | 295 // Purge the resource immediately if we're over budget |
| 279 bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxByt
es; | |
| 280 | |
| 281 // Also purge if the resource has neither a valid scratch key nor a cont
ent key. | 296 // Also purge if the resource has neither a valid scratch key nor a cont
ent key. |
| 282 bool noKey = !resource->resourcePriv().getScratchKey().isValid() && | 297 bool noKey = !resource->resourcePriv().getScratchKey().isValid() && |
| 283 !resource->getContentKey().isValid(); | 298 !resource->getContentKey().isValid(); |
| 284 if (!overBudget && !noKey) { | 299 if (!this->overBudget() && !noKey) { |
| 285 return; | 300 return; |
| 286 } | 301 } |
| 287 } | 302 } |
| 288 | 303 |
| 289 SkDEBUGCODE(int beforeCount = fCount;) | 304 SkDEBUGCODE(int beforeCount = this->getResourceCount();) |
| 290 resource->cacheAccess().release(); | 305 resource->cacheAccess().release(); |
| 291 // We should at least free this resource, perhaps dependent resources as wel
l. | 306 // We should at least free this resource, perhaps dependent resources as wel
l. |
| 292 SkASSERT(fCount < beforeCount); | 307 SkASSERT(this->getResourceCount() < beforeCount); |
| 293 this->validate(); | 308 this->validate(); |
| 294 } | 309 } |
| 295 | 310 |
| 296 void GrResourceCache::didChangeGpuMemorySize(const GrGpuResource* resource, size
_t oldSize) { | 311 void GrResourceCache::didChangeGpuMemorySize(const GrGpuResource* resource, size
_t oldSize) { |
| 297 // SkASSERT(!fPurging); GrPathRange increases size during flush. :( | 312 // SkASSERT(!fPurging); GrPathRange increases size during flush. :( |
| 298 SkASSERT(resource); | 313 SkASSERT(resource); |
| 299 SkASSERT(this->isInCache(resource)); | 314 SkASSERT(this->isInCache(resource)); |
| 300 | 315 |
| 301 ptrdiff_t delta = resource->gpuMemorySize() - oldSize; | 316 ptrdiff_t delta = resource->gpuMemorySize() - oldSize; |
| 302 | 317 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 331 this->purgeAsNeeded(); | 346 this->purgeAsNeeded(); |
| 332 } else { | 347 } else { |
| 333 --fBudgetedCount; | 348 --fBudgetedCount; |
| 334 fBudgetedBytes -= size; | 349 fBudgetedBytes -= size; |
| 335 } | 350 } |
| 336 | 351 |
| 337 this->validate(); | 352 this->validate(); |
| 338 } | 353 } |
| 339 | 354 |
| 340 void GrResourceCache::internalPurgeAsNeeded() { | 355 void GrResourceCache::internalPurgeAsNeeded() { |
| 341 SkASSERT(fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes); | 356 SkASSERT(this->overBudget()); |
| 342 | 357 |
| 343 bool stillOverbudget = true; | 358 bool stillOverbudget = true; |
| 344 while (fPurgeableQueue.count()) { | 359 while (fPurgeableQueue.count()) { |
| 345 GrGpuResource* resource = fPurgeableQueue.peek(); | 360 GrGpuResource* resource = fPurgeableQueue.peek(); |
| 346 SkASSERT(resource->isPurgeable()); | 361 SkASSERT(resource->isPurgeable()); |
| 347 resource->cacheAccess().release(); | 362 resource->cacheAccess().release(); |
| 348 if (fBudgetedCount <= fMaxCount && fBudgetedBytes <= fMaxBytes) { | 363 if (!this->overBudget()) { |
| 349 stillOverbudget = false; | 364 stillOverbudget = false; |
| 350 break; | 365 break; |
| 351 } | 366 } |
| 352 } | 367 } |
| 353 | 368 |
| 354 this->validate(); | 369 this->validate(); |
| 355 | 370 |
| 356 if (stillOverbudget) { | 371 if (stillOverbudget) { |
| 357 // Despite the purge we're still over budget. Call our over budget callb
ack. If this frees | 372 // Despite the purge we're still over budget. Call our over budget callb
ack. If this frees |
| 358 // any resources then we'll get notifyPurgeable() calls and take appropr
iate action. | 373 // any resources then we'll get notifyPurgeable() calls and take appropr
iate action. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 377 const SkTArray<GrContentKeyInvalidatedMessage>& msgs) { | 392 const SkTArray<GrContentKeyInvalidatedMessage>& msgs) { |
| 378 for (int i = 0; i < msgs.count(); ++i) { | 393 for (int i = 0; i < msgs.count(); ++i) { |
| 379 GrGpuResource* resource = this->findAndRefContentResource(msgs[i].key())
; | 394 GrGpuResource* resource = this->findAndRefContentResource(msgs[i].key())
; |
| 380 if (resource) { | 395 if (resource) { |
| 381 resource->resourcePriv().removeContentKey(); | 396 resource->resourcePriv().removeContentKey(); |
| 382 resource->unref(); // will call notifyPurgeable, if it is indeed now
purgeable. | 397 resource->unref(); // will call notifyPurgeable, if it is indeed now
purgeable. |
| 383 } | 398 } |
| 384 } | 399 } |
| 385 } | 400 } |
| 386 | 401 |
| 402 void GrResourceCache::addToNonpurgeableArray(GrGpuResource* resource) { |
| 403 int index = fNonpurgeableResources.count(); |
| 404 *fNonpurgeableResources.append() = resource; |
| 405 *resource->cacheAccess().accessCacheIndex() = index; |
| 406 } |
| 407 |
| 408 void GrResourceCache::removeFromNonpurgeableArray(GrGpuResource* resource) { |
| 409 int* index = resource->cacheAccess().accessCacheIndex(); |
| 410 // Fill the whole we will create in the array with the tail object, adjust i
ts index, and |
| 411 // then pop the array |
| 412 GrGpuResource* tail = *(fNonpurgeableResources.end() - 1); |
| 413 SkASSERT(fNonpurgeableResources[*index] == resource); |
| 414 fNonpurgeableResources[*index] = tail; |
| 415 *tail->cacheAccess().accessCacheIndex() = *index; |
| 416 fNonpurgeableResources.pop(); |
| 417 SkDEBUGCODE(*index = -1); |
| 418 } |
| 419 |
| 387 #ifdef SK_DEBUG | 420 #ifdef SK_DEBUG |
| 388 void GrResourceCache::validate() const { | 421 void GrResourceCache::validate() const { |
| 389 // Reduce the frequency of validations for large resource counts. | 422 // Reduce the frequency of validations for large resource counts. |
| 390 static SkRandom gRandom; | 423 static SkRandom gRandom; |
| 391 int mask = (SkNextPow2(fCount + 1) >> 5) - 1; | 424 int mask = (SkNextPow2(fCount + 1) >> 5) - 1; |
| 392 if (~mask && (gRandom.nextU() & mask)) { | 425 if (~mask && (gRandom.nextU() & mask)) { |
| 393 return; | 426 return; |
| 394 } | 427 } |
| 395 | 428 |
| 396 size_t bytes = 0; | 429 struct Stats { |
| 397 int count = 0; | 430 size_t fBytes; |
| 398 int budgetedCount = 0; | 431 int fBudgetedCount; |
| 399 size_t budgetedBytes = 0; | 432 size_t fBudgetedBytes; |
| 400 int locked = 0; | 433 int fLocked; |
| 401 int scratch = 0; | 434 int fScratch; |
| 402 int couldBeScratch = 0; | 435 int fCouldBeScratch; |
| 403 int content = 0; | 436 int fContent; |
| 437 const ScratchMap* fScratchMap; |
| 438 const ContentHash* fContentHash; |
| 404 | 439 |
| 405 ResourceList::Iter iter; | 440 Stats(const GrResourceCache* cache) { |
| 406 GrGpuResource* resource = iter.init(fResources, ResourceList::Iter::kHead_It
erStart); | 441 memset(this, 0, sizeof(*this)); |
| 407 for ( ; resource; resource = iter.next()) { | 442 fScratchMap = &cache->fScratchMap; |
| 408 bytes += resource->gpuMemorySize(); | 443 fContentHash = &cache->fContentHash; |
| 409 ++count; | |
| 410 | |
| 411 if (!resource->isPurgeable()) { | |
| 412 ++locked; | |
| 413 } | 444 } |
| 414 | 445 |
| 415 if (resource->cacheAccess().isScratch()) { | 446 void update(GrGpuResource* resource) { |
| 416 SkASSERT(!resource->getContentKey().isValid()); | 447 fBytes += resource->gpuMemorySize(); |
| 417 ++scratch; | 448 |
| 418 SkASSERT(fScratchMap.countForKey(resource->resourcePriv().getScratch
Key())); | 449 if (!resource->isPurgeable()) { |
| 419 SkASSERT(!resource->cacheAccess().isWrapped()); | 450 ++fLocked; |
| 420 } else if (resource->resourcePriv().getScratchKey().isValid()) { | 451 } |
| 421 SkASSERT(!resource->resourcePriv().isBudgeted() || | 452 |
| 422 resource->getContentKey().isValid()); | 453 if (resource->cacheAccess().isScratch()) { |
| 423 ++couldBeScratch; | 454 SkASSERT(!resource->getContentKey().isValid()); |
| 424 SkASSERT(fScratchMap.countForKey(resource->resourcePriv().getScratch
Key())); | 455 ++fScratch; |
| 425 SkASSERT(!resource->cacheAccess().isWrapped()); | 456 SkASSERT(fScratchMap->countForKey(resource->resourcePriv().getSc
ratchKey())); |
| 457 SkASSERT(!resource->cacheAccess().isWrapped()); |
| 458 } else if (resource->resourcePriv().getScratchKey().isValid()) { |
| 459 SkASSERT(!resource->resourcePriv().isBudgeted() || |
| 460 resource->getContentKey().isValid()); |
| 461 ++fCouldBeScratch; |
| 462 SkASSERT(fScratchMap->countForKey(resource->resourcePriv().getSc
ratchKey())); |
| 463 SkASSERT(!resource->cacheAccess().isWrapped()); |
| 464 } |
| 465 const GrContentKey& contentKey = resource->getContentKey(); |
| 466 if (contentKey.isValid()) { |
| 467 ++fContent; |
| 468 SkASSERT(fContentHash->find(contentKey) == resource); |
| 469 SkASSERT(!resource->cacheAccess().isWrapped()); |
| 470 SkASSERT(resource->resourcePriv().isBudgeted()); |
| 471 } |
| 472 |
| 473 if (resource->resourcePriv().isBudgeted()) { |
| 474 ++fBudgetedCount; |
| 475 fBudgetedBytes += resource->gpuMemorySize(); |
| 476 } |
| 426 } | 477 } |
| 427 const GrContentKey& contentKey = resource->getContentKey(); | 478 }; |
| 428 if (contentKey.isValid()) { | |
| 429 ++content; | |
| 430 SkASSERT(fContentHash.find(contentKey) == resource); | |
| 431 SkASSERT(!resource->cacheAccess().isWrapped()); | |
| 432 SkASSERT(resource->resourcePriv().isBudgeted()); | |
| 433 } | |
| 434 | 479 |
| 435 if (resource->resourcePriv().isBudgeted()) { | 480 Stats stats(this); |
| 436 ++budgetedCount; | |
| 437 budgetedBytes += resource->gpuMemorySize(); | |
| 438 } | |
| 439 | 481 |
| 440 if (!resource->isPurgeable()) { | 482 for (int i = 0; i < fNonpurgeableResources.count(); ++i) { |
| 441 SkASSERT(-1 == *resource->cacheAccess().accessCacheIndex()); | 483 SkASSERT(!fNonpurgeableResources[i]->isPurgeable()); |
| 442 } | 484 SkASSERT(*fNonpurgeableResources[i]->cacheAccess().accessCacheIndex() ==
i); |
| 485 SkASSERT(!fNonpurgeableResources[i]->wasDestroyed()); |
| 486 stats.update(fNonpurgeableResources[i]); |
| 487 } |
| 488 for (int i = 0; i < fPurgeableQueue.count(); ++i) { |
| 489 SkASSERT(fPurgeableQueue.at(i)->isPurgeable()); |
| 490 SkASSERT(*fPurgeableQueue.at(i)->cacheAccess().accessCacheIndex() == i); |
| 491 SkASSERT(!fPurgeableQueue.at(i)->wasDestroyed()); |
| 492 stats.update(fPurgeableQueue.at(i)); |
| 443 } | 493 } |
| 444 | 494 |
| 445 for (int i = 0; i < fPurgeableQueue.count(); ++i) { | 495 SkASSERT(fCount == this->getResourceCount()); |
| 446 SkASSERT(fPurgeableQueue.at(i)->isPurgeable()); | |
| 447 } | |
| 448 | |
| 449 SkASSERT(fCount - locked == fPurgeableQueue.count()); | |
| 450 SkASSERT(fBudgetedCount <= fCount); | 496 SkASSERT(fBudgetedCount <= fCount); |
| 451 SkASSERT(fBudgetedBytes <= fBudgetedBytes); | 497 SkASSERT(fBudgetedBytes <= fBytes); |
| 452 SkASSERT(bytes == fBytes); | 498 SkASSERT(stats.fBytes == fBytes); |
| 453 SkASSERT(count == fCount); | 499 SkASSERT(stats.fBudgetedBytes == fBudgetedBytes); |
| 454 SkASSERT(budgetedBytes == fBudgetedBytes); | 500 SkASSERT(stats.fBudgetedCount == fBudgetedCount); |
| 455 SkASSERT(budgetedCount == fBudgetedCount); | |
| 456 #if GR_CACHE_STATS | 501 #if GR_CACHE_STATS |
| 457 SkASSERT(fBudgetedHighWaterCount <= fHighWaterCount); | 502 SkASSERT(fBudgetedHighWaterCount <= fHighWaterCount); |
| 458 SkASSERT(fBudgetedHighWaterBytes <= fHighWaterBytes); | 503 SkASSERT(fBudgetedHighWaterBytes <= fHighWaterBytes); |
| 459 SkASSERT(bytes <= fHighWaterBytes); | 504 SkASSERT(fBytes <= fHighWaterBytes); |
| 460 SkASSERT(count <= fHighWaterCount); | 505 SkASSERT(fCount <= fHighWaterCount); |
| 461 SkASSERT(budgetedBytes <= fBudgetedHighWaterBytes); | 506 SkASSERT(fBudgetedBytes <= fBudgetedHighWaterBytes); |
| 462 SkASSERT(budgetedCount <= fBudgetedHighWaterCount); | 507 SkASSERT(fBudgetedCount <= fBudgetedHighWaterCount); |
| 463 #endif | 508 #endif |
| 464 SkASSERT(content == fContentHash.count()); | 509 SkASSERT(stats.fContent == fContentHash.count()); |
| 465 SkASSERT(scratch + couldBeScratch == fScratchMap.count()); | 510 SkASSERT(stats.fScratch + stats.fCouldBeScratch == fScratchMap.count()); |
| 466 | 511 |
| 467 // This assertion is not currently valid because we can be in recursive noti
fyIsPurgeable() | 512 // This assertion is not currently valid because we can be in recursive noti
fyIsPurgeable() |
| 468 // calls. This will be fixed when subresource registration is explicit. | 513 // calls. This will be fixed when subresource registration is explicit. |
| 469 // bool overBudget = budgetedBytes > fMaxBytes || budgetedCount > fMaxCount; | 514 // bool overBudget = budgetedBytes > fMaxBytes || budgetedCount > fMaxCount; |
| 470 // SkASSERT(!overBudget || locked == count || fPurging); | 515 // SkASSERT(!overBudget || locked == count || fPurging); |
| 471 } | 516 } |
| 517 |
| 518 bool GrResourceCache::isInCache(const GrGpuResource* resource) const { |
| 519 int index = *resource->cacheAccess().accessCacheIndex(); |
| 520 if (index < 0) { |
| 521 return false; |
| 522 } |
| 523 if (index < fPurgeableQueue.count() && fPurgeableQueue.at(index) == resource
) { |
| 524 return true; |
| 525 } |
| 526 if (index < fNonpurgeableResources.count() && fNonpurgeableResources[index]
== resource) { |
| 527 return true; |
| 528 } |
| 529 SkDEBUGFAIL("Resource index should be -1 or the resource should be in the ca
che."); |
| 530 return false; |
| 531 } |
| 532 |
| 472 #endif | 533 #endif |
| OLD | NEW |