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

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

Issue 2703633004: cc: Make image controller return a status with the callback. (Closed)
Patch Set: update Created 3 years, 10 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/image_controller.h" 5 #include "cc/tiles/image_controller.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/task_scheduler/post_task.h" 8 #include "base/task_scheduler/post_task.h"
9 #include "base/task_scheduler/task_traits.h" 9 #include "base/task_scheduler/task_traits.h"
10 #include "base/threading/thread_restrictions.h" 10 #include "base/threading/thread_restrictions.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 // The task (if one exists) would have run already, so we just need to 80 // The task (if one exists) would have run already, so we just need to
81 // complete it. 81 // complete it.
82 if (request.task) 82 if (request.task)
83 request.task->DidComplete(); 83 request.task->DidComplete();
84 84
85 // Issue the callback, and unref the image immediately. This is so that any 85 // Issue the callback, and unref the image immediately. This is so that any
86 // code waiting on the callback can proceed, although we're breaking the 86 // code waiting on the callback can proceed, although we're breaking the
87 // promise of having this image decoded. This is unfortunate, but it seems 87 // promise of having this image decoded. This is unfortunate, but it seems
88 // like the least complexity to process an image decode controller becoming 88 // like the least complexity to process an image decode controller becoming
89 // nullptr. 89 // nullptr.
90 request.callback.Run(id); 90 // TODO(vmpstr): We can move these back to |image_decode_queue_| instead
91 // and defer completion until we get a new cache and process the request
92 // again. crbug.com/693692.
93 request.callback.Run(id, ImageDecodeResult::FAILURE);
91 if (request.need_unref) 94 if (request.need_unref)
92 cache_->UnrefImage(request.draw_image); 95 cache_->UnrefImage(request.draw_image);
93 } 96 }
94 requests_needing_completion_.clear(); 97 requests_needing_completion_.clear();
95 98
96 // Finally, complete all of the tasks that never started running. This is 99 // Finally, complete all of the tasks that never started running. This is
97 // similar to the |requests_needing_completion_|, but happens at a different 100 // similar to the |requests_needing_completion_|, but happens at a different
98 // stage in the pipeline. 101 // stage in the pipeline.
99 for (auto& request_pair : image_decode_queue_) { 102 for (auto& request_pair : image_decode_queue_) {
100 ImageDecodeRequestId id = request_pair.first; 103 ImageDecodeRequestId id = request_pair.first;
101 ImageDecodeRequest& request = request_pair.second; 104 ImageDecodeRequest& request = request_pair.second;
102 105
103 if (request.task) { 106 if (request.task) {
104 // This task may have run via a different request, so only cancel it if 107 // This task may have run via a different request, so only cancel it if
105 // it's "new". That is, the same task could have been referenced by 108 // it's "new". That is, the same task could have been referenced by
106 // several different image deque requests for the same image. 109 // several different image deque requests for the same image.
107 if (request.task->state().IsNew()) 110 if (request.task->state().IsNew())
108 request.task->state().DidCancel(); 111 request.task->state().DidCancel();
109 request.task->DidComplete(); 112 request.task->DidComplete();
110 } 113 }
111 // Run the callback and unref the image. 114 // Run the callback and unref the image.
112 request.callback.Run(id); 115 // TODO(vmpstr): We can regenerate the tasks for the new cache if we get
116 // one. crbug.com/693692.
117 request.callback.Run(id, ImageDecodeResult::FAILURE);
113 cache_->UnrefImage(request.draw_image); 118 cache_->UnrefImage(request.draw_image);
114 } 119 }
115 image_decode_queue_.clear(); 120 image_decode_queue_.clear();
116 } 121 }
117 122
118 void ImageController::SetImageDecodeCache(ImageDecodeCache* cache) { 123 void ImageController::SetImageDecodeCache(ImageDecodeCache* cache) {
119 if (!cache) { 124 if (!cache) {
120 SetPredecodeImages(std::vector<DrawImage>(), 125 SetPredecodeImages(std::vector<DrawImage>(),
121 ImageDecodeCache::TracingInfo()); 126 ImageDecodeCache::TracingInfo());
122 StopWorkerTasks(); 127 StopWorkerTasks();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 ImageController::ImageDecodeRequestId ImageController::QueueImageDecode( 171 ImageController::ImageDecodeRequestId ImageController::QueueImageDecode(
167 sk_sp<const SkImage> image, 172 sk_sp<const SkImage> image,
168 const ImageDecodedCallback& callback) { 173 const ImageDecodedCallback& callback) {
169 // We must not receive any image requests if we have no worker. 174 // We must not receive any image requests if we have no worker.
170 CHECK(worker_task_runner_); 175 CHECK(worker_task_runner_);
171 176
172 // Generate the next id. 177 // Generate the next id.
173 ImageDecodeRequestId id = s_next_image_decode_queue_id_++; 178 ImageDecodeRequestId id = s_next_image_decode_queue_id_++;
174 179
175 DCHECK(image); 180 DCHECK(image);
181 bool is_image_lazy = image->isLazyGenerated();
176 auto image_bounds = image->bounds(); 182 auto image_bounds = image->bounds();
177 DrawImage draw_image(std::move(image), image_bounds, kNone_SkFilterQuality, 183 DrawImage draw_image(std::move(image), image_bounds, kNone_SkFilterQuality,
178 SkMatrix::I()); 184 SkMatrix::I());
179 185
180 // Get the tasks for this decode. 186 // Get the tasks for this decode.
181 scoped_refptr<TileTask> task; 187 scoped_refptr<TileTask> task;
182 bool need_unref = 188 bool need_unref = false;
183 cache_->GetOutOfRasterDecodeTaskForImageAndRef(draw_image, &task); 189 if (is_image_lazy) {
190 need_unref =
191 cache_->GetOutOfRasterDecodeTaskForImageAndRef(draw_image, &task);
192 }
184 // If we don't need to unref this, we don't actually have a task. 193 // If we don't need to unref this, we don't actually have a task.
185 DCHECK(need_unref || !task); 194 DCHECK(need_unref || !task);
186 195
187 // Schedule the task and signal that there is more work. 196 // Schedule the task and signal that there is more work.
188 base::AutoLock hold(lock_); 197 base::AutoLock hold(lock_);
189 image_decode_queue_[id] = 198 image_decode_queue_[id] =
190 ImageDecodeRequest(id, draw_image, callback, std::move(task), need_unref); 199 ImageDecodeRequest(id, draw_image, callback, std::move(task), need_unref);
191 200
192 // If this is the only image decode request, schedule a task to run. 201 // If this is the only image decode request, schedule a task to run.
193 // Otherwise, the task will be scheduled in the previou task's completion. 202 // Otherwise, the task will be scheduled in the previou task's completion.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 decode.task->RunOnWorkerThread(); 259 decode.task->RunOnWorkerThread();
251 decode.task->state().DidFinish(); 260 decode.task->state().DidFinish();
252 } 261 }
253 origin_task_runner_->PostTask( 262 origin_task_runner_->PostTask(
254 FROM_HERE, base::Bind(&ImageController::ImageDecodeCompleted, 263 FROM_HERE, base::Bind(&ImageController::ImageDecodeCompleted,
255 weak_ptr_factory_.GetWeakPtr(), decode.id)); 264 weak_ptr_factory_.GetWeakPtr(), decode.id));
256 } 265 }
257 266
258 void ImageController::ImageDecodeCompleted(ImageDecodeRequestId id) { 267 void ImageController::ImageDecodeCompleted(ImageDecodeRequestId id) {
259 ImageDecodedCallback callback; 268 ImageDecodedCallback callback;
269 ImageDecodeResult result = ImageDecodeResult::SUCCESS;
260 { 270 {
261 base::AutoLock hold(lock_); 271 base::AutoLock hold(lock_);
262 272
263 auto request_it = requests_needing_completion_.find(id); 273 auto request_it = requests_needing_completion_.find(id);
264 DCHECK(request_it != requests_needing_completion_.end()); 274 DCHECK(request_it != requests_needing_completion_.end());
265 id = request_it->first; 275 id = request_it->first;
266 ImageDecodeRequest& request = request_it->second; 276 ImageDecodeRequest& request = request_it->second;
267 277
278 // First, Determine the status of the decode. This has to happen here, since
279 // we conditionally move from the draw image below.
280 // Also note that if we don't need an unref for a lazy decoded images, it
281 // implies that we never attempted the decode. Some of the reasons for this
282 // would be that the image is of an empty size, or if the image doesn't fit
283 // into memory. In all cases, this implies that the decode was a failure.
Khushal 2017/02/17 23:56:38 What if we tried to decode the image and it was co
vmpstr 2017/02/24 02:43:49 As discussed offline, I think this is fine, since
284 if (!request.draw_image.image()->isLazyGenerated())
Khushal 2017/02/17 23:56:38 Could you add a ImageControllerTest for this?
vmpstr 2017/02/24 02:43:49 Done.
285 result = ImageDecodeResult::DECODE_NOT_REQUIRED;
286 else if (!request.need_unref)
287 result = ImageDecodeResult::FAILURE;
288 else
289 result = ImageDecodeResult::SUCCESS;
290
268 // If we need to unref this decode, then we have to put it into the locked 291 // If we need to unref this decode, then we have to put it into the locked
269 // images vector. 292 // images vector.
270 if (request.need_unref) 293 if (request.need_unref)
271 requested_locked_images_[id] = std::move(request.draw_image); 294 requested_locked_images_[id] = std::move(request.draw_image);
272 295
273 // If we have a task that isn't completed yet, we need to complete it. 296 // If we have a task that isn't completed yet, we need to complete it.
274 if (request.task && !request.task->HasCompleted()) { 297 if (request.task && !request.task->HasCompleted()) {
275 request.task->OnTaskCompleted(); 298 request.task->OnTaskCompleted();
276 request.task->DidComplete(); 299 request.task->DidComplete();
277 } 300 }
301
278 // Finally, save the callback so we can run it without the lock, and erase 302 // Finally, save the callback so we can run it without the lock, and erase
279 // the request from |requests_needing_completion_|. 303 // the request from |requests_needing_completion_|.
280 callback = std::move(request.callback); 304 callback = std::move(request.callback);
281 requests_needing_completion_.erase(request_it); 305 requests_needing_completion_.erase(request_it);
282 } 306 }
283 307
284 // Post another task to run. 308 // Post another task to run.
285 worker_task_runner_->PostTask( 309 worker_task_runner_->PostTask(
286 FROM_HERE, 310 FROM_HERE,
287 base::Bind(&ImageController::ProcessNextImageDecodeOnWorkerThread, 311 base::Bind(&ImageController::ProcessNextImageDecodeOnWorkerThread,
288 base::Unretained(this))); 312 base::Unretained(this)));
289 313
290 // Finally run the requested callback. 314 // Finally run the requested callback.
291 callback.Run(id); 315 callback.Run(id, result);
292 } 316 }
293 317
294 ImageController::ImageDecodeRequest::ImageDecodeRequest() = default; 318 ImageController::ImageDecodeRequest::ImageDecodeRequest() = default;
295 ImageController::ImageDecodeRequest::ImageDecodeRequest( 319 ImageController::ImageDecodeRequest::ImageDecodeRequest(
296 ImageDecodeRequestId id, 320 ImageDecodeRequestId id,
297 const DrawImage& draw_image, 321 const DrawImage& draw_image,
298 const ImageDecodedCallback& callback, 322 const ImageDecodedCallback& callback,
299 scoped_refptr<TileTask> task, 323 scoped_refptr<TileTask> task,
300 bool need_unref) 324 bool need_unref)
301 : id(id), 325 : id(id),
302 draw_image(draw_image), 326 draw_image(draw_image),
303 callback(callback), 327 callback(callback),
304 task(std::move(task)), 328 task(std::move(task)),
305 need_unref(need_unref) {} 329 need_unref(need_unref) {}
306 ImageController::ImageDecodeRequest::ImageDecodeRequest( 330 ImageController::ImageDecodeRequest::ImageDecodeRequest(
307 ImageDecodeRequest&& other) = default; 331 ImageDecodeRequest&& other) = default;
308 ImageController::ImageDecodeRequest::ImageDecodeRequest( 332 ImageController::ImageDecodeRequest::ImageDecodeRequest(
309 const ImageDecodeRequest& other) = default; 333 const ImageDecodeRequest& other) = default;
310 ImageController::ImageDecodeRequest::~ImageDecodeRequest() = default; 334 ImageController::ImageDecodeRequest::~ImageDecodeRequest() = default;
311 335
312 ImageController::ImageDecodeRequest& ImageController::ImageDecodeRequest:: 336 ImageController::ImageDecodeRequest& ImageController::ImageDecodeRequest::
313 operator=(ImageDecodeRequest&& other) = default; 337 operator=(ImageDecodeRequest&& other) = default;
314 ImageController::ImageDecodeRequest& ImageController::ImageDecodeRequest:: 338 ImageController::ImageDecodeRequest& ImageController::ImageDecodeRequest::
315 operator=(const ImageDecodeRequest& other) = default; 339 operator=(const ImageDecodeRequest& other) = default;
316 340
317 } // namespace cc 341 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698