| OLD | NEW | 
|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "cc/tiles/software_image_decode_cache.h" | 5 #include "cc/tiles/software_image_decode_cache.h" | 
| 6 | 6 | 
| 7 #include <inttypes.h> | 7 #include <inttypes.h> | 
| 8 #include <stdint.h> | 8 #include <stdint.h> | 
| 9 | 9 | 
| 10 #include <algorithm> | 10 #include <algorithm> | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 30 using base::trace_event::MemoryAllocatorDump; | 30 using base::trace_event::MemoryAllocatorDump; | 
| 31 using base::trace_event::MemoryDumpLevelOfDetail; | 31 using base::trace_event::MemoryDumpLevelOfDetail; | 
| 32 | 32 | 
| 33 namespace cc { | 33 namespace cc { | 
| 34 namespace { | 34 namespace { | 
| 35 | 35 | 
| 36 // The number of entries to keep around in the cache. This limit can be breached | 36 // The number of entries to keep around in the cache. This limit can be breached | 
| 37 // if more items are locked. That is, locked items ignore this limit. | 37 // if more items are locked. That is, locked items ignore this limit. | 
| 38 // Depending on the memory state of the system, we limit the amount of items | 38 // Depending on the memory state of the system, we limit the amount of items | 
| 39 // differently. | 39 // differently. | 
| 40 const size_t kNormalMaxItemsInCache = 1000; | 40 const size_t kSIDNormalMaxItemsInCache = 1000; | 
| 41 const size_t kThrottledMaxItemsInCache = 100; | 41 const size_t kSIDThrottledMaxItemsInCache = 100; | 
| 42 const size_t kSuspendedMaxItemsInCache = 0; | 42 const size_t kSIDSuspendedMaxItemsInCache = 0; | 
| 43 | 43 | 
| 44 // If the size of the original sized image breaches kMemoryRatioToSubrect but we | 44 // If the size of the original sized image breaches kMemoryRatioToSubrect but we | 
| 45 // don't need to scale the image, consider caching only the needed subrect. | 45 // don't need to scale the image, consider caching only the needed subrect. | 
| 46 // The second part that much be true is that we cache only the needed subrect if | 46 // The second part that much be true is that we cache only the needed subrect if | 
| 47 // the total size needed for the subrect is at most kMemoryRatioToSubrect * | 47 // the total size needed for the subrect is at most kMemoryRatioToSubrect * | 
| 48 // (size needed for the full original image). | 48 // (size needed for the full original image). | 
| 49 // Note that at least one of the dimensions has to be at least | 49 // Note that at least one of the dimensions has to be at least | 
| 50 // kMinDimensionToSubrect before an image can breach the threshold. | 50 // kMinDimensionToSubrect before an image can breach the threshold. | 
| 51 const size_t kMemoryThresholdToSubrect = 64 * 1024 * 1024; | 51 const size_t kMemoryThresholdToSubrect = 64 * 1024 * 1024; | 
| 52 const int kMinDimensionToSubrect = 4 * 1024; | 52 const int kMinDimensionToSubrect = 4 * 1024; | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
| 80   ~AutoDrawWithImageFinished() { | 80   ~AutoDrawWithImageFinished() { | 
| 81     cache_->DrawWithImageFinished(draw_image_, decoded_draw_image_); | 81     cache_->DrawWithImageFinished(draw_image_, decoded_draw_image_); | 
| 82   } | 82   } | 
| 83 | 83 | 
| 84  private: | 84  private: | 
| 85   SoftwareImageDecodeCache* cache_; | 85   SoftwareImageDecodeCache* cache_; | 
| 86   const DrawImage& draw_image_; | 86   const DrawImage& draw_image_; | 
| 87   const DecodedDrawImage& decoded_draw_image_; | 87   const DecodedDrawImage& decoded_draw_image_; | 
| 88 }; | 88 }; | 
| 89 | 89 | 
| 90 class ImageDecodeTaskImpl : public TileTask { | 90 class ImageDecodeTaskImpl2 : public TileTask { | 
| 91  public: | 91  public: | 
| 92   ImageDecodeTaskImpl(SoftwareImageDecodeCache* cache, | 92   ImageDecodeTaskImpl2(SoftwareImageDecodeCache* cache, | 
| 93                       const SoftwareImageDecodeCache::ImageKey& image_key, | 93                       const SoftwareImageDecodeCache::ImageKey& image_key, | 
| 94                       const DrawImage& image, | 94                       const DrawImage& image, | 
| 95                       SoftwareImageDecodeCache::DecodeTaskType task_type, | 95                       SoftwareImageDecodeCache::DecodeTaskType task_type, | 
| 96                       const ImageDecodeCache::TracingInfo& tracing_info) | 96                       const ImageDecodeCache::TracingInfo& tracing_info) | 
| 97       : TileTask(true), | 97       : TileTask(true), | 
| 98         cache_(cache), | 98         cache_(cache), | 
| 99         image_key_(image_key), | 99         image_key_(image_key), | 
| 100         image_(image), | 100         image_(image), | 
| 101         task_type_(task_type), | 101         task_type_(task_type), | 
| 102         tracing_info_(tracing_info) {} | 102         tracing_info_(tracing_info) {} | 
| 103 | 103 | 
| 104   // Overridden from Task: | 104   // Overridden from Task: | 
| 105   void RunOnWorkerThread() override { | 105   void RunOnWorkerThread() override { | 
| 106     TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", | 106     TRACE_EVENT2("cc", "ImageDecodeTaskImpl2::RunOnWorkerThread", "mode", | 
| 107                  "software", "source_prepare_tiles_id", | 107                  "software", "source_prepare_tiles_id", | 
| 108                  tracing_info_.prepare_tiles_id); | 108                  tracing_info_.prepare_tiles_id); | 
| 109     devtools_instrumentation::ScopedImageDecodeTask image_decode_task( | 109     devtools_instrumentation::ScopedImageDecodeTask image_decode_task( | 
| 110         image_.paint_image().GetSkImage().get(), | 110         image_.paint_image().GetSkImage().get(), | 
| 111         devtools_instrumentation::ScopedImageDecodeTask::kSoftware, | 111         devtools_instrumentation::ScopedImageDecodeTask::kSoftware, | 
| 112         ImageDecodeCache::ToScopedTaskType(tracing_info_.task_type)); | 112         ImageDecodeCache::ToScopedTaskType(tracing_info_.task_type)); | 
| 113     cache_->DecodeImage(image_key_, image_, task_type_); | 113     cache_->DecodeImage(image_key_, image_, task_type_); | 
| 114   } | 114   } | 
| 115 | 115 | 
| 116   // Overridden from TileTask: | 116   // Overridden from TileTask: | 
| 117   void OnTaskCompleted() override { | 117   void OnTaskCompleted() override { | 
| 118     cache_->RemovePendingTask(image_key_, task_type_); | 118     cache_->RemovePendingTask(image_key_, task_type_); | 
| 119   } | 119   } | 
| 120 | 120 | 
| 121  protected: | 121  protected: | 
| 122   ~ImageDecodeTaskImpl() override {} | 122   ~ImageDecodeTaskImpl2() override {} | 
| 123 | 123 | 
| 124  private: | 124  private: | 
| 125   SoftwareImageDecodeCache* cache_; | 125   SoftwareImageDecodeCache* cache_; | 
| 126   SoftwareImageDecodeCache::ImageKey image_key_; | 126   SoftwareImageDecodeCache::ImageKey image_key_; | 
| 127   DrawImage image_; | 127   DrawImage image_; | 
| 128   SoftwareImageDecodeCache::DecodeTaskType task_type_; | 128   SoftwareImageDecodeCache::DecodeTaskType task_type_; | 
| 129   const ImageDecodeCache::TracingInfo tracing_info_; | 129   const ImageDecodeCache::TracingInfo tracing_info_; | 
| 130 | 130 | 
| 131   DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl); | 131   DISALLOW_COPY_AND_ASSIGN(ImageDecodeTaskImpl2); | 
| 132 }; | 132 }; | 
| 133 | 133 | 
| 134 SkSize GetScaleAdjustment(const ImageDecodeCacheKey& key) { | 134 SkSize GetScaleAdjustment(const ImageDecodeCacheKey& key) { | 
| 135   // If the requested filter quality did not require scale, then the adjustment | 135   // If the requested filter quality did not require scale, then the adjustment | 
| 136   // is identity. | 136   // is identity. | 
| 137   if (key.can_use_original_size_decode() || key.should_use_subrect()) { | 137   if (key.can_use_original_size_decode() || key.should_use_subrect()) { | 
| 138     return SkSize::Make(1.f, 1.f); | 138     return SkSize::Make(1.f, 1.f); | 
| 139   } else if (key.filter_quality() == kMedium_SkFilterQuality) { | 139   } else if (key.filter_quality() == kMedium_SkFilterQuality) { | 
| 140     return MipMapUtil::GetScaleAdjustmentForSize(key.src_rect().size(), | 140     return MipMapUtil::GetScaleAdjustmentForSize(key.src_rect().size(), | 
| 141                                                  key.target_size()); | 141                                                  key.target_size()); | 
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 186 | 186 | 
| 187 }  // namespace | 187 }  // namespace | 
| 188 | 188 | 
| 189 SoftwareImageDecodeCache::SoftwareImageDecodeCache( | 189 SoftwareImageDecodeCache::SoftwareImageDecodeCache( | 
| 190     SkColorType color_type, | 190     SkColorType color_type, | 
| 191     size_t locked_memory_limit_bytes) | 191     size_t locked_memory_limit_bytes) | 
| 192     : decoded_images_(ImageMRUCache::NO_AUTO_EVICT), | 192     : decoded_images_(ImageMRUCache::NO_AUTO_EVICT), | 
| 193       at_raster_decoded_images_(ImageMRUCache::NO_AUTO_EVICT), | 193       at_raster_decoded_images_(ImageMRUCache::NO_AUTO_EVICT), | 
| 194       locked_images_budget_(locked_memory_limit_bytes), | 194       locked_images_budget_(locked_memory_limit_bytes), | 
| 195       color_type_(color_type), | 195       color_type_(color_type), | 
| 196       max_items_in_cache_(kNormalMaxItemsInCache) { | 196       max_items_in_cache_(kSIDNormalMaxItemsInCache) { | 
| 197   // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). | 197   // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). | 
| 198   // Don't register a dump provider in these cases. | 198   // Don't register a dump provider in these cases. | 
| 199   if (base::ThreadTaskRunnerHandle::IsSet()) { | 199   if (base::ThreadTaskRunnerHandle::IsSet()) { | 
| 200     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( | 200     base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( | 
| 201         this, "cc::SoftwareImageDecodeCache", | 201         this, "cc::SoftwareImageDecodeCache", | 
| 202         base::ThreadTaskRunnerHandle::Get()); | 202         base::ThreadTaskRunnerHandle::Get()); | 
| 203   } | 203   } | 
| 204   // Register this component with base::MemoryCoordinatorClientRegistry. | 204   // Register this component with base::MemoryCoordinatorClientRegistry. | 
| 205   base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); | 205   base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); | 
| 206 } | 206 } | 
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 311   if (!new_image_fits_in_memory && (decoded_images_ref_counts_.find(key) == | 311   if (!new_image_fits_in_memory && (decoded_images_ref_counts_.find(key) == | 
| 312                                     decoded_images_ref_counts_.end())) { | 312                                     decoded_images_ref_counts_.end())) { | 
| 313     *task = nullptr; | 313     *task = nullptr; | 
| 314     return false; | 314     return false; | 
| 315   } | 315   } | 
| 316 | 316 | 
| 317   // Actually create the task. RefImage will account for memory on the first | 317   // Actually create the task. RefImage will account for memory on the first | 
| 318   // ref. | 318   // ref. | 
| 319   RefImage(key); | 319   RefImage(key); | 
| 320   existing_task = make_scoped_refptr( | 320   existing_task = make_scoped_refptr( | 
| 321       new ImageDecodeTaskImpl(this, key, image, task_type, tracing_info)); | 321       new ImageDecodeTaskImpl2(this, key, image, task_type, tracing_info)); | 
| 322   *task = existing_task; | 322   *task = existing_task; | 
| 323   return true; | 323   return true; | 
| 324 } | 324 } | 
| 325 | 325 | 
| 326 void SoftwareImageDecodeCache::RefImage(const ImageKey& key) { | 326 void SoftwareImageDecodeCache::RefImage(const ImageKey& key) { | 
| 327   TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 327   TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 
| 328                "SoftwareImageDecodeCache::RefImage", "key", key.ToString()); | 328                "SoftwareImageDecodeCache::RefImage", "key", key.ToString()); | 
| 329   lock_.AssertAcquired(); | 329   lock_.AssertAcquired(); | 
| 330   int ref = ++decoded_images_ref_counts_[key]; | 330   int ref = ++decoded_images_ref_counts_[key]; | 
| 331   if (ref == 1) { | 331   if (ref == 1) { | 
| (...skipping 871 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1203 | 1203 | 
| 1204 size_t SoftwareImageDecodeCache::MemoryBudget::GetCurrentUsageSafe() const { | 1204 size_t SoftwareImageDecodeCache::MemoryBudget::GetCurrentUsageSafe() const { | 
| 1205   return current_usage_bytes_.ValueOrDie(); | 1205   return current_usage_bytes_.ValueOrDie(); | 
| 1206 } | 1206 } | 
| 1207 | 1207 | 
| 1208 void SoftwareImageDecodeCache::OnMemoryStateChange(base::MemoryState state) { | 1208 void SoftwareImageDecodeCache::OnMemoryStateChange(base::MemoryState state) { | 
| 1209   { | 1209   { | 
| 1210     base::AutoLock hold(lock_); | 1210     base::AutoLock hold(lock_); | 
| 1211     switch (state) { | 1211     switch (state) { | 
| 1212       case base::MemoryState::NORMAL: | 1212       case base::MemoryState::NORMAL: | 
| 1213         max_items_in_cache_ = kNormalMaxItemsInCache; | 1213         max_items_in_cache_ = kSIDNormalMaxItemsInCache; | 
| 1214         break; | 1214         break; | 
| 1215       case base::MemoryState::THROTTLED: | 1215       case base::MemoryState::THROTTLED: | 
| 1216         max_items_in_cache_ = kThrottledMaxItemsInCache; | 1216         max_items_in_cache_ = kSIDThrottledMaxItemsInCache; | 
| 1217         break; | 1217         break; | 
| 1218       case base::MemoryState::SUSPENDED: | 1218       case base::MemoryState::SUSPENDED: | 
| 1219         max_items_in_cache_ = kSuspendedMaxItemsInCache; | 1219         max_items_in_cache_ = kSIDSuspendedMaxItemsInCache; | 
| 1220         break; | 1220         break; | 
| 1221       case base::MemoryState::UNKNOWN: | 1221       case base::MemoryState::UNKNOWN: | 
| 1222         NOTREACHED(); | 1222         NOTREACHED(); | 
| 1223         return; | 1223         return; | 
| 1224     } | 1224     } | 
| 1225   } | 1225   } | 
| 1226 } | 1226 } | 
| 1227 | 1227 | 
| 1228 void SoftwareImageDecodeCache::OnPurgeMemory() { | 1228 void SoftwareImageDecodeCache::OnPurgeMemory() { | 
| 1229   base::AutoLock lock(lock_); | 1229   base::AutoLock lock(lock_); | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 1251 | 1251 | 
| 1252 void SoftwareImageDecodeCache::CacheDecodedImages( | 1252 void SoftwareImageDecodeCache::CacheDecodedImages( | 
| 1253     const ImageKey& key, | 1253     const ImageKey& key, | 
| 1254     std::unique_ptr<DecodedImage> decoded_image) { | 1254     std::unique_ptr<DecodedImage> decoded_image) { | 
| 1255   lock_.AssertAcquired(); | 1255   lock_.AssertAcquired(); | 
| 1256   frame_key_to_image_keys_[key.frame_key()].push_back(key); | 1256   frame_key_to_image_keys_[key.frame_key()].push_back(key); | 
| 1257   decoded_images_.Put(key, std::move(decoded_image)); | 1257   decoded_images_.Put(key, std::move(decoded_image)); | 
| 1258 } | 1258 } | 
| 1259 | 1259 | 
| 1260 }  // namespace cc | 1260 }  // namespace cc | 
| OLD | NEW | 
|---|