| Index: src/core/SkResourceCache.cpp
|
| diff --git a/src/core/SkResourceCache.cpp b/src/core/SkResourceCache.cpp
|
| index 4ed889a0aba3095900d934187f812f170217cca8..9da90c45dc26bb3042b44ff6e2d05f034c1c956b 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> msgs;
|
| + 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"
|
|
|