| Index: src/core/SkResourceCache.cpp
|
| diff --git a/src/core/SkResourceCache.cpp b/src/core/SkResourceCache.cpp
|
| index 85b5b907b11f08e705af4af0b0cd82451922cfb4..68248f512bd2f08e4575e06d916e462750578d1f 100644
|
| --- a/src/core/SkResourceCache.cpp
|
| +++ b/src/core/SkResourceCache.cpp
|
| @@ -187,34 +187,80 @@
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
|
|
| -bool SkResourceCache::find(const Key& key, VisitorProc visitor, void* context) {
|
| +const SkResourceCache::Rec* SkResourceCache::findAndLock(const Key& key) {
|
| Rec* rec = fHash->find(key);
|
| if (rec) {
|
| - if (visitor(*rec, context)) {
|
| - this->moveToHead(rec); // for our LRU
|
| - return true;
|
| - } else {
|
| - this->remove(rec); // stale
|
| - return false;
|
| - }
|
| - }
|
| - return false;
|
| + this->moveToHead(rec); // for our LRU
|
| + rec->fLockCount += 1;
|
| + }
|
| + return rec;
|
| +}
|
| +
|
| +const SkResourceCache::Rec* SkResourceCache::addAndLock(Rec* rec) {
|
| + SkASSERT(rec);
|
| + // See if we already have this key (racy inserts, etc.)
|
| + const Rec* existing = this->findAndLock(rec->getKey());
|
| + if (existing) {
|
| + SkDELETE(rec);
|
| + return existing;
|
| + }
|
| +
|
| + this->addToHead(rec);
|
| + SkASSERT(1 == rec->fLockCount);
|
| + fHash->add(rec);
|
| + // We may (now) be overbudget, so see if we need to purge something.
|
| + this->purgeAsNeeded();
|
| + return rec;
|
| }
|
|
|
| void SkResourceCache::add(Rec* rec) {
|
| SkASSERT(rec);
|
| // See if we already have this key (racy inserts, etc.)
|
| - Rec* existing = fHash->find(rec->getKey());
|
| + const Rec* existing = this->findAndLock(rec->getKey());
|
| if (existing) {
|
| SkDELETE(rec);
|
| + this->unlock(existing);
|
| return;
|
| }
|
|
|
| this->addToHead(rec);
|
| + SkASSERT(1 == rec->fLockCount);
|
| fHash->add(rec);
|
| + this->unlock(rec);
|
| +}
|
| +
|
| +void SkResourceCache::unlock(SkResourceCache::ID id) {
|
| + SkASSERT(id);
|
| +
|
| +#ifdef SK_DEBUG
|
| + {
|
| + bool found = false;
|
| + Rec* rec = fHead;
|
| + while (rec != NULL) {
|
| + if (rec == id) {
|
| + found = true;
|
| + break;
|
| + }
|
| + rec = rec->fNext;
|
| + }
|
| + SkASSERT(found);
|
| + }
|
| +#endif
|
| + const Rec* rec = id;
|
| + SkASSERT(rec->fLockCount > 0);
|
| + // We're under our lock, and we're the only possible mutator, so unconsting is fine.
|
| + const_cast<Rec*>(rec)->fLockCount -= 1;
|
| +
|
| + // we may have been over-budget, but now have released something, so check
|
| + // if we should purge.
|
| + if (0 == rec->fLockCount) {
|
| + this->purgeAsNeeded();
|
| + }
|
| }
|
|
|
| void SkResourceCache::remove(Rec* rec) {
|
| + SkASSERT(0 == rec->fLockCount);
|
| +
|
| size_t used = rec->bytesUsed();
|
| SkASSERT(used <= fTotalBytesUsed);
|
|
|
| @@ -246,7 +292,9 @@
|
| }
|
|
|
| Rec* prev = rec->fPrev;
|
| - this->remove(rec);
|
| + if (0 == rec->fLockCount) {
|
| + this->remove(rec);
|
| + }
|
| rec = prev;
|
| }
|
| }
|
| @@ -369,8 +417,16 @@
|
| void SkResourceCache::dump() const {
|
| this->validate();
|
|
|
| - SkDebugf("SkResourceCache: count=%d bytes=%d %s\n",
|
| - fCount, fTotalBytesUsed, fDiscardableFactory ? "discardable" : "malloc");
|
| + const Rec* rec = fHead;
|
| + int locked = 0;
|
| + while (rec) {
|
| + locked += rec->fLockCount > 0;
|
| + rec = rec->fNext;
|
| + }
|
| +
|
| + SkDebugf("SkResourceCache: count=%d bytes=%d locked=%d %s\n",
|
| + fCount, fTotalBytesUsed, locked,
|
| + fDiscardableFactory ? "discardable" : "malloc");
|
| }
|
|
|
| size_t SkResourceCache::setSingleAllocationByteLimit(size_t newLimit) {
|
| @@ -414,6 +470,35 @@
|
| return gResourceCache;
|
| }
|
|
|
| +void SkResourceCache::Unlock(SkResourceCache::ID id) {
|
| + SkAutoMutexAcquire am(gMutex);
|
| + get_cache()->unlock(id);
|
| +
|
| +// get_cache()->dump();
|
| +}
|
| +
|
| +void SkResourceCache::Remove(SkResourceCache::ID id) {
|
| + SkAutoMutexAcquire am(gMutex);
|
| + SkASSERT(id);
|
| +
|
| +#ifdef SK_DEBUG
|
| + {
|
| + bool found = false;
|
| + Rec* rec = get_cache()->fHead;
|
| + while (rec != NULL) {
|
| + if (rec == id) {
|
| + found = true;
|
| + break;
|
| + }
|
| + rec = rec->fNext;
|
| + }
|
| + SkASSERT(found);
|
| + }
|
| +#endif
|
| + const Rec* rec = id;
|
| + get_cache()->remove(const_cast<Rec*>(rec));
|
| +}
|
| +
|
| size_t SkResourceCache::GetTotalBytesUsed() {
|
| SkAutoMutexAcquire am(gMutex);
|
| return get_cache()->getTotalBytesUsed();
|
| @@ -454,9 +539,14 @@
|
| return get_cache()->purgeAll();
|
| }
|
|
|
| -bool SkResourceCache::Find(const Key& key, VisitorProc visitor, void* context) {
|
| - SkAutoMutexAcquire am(gMutex);
|
| - return get_cache()->find(key, visitor, context);
|
| +const SkResourceCache::Rec* SkResourceCache::FindAndLock(const Key& key) {
|
| + SkAutoMutexAcquire am(gMutex);
|
| + return get_cache()->findAndLock(key);
|
| +}
|
| +
|
| +const SkResourceCache::Rec* SkResourceCache::AddAndLock(Rec* rec) {
|
| + SkAutoMutexAcquire am(gMutex);
|
| + return get_cache()->addAndLock(rec);
|
| }
|
|
|
| void SkResourceCache::Add(Rec* rec) {
|
|
|