| 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 27 matching lines...) Expand all Loading... |
| 38 | 38 |
| 39 } // namespace | 39 } // namespace |
| 40 | 40 |
| 41 ImageDecodingStore::ImageDecodingStore() | 41 ImageDecodingStore::ImageDecodingStore() |
| 42 : m_heapLimitInBytes(defaultMaxTotalSizeOfHeapEntries), | 42 : m_heapLimitInBytes(defaultMaxTotalSizeOfHeapEntries), |
| 43 m_heapMemoryUsageInBytes(0) {} | 43 m_heapMemoryUsageInBytes(0) {} |
| 44 | 44 |
| 45 ImageDecodingStore::~ImageDecodingStore() { | 45 ImageDecodingStore::~ImageDecodingStore() { |
| 46 #if DCHECK_IS_ON() | 46 #if DCHECK_IS_ON() |
| 47 setCacheLimitInBytes(0); | 47 setCacheLimitInBytes(0); |
| 48 ASSERT(!m_decoderCacheMap.size()); | 48 DCHECK(!m_decoderCacheMap.size()); |
| 49 ASSERT(!m_orderedCacheList.size()); | 49 DCHECK(!m_orderedCacheList.size()); |
| 50 ASSERT(!m_decoderCacheKeyMap.size()); | 50 DCHECK(!m_decoderCacheKeyMap.size()); |
| 51 #endif | 51 #endif |
| 52 } | 52 } |
| 53 | 53 |
| 54 ImageDecodingStore& ImageDecodingStore::instance() { | 54 ImageDecodingStore& ImageDecodingStore::instance() { |
| 55 DEFINE_THREAD_SAFE_STATIC_LOCAL(ImageDecodingStore, store, | 55 DEFINE_THREAD_SAFE_STATIC_LOCAL(ImageDecodingStore, store, |
| 56 ImageDecodingStore::create().release()); | 56 ImageDecodingStore::create().release()); |
| 57 return store; | 57 return store; |
| 58 } | 58 } |
| 59 | 59 |
| 60 bool ImageDecodingStore::lockDecoder(const ImageFrameGenerator* generator, | 60 bool ImageDecodingStore::lockDecoder(const ImageFrameGenerator* generator, |
| 61 const SkISize& scaledSize, | 61 const SkISize& scaledSize, |
| 62 ImageDecoder** decoder) { | 62 ImageDecoder** decoder) { |
| 63 ASSERT(decoder); | 63 DCHECK(decoder); |
| 64 | 64 |
| 65 MutexLocker lock(m_mutex); | 65 MutexLocker lock(m_mutex); |
| 66 DecoderCacheMap::iterator iter = m_decoderCacheMap.find( | 66 DecoderCacheMap::iterator iter = m_decoderCacheMap.find( |
| 67 DecoderCacheEntry::makeCacheKey(generator, scaledSize)); | 67 DecoderCacheEntry::makeCacheKey(generator, scaledSize)); |
| 68 if (iter == m_decoderCacheMap.end()) | 68 if (iter == m_decoderCacheMap.end()) |
| 69 return false; | 69 return false; |
| 70 | 70 |
| 71 DecoderCacheEntry* cacheEntry = iter->value.get(); | 71 DecoderCacheEntry* cacheEntry = iter->value.get(); |
| 72 | 72 |
| 73 // There can only be one user of a decoder at a time. | 73 // There can only be one user of a decoder at a time. |
| 74 ASSERT(!cacheEntry->useCount()); | 74 DCHECK(!cacheEntry->useCount()); |
| 75 cacheEntry->incrementUseCount(); | 75 cacheEntry->incrementUseCount(); |
| 76 *decoder = cacheEntry->cachedDecoder(); | 76 *decoder = cacheEntry->cachedDecoder(); |
| 77 return true; | 77 return true; |
| 78 } | 78 } |
| 79 | 79 |
| 80 void ImageDecodingStore::unlockDecoder(const ImageFrameGenerator* generator, | 80 void ImageDecodingStore::unlockDecoder(const ImageFrameGenerator* generator, |
| 81 const ImageDecoder* decoder) { | 81 const ImageDecoder* decoder) { |
| 82 MutexLocker lock(m_mutex); | 82 MutexLocker lock(m_mutex); |
| 83 DecoderCacheMap::iterator iter = m_decoderCacheMap.find( | 83 DecoderCacheMap::iterator iter = m_decoderCacheMap.find( |
| 84 DecoderCacheEntry::makeCacheKey(generator, decoder)); | 84 DecoderCacheEntry::makeCacheKey(generator, decoder)); |
| 85 SECURITY_DCHECK(iter != m_decoderCacheMap.end()); | 85 SECURITY_DCHECK(iter != m_decoderCacheMap.end()); |
| 86 | 86 |
| 87 CacheEntry* cacheEntry = iter->value.get(); | 87 CacheEntry* cacheEntry = iter->value.get(); |
| 88 cacheEntry->decrementUseCount(); | 88 cacheEntry->decrementUseCount(); |
| 89 | 89 |
| 90 // Put the entry to the end of list. | 90 // Put the entry to the end of list. |
| 91 m_orderedCacheList.remove(cacheEntry); | 91 m_orderedCacheList.remove(cacheEntry); |
| 92 m_orderedCacheList.append(cacheEntry); | 92 m_orderedCacheList.append(cacheEntry); |
| 93 } | 93 } |
| 94 | 94 |
| 95 void ImageDecodingStore::insertDecoder(const ImageFrameGenerator* generator, | 95 void ImageDecodingStore::insertDecoder(const ImageFrameGenerator* generator, |
| 96 std::unique_ptr<ImageDecoder> decoder) { | 96 std::unique_ptr<ImageDecoder> decoder) { |
| 97 // Prune old cache entries to give space for the new one. | 97 // Prune old cache entries to give space for the new one. |
| 98 prune(); | 98 prune(); |
| 99 | 99 |
| 100 std::unique_ptr<DecoderCacheEntry> newCacheEntry = | 100 std::unique_ptr<DecoderCacheEntry> newCacheEntry = |
| 101 DecoderCacheEntry::create(generator, std::move(decoder)); | 101 DecoderCacheEntry::create(generator, std::move(decoder)); |
| 102 | 102 |
| 103 MutexLocker lock(m_mutex); | 103 MutexLocker lock(m_mutex); |
| 104 ASSERT(!m_decoderCacheMap.contains(newCacheEntry->cacheKey())); | 104 DCHECK(!m_decoderCacheMap.contains(newCacheEntry->cacheKey())); |
| 105 insertCacheInternal(std::move(newCacheEntry), &m_decoderCacheMap, | 105 insertCacheInternal(std::move(newCacheEntry), &m_decoderCacheMap, |
| 106 &m_decoderCacheKeyMap); | 106 &m_decoderCacheKeyMap); |
| 107 } | 107 } |
| 108 | 108 |
| 109 void ImageDecodingStore::removeDecoder(const ImageFrameGenerator* generator, | 109 void ImageDecodingStore::removeDecoder(const ImageFrameGenerator* generator, |
| 110 const ImageDecoder* decoder) { | 110 const ImageDecoder* decoder) { |
| 111 Vector<std::unique_ptr<CacheEntry>> cacheEntriesToDelete; | 111 Vector<std::unique_ptr<CacheEntry>> cacheEntriesToDelete; |
| 112 { | 112 { |
| 113 MutexLocker lock(m_mutex); | 113 MutexLocker lock(m_mutex); |
| 114 DecoderCacheMap::iterator iter = m_decoderCacheMap.find( | 114 DecoderCacheMap::iterator iter = m_decoderCacheMap.find( |
| 115 DecoderCacheEntry::makeCacheKey(generator, decoder)); | 115 DecoderCacheEntry::makeCacheKey(generator, decoder)); |
| 116 SECURITY_DCHECK(iter != m_decoderCacheMap.end()); | 116 SECURITY_DCHECK(iter != m_decoderCacheMap.end()); |
| 117 | 117 |
| 118 CacheEntry* cacheEntry = iter->value.get(); | 118 CacheEntry* cacheEntry = iter->value.get(); |
| 119 ASSERT(cacheEntry->useCount()); | 119 DCHECK(cacheEntry->useCount()); |
| 120 cacheEntry->decrementUseCount(); | 120 cacheEntry->decrementUseCount(); |
| 121 | 121 |
| 122 // Delete only one decoder cache entry. Ownership of the cache entry | 122 // Delete only one decoder cache entry. Ownership of the cache entry |
| 123 // is transfered to cacheEntriesToDelete such that object can be deleted | 123 // is transfered to cacheEntriesToDelete such that object can be deleted |
| 124 // outside of the lock. | 124 // outside of the lock. |
| 125 removeFromCacheInternal(cacheEntry, &cacheEntriesToDelete); | 125 removeFromCacheInternal(cacheEntry, &cacheEntriesToDelete); |
| 126 | 126 |
| 127 // Remove from LRU list. | 127 // Remove from LRU list. |
| 128 removeFromCacheListInternal(cacheEntriesToDelete); | 128 removeFromCacheListInternal(cacheEntriesToDelete); |
| 129 } | 129 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 "ImageDecodingStoreNumOfDecoders", m_decoderCacheMap.size()); | 234 "ImageDecodingStoreNumOfDecoders", m_decoderCacheMap.size()); |
| 235 } | 235 } |
| 236 | 236 |
| 237 template <class T, class U, class V> | 237 template <class T, class U, class V> |
| 238 void ImageDecodingStore::removeFromCacheInternal( | 238 void ImageDecodingStore::removeFromCacheInternal( |
| 239 const T* cacheEntry, | 239 const T* cacheEntry, |
| 240 U* cacheMap, | 240 U* cacheMap, |
| 241 V* identifierMap, | 241 V* identifierMap, |
| 242 Vector<std::unique_ptr<CacheEntry>>* deletionList) { | 242 Vector<std::unique_ptr<CacheEntry>>* deletionList) { |
| 243 const size_t cacheEntryBytes = cacheEntry->memoryUsageInBytes(); | 243 const size_t cacheEntryBytes = cacheEntry->memoryUsageInBytes(); |
| 244 ASSERT(m_heapMemoryUsageInBytes >= cacheEntryBytes); | 244 DCHECK_GE(m_heapMemoryUsageInBytes, cacheEntryBytes); |
| 245 m_heapMemoryUsageInBytes -= cacheEntryBytes; | 245 m_heapMemoryUsageInBytes -= cacheEntryBytes; |
| 246 | 246 |
| 247 // Remove entry from identifier map. | 247 // Remove entry from identifier map. |
| 248 typename V::iterator iter = identifierMap->find(cacheEntry->generator()); | 248 typename V::iterator iter = identifierMap->find(cacheEntry->generator()); |
| 249 ASSERT(iter != identifierMap->end()); | 249 DCHECK_NE(iter, identifierMap->end()); |
| 250 iter->value.erase(cacheEntry->cacheKey()); | 250 iter->value.erase(cacheEntry->cacheKey()); |
| 251 if (!iter->value.size()) | 251 if (!iter->value.size()) |
| 252 identifierMap->erase(iter); | 252 identifierMap->erase(iter); |
| 253 | 253 |
| 254 // Remove entry from cache map. | 254 // Remove entry from cache map. |
| 255 deletionList->push_back(cacheMap->take(cacheEntry->cacheKey())); | 255 deletionList->push_back(cacheMap->take(cacheEntry->cacheKey())); |
| 256 | 256 |
| 257 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.image_decoding"), | 257 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.image_decoding"), |
| 258 "ImageDecodingStoreHeapMemoryUsageBytes", | 258 "ImageDecodingStoreHeapMemoryUsageBytes", |
| 259 m_heapMemoryUsageInBytes); | 259 m_heapMemoryUsageInBytes); |
| 260 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.image_decoding"), | 260 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.image_decoding"), |
| 261 "ImageDecodingStoreNumOfDecoders", m_decoderCacheMap.size()); | 261 "ImageDecodingStoreNumOfDecoders", m_decoderCacheMap.size()); |
| 262 } | 262 } |
| 263 | 263 |
| 264 void ImageDecodingStore::removeFromCacheInternal( | 264 void ImageDecodingStore::removeFromCacheInternal( |
| 265 const CacheEntry* cacheEntry, | 265 const CacheEntry* cacheEntry, |
| 266 Vector<std::unique_ptr<CacheEntry>>* deletionList) { | 266 Vector<std::unique_ptr<CacheEntry>>* deletionList) { |
| 267 if (cacheEntry->type() == CacheEntry::TypeDecoder) { | 267 if (cacheEntry->type() == CacheEntry::TypeDecoder) { |
| 268 removeFromCacheInternal(static_cast<const DecoderCacheEntry*>(cacheEntry), | 268 removeFromCacheInternal(static_cast<const DecoderCacheEntry*>(cacheEntry), |
| 269 &m_decoderCacheMap, &m_decoderCacheKeyMap, | 269 &m_decoderCacheMap, &m_decoderCacheKeyMap, |
| 270 deletionList); | 270 deletionList); |
| 271 } else { | 271 } else { |
| 272 ASSERT(false); | 272 DCHECK(false); |
| 273 } | 273 } |
| 274 } | 274 } |
| 275 | 275 |
| 276 template <class U, class V> | 276 template <class U, class V> |
| 277 void ImageDecodingStore::removeCacheIndexedByGeneratorInternal( | 277 void ImageDecodingStore::removeCacheIndexedByGeneratorInternal( |
| 278 U* cacheMap, | 278 U* cacheMap, |
| 279 V* identifierMap, | 279 V* identifierMap, |
| 280 const ImageFrameGenerator* generator, | 280 const ImageFrameGenerator* generator, |
| 281 Vector<std::unique_ptr<CacheEntry>>* deletionList) { | 281 Vector<std::unique_ptr<CacheEntry>>* deletionList) { |
| 282 typename V::iterator iter = identifierMap->find(generator); | 282 typename V::iterator iter = identifierMap->find(generator); |
| 283 if (iter == identifierMap->end()) | 283 if (iter == identifierMap->end()) |
| 284 return; | 284 return; |
| 285 | 285 |
| 286 // Get all cache identifiers associated with generator. | 286 // Get all cache identifiers associated with generator. |
| 287 Vector<typename U::KeyType> cacheIdentifierList; | 287 Vector<typename U::KeyType> cacheIdentifierList; |
| 288 copyToVector(iter->value, cacheIdentifierList); | 288 copyToVector(iter->value, cacheIdentifierList); |
| 289 | 289 |
| 290 // For each cache identifier find the corresponding CacheEntry and remove it. | 290 // For each cache identifier find the corresponding CacheEntry and remove it. |
| 291 for (size_t i = 0; i < cacheIdentifierList.size(); ++i) { | 291 for (size_t i = 0; i < cacheIdentifierList.size(); ++i) { |
| 292 ASSERT(cacheMap->contains(cacheIdentifierList[i])); | 292 DCHECK(cacheMap->contains(cacheIdentifierList[i])); |
| 293 const auto& cacheEntry = cacheMap->at(cacheIdentifierList[i]); | 293 const auto& cacheEntry = cacheMap->at(cacheIdentifierList[i]); |
| 294 ASSERT(!cacheEntry->useCount()); | 294 DCHECK(!cacheEntry->useCount()); |
| 295 removeFromCacheInternal(cacheEntry, cacheMap, identifierMap, deletionList); | 295 removeFromCacheInternal(cacheEntry, cacheMap, identifierMap, deletionList); |
| 296 } | 296 } |
| 297 } | 297 } |
| 298 | 298 |
| 299 void ImageDecodingStore::removeFromCacheListInternal( | 299 void ImageDecodingStore::removeFromCacheListInternal( |
| 300 const Vector<std::unique_ptr<CacheEntry>>& deletionList) { | 300 const Vector<std::unique_ptr<CacheEntry>>& deletionList) { |
| 301 for (size_t i = 0; i < deletionList.size(); ++i) | 301 for (size_t i = 0; i < deletionList.size(); ++i) |
| 302 m_orderedCacheList.remove(deletionList[i].get()); | 302 m_orderedCacheList.remove(deletionList[i].get()); |
| 303 } | 303 } |
| 304 | 304 |
| 305 } // namespace blink | 305 } // namespace blink |
| OLD | NEW |