| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2013 Google Inc. | 2  * Copyright 2013 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include "SkChecksum.h" | 8 #include "SkChecksum.h" | 
| 9 #include "SkResourceCache.h" | 9 #include "SkResourceCache.h" | 
| 10 #include "SkMipMap.h" | 10 #include "SkMipMap.h" | 
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 180     while (rec) { | 180     while (rec) { | 
| 181         Rec* next = rec->fNext; | 181         Rec* next = rec->fNext; | 
| 182         SkDELETE(rec); | 182         SkDELETE(rec); | 
| 183         rec = next; | 183         rec = next; | 
| 184     } | 184     } | 
| 185     delete fHash; | 185     delete fHash; | 
| 186 } | 186 } | 
| 187 | 187 | 
| 188 //////////////////////////////////////////////////////////////////////////////// | 188 //////////////////////////////////////////////////////////////////////////////// | 
| 189 | 189 | 
| 190 const SkResourceCache::Rec* SkResourceCache::findAndLock(const Key& key) { | 190 bool SkResourceCache::find(const Key& key, VisitorProc visitor, void* context) { | 
| 191     Rec* rec = fHash->find(key); | 191     Rec* rec = fHash->find(key); | 
| 192     if (rec) { | 192     if (rec) { | 
| 193         this->moveToHead(rec);  // for our LRU | 193         if (visitor(*rec, context)) { | 
| 194         rec->fLockCount += 1; | 194             this->moveToHead(rec);  // for our LRU | 
|  | 195             return true; | 
|  | 196         } else { | 
|  | 197             this->remove(rec);  // stale | 
|  | 198             return false; | 
|  | 199         } | 
| 195     } | 200     } | 
| 196     return rec; | 201     return false; | 
| 197 } |  | 
| 198 |  | 
| 199 const SkResourceCache::Rec* SkResourceCache::addAndLock(Rec* rec) { |  | 
| 200     SkASSERT(rec); |  | 
| 201     // See if we already have this key (racy inserts, etc.) |  | 
| 202     const Rec* existing = this->findAndLock(rec->getKey()); |  | 
| 203     if (existing) { |  | 
| 204         SkDELETE(rec); |  | 
| 205         return existing; |  | 
| 206     } |  | 
| 207 |  | 
| 208     this->addToHead(rec); |  | 
| 209     SkASSERT(1 == rec->fLockCount); |  | 
| 210     fHash->add(rec); |  | 
| 211     // We may (now) be overbudget, so see if we need to purge something. |  | 
| 212     this->purgeAsNeeded(); |  | 
| 213     return rec; |  | 
| 214 } | 202 } | 
| 215 | 203 | 
| 216 void SkResourceCache::add(Rec* rec) { | 204 void SkResourceCache::add(Rec* rec) { | 
| 217     SkASSERT(rec); | 205     SkASSERT(rec); | 
| 218     // See if we already have this key (racy inserts, etc.) | 206     // See if we already have this key (racy inserts, etc.) | 
| 219     const Rec* existing = this->findAndLock(rec->getKey()); | 207     Rec* existing = fHash->find(rec->getKey()); | 
| 220     if (existing) { | 208     if (existing) { | 
| 221         SkDELETE(rec); | 209         SkDELETE(rec); | 
| 222         this->unlock(existing); |  | 
| 223         return; | 210         return; | 
| 224     } | 211     } | 
| 225 | 212 | 
| 226     this->addToHead(rec); | 213     this->addToHead(rec); | 
| 227     SkASSERT(1 == rec->fLockCount); |  | 
| 228     fHash->add(rec); | 214     fHash->add(rec); | 
| 229     this->unlock(rec); |  | 
| 230 } |  | 
| 231 | 215 | 
| 232 void SkResourceCache::unlock(SkResourceCache::ID id) { | 216     // since the new rec may push us over-budget, we perform a purge check now | 
| 233     SkASSERT(id); | 217     this->purgeAsNeeded(); | 
| 234 |  | 
| 235 #ifdef SK_DEBUG |  | 
| 236     { |  | 
| 237         bool found = false; |  | 
| 238         Rec* rec = fHead; |  | 
| 239         while (rec != NULL) { |  | 
| 240             if (rec == id) { |  | 
| 241                 found = true; |  | 
| 242                 break; |  | 
| 243             } |  | 
| 244             rec = rec->fNext; |  | 
| 245         } |  | 
| 246         SkASSERT(found); |  | 
| 247     } |  | 
| 248 #endif |  | 
| 249     const Rec* rec = id; |  | 
| 250     SkASSERT(rec->fLockCount > 0); |  | 
| 251     // We're under our lock, and we're the only possible mutator, so unconsting 
     is fine. |  | 
| 252     const_cast<Rec*>(rec)->fLockCount -= 1; |  | 
| 253 |  | 
| 254     // we may have been over-budget, but now have released something, so check |  | 
| 255     // if we should purge. |  | 
| 256     if (0 == rec->fLockCount) { |  | 
| 257         this->purgeAsNeeded(); |  | 
| 258     } |  | 
| 259 } | 218 } | 
| 260 | 219 | 
| 261 void SkResourceCache::remove(Rec* rec) { | 220 void SkResourceCache::remove(Rec* rec) { | 
| 262     SkASSERT(0 == rec->fLockCount); |  | 
| 263 |  | 
| 264     size_t used = rec->bytesUsed(); | 221     size_t used = rec->bytesUsed(); | 
| 265     SkASSERT(used <= fTotalBytesUsed); | 222     SkASSERT(used <= fTotalBytesUsed); | 
| 266 | 223 | 
| 267     this->detach(rec); | 224     this->detach(rec); | 
| 268     fHash->remove(rec->getKey()); | 225     fHash->remove(rec->getKey()); | 
| 269 | 226 | 
| 270     SkDELETE(rec); | 227     SkDELETE(rec); | 
| 271 | 228 | 
| 272     fTotalBytesUsed -= used; | 229     fTotalBytesUsed -= used; | 
| 273     fCount -= 1; | 230     fCount -= 1; | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 285         byteLimit = fTotalByteLimit; | 242         byteLimit = fTotalByteLimit; | 
| 286     } | 243     } | 
| 287 | 244 | 
| 288     Rec* rec = fTail; | 245     Rec* rec = fTail; | 
| 289     while (rec) { | 246     while (rec) { | 
| 290         if (!forcePurge && fTotalBytesUsed < byteLimit && fCount < countLimit) { | 247         if (!forcePurge && fTotalBytesUsed < byteLimit && fCount < countLimit) { | 
| 291             break; | 248             break; | 
| 292         } | 249         } | 
| 293 | 250 | 
| 294         Rec* prev = rec->fPrev; | 251         Rec* prev = rec->fPrev; | 
| 295         if (0 == rec->fLockCount) { | 252         this->remove(rec); | 
| 296             this->remove(rec); |  | 
| 297         } |  | 
| 298         rec = prev; | 253         rec = prev; | 
| 299     } | 254     } | 
| 300 } | 255 } | 
| 301 | 256 | 
| 302 size_t SkResourceCache::setTotalByteLimit(size_t newLimit) { | 257 size_t SkResourceCache::setTotalByteLimit(size_t newLimit) { | 
| 303     size_t prevLimit = fTotalByteLimit; | 258     size_t prevLimit = fTotalByteLimit; | 
| 304     fTotalByteLimit = newLimit; | 259     fTotalByteLimit = newLimit; | 
| 305     if (newLimit < prevLimit) { | 260     if (newLimit < prevLimit) { | 
| 306         this->purgeAsNeeded(); | 261         this->purgeAsNeeded(); | 
| 307     } | 262     } | 
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 410     } | 365     } | 
| 411 | 366 | 
| 412     SkASSERT(0 == count); | 367     SkASSERT(0 == count); | 
| 413     SkASSERT(0 == used); | 368     SkASSERT(0 == used); | 
| 414 } | 369 } | 
| 415 #endif | 370 #endif | 
| 416 | 371 | 
| 417 void SkResourceCache::dump() const { | 372 void SkResourceCache::dump() const { | 
| 418     this->validate(); | 373     this->validate(); | 
| 419 | 374 | 
| 420     const Rec* rec = fHead; | 375     SkDebugf("SkResourceCache: count=%d bytes=%d %s\n", | 
| 421     int locked = 0; | 376              fCount, fTotalBytesUsed, fDiscardableFactory ? "discardable" : "mal
     loc"); | 
| 422     while (rec) { |  | 
| 423         locked += rec->fLockCount > 0; |  | 
| 424         rec = rec->fNext; |  | 
| 425     } |  | 
| 426 |  | 
| 427     SkDebugf("SkResourceCache: count=%d bytes=%d locked=%d %s\n", |  | 
| 428              fCount, fTotalBytesUsed, locked, |  | 
| 429              fDiscardableFactory ? "discardable" : "malloc"); |  | 
| 430 } | 377 } | 
| 431 | 378 | 
| 432 size_t SkResourceCache::setSingleAllocationByteLimit(size_t newLimit) { | 379 size_t SkResourceCache::setSingleAllocationByteLimit(size_t newLimit) { | 
| 433     size_t oldLimit = fSingleAllocationByteLimit; | 380     size_t oldLimit = fSingleAllocationByteLimit; | 
| 434     fSingleAllocationByteLimit = newLimit; | 381     fSingleAllocationByteLimit = newLimit; | 
| 435     return oldLimit; | 382     return oldLimit; | 
| 436 } | 383 } | 
| 437 | 384 | 
| 438 size_t SkResourceCache::getSingleAllocationByteLimit() const { | 385 size_t SkResourceCache::getSingleAllocationByteLimit() const { | 
| 439     return fSingleAllocationByteLimit; | 386     return fSingleAllocationByteLimit; | 
| (...skipping 23 matching lines...) Expand all  Loading... | 
| 463 #ifdef SK_USE_DISCARDABLE_SCALEDIMAGECACHE | 410 #ifdef SK_USE_DISCARDABLE_SCALEDIMAGECACHE | 
| 464         gResourceCache = SkNEW_ARGS(SkResourceCache, (SkDiscardableMemory::Creat
     e)); | 411         gResourceCache = SkNEW_ARGS(SkResourceCache, (SkDiscardableMemory::Creat
     e)); | 
| 465 #else | 412 #else | 
| 466         gResourceCache = SkNEW_ARGS(SkResourceCache, (SK_DEFAULT_IMAGE_CACHE_LIM
     IT)); | 413         gResourceCache = SkNEW_ARGS(SkResourceCache, (SK_DEFAULT_IMAGE_CACHE_LIM
     IT)); | 
| 467 #endif | 414 #endif | 
| 468         atexit(cleanup_gResourceCache); | 415         atexit(cleanup_gResourceCache); | 
| 469     } | 416     } | 
| 470     return gResourceCache; | 417     return gResourceCache; | 
| 471 } | 418 } | 
| 472 | 419 | 
| 473 void SkResourceCache::Unlock(SkResourceCache::ID id) { |  | 
| 474     SkAutoMutexAcquire am(gMutex); |  | 
| 475     get_cache()->unlock(id); |  | 
| 476 |  | 
| 477 //    get_cache()->dump(); |  | 
| 478 } |  | 
| 479 |  | 
| 480 void SkResourceCache::Remove(SkResourceCache::ID id) { |  | 
| 481     SkAutoMutexAcquire am(gMutex); |  | 
| 482     SkASSERT(id); |  | 
| 483 |  | 
| 484 #ifdef SK_DEBUG |  | 
| 485     { |  | 
| 486         bool found = false; |  | 
| 487         Rec* rec = get_cache()->fHead; |  | 
| 488         while (rec != NULL) { |  | 
| 489             if (rec == id) { |  | 
| 490                 found = true; |  | 
| 491                 break; |  | 
| 492             } |  | 
| 493             rec = rec->fNext; |  | 
| 494         } |  | 
| 495         SkASSERT(found); |  | 
| 496     } |  | 
| 497 #endif |  | 
| 498     const Rec* rec = id; |  | 
| 499     get_cache()->remove(const_cast<Rec*>(rec)); |  | 
| 500 } |  | 
| 501 |  | 
| 502 size_t SkResourceCache::GetTotalBytesUsed() { | 420 size_t SkResourceCache::GetTotalBytesUsed() { | 
| 503     SkAutoMutexAcquire am(gMutex); | 421     SkAutoMutexAcquire am(gMutex); | 
| 504     return get_cache()->getTotalBytesUsed(); | 422     return get_cache()->getTotalBytesUsed(); | 
| 505 } | 423 } | 
| 506 | 424 | 
| 507 size_t SkResourceCache::GetTotalByteLimit() { | 425 size_t SkResourceCache::GetTotalByteLimit() { | 
| 508     SkAutoMutexAcquire am(gMutex); | 426     SkAutoMutexAcquire am(gMutex); | 
| 509     return get_cache()->getTotalByteLimit(); | 427     return get_cache()->getTotalByteLimit(); | 
| 510 } | 428 } | 
| 511 | 429 | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 532 size_t SkResourceCache::GetSingleAllocationByteLimit() { | 450 size_t SkResourceCache::GetSingleAllocationByteLimit() { | 
| 533     SkAutoMutexAcquire am(gMutex); | 451     SkAutoMutexAcquire am(gMutex); | 
| 534     return get_cache()->getSingleAllocationByteLimit(); | 452     return get_cache()->getSingleAllocationByteLimit(); | 
| 535 } | 453 } | 
| 536 | 454 | 
| 537 void SkResourceCache::PurgeAll() { | 455 void SkResourceCache::PurgeAll() { | 
| 538     SkAutoMutexAcquire am(gMutex); | 456     SkAutoMutexAcquire am(gMutex); | 
| 539     return get_cache()->purgeAll(); | 457     return get_cache()->purgeAll(); | 
| 540 } | 458 } | 
| 541 | 459 | 
| 542 const SkResourceCache::Rec* SkResourceCache::FindAndLock(const Key& key) { | 460 bool SkResourceCache::Find(const Key& key, VisitorProc visitor, void* context) { | 
| 543     SkAutoMutexAcquire am(gMutex); | 461     SkAutoMutexAcquire am(gMutex); | 
| 544     return get_cache()->findAndLock(key); | 462     return get_cache()->find(key, visitor, context); | 
| 545 } |  | 
| 546 |  | 
| 547 const SkResourceCache::Rec* SkResourceCache::AddAndLock(Rec* rec) { |  | 
| 548     SkAutoMutexAcquire am(gMutex); |  | 
| 549     return get_cache()->addAndLock(rec); |  | 
| 550 } | 463 } | 
| 551 | 464 | 
| 552 void SkResourceCache::Add(Rec* rec) { | 465 void SkResourceCache::Add(Rec* rec) { | 
| 553     SkAutoMutexAcquire am(gMutex); | 466     SkAutoMutexAcquire am(gMutex); | 
| 554     get_cache()->add(rec); | 467     get_cache()->add(rec); | 
| 555 } | 468 } | 
| 556 | 469 | 
| 557 /////////////////////////////////////////////////////////////////////////////// | 470 /////////////////////////////////////////////////////////////////////////////// | 
| 558 | 471 | 
| 559 #include "SkGraphics.h" | 472 #include "SkGraphics.h" | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 575 } | 488 } | 
| 576 | 489 | 
| 577 size_t SkGraphics::SetResourceCacheSingleAllocationByteLimit(size_t newLimit) { | 490 size_t SkGraphics::SetResourceCacheSingleAllocationByteLimit(size_t newLimit) { | 
| 578     return SkResourceCache::SetSingleAllocationByteLimit(newLimit); | 491     return SkResourceCache::SetSingleAllocationByteLimit(newLimit); | 
| 579 } | 492 } | 
| 580 | 493 | 
| 581 void SkGraphics::PurgeResourceCache() { | 494 void SkGraphics::PurgeResourceCache() { | 
| 582     return SkResourceCache::PurgeAll(); | 495     return SkResourceCache::PurgeAll(); | 
| 583 } | 496 } | 
| 584 | 497 | 
| OLD | NEW | 
|---|