Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: cc/tiles/checker_image_tracker.cc

Issue 2928433003: cc: Add scaling for checkered images. (Closed)
Patch Set: fixd tests Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 83
84 if (can_clear_decode_policy_tracking) { 84 if (can_clear_decode_policy_tracking) {
85 image_async_decode_state_.clear(); 85 image_async_decode_state_.clear();
86 } else { 86 } else {
87 // If we can't clear the decode policy, we need to make sure we still 87 // If we can't clear the decode policy, we need to make sure we still
88 // re-decode and checker images that were pending invalidation. 88 // re-decode and checker images that were pending invalidation.
89 for (auto image_id : images_pending_invalidation_) { 89 for (auto image_id : images_pending_invalidation_) {
90 auto it = image_async_decode_state_.find(image_id); 90 auto it = image_async_decode_state_.find(image_id);
91 91
92 DCHECK(it != image_async_decode_state_.end()); 92 DCHECK(it != image_async_decode_state_.end());
93 DCHECK_EQ(it->second, DecodePolicy::SYNC_DECODED_ONCE); 93 DCHECK_EQ(it->second.policy, DecodePolicy::SYNC_DECODED_ONCE);
94 94
95 it->second = DecodePolicy::ASYNC; 95 it->second.policy = DecodePolicy::ASYNC;
96 } 96 }
97 } 97 }
98 images_pending_invalidation_.clear(); 98 images_pending_invalidation_.clear();
99 } 99 }
100 100
101 void CheckerImageTracker::DidFinishImageDecode( 101 void CheckerImageTracker::DidFinishImageDecode(
102 PaintImage::Id image_id, 102 PaintImage::Id image_id,
103 ImageController::ImageDecodeRequestId request_id, 103 ImageController::ImageDecodeRequestId request_id,
104 ImageController::ImageDecodeResult result) { 104 ImageController::ImageDecodeResult result) {
105 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 105 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
106 "CheckerImageTracker::DidFinishImageDecode"); 106 "CheckerImageTracker::DidFinishImageDecode");
107 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", 107 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode",
108 image_id); 108 image_id);
109 109
110 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result); 110 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result);
111 DCHECK_EQ(outstanding_image_decode_.value().stable_id(), image_id); 111 DCHECK_EQ(outstanding_image_decode_.value().stable_id(), image_id);
112 outstanding_image_decode_.reset(); 112 outstanding_image_decode_.reset();
113 113
114 // 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
115 // before this decode could be finished. 115 // before this decode could be finished.
116 auto it = image_async_decode_state_.find(image_id); 116 auto it = image_async_decode_state_.find(image_id);
117 if (it == image_async_decode_state_.end()) { 117 if (it == image_async_decode_state_.end()) {
118 DCHECK_EQ(image_id_to_decode_.count(image_id), 0u); 118 DCHECK_EQ(image_id_to_decode_.count(image_id), 0u);
119 return; 119 return;
120 } 120 }
121 121
122 it->second = DecodePolicy::SYNC_DECODED_ONCE; 122 it->second.policy = DecodePolicy::SYNC_DECODED_ONCE;
123 images_pending_invalidation_.insert(image_id); 123 images_pending_invalidation_.insert(image_id);
124 ScheduleNextImageDecode(); 124 ScheduleNextImageDecode();
125 client_->NeedsInvalidationForCheckerImagedTiles(); 125 client_->NeedsInvalidationForCheckerImagedTiles();
126 } 126 }
127 127
128 bool CheckerImageTracker::ShouldCheckerImage(const PaintImage& image, 128 bool CheckerImageTracker::ShouldCheckerImage(const DrawImage& draw_image,
129 WhichTree tree) { 129 WhichTree tree) {
130 const PaintImage& image = draw_image.paint_image();
131 PaintImage::Id image_id = image.stable_id();
130 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", 132 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id",
131 image.stable_id()); 133 image_id);
132 134
133 if (!enable_checker_imaging_) 135 if (!enable_checker_imaging_)
134 return false; 136 return false;
135 137
136 PaintImage::Id image_id = image.stable_id();
137
138 // 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
139 // 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
140 // the image update is atomic for the frame. 140 // the image update is atomic for the frame.
141 if (invalidated_images_on_current_sync_tree_.count(image_id) != 0 && 141 if (invalidated_images_on_current_sync_tree_.count(image_id) != 0 &&
142 tree == WhichTree::ACTIVE_TREE) { 142 tree == WhichTree::ACTIVE_TREE) {
143 return true; 143 return true;
144 } 144 }
145 145
146 // If the image is pending invalidation, continue checkering it. All tiles 146 // If the image is pending invalidation, continue checkering it. All tiles
147 // for these images will be invalidated on the next pending tree. 147 // for these images will be invalidated on the next pending tree.
148 if (images_pending_invalidation_.find(image_id) != 148 if (images_pending_invalidation_.find(image_id) !=
149 images_pending_invalidation_.end()) { 149 images_pending_invalidation_.end()) {
150 return true; 150 return true;
151 } 151 }
152 152
153 auto insert_result = 153 auto insert_result = image_async_decode_state_.insert(
154 image_async_decode_state_.insert(std::pair<PaintImage::Id, DecodePolicy>( 154 std::pair<PaintImage::Id, DecodeState>(image_id, DecodeState()));
155 image_id, DecodePolicy::SYNC_PERMANENT));
156 auto it = insert_result.first; 155 auto it = insert_result.first;
157 if (insert_result.second) { 156 if (insert_result.second) {
158 bool can_checker_image = 157 bool complete =
159 image.animation_type() == PaintImage::AnimationType::STATIC &&
160 image.completion_state() == PaintImage::CompletionState::DONE; 158 image.completion_state() == PaintImage::CompletionState::DONE;
161 if (can_checker_image) { 159 bool static_image =
160 image.animation_type() == PaintImage::AnimationType::STATIC;
161 // Only checker images that are static and completely loaded.
162 if (complete && static_image) {
162 size_t size = SafeSizeOfImage(image.sk_image().get()); 163 size_t size = SafeSizeOfImage(image.sk_image().get());
163 it->second = (size >= kMinImageSizeToCheckerBytes && 164 bool too_small = size < kMinImageSizeToCheckerBytes;
164 size <= image_controller_->image_cache_max_limit_bytes()) 165 bool too_large = size > image_controller_->image_cache_max_limit_bytes();
165 ? DecodePolicy::ASYNC 166 it->second.policy = (too_small || too_large)
ericrk 2017/06/06 22:39:51 The policy already defaults to SYNC_PERMANENT, and
Khushal 2017/06/07 00:43:31 How does it look now? I broke the size part sepera
166 : DecodePolicy::SYNC_PERMANENT; 167 ? DecodePolicy::SYNC_PERMANENT
168 : DecodePolicy::ASYNC;
169 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
170 "CheckerImageTracker::CheckerImagingDecision", "too_small",
171 too_small, "too_large", too_large);
172 } else {
173 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
174 "CheckerImageTracker::CanNotChecker", "complete", complete,
175 "static", static_image);
ericrk 2017/06/06 22:39:51 nit: The naming of these trace values seems a bit
Khushal 2017/06/07 00:43:31 You're right. Its because I went to look for TRACE
167 } 176 }
168 } 177 }
169 178
170 return it->second == DecodePolicy::ASYNC; 179 // Update the decode state from the latest image we have seen. Note that it
180 // is not necessary to perform this in the early out cases above since in
181 // each of those cases the image has already been decoded.
182 UpdateDecodeState(draw_image, image_id, &it->second);
183
184 return it->second.policy == DecodePolicy::ASYNC;
185 }
186
187 void CheckerImageTracker::UpdateDecodeState(const DrawImage& draw_image,
188 PaintImage::Id paint_image_id,
189 DecodeState* decode_state) {
190 // If the policy is not async then either we decoded this image already or
191 // we decided not to ever checker it.
192 if (decode_state->policy != DecodePolicy::ASYNC)
193 return;
194
195 // If the decode is already in flight, then we will have to live with what we
196 // have now.
197 if (outstanding_image_decode_.has_value() &&
198 outstanding_image_decode_.value().stable_id() == paint_image_id) {
199 return;
200 }
201
202 // Choose the max scale, going up till the original decode size, and filter
203 // quality. This keeps the memory usage to the minimum possible while still
204 // increasing the possibility of getting a cache hit.
205 decode_state->scale.fWidth = std::min(
ericrk 2017/06/06 22:39:51 Do we really not want to scale up at this point? T
Khushal 2017/06/07 00:43:31 I don't think the memory impact would be much. Now
206 1.0f, std::max(decode_state->scale.fWidth, draw_image.scale().fWidth));
207 decode_state->scale.fHeight = std::min(
ericrk 2017/06/06 22:39:51 Is this ever called with a non-default DecodeState
Khushal 2017/06/07 00:43:31 It will be called with a non-default state if we s
208 1.0f, std::max(decode_state->scale.fHeight, draw_image.scale().fHeight));
209 decode_state->filter_quality =
210 std::max(decode_state->filter_quality, draw_image.filter_quality());
211 decode_state->color_space = draw_image.target_color_space();
171 } 212 }
172 213
173 void CheckerImageTracker::ScheduleNextImageDecode() { 214 void CheckerImageTracker::ScheduleNextImageDecode() {
174 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 215 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
175 "CheckerImageTracker::ScheduleNextImageDecode"); 216 "CheckerImageTracker::ScheduleNextImageDecode");
176 // We can have only one outsanding decode pending completion with the decode 217 // We can have only one outsanding decode pending completion with the decode
177 // service. We'll come back here when it is completed. 218 // service. We'll come back here when it is completed.
178 if (outstanding_image_decode_.has_value()) 219 if (outstanding_image_decode_.has_value())
179 return; 220 return;
180 221
222 DrawImage draw_image;
181 while (!image_decode_queue_.empty()) { 223 while (!image_decode_queue_.empty()) {
182 auto candidate = std::move(image_decode_queue_.front()); 224 auto candidate = std::move(image_decode_queue_.front());
183 image_decode_queue_.erase(image_decode_queue_.begin()); 225 image_decode_queue_.erase(image_decode_queue_.begin());
184 226
185 // Once an image has been decoded, it can still be present in the decode 227 // Once an image has been decoded, it can still be present in the decode
186 // queue (duplicate entries), or while an image is still being skipped on 228 // queue (duplicate entries), or while an image is still being skipped on
187 // the active tree. Check if the image is still ASYNC to see if a decode is 229 // the active tree. Check if the image is still ASYNC to see if a decode is
188 // needed. 230 // needed.
189 PaintImage::Id image_id = candidate.stable_id(); 231 PaintImage::Id image_id = candidate.stable_id();
190 auto it = image_async_decode_state_.find(image_id); 232 auto it = image_async_decode_state_.find(image_id);
191 DCHECK(it != image_async_decode_state_.end()); 233 DCHECK(it != image_async_decode_state_.end());
192 if (it->second != DecodePolicy::ASYNC) 234 if (it->second.policy != DecodePolicy::ASYNC)
193 continue; 235 continue;
194 236
237 draw_image = DrawImage(candidate, candidate.sk_image()->bounds(),
238 it->second.filter_quality,
239 SkMatrix::MakeScale(it->second.scale.width(),
240 it->second.scale.height()),
241 it->second.color_space);
195 outstanding_image_decode_.emplace(candidate); 242 outstanding_image_decode_.emplace(candidate);
196 break; 243 break;
197 } 244 }
198 245
199 // We either found an image to decode or we reached the end of the queue. If 246 // We either found an image to decode or we reached the end of the queue. If
200 // we couldn't find an image, we're done. 247 // we couldn't find an image, we're done.
201 if (!outstanding_image_decode_.has_value()) { 248 if (!outstanding_image_decode_.has_value()) {
202 DCHECK(image_decode_queue_.empty()); 249 DCHECK(image_decode_queue_.empty());
203 return; 250 return;
204 } 251 }
205 252
206 PaintImage::Id image_id = outstanding_image_decode_.value().stable_id(); 253 PaintImage::Id image_id = outstanding_image_decode_.value().stable_id();
207 DCHECK_EQ(image_id_to_decode_.count(image_id), 0u); 254 DCHECK_EQ(image_id_to_decode_.count(image_id), 0u);
208 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", 255 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode",
209 image_id); 256 image_id);
210 ImageController::ImageDecodeRequestId request_id = 257 ImageController::ImageDecodeRequestId request_id =
211 image_controller_->QueueImageDecode( 258 image_controller_->QueueImageDecode(
212 outstanding_image_decode_.value().sk_image(), 259 draw_image, base::Bind(&CheckerImageTracker::DidFinishImageDecode,
213 base::Bind(&CheckerImageTracker::DidFinishImageDecode, 260 weak_factory_.GetWeakPtr(), image_id));
214 weak_factory_.GetWeakPtr(), image_id));
215 261
216 image_id_to_decode_.emplace(image_id, base::MakeUnique<ScopedDecodeHolder>( 262 image_id_to_decode_.emplace(image_id, base::MakeUnique<ScopedDecodeHolder>(
217 image_controller_, request_id)); 263 image_controller_, request_id));
218 } 264 }
219 265
220 } // namespace cc 266 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698