| 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 : heap_limit_in_bytes_(kDefaultMaxTotalSizeOfHeapEntries), | 42 : heap_limit_in_bytes_(kDefaultMaxTotalSizeOfHeapEntries), |
| 43 heap_memory_usage_in_bytes_(0) {} | 43 heap_memory_usage_in_bytes_(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(!decoder_cache_map_.size()); | 48 DCHECK(!decoder_cache_map_.size()); |
| 49 ASSERT(!ordered_cache_list_.size()); | 49 DCHECK(!ordered_cache_list_.size()); |
| 50 ASSERT(!decoder_cache_key_map_.size()); | 50 DCHECK(!decoder_cache_key_map_.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& scaled_size, | 61 const SkISize& scaled_size, |
| 62 ImageDecoder** decoder) { | 62 ImageDecoder** decoder) { |
| 63 ASSERT(decoder); | 63 DCHECK(decoder); |
| 64 | 64 |
| 65 MutexLocker lock(mutex_); | 65 MutexLocker lock(mutex_); |
| 66 DecoderCacheMap::iterator iter = decoder_cache_map_.Find( | 66 DecoderCacheMap::iterator iter = decoder_cache_map_.Find( |
| 67 DecoderCacheEntry::MakeCacheKey(generator, scaled_size)); | 67 DecoderCacheEntry::MakeCacheKey(generator, scaled_size)); |
| 68 if (iter == decoder_cache_map_.end()) | 68 if (iter == decoder_cache_map_.end()) |
| 69 return false; | 69 return false; |
| 70 | 70 |
| 71 DecoderCacheEntry* cache_entry = iter->value.get(); | 71 DecoderCacheEntry* cache_entry = 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(!cache_entry->UseCount()); | 74 DCHECK(!cache_entry->UseCount()); |
| 75 cache_entry->IncrementUseCount(); | 75 cache_entry->IncrementUseCount(); |
| 76 *decoder = cache_entry->CachedDecoder(); | 76 *decoder = cache_entry->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(mutex_); | 82 MutexLocker lock(mutex_); |
| 83 DecoderCacheMap::iterator iter = decoder_cache_map_.Find( | 83 DecoderCacheMap::iterator iter = decoder_cache_map_.Find( |
| 84 DecoderCacheEntry::MakeCacheKey(generator, decoder)); | 84 DecoderCacheEntry::MakeCacheKey(generator, decoder)); |
| 85 SECURITY_DCHECK(iter != decoder_cache_map_.end()); | 85 SECURITY_DCHECK(iter != decoder_cache_map_.end()); |
| 86 | 86 |
| 87 CacheEntry* cache_entry = iter->value.get(); | 87 CacheEntry* cache_entry = iter->value.get(); |
| 88 cache_entry->DecrementUseCount(); | 88 cache_entry->DecrementUseCount(); |
| 89 | 89 |
| 90 // Put the entry to the end of list. | 90 // Put the entry to the end of list. |
| 91 ordered_cache_list_.Remove(cache_entry); | 91 ordered_cache_list_.Remove(cache_entry); |
| 92 ordered_cache_list_.Append(cache_entry); | 92 ordered_cache_list_.Append(cache_entry); |
| 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> new_cache_entry = | 100 std::unique_ptr<DecoderCacheEntry> new_cache_entry = |
| 101 DecoderCacheEntry::Create(generator, std::move(decoder)); | 101 DecoderCacheEntry::Create(generator, std::move(decoder)); |
| 102 | 102 |
| 103 MutexLocker lock(mutex_); | 103 MutexLocker lock(mutex_); |
| 104 ASSERT(!decoder_cache_map_.Contains(new_cache_entry->CacheKey())); | 104 DCHECK(!decoder_cache_map_.Contains(new_cache_entry->CacheKey())); |
| 105 InsertCacheInternal(std::move(new_cache_entry), &decoder_cache_map_, | 105 InsertCacheInternal(std::move(new_cache_entry), &decoder_cache_map_, |
| 106 &decoder_cache_key_map_); | 106 &decoder_cache_key_map_); |
| 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>> cache_entries_to_delete; | 111 Vector<std::unique_ptr<CacheEntry>> cache_entries_to_delete; |
| 112 { | 112 { |
| 113 MutexLocker lock(mutex_); | 113 MutexLocker lock(mutex_); |
| 114 DecoderCacheMap::iterator iter = decoder_cache_map_.Find( | 114 DecoderCacheMap::iterator iter = decoder_cache_map_.Find( |
| 115 DecoderCacheEntry::MakeCacheKey(generator, decoder)); | 115 DecoderCacheEntry::MakeCacheKey(generator, decoder)); |
| 116 SECURITY_DCHECK(iter != decoder_cache_map_.end()); | 116 SECURITY_DCHECK(iter != decoder_cache_map_.end()); |
| 117 | 117 |
| 118 CacheEntry* cache_entry = iter->value.get(); | 118 CacheEntry* cache_entry = iter->value.get(); |
| 119 ASSERT(cache_entry->UseCount()); | 119 DCHECK(cache_entry->UseCount()); |
| 120 cache_entry->DecrementUseCount(); | 120 cache_entry->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(cache_entry, &cache_entries_to_delete); | 125 RemoveFromCacheInternal(cache_entry, &cache_entries_to_delete); |
| 126 | 126 |
| 127 // Remove from LRU list. | 127 // Remove from LRU list. |
| 128 RemoveFromCacheListInternal(cache_entries_to_delete); | 128 RemoveFromCacheListInternal(cache_entries_to_delete); |
| 129 } | 129 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 235 "ImageDecodingStoreNumOfDecoders", decoder_cache_map_.size()); | 235 "ImageDecodingStoreNumOfDecoders", decoder_cache_map_.size()); |
| 236 } | 236 } |
| 237 | 237 |
| 238 template <class T, class U, class V> | 238 template <class T, class U, class V> |
| 239 void ImageDecodingStore::RemoveFromCacheInternal( | 239 void ImageDecodingStore::RemoveFromCacheInternal( |
| 240 const T* cache_entry, | 240 const T* cache_entry, |
| 241 U* cache_map, | 241 U* cache_map, |
| 242 V* identifier_map, | 242 V* identifier_map, |
| 243 Vector<std::unique_ptr<CacheEntry>>* deletion_list) { | 243 Vector<std::unique_ptr<CacheEntry>>* deletion_list) { |
| 244 const size_t cache_entry_bytes = cache_entry->MemoryUsageInBytes(); | 244 const size_t cache_entry_bytes = cache_entry->MemoryUsageInBytes(); |
| 245 ASSERT(heap_memory_usage_in_bytes_ >= cache_entry_bytes); | 245 DCHECK_GE(heap_memory_usage_in_bytes_, cache_entry_bytes); |
| 246 heap_memory_usage_in_bytes_ -= cache_entry_bytes; | 246 heap_memory_usage_in_bytes_ -= cache_entry_bytes; |
| 247 | 247 |
| 248 // Remove entry from identifier map. | 248 // Remove entry from identifier map. |
| 249 typename V::iterator iter = identifier_map->Find(cache_entry->Generator()); | 249 typename V::iterator iter = identifier_map->Find(cache_entry->Generator()); |
| 250 ASSERT(iter != identifier_map->end()); | 250 DCHECK(iter != identifier_map->end()); |
| 251 iter->value.erase(cache_entry->CacheKey()); | 251 iter->value.erase(cache_entry->CacheKey()); |
| 252 if (!iter->value.size()) | 252 if (!iter->value.size()) |
| 253 identifier_map->erase(iter); | 253 identifier_map->erase(iter); |
| 254 | 254 |
| 255 // Remove entry from cache map. | 255 // Remove entry from cache map. |
| 256 deletion_list->push_back(cache_map->Take(cache_entry->CacheKey())); | 256 deletion_list->push_back(cache_map->Take(cache_entry->CacheKey())); |
| 257 | 257 |
| 258 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.image_decoding"), | 258 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.image_decoding"), |
| 259 "ImageDecodingStoreHeapMemoryUsageBytes", | 259 "ImageDecodingStoreHeapMemoryUsageBytes", |
| 260 heap_memory_usage_in_bytes_); | 260 heap_memory_usage_in_bytes_); |
| 261 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.image_decoding"), | 261 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink.image_decoding"), |
| 262 "ImageDecodingStoreNumOfDecoders", decoder_cache_map_.size()); | 262 "ImageDecodingStoreNumOfDecoders", decoder_cache_map_.size()); |
| 263 } | 263 } |
| 264 | 264 |
| 265 void ImageDecodingStore::RemoveFromCacheInternal( | 265 void ImageDecodingStore::RemoveFromCacheInternal( |
| 266 const CacheEntry* cache_entry, | 266 const CacheEntry* cache_entry, |
| 267 Vector<std::unique_ptr<CacheEntry>>* deletion_list) { | 267 Vector<std::unique_ptr<CacheEntry>>* deletion_list) { |
| 268 if (cache_entry->GetType() == CacheEntry::kTypeDecoder) { | 268 if (cache_entry->GetType() == CacheEntry::kTypeDecoder) { |
| 269 RemoveFromCacheInternal(static_cast<const DecoderCacheEntry*>(cache_entry), | 269 RemoveFromCacheInternal(static_cast<const DecoderCacheEntry*>(cache_entry), |
| 270 &decoder_cache_map_, &decoder_cache_key_map_, | 270 &decoder_cache_map_, &decoder_cache_key_map_, |
| 271 deletion_list); | 271 deletion_list); |
| 272 } else { | 272 } else { |
| 273 ASSERT(false); | 273 DCHECK(false); |
| 274 } | 274 } |
| 275 } | 275 } |
| 276 | 276 |
| 277 template <class U, class V> | 277 template <class U, class V> |
| 278 void ImageDecodingStore::RemoveCacheIndexedByGeneratorInternal( | 278 void ImageDecodingStore::RemoveCacheIndexedByGeneratorInternal( |
| 279 U* cache_map, | 279 U* cache_map, |
| 280 V* identifier_map, | 280 V* identifier_map, |
| 281 const ImageFrameGenerator* generator, | 281 const ImageFrameGenerator* generator, |
| 282 Vector<std::unique_ptr<CacheEntry>>* deletion_list) { | 282 Vector<std::unique_ptr<CacheEntry>>* deletion_list) { |
| 283 typename V::iterator iter = identifier_map->Find(generator); | 283 typename V::iterator iter = identifier_map->Find(generator); |
| 284 if (iter == identifier_map->end()) | 284 if (iter == identifier_map->end()) |
| 285 return; | 285 return; |
| 286 | 286 |
| 287 // Get all cache identifiers associated with generator. | 287 // Get all cache identifiers associated with generator. |
| 288 Vector<typename U::KeyType> cache_identifier_list; | 288 Vector<typename U::KeyType> cache_identifier_list; |
| 289 CopyToVector(iter->value, cache_identifier_list); | 289 CopyToVector(iter->value, cache_identifier_list); |
| 290 | 290 |
| 291 // For each cache identifier find the corresponding CacheEntry and remove it. | 291 // For each cache identifier find the corresponding CacheEntry and remove it. |
| 292 for (size_t i = 0; i < cache_identifier_list.size(); ++i) { | 292 for (size_t i = 0; i < cache_identifier_list.size(); ++i) { |
| 293 ASSERT(cache_map->Contains(cache_identifier_list[i])); | 293 DCHECK(cache_map->Contains(cache_identifier_list[i])); |
| 294 const auto& cache_entry = cache_map->at(cache_identifier_list[i]); | 294 const auto& cache_entry = cache_map->at(cache_identifier_list[i]); |
| 295 ASSERT(!cache_entry->UseCount()); | 295 DCHECK(!cache_entry->UseCount()); |
| 296 RemoveFromCacheInternal(cache_entry, cache_map, identifier_map, | 296 RemoveFromCacheInternal(cache_entry, cache_map, identifier_map, |
| 297 deletion_list); | 297 deletion_list); |
| 298 } | 298 } |
| 299 } | 299 } |
| 300 | 300 |
| 301 void ImageDecodingStore::RemoveFromCacheListInternal( | 301 void ImageDecodingStore::RemoveFromCacheListInternal( |
| 302 const Vector<std::unique_ptr<CacheEntry>>& deletion_list) { | 302 const Vector<std::unique_ptr<CacheEntry>>& deletion_list) { |
| 303 for (size_t i = 0; i < deletion_list.size(); ++i) | 303 for (size_t i = 0; i < deletion_list.size(); ++i) |
| 304 ordered_cache_list_.Remove(deletion_list[i].get()); | 304 ordered_cache_list_.Remove(deletion_list[i].get()); |
| 305 } | 305 } |
| 306 | 306 |
| 307 } // namespace blink | 307 } // namespace blink |
| OLD | NEW |