| 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 : TileTask(true), |
| 64 controller_(controller), |
| 64 image_key_(image_key), | 65 image_key_(image_key), |
| 65 image_(image), | 66 image_(image), |
| 66 image_ref_(skia::SharePtr(image.image())), | 67 image_ref_(skia::SharePtr(image.image())), |
| 67 source_prepare_tiles_id_(source_prepare_tiles_id) {} | 68 source_prepare_tiles_id_(source_prepare_tiles_id) {} |
| 68 | 69 |
| 69 // Overridden from Task: | 70 // Overridden from Task: |
| 70 void RunOnWorkerThread() override { | 71 void RunOnWorkerThread() override { |
| 71 TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", | 72 TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", |
| 72 "software", "source_prepare_tiles_id", | 73 "software", "source_prepare_tiles_id", |
| 73 source_prepare_tiles_id_); | 74 source_prepare_tiles_id_); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 DCHECK_EQ(0u, at_raster_decoded_images_ref_counts_.size()); | 146 DCHECK_EQ(0u, at_raster_decoded_images_ref_counts_.size()); |
| 146 | 147 |
| 147 // It is safe to unregister, even if we didn't register in the constructor. | 148 // It is safe to unregister, even if we didn't register in the constructor. |
| 148 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( | 149 base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( |
| 149 this); | 150 this); |
| 150 } | 151 } |
| 151 | 152 |
| 152 bool SoftwareImageDecodeController::GetTaskForImageAndRef( | 153 bool SoftwareImageDecodeController::GetTaskForImageAndRef( |
| 153 const DrawImage& image, | 154 const DrawImage& image, |
| 154 uint64_t prepare_tiles_id, | 155 uint64_t prepare_tiles_id, |
| 155 scoped_refptr<ImageDecodeTask>* task) { | 156 scoped_refptr<TileTask>* task) { |
| 156 // If the image already exists or if we're going to create a task for it, then | 157 // 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 | 158 // 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 | 159 // 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 | 160 // 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 | 161 // 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 | 162 // will be decoded at raster time which is when it will be temporarily put in |
| 162 // the cache. | 163 // the cache. |
| 163 ImageKey key = ImageKey::FromDrawImage(image); | 164 ImageKey key = ImageKey::FromDrawImage(image); |
| 164 TRACE_EVENT1("disabled-by-default-cc.debug", | 165 TRACE_EVENT1("disabled-by-default-cc.debug", |
| 165 "SoftwareImageDecodeController::GetTaskForImageAndRef", "key", | 166 "SoftwareImageDecodeController::GetTaskForImageAndRef", "key", |
| 166 key.ToString()); | 167 key.ToString()); |
| 167 | 168 |
| 168 // If the target size is empty, we can skip this image during draw (and thus | 169 // 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). | 170 // we don't need to decode it or ref it). |
| 170 if (key.target_size().IsEmpty()) { | 171 if (key.target_size().IsEmpty()) { |
| 171 *task = nullptr; | 172 *task = nullptr; |
| 172 return false; | 173 return false; |
| 173 } | 174 } |
| 174 | 175 |
| 175 // If we're not going to do a scale, we will just create a task to preroll the | 176 // 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. | 177 // 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 | 178 // TODO(vmpstr): We can also lock the original sized image, in which case it |
| 178 // does require memory bookkeeping. | 179 // does require memory bookkeeping. |
| 179 if (!CanHandleImage(key)) { | 180 if (!CanHandleImage(key)) { |
| 180 base::AutoLock lock(lock_); | 181 base::AutoLock lock(lock_); |
| 181 if (prerolled_images_.count(key.image_id()) == 0) { | 182 if (prerolled_images_.count(key.image_id()) == 0) { |
| 182 scoped_refptr<ImageDecodeTask>& existing_task = pending_image_tasks_[key]; | 183 scoped_refptr<TileTask>& existing_task = pending_image_tasks_[key]; |
| 183 if (!existing_task) { | 184 if (!existing_task) { |
| 184 existing_task = make_scoped_refptr( | 185 existing_task = make_scoped_refptr( |
| 185 new ImageDecodeTaskImpl(this, key, image, prepare_tiles_id)); | 186 new ImageDecodeTaskImpl(this, key, image, prepare_tiles_id)); |
| 186 } | 187 } |
| 187 *task = existing_task; | 188 *task = existing_task; |
| 188 } else { | 189 } else { |
| 189 *task = nullptr; | 190 *task = nullptr; |
| 190 } | 191 } |
| 191 return false; | 192 return false; |
| 192 } | 193 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 205 SanityCheckState(__LINE__, true); | 206 SanityCheckState(__LINE__, true); |
| 206 return true; | 207 return true; |
| 207 } | 208 } |
| 208 // If the image fits in memory, then we at least tried to lock it and | 209 // 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. | 210 // failed. This means that it's not valid anymore. |
| 210 if (new_image_fits_in_memory) | 211 if (new_image_fits_in_memory) |
| 211 decoded_images_.Erase(decoded_it); | 212 decoded_images_.Erase(decoded_it); |
| 212 } | 213 } |
| 213 | 214 |
| 214 // If the task exists, return it. | 215 // If the task exists, return it. |
| 215 scoped_refptr<ImageDecodeTask>& existing_task = pending_image_tasks_[key]; | 216 scoped_refptr<TileTask>& existing_task = pending_image_tasks_[key]; |
| 216 if (existing_task) { | 217 if (existing_task) { |
| 217 RefImage(key); | 218 RefImage(key); |
| 218 *task = existing_task; | 219 *task = existing_task; |
| 219 SanityCheckState(__LINE__, true); | 220 SanityCheckState(__LINE__, true); |
| 220 return true; | 221 return true; |
| 221 } | 222 } |
| 222 | 223 |
| 223 // At this point, we have to create a new image/task, so we need to abort if | 224 // 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 | 225 // 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 | 226 // 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() { | 933 void SoftwareImageDecodeController::MemoryBudget::ResetUsage() { |
| 933 current_usage_bytes_ = 0; | 934 current_usage_bytes_ = 0; |
| 934 } | 935 } |
| 935 | 936 |
| 936 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() | 937 size_t SoftwareImageDecodeController::MemoryBudget::GetCurrentUsageSafe() |
| 937 const { | 938 const { |
| 938 return current_usage_bytes_.ValueOrDie(); | 939 return current_usage_bytes_.ValueOrDie(); |
| 939 } | 940 } |
| 940 | 941 |
| 941 } // namespace cc | 942 } // namespace cc |
| OLD | NEW |