| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkLruImageCache.h" | 8 #include "SkLruImageCache.h" |
| 9 | 9 |
| 10 static intptr_t NextGenerationID() { | 10 static intptr_t NextGenerationID() { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 #endif | 67 #endif |
| 68 SkDELETE(pixels); | 68 SkDELETE(pixels); |
| 69 pixels = prev; | 69 pixels = prev; |
| 70 } | 70 } |
| 71 #ifdef SK_DEBUG | 71 #ifdef SK_DEBUG |
| 72 SkASSERT(fRamUsed == 0); | 72 SkASSERT(fRamUsed == 0); |
| 73 #endif | 73 #endif |
| 74 } | 74 } |
| 75 | 75 |
| 76 #ifdef SK_DEBUG | 76 #ifdef SK_DEBUG |
| 77 SkImageCache::CacheStatus SkLruImageCache::getCacheStatus(intptr_t ID) const { | 77 SkImageCache::MemoryStatus SkLruImageCache::getMemoryStatus(intptr_t ID) const { |
| 78 if (SkImageCache::UNINITIALIZED_ID == ID) { |
| 79 return SkImageCache::kFreed_MemoryStatus; |
| 80 } |
| 78 SkAutoMutexAcquire ac(&fMutex); | 81 SkAutoMutexAcquire ac(&fMutex); |
| 79 CachedPixels* pixels = this->findByID(ID); | 82 CachedPixels* pixels = this->findByID(ID); |
| 80 if (NULL == pixels) { | 83 if (NULL == pixels) { |
| 81 return SkImageCache::kThrownAway_CacheStatus; | 84 return SkImageCache::kFreed_MemoryStatus; |
| 82 } | 85 } |
| 83 if (pixels->isLocked()) { | 86 if (pixels->isLocked()) { |
| 84 return SkImageCache::kPinned_CacheStatus; | 87 return SkImageCache::kPinned_MemoryStatus; |
| 85 } | 88 } |
| 86 return SkImageCache::kUnpinned_CacheStatus; | 89 return SkImageCache::kUnpinned_MemoryStatus; |
| 90 } |
| 91 |
| 92 void SkLruImageCache::purgeAllUnpinnedCaches() { |
| 93 SkAutoMutexAcquire ac(&fMutex); |
| 94 this->purgeTilAtOrBelow(0); |
| 87 } | 95 } |
| 88 #endif | 96 #endif |
| 89 | 97 |
| 90 size_t SkLruImageCache::setImageCacheLimit(size_t newLimit) { | 98 size_t SkLruImageCache::setImageCacheLimit(size_t newLimit) { |
| 91 size_t oldLimit = fRamBudget; | 99 size_t oldLimit = fRamBudget; |
| 92 SkAutoMutexAcquire ac(&fMutex); | 100 SkAutoMutexAcquire ac(&fMutex); |
| 93 fRamBudget = newLimit; | 101 fRamBudget = newLimit; |
| 94 this->purgeIfNeeded(); | 102 this->purgeIfNeeded(); |
| 95 return oldLimit; | 103 return oldLimit; |
| 96 } | 104 } |
| 97 | 105 |
| 98 void* SkLruImageCache::allocAndPinCache(size_t bytes, intptr_t* ID) { | 106 void* SkLruImageCache::allocAndPinCache(size_t bytes, intptr_t* ID) { |
| 99 SkAutoMutexAcquire ac(&fMutex); | 107 SkAutoMutexAcquire ac(&fMutex); |
| 100 CachedPixels* pixels = SkNEW_ARGS(CachedPixels, (bytes)); | 108 CachedPixels* pixels = SkNEW_ARGS(CachedPixels, (bytes)); |
| 101 if (ID != NULL) { | 109 if (ID != NULL) { |
| 102 *ID = pixels->getID(); | 110 *ID = pixels->getID(); |
| 103 } | 111 } |
| 104 pixels->lock(); | 112 pixels->lock(); |
| 105 fRamUsed += bytes; | 113 fRamUsed += bytes; |
| 106 fLRU.addToHead(pixels); | 114 fLRU.addToHead(pixels); |
| 107 this->purgeIfNeeded(); | 115 this->purgeIfNeeded(); |
| 108 return pixels->getData(); | 116 return pixels->getData(); |
| 109 } | 117 } |
| 110 | 118 |
| 111 void* SkLruImageCache::pinCache(intptr_t ID) { | 119 void* SkLruImageCache::pinCache(intptr_t ID, SkImageCache::DataStatus* status) { |
| 112 SkASSERT(ID != SkImageCache::UNINITIALIZED_ID); | 120 SkASSERT(ID != SkImageCache::UNINITIALIZED_ID); |
| 113 SkAutoMutexAcquire ac(&fMutex); | 121 SkAutoMutexAcquire ac(&fMutex); |
| 114 CachedPixels* pixels = this->findByID(ID); | 122 CachedPixels* pixels = this->findByID(ID); |
| 115 if (NULL == pixels) { | 123 if (NULL == pixels) { |
| 116 return NULL; | 124 return NULL; |
| 117 } | 125 } |
| 118 if (pixels != fLRU.head()) { | 126 if (pixels != fLRU.head()) { |
| 119 fLRU.remove(pixels); | 127 fLRU.remove(pixels); |
| 120 fLRU.addToHead(pixels); | 128 fLRU.addToHead(pixels); |
| 121 } | 129 } |
| 130 SkASSERT(status != NULL); |
| 131 // This cache will never return pinned memory whose data has been overwritte
n. |
| 132 *status = SkImageCache::kRetained_DataStatus; |
| 122 pixels->lock(); | 133 pixels->lock(); |
| 123 return pixels->getData(); | 134 return pixels->getData(); |
| 124 } | 135 } |
| 125 | 136 |
| 126 void SkLruImageCache::releaseCache(intptr_t ID) { | 137 void SkLruImageCache::releaseCache(intptr_t ID) { |
| 127 SkASSERT(ID != SkImageCache::UNINITIALIZED_ID); | 138 SkASSERT(ID != SkImageCache::UNINITIALIZED_ID); |
| 128 SkAutoMutexAcquire ac(&fMutex); | 139 SkAutoMutexAcquire ac(&fMutex); |
| 129 CachedPixels* pixels = this->findByID(ID); | 140 CachedPixels* pixels = this->findByID(ID); |
| 130 SkASSERT(pixels != NULL); | 141 SkASSERT(pixels != NULL); |
| 131 pixels->unlock(); | 142 pixels->unlock(); |
| 132 this->purgeIfNeeded(); | 143 this->purgeIfNeeded(); |
| 133 } | 144 } |
| 134 | 145 |
| 135 void SkLruImageCache::throwAwayCache(intptr_t ID) { | 146 void SkLruImageCache::throwAwayCache(intptr_t ID) { |
| 147 SkASSERT(ID != SkImageCache::UNINITIALIZED_ID); |
| 136 SkAutoMutexAcquire ac(&fMutex); | 148 SkAutoMutexAcquire ac(&fMutex); |
| 137 CachedPixels* pixels = this->findByID(ID); | 149 CachedPixels* pixels = this->findByID(ID); |
| 138 if (pixels != NULL) { | 150 if (pixels != NULL) { |
| 139 if (pixels->isLocked()) { | 151 if (pixels->isLocked()) { |
| 140 pixels->unlock(); | 152 pixels->unlock(); |
| 141 } | 153 } |
| 142 this->removePixels(pixels); | 154 this->removePixels(pixels); |
| 143 } | 155 } |
| 144 } | 156 } |
| 145 | 157 |
| 146 void SkLruImageCache::removePixels(CachedPixels* pixels) { | 158 void SkLruImageCache::removePixels(CachedPixels* pixels) { |
| 147 // Mutex is already locked. | 159 // Mutex is already locked. |
| 148 SkASSERT(!pixels->isLocked()); | 160 SkASSERT(!pixels->isLocked()); |
| 149 const size_t size = pixels->getLength(); | 161 const size_t size = pixels->getLength(); |
| 150 SkASSERT(size <= fRamUsed); | 162 SkASSERT(size <= fRamUsed); |
| 151 fLRU.remove(pixels); | 163 fLRU.remove(pixels); |
| 152 SkDELETE(pixels); | 164 SkDELETE(pixels); |
| 153 fRamUsed -= size; | 165 fRamUsed -= size; |
| 154 } | 166 } |
| 155 | 167 |
| 156 CachedPixels* SkLruImageCache::findByID(intptr_t ID) const { | 168 CachedPixels* SkLruImageCache::findByID(intptr_t ID) const { |
| 157 // Mutex is already locked. | 169 // Mutex is already locked. |
| 158 if (SkImageCache::UNINITIALIZED_ID == ID) { | |
| 159 return NULL; | |
| 160 } | |
| 161 Iter iter; | 170 Iter iter; |
| 162 // Start from the head, most recently used. | 171 // Start from the head, most recently used. |
| 163 CachedPixels* pixels = iter.init(fLRU, Iter::kHead_IterStart); | 172 CachedPixels* pixels = iter.init(fLRU, Iter::kHead_IterStart); |
| 164 while (pixels != NULL) { | 173 while (pixels != NULL) { |
| 165 if (pixels->getID() == ID) { | 174 if (pixels->getID() == ID) { |
| 166 return pixels; | 175 return pixels; |
| 167 } | 176 } |
| 168 pixels = iter.next(); | 177 pixels = iter.next(); |
| 169 } | 178 } |
| 170 return NULL; | 179 return NULL; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 185 CachedPixels* pixels = iter.init(fLRU, Iter::kTail_IterStart); | 194 CachedPixels* pixels = iter.init(fLRU, Iter::kTail_IterStart); |
| 186 while (pixels != NULL && fRamUsed > limit) { | 195 while (pixels != NULL && fRamUsed > limit) { |
| 187 CachedPixels* prev = iter.prev(); | 196 CachedPixels* prev = iter.prev(); |
| 188 if (!pixels->isLocked()) { | 197 if (!pixels->isLocked()) { |
| 189 this->removePixels(pixels); | 198 this->removePixels(pixels); |
| 190 } | 199 } |
| 191 pixels = prev; | 200 pixels = prev; |
| 192 } | 201 } |
| 193 } | 202 } |
| 194 } | 203 } |
| OLD | NEW |