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 |