OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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/checker_image_tracker.h" | 5 #include "cc/tiles/checker_image_tracker.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 "CheckerImageTracker::ScheduleImageDecodeQueue"); | 39 "CheckerImageTracker::ScheduleImageDecodeQueue"); |
40 // Only checker-imaged (async updated) images are decoded using the image | 40 // Only checker-imaged (async updated) images are decoded using the image |
41 // decode service. If |enable_checker_imaging_| is false, no image should | 41 // decode service. If |enable_checker_imaging_| is false, no image should |
42 // be checkered. | 42 // be checkered. |
43 DCHECK(image_decode_queue.empty() || enable_checker_imaging_); | 43 DCHECK(image_decode_queue.empty() || enable_checker_imaging_); |
44 | 44 |
45 image_decode_queue_ = std::move(image_decode_queue); | 45 image_decode_queue_ = std::move(image_decode_queue); |
46 ScheduleNextImageDecode(); | 46 ScheduleNextImageDecode(); |
47 } | 47 } |
48 | 48 |
49 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { | 49 const PaintImageIdFlatSet& |
| 50 CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { |
50 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 51 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
51 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree"); | 52 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree"); |
52 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) | 53 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) |
53 << "Sync tree can not be invalidated more than once"; | 54 << "Sync tree can not be invalidated more than once"; |
54 | 55 |
55 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); | 56 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); |
56 images_pending_invalidation_.clear(); | 57 images_pending_invalidation_.clear(); |
57 return invalidated_images_on_current_sync_tree_; | 58 return invalidated_images_on_current_sync_tree_; |
58 } | 59 } |
59 | 60 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 DCHECK(it != image_async_decode_state_.end()); | 92 DCHECK(it != image_async_decode_state_.end()); |
92 DCHECK_EQ(it->second, DecodePolicy::SYNC_DECODED_ONCE); | 93 DCHECK_EQ(it->second, DecodePolicy::SYNC_DECODED_ONCE); |
93 | 94 |
94 it->second = DecodePolicy::ASYNC; | 95 it->second = DecodePolicy::ASYNC; |
95 } | 96 } |
96 } | 97 } |
97 images_pending_invalidation_.clear(); | 98 images_pending_invalidation_.clear(); |
98 } | 99 } |
99 | 100 |
100 void CheckerImageTracker::DidFinishImageDecode( | 101 void CheckerImageTracker::DidFinishImageDecode( |
101 ImageId image_id, | 102 PaintImage::Id image_id, |
102 ImageController::ImageDecodeRequestId request_id, | 103 ImageController::ImageDecodeRequestId request_id, |
103 ImageController::ImageDecodeResult result) { | 104 ImageController::ImageDecodeResult result) { |
104 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 105 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
105 "CheckerImageTracker::DidFinishImageDecode"); | 106 "CheckerImageTracker::DidFinishImageDecode"); |
106 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", | 107 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", |
107 image_id); | 108 image_id); |
108 | 109 |
109 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result); | 110 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result); |
110 DCHECK_EQ(outstanding_image_decode_->uniqueID(), image_id); | 111 DCHECK_EQ(outstanding_image_decode_.value().stable_id(), image_id); |
111 outstanding_image_decode_ = nullptr; | 112 outstanding_image_decode_.reset(); |
112 | 113 |
113 // The async decode state may have been cleared if the tracker was cleared | 114 // The async decode state may have been cleared if the tracker was cleared |
114 // before this decode could be finished. | 115 // before this decode could be finished. |
115 auto it = image_async_decode_state_.find(image_id); | 116 auto it = image_async_decode_state_.find(image_id); |
116 if (it == image_async_decode_state_.end()) { | 117 if (it == image_async_decode_state_.end()) { |
117 DCHECK_EQ(image_id_to_decode_.count(image_id), 0u); | 118 DCHECK_EQ(image_id_to_decode_.count(image_id), 0u); |
118 return; | 119 return; |
119 } | 120 } |
120 | 121 |
121 it->second = DecodePolicy::SYNC_DECODED_ONCE; | 122 it->second = DecodePolicy::SYNC_DECODED_ONCE; |
122 images_pending_invalidation_.insert(image_id); | 123 images_pending_invalidation_.insert(image_id); |
123 ScheduleNextImageDecode(); | 124 ScheduleNextImageDecode(); |
124 client_->NeedsInvalidationForCheckerImagedTiles(); | 125 client_->NeedsInvalidationForCheckerImagedTiles(); |
125 } | 126 } |
126 | 127 |
127 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, | 128 bool CheckerImageTracker::ShouldCheckerImage(const PaintImage& image, |
128 WhichTree tree) { | 129 WhichTree tree) { |
129 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", | 130 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", |
130 image->uniqueID()); | 131 image.stable_id()); |
131 | 132 |
132 if (!enable_checker_imaging_) | 133 if (!enable_checker_imaging_) |
133 return false; | 134 return false; |
134 | 135 |
| 136 PaintImage::Id image_id = image.stable_id(); |
| 137 |
135 // If the image was invalidated on the current sync tree and the tile is | 138 // If the image was invalidated on the current sync tree and the tile is |
136 // for the active tree, continue checkering it on the active tree to ensure | 139 // for the active tree, continue checkering it on the active tree to ensure |
137 // the image update is atomic for the frame. | 140 // the image update is atomic for the frame. |
138 if (invalidated_images_on_current_sync_tree_.count(image->uniqueID()) != 0 && | 141 if (invalidated_images_on_current_sync_tree_.count(image_id) != 0 && |
139 tree == WhichTree::ACTIVE_TREE) { | 142 tree == WhichTree::ACTIVE_TREE) { |
140 return true; | 143 return true; |
141 } | 144 } |
142 | 145 |
143 // If the image is pending invalidation, continue checkering it. All tiles | 146 // If the image is pending invalidation, continue checkering it. All tiles |
144 // for these images will be invalidated on the next pending tree. | 147 // for these images will be invalidated on the next pending tree. |
145 if (images_pending_invalidation_.find(image->uniqueID()) != | 148 if (images_pending_invalidation_.find(image_id) != |
146 images_pending_invalidation_.end()) { | 149 images_pending_invalidation_.end()) { |
147 return true; | 150 return true; |
148 } | 151 } |
149 | 152 |
150 ImageId image_id = image->uniqueID(); | 153 auto insert_result = |
151 auto insert_result = image_async_decode_state_.insert( | 154 image_async_decode_state_.insert(std::pair<PaintImage::Id, DecodePolicy>( |
152 std::pair<ImageId, DecodePolicy>(image_id, DecodePolicy::ASYNC)); | 155 image_id, DecodePolicy::SYNC_PERMANENT)); |
153 auto it = insert_result.first; | 156 auto it = insert_result.first; |
154 if (insert_result.second) { | 157 if (insert_result.second) { |
155 size_t size = SafeSizeOfImage(image.get()); | 158 bool can_checker_image = |
156 it->second = (size >= kMinImageSizeToCheckerBytes && | 159 image.animation_type() == PaintImage::AnimationType::STATIC && |
157 size <= image_controller_->image_cache_max_limit_bytes()) | 160 image.completion_state() == PaintImage::CompletionState::DONE; |
158 ? DecodePolicy::ASYNC | 161 if (can_checker_image) { |
159 : DecodePolicy::SYNC_PERMANENT; | 162 size_t size = SafeSizeOfImage(image.sk_image().get()); |
| 163 it->second = (size >= kMinImageSizeToCheckerBytes && |
| 164 size <= image_controller_->image_cache_max_limit_bytes()) |
| 165 ? DecodePolicy::ASYNC |
| 166 : DecodePolicy::SYNC_PERMANENT; |
| 167 } |
160 } | 168 } |
161 | 169 |
162 return it->second == DecodePolicy::ASYNC; | 170 return it->second == DecodePolicy::ASYNC; |
163 } | 171 } |
164 | 172 |
165 void CheckerImageTracker::ScheduleNextImageDecode() { | 173 void CheckerImageTracker::ScheduleNextImageDecode() { |
166 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), | 174 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), |
167 "CheckerImageTracker::ScheduleNextImageDecode"); | 175 "CheckerImageTracker::ScheduleNextImageDecode"); |
168 // We can have only one outsanding decode pending completion with the decode | 176 // We can have only one outsanding decode pending completion with the decode |
169 // service. We'll come back here when it is completed. | 177 // service. We'll come back here when it is completed. |
170 if (outstanding_image_decode_) | 178 if (outstanding_image_decode_.has_value()) |
171 return; | 179 return; |
172 | 180 |
173 while (!image_decode_queue_.empty()) { | 181 while (!image_decode_queue_.empty()) { |
174 auto candidate = std::move(image_decode_queue_.front()); | 182 auto candidate = std::move(image_decode_queue_.front()); |
175 image_decode_queue_.erase(image_decode_queue_.begin()); | 183 image_decode_queue_.erase(image_decode_queue_.begin()); |
176 | 184 |
177 // Once an image has been decoded, it can still be present in the decode | 185 // Once an image has been decoded, it can still be present in the decode |
178 // queue (duplicate entries), or while an image is still being skipped on | 186 // queue (duplicate entries), or while an image is still being skipped on |
179 // the active tree. Check if the image is still ASYNC to see if a decode is | 187 // the active tree. Check if the image is still ASYNC to see if a decode is |
180 // needed. | 188 // needed. |
181 ImageId image_id = candidate->uniqueID(); | 189 PaintImage::Id image_id = candidate.stable_id(); |
182 auto it = image_async_decode_state_.find(image_id); | 190 auto it = image_async_decode_state_.find(image_id); |
183 DCHECK(it != image_async_decode_state_.end()); | 191 DCHECK(it != image_async_decode_state_.end()); |
184 if (it->second != DecodePolicy::ASYNC) | 192 if (it->second != DecodePolicy::ASYNC) |
185 continue; | 193 continue; |
186 | 194 |
187 outstanding_image_decode_ = std::move(candidate); | 195 outstanding_image_decode_.emplace(candidate); |
188 break; | 196 break; |
189 } | 197 } |
190 | 198 |
191 // We either found an image to decode or we reached the end of the queue. If | 199 // We either found an image to decode or we reached the end of the queue. If |
192 // we couldn't find an image, we're done. | 200 // we couldn't find an image, we're done. |
193 if (!outstanding_image_decode_) { | 201 if (!outstanding_image_decode_.has_value()) { |
194 DCHECK(image_decode_queue_.empty()); | 202 DCHECK(image_decode_queue_.empty()); |
195 return; | 203 return; |
196 } | 204 } |
197 | 205 |
198 ImageId image_id = outstanding_image_decode_->uniqueID(); | 206 PaintImage::Id image_id = outstanding_image_decode_.value().stable_id(); |
199 DCHECK_EQ(image_id_to_decode_.count(image_id), 0u); | 207 DCHECK_EQ(image_id_to_decode_.count(image_id), 0u); |
200 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", | 208 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", |
201 image_id); | 209 image_id); |
202 ImageController::ImageDecodeRequestId request_id = | 210 ImageController::ImageDecodeRequestId request_id = |
203 image_controller_->QueueImageDecode( | 211 image_controller_->QueueImageDecode( |
204 outstanding_image_decode_, | 212 outstanding_image_decode_.value().sk_image(), |
205 base::Bind(&CheckerImageTracker::DidFinishImageDecode, | 213 base::Bind(&CheckerImageTracker::DidFinishImageDecode, |
206 weak_factory_.GetWeakPtr(), image_id)); | 214 weak_factory_.GetWeakPtr(), image_id)); |
207 | 215 |
208 image_id_to_decode_.emplace(image_id, base::MakeUnique<ScopedDecodeHolder>( | 216 image_id_to_decode_.emplace(image_id, base::MakeUnique<ScopedDecodeHolder>( |
209 image_controller_, request_id)); | 217 image_controller_, request_id)); |
210 } | 218 } |
211 | 219 |
212 } // namespace cc | 220 } // namespace cc |
OLD | NEW |