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 |