OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 15 matching lines...) Expand all Loading... |
26 #include "config.h" | 26 #include "config.h" |
27 #include "platform/graphics/ImageDecodingStore.h" | 27 #include "platform/graphics/ImageDecodingStore.h" |
28 | 28 |
29 #include "platform/TraceEvent.h" | 29 #include "platform/TraceEvent.h" |
30 #include "wtf/Threading.h" | 30 #include "wtf/Threading.h" |
31 | 31 |
32 namespace blink { | 32 namespace blink { |
33 | 33 |
34 namespace { | 34 namespace { |
35 | 35 |
36 // Allow up to 256 MBytes of discardable entries. The previous limit allowed up
to | |
37 // 128 entries (independently of their size) which caused OOM errors on websites | |
38 // with a lot of (very) large images. | |
39 static const size_t maxTotalSizeOfDiscardableEntries = 256 * 1024 * 1024; | |
40 static const size_t defaultMaxTotalSizeOfHeapEntries = 32 * 1024 * 1024; | 36 static const size_t defaultMaxTotalSizeOfHeapEntries = 32 * 1024 * 1024; |
41 static bool s_imageCachingEnabled = true; | |
42 | 37 |
43 } // namespace | 38 } // namespace |
44 | 39 |
45 ImageDecodingStore::ImageDecodingStore() | 40 ImageDecodingStore::ImageDecodingStore() |
46 : m_heapLimitInBytes(defaultMaxTotalSizeOfHeapEntries) | 41 : m_heapLimitInBytes(defaultMaxTotalSizeOfHeapEntries) |
47 , m_heapMemoryUsageInBytes(0) | 42 , m_heapMemoryUsageInBytes(0) |
48 , m_discardableMemoryUsageInBytes(0) | |
49 { | 43 { |
50 } | 44 } |
51 | 45 |
52 ImageDecodingStore::~ImageDecodingStore() | 46 ImageDecodingStore::~ImageDecodingStore() |
53 { | 47 { |
54 #if ENABLE(ASSERT) | 48 #if ENABLE(ASSERT) |
55 setCacheLimitInBytes(0); | 49 setCacheLimitInBytes(0); |
56 ASSERT(!m_imageCacheMap.size()); | |
57 ASSERT(!m_decoderCacheMap.size()); | 50 ASSERT(!m_decoderCacheMap.size()); |
58 ASSERT(!m_orderedCacheList.size()); | 51 ASSERT(!m_orderedCacheList.size()); |
59 ASSERT(!m_imageCacheKeyMap.size()); | |
60 ASSERT(!m_decoderCacheKeyMap.size()); | 52 ASSERT(!m_decoderCacheKeyMap.size()); |
61 #endif | 53 #endif |
62 } | 54 } |
63 | 55 |
64 ImageDecodingStore* ImageDecodingStore::instance() | 56 ImageDecodingStore* ImageDecodingStore::instance() |
65 { | 57 { |
66 AtomicallyInitializedStatic(ImageDecodingStore*, store = ImageDecodingStore:
:create().leakPtr()); | 58 AtomicallyInitializedStatic(ImageDecodingStore*, store = ImageDecodingStore:
:create().leakPtr()); |
67 return store; | 59 return store; |
68 } | 60 } |
69 | 61 |
70 void ImageDecodingStore::setImageCachingEnabled(bool enabled) | |
71 { | |
72 s_imageCachingEnabled = enabled; | |
73 } | |
74 | |
75 bool ImageDecodingStore::lockCache(const ImageFrameGenerator* generator, const S
kISize& scaledSize, size_t index, const ScaledImageFragment** cachedImage) | |
76 { | |
77 ASSERT(cachedImage); | |
78 | |
79 Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete; | |
80 { | |
81 MutexLocker lock(m_mutex); | |
82 // Public access is restricted to complete images only. | |
83 ImageCacheMap::iterator iter = m_imageCacheMap.find(ImageCacheEntry::mak
eCacheKey(generator, scaledSize, index, ScaledImageFragment::CompleteImage)); | |
84 if (iter == m_imageCacheMap.end()) | |
85 return false; | |
86 return lockCacheEntryInternal(iter->value.get(), cachedImage, &cacheEntr
iesToDelete); | |
87 } | |
88 } | |
89 | |
90 void ImageDecodingStore::unlockCache(const ImageFrameGenerator* generator, const
ScaledImageFragment* cachedImage) | |
91 { | |
92 Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete; | |
93 { | |
94 MutexLocker lock(m_mutex); | |
95 cachedImage->bitmap().unlockPixels(); | |
96 ImageCacheMap::iterator iter = m_imageCacheMap.find(ImageCacheEntry::mak
eCacheKey(generator, cachedImage->scaledSize(), cachedImage->index(), cachedImag
e->generation())); | |
97 ASSERT_WITH_SECURITY_IMPLICATION(iter != m_imageCacheMap.end()); | |
98 | |
99 CacheEntry* cacheEntry = iter->value.get(); | |
100 cacheEntry->decrementUseCount(); | |
101 | |
102 // Put the entry to the end of list. | |
103 m_orderedCacheList.remove(cacheEntry); | |
104 m_orderedCacheList.append(cacheEntry); | |
105 | |
106 // FIXME: This code is temporary such that in the new Skia | |
107 // discardable memory path we do not cache images. | |
108 // Once the transition is complete the logic to handle | |
109 // image caching should be removed entirely. | |
110 if (!s_imageCachingEnabled && !cacheEntry->useCount()) { | |
111 removeFromCacheInternal(cacheEntry, &cacheEntriesToDelete); | |
112 removeFromCacheListInternal(cacheEntriesToDelete); | |
113 } | |
114 } | |
115 } | |
116 | |
117 const ScaledImageFragment* ImageDecodingStore::insertAndLockCache(const ImageFra
meGenerator* generator, PassOwnPtr<ScaledImageFragment> image) | |
118 { | |
119 // Prune old cache entries to give space for the new one. | |
120 prune(); | |
121 | |
122 ScaledImageFragment* newImage = image.get(); | |
123 OwnPtr<ImageCacheEntry> newCacheEntry = ImageCacheEntry::createAndUse(genera
tor, image); | |
124 Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete; | |
125 { | |
126 MutexLocker lock(m_mutex); | |
127 | |
128 ImageCacheMap::iterator iter = m_imageCacheMap.find(newCacheEntry->cache
Key()); | |
129 | |
130 // It is rare but possible that the key of a new cache entry is found. | |
131 // This happens if the generation ID of the image object wraps around. | |
132 // In this case we will try to return the existing cached object and | |
133 // discard the new cache object. | |
134 if (iter != m_imageCacheMap.end()) { | |
135 const ScaledImageFragment* oldImage; | |
136 if (lockCacheEntryInternal(iter->value.get(), &oldImage, &cacheEntri
esToDelete)) { | |
137 newCacheEntry->decrementUseCount(); | |
138 return oldImage; | |
139 } | |
140 } | |
141 | |
142 // The new image is not locked yet so do it here. | |
143 newImage->bitmap().lockPixels(); | |
144 insertCacheInternal(newCacheEntry.release(), &m_imageCacheMap, &m_imageC
acheKeyMap); | |
145 } | |
146 return newImage; | |
147 } | |
148 | |
149 bool ImageDecodingStore::lockDecoder(const ImageFrameGenerator* generator, const
SkISize& scaledSize, ImageDecoder** decoder) | 62 bool ImageDecodingStore::lockDecoder(const ImageFrameGenerator* generator, const
SkISize& scaledSize, ImageDecoder** decoder) |
150 { | 63 { |
151 ASSERT(decoder); | 64 ASSERT(decoder); |
152 | 65 |
153 MutexLocker lock(m_mutex); | 66 MutexLocker lock(m_mutex); |
154 DecoderCacheMap::iterator iter = m_decoderCacheMap.find(DecoderCacheEntry::m
akeCacheKey(generator, scaledSize)); | 67 DecoderCacheMap::iterator iter = m_decoderCacheMap.find(DecoderCacheEntry::m
akeCacheKey(generator, scaledSize)); |
155 if (iter == m_decoderCacheMap.end()) | 68 if (iter == m_decoderCacheMap.end()) |
156 return false; | 69 return false; |
157 | 70 |
158 DecoderCacheEntry* cacheEntry = iter->value.get(); | 71 DecoderCacheEntry* cacheEntry = iter->value.get(); |
(...skipping 12 matching lines...) Expand all Loading... |
171 ASSERT_WITH_SECURITY_IMPLICATION(iter != m_decoderCacheMap.end()); | 84 ASSERT_WITH_SECURITY_IMPLICATION(iter != m_decoderCacheMap.end()); |
172 | 85 |
173 CacheEntry* cacheEntry = iter->value.get(); | 86 CacheEntry* cacheEntry = iter->value.get(); |
174 cacheEntry->decrementUseCount(); | 87 cacheEntry->decrementUseCount(); |
175 | 88 |
176 // Put the entry to the end of list. | 89 // Put the entry to the end of list. |
177 m_orderedCacheList.remove(cacheEntry); | 90 m_orderedCacheList.remove(cacheEntry); |
178 m_orderedCacheList.append(cacheEntry); | 91 m_orderedCacheList.append(cacheEntry); |
179 } | 92 } |
180 | 93 |
181 void ImageDecodingStore::insertDecoder(const ImageFrameGenerator* generator, Pas
sOwnPtr<ImageDecoder> decoder, bool isDiscardable) | 94 void ImageDecodingStore::insertDecoder(const ImageFrameGenerator* generator, Pas
sOwnPtr<ImageDecoder> decoder) |
182 { | 95 { |
183 // Prune old cache entries to give space for the new one. | 96 // Prune old cache entries to give space for the new one. |
184 prune(); | 97 prune(); |
185 | 98 |
186 OwnPtr<DecoderCacheEntry> newCacheEntry = DecoderCacheEntry::create(generato
r, decoder, isDiscardable); | 99 OwnPtr<DecoderCacheEntry> newCacheEntry = DecoderCacheEntry::create(generato
r, decoder); |
187 | 100 |
188 MutexLocker lock(m_mutex); | 101 MutexLocker lock(m_mutex); |
189 ASSERT(!m_decoderCacheMap.contains(newCacheEntry->cacheKey())); | 102 ASSERT(!m_decoderCacheMap.contains(newCacheEntry->cacheKey())); |
190 insertCacheInternal(newCacheEntry.release(), &m_decoderCacheMap, &m_decoderC
acheKeyMap); | 103 insertCacheInternal(newCacheEntry.release(), &m_decoderCacheMap, &m_decoderC
acheKeyMap); |
191 } | 104 } |
192 | 105 |
193 void ImageDecodingStore::removeDecoder(const ImageFrameGenerator* generator, con
st ImageDecoder* decoder) | 106 void ImageDecodingStore::removeDecoder(const ImageFrameGenerator* generator, con
st ImageDecoder* decoder) |
194 { | 107 { |
195 Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete; | 108 Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete; |
196 { | 109 { |
197 MutexLocker lock(m_mutex); | 110 MutexLocker lock(m_mutex); |
198 DecoderCacheMap::iterator iter = m_decoderCacheMap.find(DecoderCacheEntr
y::makeCacheKey(generator, decoder)); | 111 DecoderCacheMap::iterator iter = m_decoderCacheMap.find(DecoderCacheEntr
y::makeCacheKey(generator, decoder)); |
199 ASSERT_WITH_SECURITY_IMPLICATION(iter != m_decoderCacheMap.end()); | 112 ASSERT_WITH_SECURITY_IMPLICATION(iter != m_decoderCacheMap.end()); |
200 | 113 |
201 CacheEntry* cacheEntry = iter->value.get(); | 114 CacheEntry* cacheEntry = iter->value.get(); |
202 ASSERT(cacheEntry->useCount()); | 115 ASSERT(cacheEntry->useCount()); |
203 cacheEntry->decrementUseCount(); | 116 cacheEntry->decrementUseCount(); |
204 | 117 |
205 // Delete only one decoder cache entry. Ownership of the cache entry | 118 // Delete only one decoder cache entry. Ownership of the cache entry |
206 // is transfered to cacheEntriesToDelete such that object can be deleted | 119 // is transfered to cacheEntriesToDelete such that object can be deleted |
207 // outside of the lock. | 120 // outside of the lock. |
208 removeFromCacheInternal(cacheEntry, &cacheEntriesToDelete); | 121 removeFromCacheInternal(cacheEntry, &cacheEntriesToDelete); |
209 | 122 |
210 // Remove from LRU list. | 123 // Remove from LRU list. |
211 removeFromCacheListInternal(cacheEntriesToDelete); | 124 removeFromCacheListInternal(cacheEntriesToDelete); |
212 } | 125 } |
213 } | 126 } |
214 | 127 |
215 bool ImageDecodingStore::isCached(const ImageFrameGenerator* generator, const Sk
ISize& scaledSize, size_t index) | |
216 { | |
217 MutexLocker lock(m_mutex); | |
218 ImageCacheMap::iterator iter = m_imageCacheMap.find(ImageCacheEntry::makeCac
heKey(generator, scaledSize, index, ScaledImageFragment::CompleteImage)); | |
219 if (iter == m_imageCacheMap.end()) | |
220 return false; | |
221 return true; | |
222 } | |
223 | |
224 void ImageDecodingStore::removeCacheIndexedByGenerator(const ImageFrameGenerator
* generator) | 128 void ImageDecodingStore::removeCacheIndexedByGenerator(const ImageFrameGenerator
* generator) |
225 { | 129 { |
226 Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete; | 130 Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete; |
227 { | 131 { |
228 MutexLocker lock(m_mutex); | 132 MutexLocker lock(m_mutex); |
229 | 133 |
230 // Remove image cache objects and decoder cache objects associated | 134 // Remove image cache objects and decoder cache objects associated |
231 // with a ImageFrameGenerator. | 135 // with a ImageFrameGenerator. |
232 removeCacheIndexedByGeneratorInternal(&m_imageCacheMap, &m_imageCacheKey
Map, generator, &cacheEntriesToDelete); | |
233 removeCacheIndexedByGeneratorInternal(&m_decoderCacheMap, &m_decoderCach
eKeyMap, generator, &cacheEntriesToDelete); | 136 removeCacheIndexedByGeneratorInternal(&m_decoderCacheMap, &m_decoderCach
eKeyMap, generator, &cacheEntriesToDelete); |
234 | 137 |
235 // Remove from LRU list as well. | 138 // Remove from LRU list as well. |
236 removeFromCacheListInternal(cacheEntriesToDelete); | 139 removeFromCacheListInternal(cacheEntriesToDelete); |
237 } | 140 } |
238 } | 141 } |
239 | 142 |
240 void ImageDecodingStore::clear() | 143 void ImageDecodingStore::clear() |
241 { | 144 { |
242 size_t cacheLimitInBytes; | 145 size_t cacheLimitInBytes; |
243 { | 146 { |
244 MutexLocker lock(m_mutex); | 147 MutexLocker lock(m_mutex); |
245 cacheLimitInBytes = m_heapLimitInBytes; | 148 cacheLimitInBytes = m_heapLimitInBytes; |
246 m_heapLimitInBytes = 0; | 149 m_heapLimitInBytes = 0; |
247 } | 150 } |
248 | 151 |
249 prune(); | 152 prune(); |
250 | 153 |
251 { | 154 { |
252 MutexLocker lock(m_mutex); | 155 MutexLocker lock(m_mutex); |
253 m_heapLimitInBytes = cacheLimitInBytes; | 156 m_heapLimitInBytes = cacheLimitInBytes; |
254 } | 157 } |
255 } | 158 } |
256 | 159 |
257 void ImageDecodingStore::setCacheLimitInBytes(size_t cacheLimit) | 160 void ImageDecodingStore::setCacheLimitInBytes(size_t cacheLimit) |
258 { | 161 { |
259 // Note that the discardable entries limit is constant (i.e. only the heap l
imit is updated). | |
260 { | 162 { |
261 MutexLocker lock(m_mutex); | 163 MutexLocker lock(m_mutex); |
262 m_heapLimitInBytes = cacheLimit; | 164 m_heapLimitInBytes = cacheLimit; |
263 } | 165 } |
264 prune(); | 166 prune(); |
265 } | 167 } |
266 | 168 |
267 size_t ImageDecodingStore::memoryUsageInBytes() | 169 size_t ImageDecodingStore::memoryUsageInBytes() |
268 { | 170 { |
269 MutexLocker lock(m_mutex); | 171 MutexLocker lock(m_mutex); |
270 return m_heapMemoryUsageInBytes; | 172 return m_heapMemoryUsageInBytes; |
271 } | 173 } |
272 | 174 |
273 int ImageDecodingStore::cacheEntries() | 175 int ImageDecodingStore::cacheEntries() |
274 { | 176 { |
275 MutexLocker lock(m_mutex); | 177 MutexLocker lock(m_mutex); |
276 return m_imageCacheMap.size() + m_decoderCacheMap.size(); | 178 return m_decoderCacheMap.size(); |
277 } | |
278 | |
279 int ImageDecodingStore::imageCacheEntries() | |
280 { | |
281 MutexLocker lock(m_mutex); | |
282 return m_imageCacheMap.size(); | |
283 } | 179 } |
284 | 180 |
285 int ImageDecodingStore::decoderCacheEntries() | 181 int ImageDecodingStore::decoderCacheEntries() |
286 { | 182 { |
287 MutexLocker lock(m_mutex); | 183 MutexLocker lock(m_mutex); |
288 return m_decoderCacheMap.size(); | 184 return m_decoderCacheMap.size(); |
289 } | 185 } |
290 | 186 |
291 void ImageDecodingStore::prune() | 187 void ImageDecodingStore::prune() |
292 { | 188 { |
293 TRACE_EVENT0("blink", "ImageDecodingStore::prune"); | 189 TRACE_EVENT0("blink", "ImageDecodingStore::prune"); |
294 | 190 |
295 Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete; | 191 Vector<OwnPtr<CacheEntry> > cacheEntriesToDelete; |
296 { | 192 { |
297 MutexLocker lock(m_mutex); | 193 MutexLocker lock(m_mutex); |
298 | 194 |
299 // Head of the list is the least recently used entry. | 195 // Head of the list is the least recently used entry. |
300 const CacheEntry* cacheEntry = m_orderedCacheList.head(); | 196 const CacheEntry* cacheEntry = m_orderedCacheList.head(); |
301 | 197 |
302 // Walk the list of cache entries starting from the least recently used | 198 // Walk the list of cache entries starting from the least recently used |
303 // and then keep them for deletion later. | 199 // and then keep them for deletion later. |
304 while (cacheEntry) { | 200 while (cacheEntry) { |
305 const bool isPruneNeeded = m_heapMemoryUsageInBytes > m_heapLimitInB
ytes || !m_heapLimitInBytes | 201 const bool isPruneNeeded = m_heapMemoryUsageInBytes > m_heapLimitInB
ytes || !m_heapLimitInBytes; |
306 || m_discardableMemoryUsageInBytes > maxTotalSizeOfDiscardableEn
tries; | |
307 if (!isPruneNeeded) | 202 if (!isPruneNeeded) |
308 break; | 203 break; |
309 | 204 |
310 // Cache is not used; Remove it. | 205 // Cache is not used; Remove it. |
311 if (!cacheEntry->useCount()) | 206 if (!cacheEntry->useCount()) |
312 removeFromCacheInternal(cacheEntry, &cacheEntriesToDelete); | 207 removeFromCacheInternal(cacheEntry, &cacheEntriesToDelete); |
313 cacheEntry = cacheEntry->next(); | 208 cacheEntry = cacheEntry->next(); |
314 } | 209 } |
315 | 210 |
316 // Remove from cache list as well. | 211 // Remove from cache list as well. |
317 removeFromCacheListInternal(cacheEntriesToDelete); | 212 removeFromCacheListInternal(cacheEntriesToDelete); |
318 } | 213 } |
319 } | 214 } |
320 | 215 |
321 bool ImageDecodingStore::lockCacheEntryInternal(ImageCacheEntry* cacheEntry, con
st ScaledImageFragment** cachedImage, Vector<OwnPtr<CacheEntry> >* deletionList) | |
322 { | |
323 ScaledImageFragment* image = cacheEntry->cachedImage(); | |
324 | |
325 image->bitmap().lockPixels(); | |
326 | |
327 // Memory for this image entry might be discarded already. | |
328 // In this case remove the entry. | |
329 if (!image->bitmap().getPixels()) { | |
330 image->bitmap().unlockPixels(); | |
331 removeFromCacheInternal(cacheEntry, &m_imageCacheMap, &m_imageCacheKeyMa
p, deletionList); | |
332 removeFromCacheListInternal(*deletionList); | |
333 return false; | |
334 } | |
335 cacheEntry->incrementUseCount(); | |
336 *cachedImage = image; | |
337 return true; | |
338 } | |
339 | |
340 template<class T, class U, class V> | 216 template<class T, class U, class V> |
341 void ImageDecodingStore::insertCacheInternal(PassOwnPtr<T> cacheEntry, U* cacheM
ap, V* identifierMap) | 217 void ImageDecodingStore::insertCacheInternal(PassOwnPtr<T> cacheEntry, U* cacheM
ap, V* identifierMap) |
342 { | 218 { |
343 const size_t cacheEntryBytes = cacheEntry->memoryUsageInBytes(); | 219 const size_t cacheEntryBytes = cacheEntry->memoryUsageInBytes(); |
344 if (cacheEntry->isDiscardable()) | 220 m_heapMemoryUsageInBytes += cacheEntryBytes; |
345 m_discardableMemoryUsageInBytes += cacheEntryBytes; | |
346 else | |
347 m_heapMemoryUsageInBytes += cacheEntryBytes; | |
348 | 221 |
349 // m_orderedCacheList is used to support LRU operations to reorder cache | 222 // m_orderedCacheList is used to support LRU operations to reorder cache |
350 // entries quickly. | 223 // entries quickly. |
351 m_orderedCacheList.append(cacheEntry.get()); | 224 m_orderedCacheList.append(cacheEntry.get()); |
352 | 225 |
353 typename U::KeyType key = cacheEntry->cacheKey(); | 226 typename U::KeyType key = cacheEntry->cacheKey(); |
354 typename V::AddResult result = identifierMap->add(cacheEntry->generator(), t
ypename V::MappedType()); | 227 typename V::AddResult result = identifierMap->add(cacheEntry->generator(), t
ypename V::MappedType()); |
355 result.storedValue->value.add(key); | 228 result.storedValue->value.add(key); |
356 cacheMap->add(key, cacheEntry); | 229 cacheMap->add(key, cacheEntry); |
357 | 230 |
358 TRACE_COUNTER1("blink", "ImageDecodingStoreDiscardableMemoryUsageBytes", m_d
iscardableMemoryUsageInBytes); | |
359 TRACE_COUNTER1("blink", "ImageDecodingStoreHeapMemoryUsageBytes", m_heapMemo
ryUsageInBytes); | 231 TRACE_COUNTER1("blink", "ImageDecodingStoreHeapMemoryUsageBytes", m_heapMemo
ryUsageInBytes); |
360 TRACE_COUNTER1("blink", "ImageDecodingStoreNumOfImages", m_imageCacheMap.siz
e()); | |
361 TRACE_COUNTER1("blink", "ImageDecodingStoreNumOfDecoders", m_decoderCacheMap
.size()); | 232 TRACE_COUNTER1("blink", "ImageDecodingStoreNumOfDecoders", m_decoderCacheMap
.size()); |
362 } | 233 } |
363 | 234 |
364 template<class T, class U, class V> | 235 template<class T, class U, class V> |
365 void ImageDecodingStore::removeFromCacheInternal(const T* cacheEntry, U* cacheMa
p, V* identifierMap, Vector<OwnPtr<CacheEntry> >* deletionList) | 236 void ImageDecodingStore::removeFromCacheInternal(const T* cacheEntry, U* cacheMa
p, V* identifierMap, Vector<OwnPtr<CacheEntry> >* deletionList) |
366 { | 237 { |
367 const size_t cacheEntryBytes = cacheEntry->memoryUsageInBytes(); | 238 const size_t cacheEntryBytes = cacheEntry->memoryUsageInBytes(); |
368 if (cacheEntry->isDiscardable()) { | 239 ASSERT(m_heapMemoryUsageInBytes >= cacheEntryBytes); |
369 ASSERT(m_discardableMemoryUsageInBytes >= cacheEntryBytes); | 240 m_heapMemoryUsageInBytes -= cacheEntryBytes; |
370 m_discardableMemoryUsageInBytes -= cacheEntryBytes; | |
371 } else { | |
372 ASSERT(m_heapMemoryUsageInBytes >= cacheEntryBytes); | |
373 m_heapMemoryUsageInBytes -= cacheEntryBytes; | |
374 | |
375 } | |
376 | 241 |
377 // Remove entry from identifier map. | 242 // Remove entry from identifier map. |
378 typename V::iterator iter = identifierMap->find(cacheEntry->generator()); | 243 typename V::iterator iter = identifierMap->find(cacheEntry->generator()); |
379 ASSERT(iter != identifierMap->end()); | 244 ASSERT(iter != identifierMap->end()); |
380 iter->value.remove(cacheEntry->cacheKey()); | 245 iter->value.remove(cacheEntry->cacheKey()); |
381 if (!iter->value.size()) | 246 if (!iter->value.size()) |
382 identifierMap->remove(iter); | 247 identifierMap->remove(iter); |
383 | 248 |
384 // Remove entry from cache map. | 249 // Remove entry from cache map. |
385 deletionList->append(cacheMap->take(cacheEntry->cacheKey())); | 250 deletionList->append(cacheMap->take(cacheEntry->cacheKey())); |
386 | 251 |
387 TRACE_COUNTER1("blink", "ImageDecodingStoreDiscardableMemoryUsageBytes", m_d
iscardableMemoryUsageInBytes); | |
388 TRACE_COUNTER1("blink", "ImageDecodingStoreHeapMemoryUsageBytes", m_heapMemo
ryUsageInBytes); | 252 TRACE_COUNTER1("blink", "ImageDecodingStoreHeapMemoryUsageBytes", m_heapMemo
ryUsageInBytes); |
389 TRACE_COUNTER1("blink", "ImageDecodingStoreNumOfImages", m_imageCacheMap.siz
e()); | |
390 TRACE_COUNTER1("blink", "ImageDecodingStoreNumOfDecoders", m_decoderCacheMap
.size()); | 253 TRACE_COUNTER1("blink", "ImageDecodingStoreNumOfDecoders", m_decoderCacheMap
.size()); |
391 } | 254 } |
392 | 255 |
393 void ImageDecodingStore::removeFromCacheInternal(const CacheEntry* cacheEntry, V
ector<OwnPtr<CacheEntry> >* deletionList) | 256 void ImageDecodingStore::removeFromCacheInternal(const CacheEntry* cacheEntry, V
ector<OwnPtr<CacheEntry> >* deletionList) |
394 { | 257 { |
395 if (cacheEntry->type() == CacheEntry::TypeImage) { | 258 if (cacheEntry->type() == CacheEntry::TypeDecoder) { |
396 removeFromCacheInternal(static_cast<const ImageCacheEntry*>(cacheEntry),
&m_imageCacheMap, &m_imageCacheKeyMap, deletionList); | |
397 } else if (cacheEntry->type() == CacheEntry::TypeDecoder) { | |
398 removeFromCacheInternal(static_cast<const DecoderCacheEntry*>(cacheEntry
), &m_decoderCacheMap, &m_decoderCacheKeyMap, deletionList); | 259 removeFromCacheInternal(static_cast<const DecoderCacheEntry*>(cacheEntry
), &m_decoderCacheMap, &m_decoderCacheKeyMap, deletionList); |
399 } else { | 260 } else { |
400 ASSERT(false); | 261 ASSERT(false); |
401 } | 262 } |
402 } | 263 } |
403 | 264 |
404 template<class U, class V> | 265 template<class U, class V> |
405 void ImageDecodingStore::removeCacheIndexedByGeneratorInternal(U* cacheMap, V* i
dentifierMap, const ImageFrameGenerator* generator, Vector<OwnPtr<CacheEntry> >*
deletionList) | 266 void ImageDecodingStore::removeCacheIndexedByGeneratorInternal(U* cacheMap, V* i
dentifierMap, const ImageFrameGenerator* generator, Vector<OwnPtr<CacheEntry> >*
deletionList) |
406 { | 267 { |
407 typename V::iterator iter = identifierMap->find(generator); | 268 typename V::iterator iter = identifierMap->find(generator); |
(...skipping 13 matching lines...) Expand all Loading... |
421 } | 282 } |
422 } | 283 } |
423 | 284 |
424 void ImageDecodingStore::removeFromCacheListInternal(const Vector<OwnPtr<CacheEn
try> >& deletionList) | 285 void ImageDecodingStore::removeFromCacheListInternal(const Vector<OwnPtr<CacheEn
try> >& deletionList) |
425 { | 286 { |
426 for (size_t i = 0; i < deletionList.size(); ++i) | 287 for (size_t i = 0; i < deletionList.size(); ++i) |
427 m_orderedCacheList.remove(deletionList[i].get()); | 288 m_orderedCacheList.remove(deletionList[i].get()); |
428 } | 289 } |
429 | 290 |
430 } // namespace blink | 291 } // namespace blink |
OLD | NEW |