| 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 "SkDiscardableMemory.h" | 8 #include "SkDiscardableMemory.h" |
| 9 #include "SkDiscardableMemoryPool.h" | 9 #include "SkDiscardableMemoryPool.h" |
| 10 #include "SkImageGenerator.h" | 10 #include "SkImageGenerator.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 | 22 |
| 23 /** | 23 /** |
| 24 * This non-global pool can be used for unit tests to verify that the | 24 * This non-global pool can be used for unit tests to verify that the |
| 25 * pool works. | 25 * pool works. |
| 26 */ | 26 */ |
| 27 class DiscardableMemoryPool : public SkDiscardableMemoryPool { | 27 class DiscardableMemoryPool : public SkDiscardableMemoryPool { |
| 28 public: | 28 public: |
| 29 /** | 29 /** |
| 30 * Without mutex, will be not be thread safe. | 30 * Without mutex, will be not be thread safe. |
| 31 */ | 31 */ |
| 32 DiscardableMemoryPool(size_t budget, SkBaseMutex* mutex = NULL); | 32 DiscardableMemoryPool(size_t budget, SkBaseMutex* mutex = nullptr); |
| 33 virtual ~DiscardableMemoryPool(); | 33 virtual ~DiscardableMemoryPool(); |
| 34 | 34 |
| 35 SkDiscardableMemory* create(size_t bytes) override; | 35 SkDiscardableMemory* create(size_t bytes) override; |
| 36 | 36 |
| 37 size_t getRAMUsed() override; | 37 size_t getRAMUsed() override; |
| 38 void setRAMBudget(size_t budget) override; | 38 void setRAMBudget(size_t budget) override; |
| 39 size_t getRAMBudget() override { return fBudget; } | 39 size_t getRAMBudget() override { return fBudget; } |
| 40 | 40 |
| 41 /** purges all unlocked DMs */ | 41 /** purges all unlocked DMs */ |
| 42 void dumpPool() override; | 42 void dumpPool() override; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 const size_t fBytes; | 92 const size_t fBytes; |
| 93 }; | 93 }; |
| 94 | 94 |
| 95 PoolDiscardableMemory::PoolDiscardableMemory(DiscardableMemoryPool* pool, | 95 PoolDiscardableMemory::PoolDiscardableMemory(DiscardableMemoryPool* pool, |
| 96 void* pointer, | 96 void* pointer, |
| 97 size_t bytes) | 97 size_t bytes) |
| 98 : fPool(pool) | 98 : fPool(pool) |
| 99 , fLocked(true) | 99 , fLocked(true) |
| 100 , fPointer(pointer) | 100 , fPointer(pointer) |
| 101 , fBytes(bytes) { | 101 , fBytes(bytes) { |
| 102 SkASSERT(fPool != NULL); | 102 SkASSERT(fPool != nullptr); |
| 103 SkASSERT(fPointer != NULL); | 103 SkASSERT(fPointer != nullptr); |
| 104 SkASSERT(fBytes > 0); | 104 SkASSERT(fBytes > 0); |
| 105 fPool->ref(); | 105 fPool->ref(); |
| 106 } | 106 } |
| 107 | 107 |
| 108 PoolDiscardableMemory::~PoolDiscardableMemory() { | 108 PoolDiscardableMemory::~PoolDiscardableMemory() { |
| 109 SkASSERT(!fLocked); // contract for SkDiscardableMemory | 109 SkASSERT(!fLocked); // contract for SkDiscardableMemory |
| 110 fPool->free(this); | 110 fPool->free(this); |
| 111 fPool->unref(); | 111 fPool->unref(); |
| 112 } | 112 } |
| 113 | 113 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 139 #endif // SK_LAZY_CACHE_STATS | 139 #endif // SK_LAZY_CACHE_STATS |
| 140 } | 140 } |
| 141 DiscardableMemoryPool::~DiscardableMemoryPool() { | 141 DiscardableMemoryPool::~DiscardableMemoryPool() { |
| 142 // PoolDiscardableMemory objects that belong to this pool are | 142 // PoolDiscardableMemory objects that belong to this pool are |
| 143 // always deleted before deleting this pool since each one has a | 143 // always deleted before deleting this pool since each one has a |
| 144 // ref to the pool. | 144 // ref to the pool. |
| 145 SkASSERT(fList.isEmpty()); | 145 SkASSERT(fList.isEmpty()); |
| 146 } | 146 } |
| 147 | 147 |
| 148 void DiscardableMemoryPool::dumpDownTo(size_t budget) { | 148 void DiscardableMemoryPool::dumpDownTo(size_t budget) { |
| 149 if (fMutex != NULL) { | 149 if (fMutex != nullptr) { |
| 150 fMutex->assertHeld(); | 150 fMutex->assertHeld(); |
| 151 } | 151 } |
| 152 if (fUsed <= budget) { | 152 if (fUsed <= budget) { |
| 153 return; | 153 return; |
| 154 } | 154 } |
| 155 typedef SkTInternalLList<PoolDiscardableMemory>::Iter Iter; | 155 typedef SkTInternalLList<PoolDiscardableMemory>::Iter Iter; |
| 156 Iter iter; | 156 Iter iter; |
| 157 PoolDiscardableMemory* cur = iter.init(fList, Iter::kTail_IterStart); | 157 PoolDiscardableMemory* cur = iter.init(fList, Iter::kTail_IterStart); |
| 158 while ((fUsed > budget) && (cur)) { | 158 while ((fUsed > budget) && (cur)) { |
| 159 if (!cur->fLocked) { | 159 if (!cur->fLocked) { |
| 160 PoolDiscardableMemory* dm = cur; | 160 PoolDiscardableMemory* dm = cur; |
| 161 SkASSERT(dm->fPointer != NULL); | 161 SkASSERT(dm->fPointer != nullptr); |
| 162 sk_free(dm->fPointer); | 162 sk_free(dm->fPointer); |
| 163 dm->fPointer = NULL; | 163 dm->fPointer = nullptr; |
| 164 SkASSERT(fUsed >= dm->fBytes); | 164 SkASSERT(fUsed >= dm->fBytes); |
| 165 fUsed -= dm->fBytes; | 165 fUsed -= dm->fBytes; |
| 166 cur = iter.prev(); | 166 cur = iter.prev(); |
| 167 // Purged DMs are taken out of the list. This saves times | 167 // Purged DMs are taken out of the list. This saves times |
| 168 // looking them up. Purged DMs are NOT deleted. | 168 // looking them up. Purged DMs are NOT deleted. |
| 169 fList.remove(dm); | 169 fList.remove(dm); |
| 170 } else { | 170 } else { |
| 171 cur = iter.prev(); | 171 cur = iter.prev(); |
| 172 } | 172 } |
| 173 } | 173 } |
| 174 } | 174 } |
| 175 | 175 |
| 176 SkDiscardableMemory* DiscardableMemoryPool::create(size_t bytes) { | 176 SkDiscardableMemory* DiscardableMemoryPool::create(size_t bytes) { |
| 177 void* addr = sk_malloc_flags(bytes, 0); | 177 void* addr = sk_malloc_flags(bytes, 0); |
| 178 if (NULL == addr) { | 178 if (nullptr == addr) { |
| 179 return NULL; | 179 return nullptr; |
| 180 } | 180 } |
| 181 PoolDiscardableMemory* dm = new PoolDiscardableMemory(this, addr, bytes); | 181 PoolDiscardableMemory* dm = new PoolDiscardableMemory(this, addr, bytes); |
| 182 SkAutoMutexAcquire autoMutexAcquire(fMutex); | 182 SkAutoMutexAcquire autoMutexAcquire(fMutex); |
| 183 fList.addToHead(dm); | 183 fList.addToHead(dm); |
| 184 fUsed += bytes; | 184 fUsed += bytes; |
| 185 this->dumpDownTo(fBudget); | 185 this->dumpDownTo(fBudget); |
| 186 return dm; | 186 return dm; |
| 187 } | 187 } |
| 188 | 188 |
| 189 void DiscardableMemoryPool::free(PoolDiscardableMemory* dm) { | 189 void DiscardableMemoryPool::free(PoolDiscardableMemory* dm) { |
| 190 SkAutoMutexAcquire autoMutexAcquire(fMutex); | 190 SkAutoMutexAcquire autoMutexAcquire(fMutex); |
| 191 // This is called by dm's destructor. | 191 // This is called by dm's destructor. |
| 192 if (dm->fPointer != NULL) { | 192 if (dm->fPointer != nullptr) { |
| 193 sk_free(dm->fPointer); | 193 sk_free(dm->fPointer); |
| 194 dm->fPointer = NULL; | 194 dm->fPointer = nullptr; |
| 195 SkASSERT(fUsed >= dm->fBytes); | 195 SkASSERT(fUsed >= dm->fBytes); |
| 196 fUsed -= dm->fBytes; | 196 fUsed -= dm->fBytes; |
| 197 fList.remove(dm); | 197 fList.remove(dm); |
| 198 } else { | 198 } else { |
| 199 SkASSERT(!fList.isInList(dm)); | 199 SkASSERT(!fList.isInList(dm)); |
| 200 } | 200 } |
| 201 } | 201 } |
| 202 | 202 |
| 203 bool DiscardableMemoryPool::lock(PoolDiscardableMemory* dm) { | 203 bool DiscardableMemoryPool::lock(PoolDiscardableMemory* dm) { |
| 204 SkASSERT(dm != NULL); | 204 SkASSERT(dm != nullptr); |
| 205 if (NULL == dm->fPointer) { | 205 if (nullptr == dm->fPointer) { |
| 206 #if SK_LAZY_CACHE_STATS | 206 #if SK_LAZY_CACHE_STATS |
| 207 SkAutoMutexAcquire autoMutexAcquire(fMutex); | 207 SkAutoMutexAcquire autoMutexAcquire(fMutex); |
| 208 ++fCacheMisses; | 208 ++fCacheMisses; |
| 209 #endif // SK_LAZY_CACHE_STATS | 209 #endif // SK_LAZY_CACHE_STATS |
| 210 return false; | 210 return false; |
| 211 } | 211 } |
| 212 SkAutoMutexAcquire autoMutexAcquire(fMutex); | 212 SkAutoMutexAcquire autoMutexAcquire(fMutex); |
| 213 if (NULL == dm->fPointer) { | 213 if (nullptr == dm->fPointer) { |
| 214 // May have been purged while waiting for lock. | 214 // May have been purged while waiting for lock. |
| 215 #if SK_LAZY_CACHE_STATS | 215 #if SK_LAZY_CACHE_STATS |
| 216 ++fCacheMisses; | 216 ++fCacheMisses; |
| 217 #endif // SK_LAZY_CACHE_STATS | 217 #endif // SK_LAZY_CACHE_STATS |
| 218 return false; | 218 return false; |
| 219 } | 219 } |
| 220 dm->fLocked = true; | 220 dm->fLocked = true; |
| 221 fList.remove(dm); | 221 fList.remove(dm); |
| 222 fList.addToHead(dm); | 222 fList.addToHead(dm); |
| 223 #if SK_LAZY_CACHE_STATS | 223 #if SK_LAZY_CACHE_STATS |
| 224 ++fCacheHits; | 224 ++fCacheHits; |
| 225 #endif // SK_LAZY_CACHE_STATS | 225 #endif // SK_LAZY_CACHE_STATS |
| 226 return true; | 226 return true; |
| 227 } | 227 } |
| 228 | 228 |
| 229 void DiscardableMemoryPool::unlock(PoolDiscardableMemory* dm) { | 229 void DiscardableMemoryPool::unlock(PoolDiscardableMemory* dm) { |
| 230 SkASSERT(dm != NULL); | 230 SkASSERT(dm != nullptr); |
| 231 SkAutoMutexAcquire autoMutexAcquire(fMutex); | 231 SkAutoMutexAcquire autoMutexAcquire(fMutex); |
| 232 dm->fLocked = false; | 232 dm->fLocked = false; |
| 233 this->dumpDownTo(fBudget); | 233 this->dumpDownTo(fBudget); |
| 234 } | 234 } |
| 235 | 235 |
| 236 size_t DiscardableMemoryPool::getRAMUsed() { | 236 size_t DiscardableMemoryPool::getRAMUsed() { |
| 237 return fUsed; | 237 return fUsed; |
| 238 } | 238 } |
| 239 void DiscardableMemoryPool::setRAMBudget(size_t budget) { | 239 void DiscardableMemoryPool::setRAMBudget(size_t budget) { |
| 240 SkAutoMutexAcquire autoMutexAcquire(fMutex); | 240 SkAutoMutexAcquire autoMutexAcquire(fMutex); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 259 return new DiscardableMemoryPool(size, mutex); | 259 return new DiscardableMemoryPool(size, mutex); |
| 260 } | 260 } |
| 261 | 261 |
| 262 SK_DECLARE_STATIC_LAZY_PTR(SkDiscardableMemoryPool, global, create_global_pool); | 262 SK_DECLARE_STATIC_LAZY_PTR(SkDiscardableMemoryPool, global, create_global_pool); |
| 263 | 263 |
| 264 SkDiscardableMemoryPool* SkGetGlobalDiscardableMemoryPool() { | 264 SkDiscardableMemoryPool* SkGetGlobalDiscardableMemoryPool() { |
| 265 return global.get(); | 265 return global.get(); |
| 266 } | 266 } |
| 267 | 267 |
| 268 //////////////////////////////////////////////////////////////////////////////// | 268 //////////////////////////////////////////////////////////////////////////////// |
| OLD | NEW |