| 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_controller.h" | 5 #include "cc/tiles/software_image_decode_controller.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <functional> | 9 #include <functional> |
| 10 | 10 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 const size_t kMaxHighQualityImageSizeBytes = 64 * 1024 * 1024; | 34 const size_t kMaxHighQualityImageSizeBytes = 64 * 1024 * 1024; |
| 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 const size_t kMaxItemsInCache = 1000; | 38 const size_t kMaxItemsInCache = 1000; |
| 39 | 39 |
| 40 class AutoRemoveKeyFromTaskMap { | 40 class AutoRemoveKeyFromTaskMap { |
| 41 public: | 41 public: |
| 42 AutoRemoveKeyFromTaskMap( | 42 AutoRemoveKeyFromTaskMap( |
| 43 std::unordered_map<SoftwareImageDecodeController::ImageKey, | 43 std::unordered_map<SoftwareImageDecodeController::ImageKey, |
| 44 scoped_refptr<ImageDecodeTask>, | 44 scoped_refptr<TileTask>, |
| 45 SoftwareImageDecodeController::ImageKeyHash>* task_map, | 45 SoftwareImageDecodeController::ImageKeyHash>* task_map, |
| 46 const SoftwareImageDecodeController::ImageKey& key) | 46 const SoftwareImageDecodeController::ImageKey& key) |
| 47 : task_map_(task_map), key_(key) {} | 47 : task_map_(task_map), key_(key) {} |
| 48 ~AutoRemoveKeyFromTaskMap() { task_map_->erase(key_); } | 48 ~AutoRemoveKeyFromTaskMap() { task_map_->erase(key_); } |
| 49 | 49 |
| 50 private: | 50 private: |
| 51 std::unordered_map<SoftwareImageDecodeController::ImageKey, | 51 std::unordered_map<SoftwareImageDecodeController::ImageKey, |
| 52 scoped_refptr<ImageDecodeTask>, | 52 scoped_refptr<TileTask>, |
| 53 SoftwareImageDecodeController::ImageKeyHash>* task_map_; | 53 SoftwareImageDecodeController::ImageKeyHash>* task_map_; |
| 54 SoftwareImageDecodeController::ImageKey key_; | 54 SoftwareImageDecodeController::ImageKey key_; |
| 55 }; | 55 }; |
| 56 | 56 |
| 57 class ImageDecodeTaskImpl : public ImageDecodeTask { | 57 class ImageDecodeTaskImpl : public TileTask { |
| 58 public: | 58 public: |
| 59 ImageDecodeTaskImpl(SoftwareImageDecodeController* controller, | 59 ImageDecodeTaskImpl(SoftwareImageDecodeController* controller, |
| 60 const SoftwareImageDecodeController::ImageKey& image_key, | 60 const SoftwareImageDecodeController::ImageKey& image_key, |
| 61 const DrawImage& image, | 61 const DrawImage& image, |
| 62 uint64_t source_prepare_tiles_id) | 62 uint64_t source_prepare_tiles_id) |
| 63 : controller_(controller), | 63 : controller_(controller), |
| 64 image_key_(image_key), | 64 image_key_(image_key), |
| 65 image_(image), | 65 image_(image), |
| 66 image_ref_(skia::SharePtr(image.image())), | 66 image_ref_(skia::SharePtr(image.image())), |
| 67 source_prepare_tiles_id_(source_prepare_tiles_id) {} | 67 source_prepare_tiles_id_(source_prepare_tiles_id) {} |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 DCHECK_EQ(0u, at_raster_decoded_images_ref_counts_.size()); | 145 DCHECK_EQ(0u, at_raster_decoded_images_ref_counts_.size()); |
| 146 | 146 |
| 147 // It is safe to unregister, even if we didn't register in the constructor. | 147 // It is safe to unregister, even if we didn't register in the constructor. |
| 148 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( | 148 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( |
| 149 this); | 149 this); |
| 150 } | 150 } |
| 151 | 151 |
| 152 bool SoftwareImageDecodeController::GetTaskForImageAndRef( | 152 bool SoftwareImageDecodeController::GetTaskForImageAndRef( |
| 153 const DrawImage& image, | 153 const DrawImage& image, |
| 154 uint64_t prepare_tiles_id, | 154 uint64_t prepare_tiles_id, |
| 155 scoped_refptr<ImageDecodeTask>* task) { | 155 scoped_refptr<TileTask>* task) { |
| 156 // If the image already exists or if we're going to create a task for it, then | 156 // If the image already exists or if we're going to create a task for it, then |
| 157 // we'll likely need to ref this image (the exception is if we're prerolling | 157 // we'll likely need to ref this image (the exception is if we're prerolling |
| 158 // the image only). That means the image is or will be in the cache. When the | 158 // the image only). That means the image is or will be in the cache. When the |
| 159 // ref goes to 0, it will be unpinned but will remain in the cache. If the | 159 // ref goes to 0, it will be unpinned but will remain in the cache. If the |
| 160 // image does not fit into the budget, then we don't ref this image, since it | 160 // image does not fit into the budget, then we don't ref this image, since it |
| 161 // will be decoded at raster time which is when it will be temporarily put in | 161 // will be decoded at raster time which is when it will be temporarily put in |
| 162 // the cache. | 162 // the cache. |
| 163 ImageKey key = ImageKey::FromDrawImage(image); | 163 ImageKey key = ImageKey::FromDrawImage(image); |
| 164 TRACE_EVENT1("disabled-by-default-cc.debug", | 164 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 165 "SoftwareImageDecodeController::GetTaskForImageAndRef", "key", | 165 "SoftwareImageDecodeController::GetTaskForImageAndRef", "key", |
| 166 key.ToString()); | 166 key.ToString()); |
| 167 | 167 |
| 168 // If the target size is empty, we can skip this image during draw (and thus | 168 // If the target size is empty, we can skip this image during draw (and thus |
| 169 // we don't need to decode it or ref it). | 169 // we don't need to decode it or ref it). |
| 170 if (key.target_size().IsEmpty()) { | 170 if (key.target_size().IsEmpty()) { |
| 171 *task = nullptr; | 171 *task = nullptr; |
| 172 return false; | 172 return false; |
| 173 } | 173 } |
| 174 | 174 |
| 175 // If we're not going to do a scale, we will just create a task to preroll the | 175 // If we're not going to do a scale, we will just create a task to preroll the |
| 176 // image the first time we see it. This doesn't need to account for memory. | 176 // image the first time we see it. This doesn't need to account for memory. |
| 177 // TODO(vmpstr): We can also lock the original sized image, in which case it | 177 // TODO(vmpstr): We can also lock the original sized image, in which case it |
| 178 // does require memory bookkeeping. | 178 // does require memory bookkeeping. |
| 179 if (!CanHandleImage(key)) { | 179 if (!CanHandleImage(key)) { |
| 180 base::AutoLock lock(lock_); | 180 base::AutoLock lock(lock_); |
| 181 if (prerolled_images_.count(key.image_id()) == 0) { | 181 if (prerolled_images_.count(key.image_id()) == 0) { |
| 182 scoped_refptr<ImageDecodeTask>& existing_task = pending_image_tasks_[key]; | 182 scoped_refptr<TileTask>& existing_task = pending_image_tasks_[key]; |
| 183 if (!existing_task) { | 183 if (!existing_task) { |
| 184 existing_task = make_scoped_refptr( | 184 existing_task = make_scoped_refptr( |
| 185 new ImageDecodeTaskImpl(this, key, image, prepare_tiles_id)); | 185 new ImageDecodeTaskImpl(this, key, image, prepare_tiles_id)); |
| 186 } | 186 } |
| 187 *task = existing_task; | 187 *task = existing_task; |
| 188 } else { | 188 } else { |
| 189 *task = nullptr; | 189 *task = nullptr; |
| 190 } | 190 } |
| 191 return false; | 191 return false; |
| 192 } | 192 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 205 SanityCheckState(__LINE__, true); | 205 SanityCheckState(__LINE__, true); |
| 206 return true; | 206 return true; |
| 207 } | 207 } |
| 208 // If the image fits in memory, then we at least tried to lock it and | 208 // If the image fits in memory, then we at least tried to lock it and |
| 209 // failed. This means that it's not valid anymore. | 209 // failed. This means that it's not valid anymore. |
| 210 if (new_image_fits_in_memory) | 210 if (new_image_fits_in_memory) |
| 211 decoded_images_.Erase(decoded_it); | 211 decoded_images_.Erase(decoded_it); |
| 212 } | 212 } |
| 213 | 213 |
| 214 // If the task exists, return it. | 214 // If the task exists, return it. |
| 215 scoped_refptr<ImageDecodeTask>& existing_task = pending_image_tasks_[key]; | 215 scoped_refptr<TileTask>& existing_task = pending_image_tasks_[key]; |
| 216 if (existing_task) { | 216 if (existing_task) { |
| 217 RefImage(key); | 217 RefImage(key); |
| 218 *task = existing_task; | 218 *task = existing_task; |
| 219 SanityCheckState(__LINE__, true); | 219 SanityCheckState(__LINE__, true); |
| 220 return true; | 220 return true; |
| 221 } | 221 } |
| 222 | 222 |
| 223 // At this point, we have to create a new image/task, so we need to abort if | 223 // At this point, we have to create a new image/task, so we need to abort if |
| 224 // it doesn't fit into memory and there are currently no raster tasks that | 224 // it doesn't fit into memory and there are currently no raster tasks that |
| 225 // would have already accounted for memory. The latter part is possible if | 225 // would have already accounted for memory. The latter part is possible if |
| (...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 932 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { | 932 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { |
| 933 current_usage_bytes_ = 0; | 933 current_usage_bytes_ = 0; |
| 934 } | 934 } |
| 935 | 935 |
| 936 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() | 936 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() |
| 937 const { | 937 const { |
| 938 return current_usage_bytes_.ValueOrDie(); | 938 return current_usage_bytes_.ValueOrDie(); |
| 939 } | 939 } |
| 940 | 940 |
| 941 } // namespace cc | 941 } // namespace cc |
| OLD | NEW |