aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkResourceCache.cpp
diff options
context:
space:
mode:
authorGravatar reed <reed@chromium.org>2015-02-24 13:54:23 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-02-24 13:54:23 -0800
commit7eeba2587760a0802fd2b90765b4fd0e5e895375 (patch)
treedad9caa7dde038c52728034710c3d6d4926bfff2 /src/core/SkResourceCache.cpp
parent4b583ac54b92ad6e7685bdfa2b68e7dd11ba0d28 (diff)
Notify resource caches when pixelref genID goes stale
patch from issue 954443002 at patchset 40001 (http://crrev.com/954443002#ps40001) BUG=skia: Review URL: https://codereview.chromium.org/950363002
Diffstat (limited to 'src/core/SkResourceCache.cpp')
-rw-r--r--src/core/SkResourceCache.cpp57
1 files changed, 51 insertions, 6 deletions
diff --git a/src/core/SkResourceCache.cpp b/src/core/SkResourceCache.cpp
index 4ed889a0ab..9da90c45dc 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"