| 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 |