Chromium Code Reviews| Index: src/core/SkResourceCache.cpp |
| diff --git a/src/core/SkResourceCache.cpp b/src/core/SkResourceCache.cpp |
| index 4ed889a0aba3095900d934187f812f170217cca8..2434006e3bf6e6f44c17411422174830c166ce08 100644 |
| --- a/src/core/SkResourceCache.cpp |
| +++ b/src/core/SkResourceCache.cpp |
| @@ -6,12 +6,15 @@ |
| */ |
| #include "SkChecksum.h" |
| -#include "SkResourceCache.h" |
| +#include "SkMessageBus.h" |
| #include "SkMipMap.h" |
| #include "SkPixelRef.h" |
| +#include "SkResourceCache.h" |
| #include <stddef.h> |
| +DECLARE_SKMESSAGEBUS_MESSAGE(SkResourceCache::PurgeSharedIDMessage) |
| + |
| // This can be defined by the caller's build system |
| //#define SK_USE_DISCARDABLE_SCALEDIMAGECACHE |
| @@ -23,18 +26,22 @@ |
| #define SK_DEFAULT_IMAGE_CACHE_LIMIT (2 * 1024 * 1024) |
| #endif |
| -void SkResourceCache::Key::init(void* nameSpace, size_t length) { |
| +void SkResourceCache::Key::init(void* nameSpace, uint64_t sharedID, size_t length) { |
| SkASSERT(SkAlign4(length) == length); |
| // fCount32 and fHash are not hashed |
| - static const int kUnhashedLocal32s = 2; |
| - static const int kLocal32s = kUnhashedLocal32s + (sizeof(fNamespace) >> 2); |
| + static const int kUnhashedLocal32s = 2; // fCache32 + fHash |
| + static const int kSharedIDLocal32s = 2; // fSharedID_lo + fSharedID_hi |
| + static const int kHashedLocal32s = kSharedIDLocal32s + (sizeof(fNamespace) >> 2); |
| + static const int kLocal32s = kUnhashedLocal32s + kHashedLocal32s; |
| SK_COMPILE_ASSERT(sizeof(Key) == (kLocal32s << 2), unaccounted_key_locals); |
| SK_COMPILE_ASSERT(sizeof(Key) == offsetof(Key, fNamespace) + sizeof(fNamespace), |
| namespace_field_must_be_last); |
| fCount32 = SkToS32(kLocal32s + (length >> 2)); |
| + fSharedID_lo = (uint32_t)sharedID; |
| + fSharedID_hi = (uint32_t)(sharedID >> 32); |
| fNamespace = nameSpace; |
| // skip unhashed fields when computing the murmur |
| fHash = SkChecksum::Murmur3(this->as32() + kUnhashedLocal32s, |
| @@ -199,7 +206,9 @@ SkResourceCache::~SkResourceCache() { |
| //////////////////////////////////////////////////////////////////////////////// |
| -bool SkResourceCache::find(const Key& key, VisitorProc visitor, void* context) { |
| +bool SkResourceCache::find(const Key& key, FindVisitor visitor, void* context) { |
| + this->checkMessages(); |
| + |
| Rec* rec = fHash->find(key); |
| if (rec) { |
| if (visitor(*rec, context)) { |
| @@ -226,6 +235,8 @@ static void make_size_str(size_t size, SkString* str) { |
| static bool gDumpCacheTransactions; |
| void SkResourceCache::add(Rec* rec) { |
| + this->checkMessages(); |
| + |
| SkASSERT(rec); |
| // See if we already have this key (racy inserts, etc.) |
| Rec* existing = fHash->find(rec->getKey()); |
| @@ -294,6 +305,24 @@ void SkResourceCache::purgeAsNeeded(bool forcePurge) { |
| } |
| } |
| +void SkResourceCache::purgeSharedID(uint64_t sharedID) { |
| + if (0 == sharedID) { |
| + return; |
| + } |
| + |
| + // go backwards, just like purgeAsNeeded, just to make the code similar. |
| + // could iterate either direction and still be correct. |
| + Rec* rec = fTail; |
| + while (rec) { |
| + Rec* prev = rec->fPrev; |
| + if (rec->getKey().getSharedID() == sharedID) { |
| +// SkDebugf("purgeSharedID id=%llx rec=%p\n", sharedID, rec); |
| + this->remove(rec); |
| + } |
| + rec = prev; |
| + } |
| +} |
| + |
| size_t SkResourceCache::setTotalByteLimit(size_t newLimit) { |
| size_t prevLimit = fTotalByteLimit; |
| fTotalByteLimit = newLimit; |
| @@ -304,6 +333,8 @@ size_t SkResourceCache::setTotalByteLimit(size_t newLimit) { |
| } |
| SkCachedData* SkResourceCache::newCachedData(size_t bytes) { |
| + this->checkMessages(); |
| + |
| if (fDiscardableFactory) { |
| SkDiscardableMemory* dm = fDiscardableFactory(bytes); |
| return dm ? SkNEW_ARGS(SkCachedData, (bytes, dm)) : NULL; |
| @@ -451,6 +482,14 @@ size_t SkResourceCache::getEffectiveSingleAllocationByteLimit() const { |
| return limit; |
| } |
| +void SkResourceCache::checkMessages() { |
| + SkTArray<PurgeSharedIDMessage, true> msgs; |
|
mtklein
2015/02/24 21:24:59
You'd better check with Brian if you switch this o
reed2
2015/02/24 21:30:08
Already undid this change.
|
| + fPurgeSharedIDInbox.poll(&msgs); |
| + for (int i = 0; i < msgs.count(); ++i) { |
| + this->purgeSharedID(msgs[i].fSharedID); |
| + } |
| +} |
| + |
| /////////////////////////////////////////////////////////////////////////////// |
| #include "SkThread.h" |
| @@ -537,7 +576,7 @@ void SkResourceCache::PurgeAll() { |
| return get_cache()->purgeAll(); |
| } |
| -bool SkResourceCache::Find(const Key& key, VisitorProc visitor, void* context) { |
| +bool SkResourceCache::Find(const Key& key, FindVisitor visitor, void* context) { |
| SkAutoMutexAcquire am(gMutex); |
| return get_cache()->find(key, visitor, context); |
| } |
| @@ -547,6 +586,12 @@ void SkResourceCache::Add(Rec* rec) { |
| get_cache()->add(rec); |
| } |
| +void SkResourceCache::PostPurgeSharedID(uint64_t sharedID) { |
| + if (sharedID) { |
| + SkMessageBus<PurgeSharedIDMessage>::Post(PurgeSharedIDMessage(sharedID)); |
| + } |
| +} |
| + |
| /////////////////////////////////////////////////////////////////////////////// |
| #include "SkGraphics.h" |