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 |