Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(571)

Unified Diff: src/lazy/SkPurgeableImageCache.cpp

Issue 12433020: Improvements/additions to SkImageCache/SkLazyPixelRef. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Respond to comments. Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/lazy/SkLruImageCache.cpp ('k') | src/ports/SkAshmemImageCache.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/lazy/SkPurgeableImageCache.cpp
diff --git a/src/lazy/SkPurgeableImageCache.cpp b/src/lazy/SkPurgeableImageCache.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0f2c5e3c8e382f2f8e067ef376edafe555bd02d8
--- /dev/null
+++ b/src/lazy/SkPurgeableImageCache.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkThread.h"
+#include "SkPurgeableImageCache.h"
+#include "SkPurgeableMemoryBlock.h"
+
+#ifdef SK_DEBUG
+ #include "SkTSearch.h"
+#endif
+
+SK_DECLARE_STATIC_MUTEX(gPurgeableImageMutex);
+
+SkImageCache* SkPurgeableImageCache::Create() {
+ if (!SkPurgeableMemoryBlock::IsSupported()) {
+ return NULL;
+ }
+ SkAutoMutexAcquire ac(&gPurgeableImageMutex);
+ static SkPurgeableImageCache gCache;
+ gCache.ref();
+ return &gCache;
+}
+
+SkPurgeableImageCache::SkPurgeableImageCache() {}
+
+#ifdef SK_DEBUG
+SkPurgeableImageCache::~SkPurgeableImageCache() {
+ SkASSERT(fRecs.count() == 0);
+}
+#endif
+
+
+void* SkPurgeableImageCache::allocAndPinCache(size_t bytes, intptr_t* ID) {
+ SkAutoMutexAcquire ac(&gPurgeableImageMutex);
+
+ SkPurgeableMemoryBlock* block = SkPurgeableMemoryBlock::Create(bytes);
+ if (NULL == block) {
+ return NULL;
+ }
+
+ SkPurgeableMemoryBlock::PinResult pinResult;
+ void* data = block->pin(&pinResult);
+ if (NULL == data) {
+ SkDELETE(block);
+ return NULL;
+ }
+
+ SkASSERT(ID != NULL);
+ *ID = reinterpret_cast<intptr_t>(block);
+#ifdef SK_DEBUG
+ // Insert into the array of all recs:
+ int index = this->findRec(*ID);
+ SkASSERT(index < 0);
+ fRecs.insert(~index, 1, ID);
+#endif
+ return data;
+}
+
+void* SkPurgeableImageCache::pinCache(intptr_t ID, SkImageCache::DataStatus* status) {
+ SkASSERT(ID != SkImageCache::UNINITIALIZED_ID);
+ SkAutoMutexAcquire ac(&gPurgeableImageMutex);
+
+ SkASSERT(this->findRec(ID) >= 0);
+ SkPurgeableMemoryBlock* block = reinterpret_cast<SkPurgeableMemoryBlock*>(ID);
+ SkPurgeableMemoryBlock::PinResult pinResult;
+ void* data = block->pin(&pinResult);
+ if (NULL == data) {
+ this->removeRec(ID);
+ return NULL;
+ }
+
+ switch (pinResult) {
+ case SkPurgeableMemoryBlock::kRetained_PinResult:
+ *status = SkImageCache::kRetained_DataStatus;
+ break;
+
+ case SkPurgeableMemoryBlock::kUninitialized_PinResult:
+ *status = SkImageCache::kUninitialized_DataStatus;
+ break;
+
+ default:
+ // Invalid value. Treat as a failure to pin.
+ SkASSERT(false);
+ this->removeRec(ID);
+ return NULL;
+ }
+
+ return data;
+}
+
+void SkPurgeableImageCache::releaseCache(intptr_t ID) {
+ SkASSERT(ID != SkImageCache::UNINITIALIZED_ID);
+ SkAutoMutexAcquire ac(&gPurgeableImageMutex);
+
+ SkASSERT(this->findRec(ID) >= 0);
+ SkPurgeableMemoryBlock* block = reinterpret_cast<SkPurgeableMemoryBlock*>(ID);
+ block->unpin();
+}
+
+void SkPurgeableImageCache::throwAwayCache(intptr_t ID) {
+ SkASSERT(ID != SkImageCache::UNINITIALIZED_ID);
+ SkAutoMutexAcquire ac(&gPurgeableImageMutex);
+
+ this->removeRec(ID);
+}
+
+#ifdef SK_DEBUG
+SkImageCache::MemoryStatus SkPurgeableImageCache::getMemoryStatus(intptr_t ID) const {
+ SkAutoMutexAcquire ac(&gPurgeableImageMutex);
+ if (SkImageCache::UNINITIALIZED_ID == ID || this->findRec(ID) < 0) {
+ return SkImageCache::kFreed_MemoryStatus;
+ }
+
+ SkPurgeableMemoryBlock* block = reinterpret_cast<SkPurgeableMemoryBlock*>(ID);
+ if (block->isPinned()) {
+ return SkImageCache::kPinned_MemoryStatus;
+ }
+ return SkImageCache::kUnpinned_MemoryStatus;
+}
+
+void SkPurgeableImageCache::purgeAllUnpinnedCaches() {
+ SkAutoMutexAcquire ac(&gPurgeableImageMutex);
+ if (SkPurgeableMemoryBlock::PlatformSupportsPurgingAllUnpinnedBlocks()) {
+ SkPurgeableMemoryBlock::PurgeAllUnpinnedBlocks();
+ } else {
+ // Go through the blocks, and purge them individually.
+ // Rather than deleting the blocks, which would interfere with further calls, purge them
+ // and keep them around.
+ for (int i = 0; i < fRecs.count(); i++) {
+ SkPurgeableMemoryBlock* block = reinterpret_cast<SkPurgeableMemoryBlock*>(fRecs[i]);
+ if (!block->isPinned()) {
+ if (!block->purge()) {
+ // FIXME: This should be more meaningful (which one, etc...)
+ SkDebugf("Failed to purge\n");
+ }
+ }
+ }
+ }
+}
+
+int SkPurgeableImageCache::findRec(intptr_t rec) const {
+ return SkTSearch(fRecs.begin(), fRecs.count(), rec, sizeof(intptr_t));
+}
+#endif
+
+void SkPurgeableImageCache::removeRec(intptr_t ID) {
+#ifdef SK_DEBUG
+ int index = this->findRec(ID);
+ SkASSERT(index >= 0);
+ fRecs.remove(index);
+#endif
+ SkPurgeableMemoryBlock* block = reinterpret_cast<SkPurgeableMemoryBlock*>(ID);
+ SkASSERT(!block->isPinned());
+ SkDELETE(block);
+}
« no previous file with comments | « src/lazy/SkLruImageCache.cpp ('k') | src/ports/SkAshmemImageCache.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698