Index: src/ports/SkAshmemImageCache.cpp |
diff --git a/src/ports/SkAshmemImageCache.cpp b/src/ports/SkAshmemImageCache.cpp |
index b7c6c7058b7d23f96c87b5bed293a6f985a8f4ca..f13d1e718f6cfb9608b36763239d5d8fee3764c5 100644 |
--- a/src/ports/SkAshmemImageCache.cpp |
+++ b/src/ports/SkAshmemImageCache.cpp |
@@ -34,7 +34,7 @@ SkAshmemImageCache::~SkAshmemImageCache() { |
#endif |
// ashmem likes lengths on page boundaries. |
-static size_t roundToPageSize(size_t size) { |
+static size_t round_to_page_size(size_t size) { |
const size_t mask = getpagesize() - 1; |
size_t newSize = (size + mask) & ~mask; |
return newSize; |
@@ -45,21 +45,8 @@ void* SkAshmemImageCache::allocAndPinCache(size_t bytes, intptr_t* ID) { |
SkAutoMutexAcquire ac(&gAshmemMutex); |
- if (*ID != SkImageCache::UNINITIALIZED_ID) { |
- // This rec was previously allocated, but pinCache subsequently |
- // failed. |
- AshmemRec* pRec = reinterpret_cast<AshmemRec*>(*ID); |
- SkASSERT(roundToPageSize(bytes) == pRec->fSize); |
- SkASSERT(pRec->fFD != -1); |
- (void) ashmem_pin_region(pRec->fFD, 0, 0); |
-#ifdef SK_DEBUG |
- pRec->fPinned = true; |
-#endif |
- return pRec->fAddr; |
- } |
- |
AshmemRec rec; |
- rec.fSize = roundToPageSize(bytes); |
+ rec.fSize = round_to_page_size(bytes); |
rec.fFD = ashmem_create_region(NULL, rec.fSize); |
if (-1 == rec.fFD) { |
@@ -92,19 +79,25 @@ void* SkAshmemImageCache::allocAndPinCache(size_t bytes, intptr_t* ID) { |
return rec.fAddr; |
} |
-void* SkAshmemImageCache::pinCache(intptr_t ID) { |
+void* SkAshmemImageCache::pinCache(intptr_t ID, PurgeStatus* status) { |
+ SkASSERT(ID != SkImageCache::UNINITIALIZED_ID); |
+ SkASSERT(status != NULL); |
SkAutoMutexAcquire ac(&gAshmemMutex); |
AshmemRec* rec = reinterpret_cast<AshmemRec*>(ID); |
const int fd = rec->fFD; |
int pin = ashmem_pin_region(fd, 0, 0); |
if (ASHMEM_NOT_PURGED == pin) { |
+ *status = SkImageCache::kNotPurged_PurgeStatus; |
+ } else if (ASHMEM_WAS_PURGED == pin) { |
+ *status = SkImageCache::kPurged_PurgeStatus; |
+ } else { |
+ this->throwAwayCacheInternal(ID); |
+ return NULL; |
+ } |
#ifdef SK_DEBUG |
- rec->fPinned = true; |
+ rec->fPinned = true; |
#endif |
- return rec->fAddr; |
- } |
- ashmem_unpin_region(fd, 0, 0); |
- return NULL; |
+ return rec->fAddr; |
} |
void SkAshmemImageCache::releaseCache(intptr_t ID) { |
@@ -118,9 +111,18 @@ void SkAshmemImageCache::releaseCache(intptr_t ID) { |
void SkAshmemImageCache::throwAwayCache(intptr_t ID) { |
SkAutoMutexAcquire ac(&gAshmemMutex); |
+ this->throwAwayCacheInternal(ID); |
+} |
+ |
+void SkAshmemImageCache::throwAwayCacheInternal(intptr_t ID) { |
+ if (SkImageCache::UNINITIALIZED_ID == ID) { |
+ return; |
+ } |
AshmemRec* rec = reinterpret_cast<AshmemRec*>(ID); |
- munmap(rec->fAddr, rec->fSize); |
- close(rec->fFD); |
+ if (rec->fFD != -1) { |
+ munmap(rec->fAddr, rec->fSize); |
+ close(rec->fFD); |
+ } |
#ifdef SK_DEBUG |
SkASSERT(!rec->fPinned); |
int index = this->findRec(rec); |
@@ -148,14 +150,31 @@ int SkAshmemImageCache::findRec(const SkAshmemImageCache::AshmemRec* rec) const |
sizeof(intptr_t), AshmemRec::Compare); |
} |
-SkImageCache::CacheStatus SkAshmemImageCache::getCacheStatus(intptr_t ID) const { |
+SkImageCache::PinStatus SkAshmemImageCache::getPinStatus(intptr_t ID) const { |
SkAutoMutexAcquire ac(&gAshmemMutex); |
AshmemRec* rec = reinterpret_cast<AshmemRec*>(ID); |
+ // findRec searches purely based on the value of ID. If rec has already been deleted, it will |
+ // not be in the array. rec will only be accessed if it has not been deleted. |
int index = this->findRec(rec); |
if (index < 0) { |
- return SkImageCache::kThrownAway_CacheStatus; |
+ return SkImageCache::kThrownAway_PinStatus; |
+ } |
+ return rec->fPinned ? SkImageCache::kPinned_PinStatus |
+ : SkImageCache::kNeedsPin_PinStatus; |
+} |
+ |
+void SkAshmemImageCache::purgeAllCaches() { |
+ SkAutoMutexAcquire ac(&gAshmemMutex); |
+ // FIXME: How to use the ashmem API to do this? |
+ for (int i = 0; i < fRecs.count(); i++) { |
+ AshmemRec* rec = fRecs.getAt(i); |
+ if (!rec->fPinned) { |
+ munmap(rec->fAddr, rec->fSize); |
+ close(rec->fFD); |
+ rec->fFD = -1; |
+ rec->fAddr = NULL; |
+ rec->fSize = 0; |
+ } |
} |
- return rec->fPinned ? SkImageCache::kPinned_CacheStatus |
- : SkImageCache::kUnpinned_CacheStatus; |
} |
#endif |