Revert 264226 "Reduce dependency of TiclInvalidationService on P..."
[chromium-blink-merge.git] / cc / resources / pixel_buffer_raster_worker_pool.cc
blob4c8ca7b6221a76067599b8e57d85e5f8fb7819cb
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/resources/pixel_buffer_raster_worker_pool.h"
7 #include <algorithm>
9 #include "base/containers/stack_container.h"
10 #include "base/debug/trace_event.h"
11 #include "cc/debug/traced_value.h"
12 #include "cc/resources/resource.h"
14 namespace cc {
15 namespace {
17 const int kCheckForCompletedRasterTasksDelayMs = 6;
19 const size_t kMaxScheduledRasterTasks = 48;
21 typedef base::StackVector<RasterTask*, kMaxScheduledRasterTasks>
22 RasterTaskVector;
24 } // namespace
26 // static
27 scoped_ptr<RasterWorkerPool> PixelBufferRasterWorkerPool::Create(
28 base::SequencedTaskRunner* task_runner,
29 TaskGraphRunner* task_graph_runner,
30 ResourceProvider* resource_provider,
31 size_t max_transfer_buffer_usage_bytes) {
32 return make_scoped_ptr<RasterWorkerPool>(
33 new PixelBufferRasterWorkerPool(task_runner,
34 task_graph_runner,
35 resource_provider,
36 max_transfer_buffer_usage_bytes));
39 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
40 base::SequencedTaskRunner* task_runner,
41 TaskGraphRunner* task_graph_runner,
42 ResourceProvider* resource_provider,
43 size_t max_transfer_buffer_usage_bytes)
44 : task_runner_(task_runner),
45 task_graph_runner_(task_graph_runner),
46 namespace_token_(task_graph_runner->GetNamespaceToken()),
47 resource_provider_(resource_provider),
48 shutdown_(false),
49 scheduled_raster_task_count_(0u),
50 raster_tasks_required_for_activation_count_(0u),
51 bytes_pending_upload_(0u),
52 max_bytes_pending_upload_(max_transfer_buffer_usage_bytes),
53 has_performed_uploads_since_last_flush_(false),
54 check_for_completed_raster_tasks_pending_(false),
55 should_notify_client_if_no_tasks_are_pending_(false),
56 should_notify_client_if_no_tasks_required_for_activation_are_pending_(
57 false),
58 raster_finished_task_pending_(false),
59 raster_required_for_activation_finished_task_pending_(false),
60 raster_finished_weak_ptr_factory_(this),
61 weak_ptr_factory_(this) {}
63 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
64 DCHECK(!check_for_completed_raster_tasks_pending_);
65 DCHECK_EQ(0u, raster_task_states_.size());
66 DCHECK_EQ(0u, raster_tasks_with_pending_upload_.size());
67 DCHECK_EQ(0u, completed_raster_tasks_.size());
68 DCHECK_EQ(0u, completed_image_decode_tasks_.size());
69 DCHECK_EQ(0u, raster_tasks_required_for_activation_count_);
72 Rasterizer* PixelBufferRasterWorkerPool::AsRasterizer() { return this; }
74 void PixelBufferRasterWorkerPool::SetClient(RasterizerClient* client) {
75 client_ = client;
78 void PixelBufferRasterWorkerPool::Shutdown() {
79 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::Shutdown");
81 shutdown_ = true;
83 TaskGraph empty;
84 task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
85 task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
87 CheckForCompletedRasterizerTasks();
88 CheckForCompletedUploads();
90 check_for_completed_raster_tasks_pending_ = false;
92 for (RasterTaskState::Vector::iterator it = raster_task_states_.begin();
93 it != raster_task_states_.end();
94 ++it) {
95 RasterTaskState& state = *it;
97 // All unscheduled tasks need to be canceled.
98 if (state.type == RasterTaskState::UNSCHEDULED) {
99 completed_raster_tasks_.push_back(state.task);
100 state.type = RasterTaskState::COMPLETED;
103 DCHECK_EQ(completed_raster_tasks_.size(), raster_task_states_.size());
106 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
107 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
109 DCHECK_EQ(queue->required_for_activation_count,
110 static_cast<size_t>(
111 std::count_if(queue->items.begin(),
112 queue->items.end(),
113 RasterTaskQueue::Item::IsRequiredForActivation)));
115 if (!should_notify_client_if_no_tasks_are_pending_)
116 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
118 should_notify_client_if_no_tasks_are_pending_ = true;
119 should_notify_client_if_no_tasks_required_for_activation_are_pending_ = true;
121 raster_tasks_required_for_activation_count_ = 0u;
123 // Update raster task state and remove items from old queue.
124 for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
125 it != queue->items.end();
126 ++it) {
127 const RasterTaskQueue::Item& item = *it;
128 RasterTask* task = item.task;
130 // Remove any old items that are associated with this task. The result is
131 // that the old queue is left with all items not present in this queue,
132 // which we use below to determine what tasks need to be canceled.
133 RasterTaskQueue::Item::Vector::iterator old_it =
134 std::find_if(raster_tasks_.items.begin(),
135 raster_tasks_.items.end(),
136 RasterTaskQueue::Item::TaskComparator(task));
137 if (old_it != raster_tasks_.items.end()) {
138 std::swap(*old_it, raster_tasks_.items.back());
139 raster_tasks_.items.pop_back();
142 RasterTaskState::Vector::iterator state_it =
143 std::find_if(raster_task_states_.begin(),
144 raster_task_states_.end(),
145 RasterTaskState::TaskComparator(task));
146 if (state_it != raster_task_states_.end()) {
147 RasterTaskState& state = *state_it;
149 state.required_for_activation = item.required_for_activation;
150 // |raster_tasks_required_for_activation_count| accounts for all tasks
151 // that need to complete before we can send a "ready to activate" signal.
152 // Tasks that have already completed should not be part of this count.
153 if (state.type != RasterTaskState::COMPLETED) {
154 raster_tasks_required_for_activation_count_ +=
155 item.required_for_activation;
157 continue;
160 DCHECK(!task->HasBeenScheduled());
161 raster_task_states_.push_back(
162 RasterTaskState(task, item.required_for_activation));
163 raster_tasks_required_for_activation_count_ += item.required_for_activation;
166 // Determine what tasks in old queue need to be canceled.
167 for (RasterTaskQueue::Item::Vector::const_iterator it =
168 raster_tasks_.items.begin();
169 it != raster_tasks_.items.end();
170 ++it) {
171 const RasterTaskQueue::Item& item = *it;
172 RasterTask* task = item.task;
174 RasterTaskState::Vector::iterator state_it =
175 std::find_if(raster_task_states_.begin(),
176 raster_task_states_.end(),
177 RasterTaskState::TaskComparator(task));
178 // We've already processed completion if we can't find a RasterTaskState for
179 // this task.
180 if (state_it == raster_task_states_.end())
181 continue;
183 RasterTaskState& state = *state_it;
185 // Unscheduled task can be canceled.
186 if (state.type == RasterTaskState::UNSCHEDULED) {
187 DCHECK(!task->HasBeenScheduled());
188 DCHECK(std::find(completed_raster_tasks_.begin(),
189 completed_raster_tasks_.end(),
190 task) == completed_raster_tasks_.end());
191 completed_raster_tasks_.push_back(task);
192 state.type = RasterTaskState::COMPLETED;
195 // No longer required for activation.
196 state.required_for_activation = false;
199 raster_tasks_.Swap(queue);
201 // Check for completed tasks when ScheduleTasks() is called as
202 // priorities might have changed and this maximizes the number
203 // of top priority tasks that are scheduled.
204 CheckForCompletedRasterizerTasks();
205 CheckForCompletedUploads();
206 FlushUploads();
208 // Schedule new tasks.
209 ScheduleMoreTasks();
211 // Cancel any pending check for completed raster tasks and schedule
212 // another check.
213 check_for_completed_raster_tasks_time_ = base::TimeTicks();
214 ScheduleCheckForCompletedRasterTasks();
216 TRACE_EVENT_ASYNC_STEP_INTO1(
217 "cc",
218 "ScheduledTasks",
219 this,
220 StateName(),
221 "state",
222 TracedValue::FromValue(StateAsValue().release()));
225 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
226 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
228 CheckForCompletedRasterizerTasks();
229 CheckForCompletedUploads();
230 FlushUploads();
232 for (RasterizerTask::Vector::const_iterator it =
233 completed_image_decode_tasks_.begin();
234 it != completed_image_decode_tasks_.end();
235 ++it) {
236 RasterizerTask* task = it->get();
237 task->RunReplyOnOriginThread();
239 completed_image_decode_tasks_.clear();
241 for (RasterTask::Vector::const_iterator it = completed_raster_tasks_.begin();
242 it != completed_raster_tasks_.end();
243 ++it) {
244 RasterTask* task = it->get();
245 RasterTaskState::Vector::iterator state_it =
246 std::find_if(raster_task_states_.begin(),
247 raster_task_states_.end(),
248 RasterTaskState::TaskComparator(task));
249 DCHECK(state_it != raster_task_states_.end());
250 DCHECK_EQ(RasterTaskState::COMPLETED, state_it->type);
252 std::swap(*state_it, raster_task_states_.back());
253 raster_task_states_.pop_back();
255 task->RunReplyOnOriginThread();
257 completed_raster_tasks_.clear();
260 SkCanvas* PixelBufferRasterWorkerPool::AcquireCanvasForRaster(
261 RasterTask* task) {
262 DCHECK(std::find_if(raster_task_states_.begin(),
263 raster_task_states_.end(),
264 RasterTaskState::TaskComparator(task)) !=
265 raster_task_states_.end());
266 resource_provider_->AcquirePixelRasterBuffer(task->resource()->id());
267 return resource_provider_->MapPixelRasterBuffer(task->resource()->id());
270 void PixelBufferRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) {
271 DCHECK(std::find_if(raster_task_states_.begin(),
272 raster_task_states_.end(),
273 RasterTaskState::TaskComparator(task)) !=
274 raster_task_states_.end());
275 resource_provider_->ReleasePixelRasterBuffer(task->resource()->id());
278 void PixelBufferRasterWorkerPool::OnRasterFinished() {
279 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::OnRasterFinished");
281 // |should_notify_client_if_no_tasks_are_pending_| can be set to false as
282 // a result of a scheduled CheckForCompletedRasterTasks() call. No need to
283 // perform another check in that case as we've already notified the client.
284 if (!should_notify_client_if_no_tasks_are_pending_)
285 return;
286 raster_finished_task_pending_ = false;
288 // Call CheckForCompletedRasterTasks() when we've finished running all
289 // raster tasks needed since last time ScheduleTasks() was called.
290 // This reduces latency between the time when all tasks have finished
291 // running and the time when the client is notified.
292 CheckForCompletedRasterTasks();
295 void PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished() {
296 TRACE_EVENT0(
297 "cc",
298 "PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished");
300 // Analogous to OnRasterTasksFinished(), there's no need to call
301 // CheckForCompletedRasterTasks() if the client has already been notified.
302 if (!should_notify_client_if_no_tasks_required_for_activation_are_pending_)
303 return;
304 raster_required_for_activation_finished_task_pending_ = false;
306 // This reduces latency between the time when all tasks required for
307 // activation have finished running and the time when the client is
308 // notified.
309 CheckForCompletedRasterTasks();
312 void PixelBufferRasterWorkerPool::FlushUploads() {
313 if (!has_performed_uploads_since_last_flush_)
314 return;
316 resource_provider_->ShallowFlushIfSupported();
317 has_performed_uploads_since_last_flush_ = false;
320 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
321 RasterTask::Vector tasks_with_completed_uploads;
323 // First check if any have completed.
324 while (!raster_tasks_with_pending_upload_.empty()) {
325 RasterTask* task = raster_tasks_with_pending_upload_.front().get();
326 DCHECK(std::find_if(raster_task_states_.begin(),
327 raster_task_states_.end(),
328 RasterTaskState::TaskComparator(task)) !=
329 raster_task_states_.end());
330 DCHECK_EQ(RasterTaskState::UPLOADING,
331 std::find_if(raster_task_states_.begin(),
332 raster_task_states_.end(),
333 RasterTaskState::TaskComparator(task))->type);
335 // Uploads complete in the order they are issued.
336 if (!resource_provider_->DidSetPixelsComplete(task->resource()->id()))
337 break;
339 tasks_with_completed_uploads.push_back(task);
340 raster_tasks_with_pending_upload_.pop_front();
343 DCHECK(client_);
344 bool should_force_some_uploads_to_complete =
345 shutdown_ || client_->ShouldForceTasksRequiredForActivationToComplete();
347 if (should_force_some_uploads_to_complete) {
348 RasterTask::Vector tasks_with_uploads_to_force;
349 RasterTaskDeque::iterator it = raster_tasks_with_pending_upload_.begin();
350 while (it != raster_tasks_with_pending_upload_.end()) {
351 RasterTask* task = it->get();
352 RasterTaskState::Vector::const_iterator state_it =
353 std::find_if(raster_task_states_.begin(),
354 raster_task_states_.end(),
355 RasterTaskState::TaskComparator(task));
356 DCHECK(state_it != raster_task_states_.end());
357 const RasterTaskState& state = *state_it;
359 // Force all uploads required for activation to complete.
360 // During shutdown, force all pending uploads to complete.
361 if (shutdown_ || state.required_for_activation) {
362 tasks_with_uploads_to_force.push_back(task);
363 tasks_with_completed_uploads.push_back(task);
364 it = raster_tasks_with_pending_upload_.erase(it);
365 continue;
368 ++it;
371 // Force uploads in reverse order. Since forcing can cause a wait on
372 // all previous uploads, we would rather wait only once downstream.
373 for (RasterTask::Vector::reverse_iterator it =
374 tasks_with_uploads_to_force.rbegin();
375 it != tasks_with_uploads_to_force.rend();
376 ++it) {
377 RasterTask* task = it->get();
379 resource_provider_->ForceSetPixelsToComplete(task->resource()->id());
380 has_performed_uploads_since_last_flush_ = true;
384 // Release shared memory and move tasks with completed uploads
385 // to |completed_raster_tasks_|.
386 for (RasterTask::Vector::const_iterator it =
387 tasks_with_completed_uploads.begin();
388 it != tasks_with_completed_uploads.end();
389 ++it) {
390 RasterTask* task = it->get();
391 RasterTaskState::Vector::iterator state_it =
392 std::find_if(raster_task_states_.begin(),
393 raster_task_states_.end(),
394 RasterTaskState::TaskComparator(task));
395 DCHECK(state_it != raster_task_states_.end());
396 RasterTaskState& state = *state_it;
398 bytes_pending_upload_ -= task->resource()->bytes();
400 task->WillComplete();
401 task->CompleteOnOriginThread(this);
402 task->DidComplete();
404 // Async set pixels commands are not necessarily processed in-sequence with
405 // drawing commands. Read lock fences are required to ensure that async
406 // commands don't access the resource while used for drawing.
407 resource_provider_->EnableReadLockFences(task->resource()->id(), true);
409 DCHECK(std::find(completed_raster_tasks_.begin(),
410 completed_raster_tasks_.end(),
411 task) == completed_raster_tasks_.end());
412 completed_raster_tasks_.push_back(task);
413 state.type = RasterTaskState::COMPLETED;
414 DCHECK_LE(static_cast<size_t>(state.required_for_activation),
415 raster_tasks_required_for_activation_count_);
416 raster_tasks_required_for_activation_count_ -=
417 state.required_for_activation;
421 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() {
422 base::TimeDelta delay =
423 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs);
424 if (check_for_completed_raster_tasks_time_.is_null())
425 check_for_completed_raster_tasks_time_ = base::TimeTicks::Now() + delay;
427 if (check_for_completed_raster_tasks_pending_)
428 return;
430 task_runner_->PostDelayedTask(
431 FROM_HERE,
432 base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks,
433 weak_ptr_factory_.GetWeakPtr()),
434 delay);
435 check_for_completed_raster_tasks_pending_ = true;
438 void PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks() {
439 if (check_for_completed_raster_tasks_time_.is_null()) {
440 check_for_completed_raster_tasks_pending_ = false;
441 return;
444 base::TimeDelta delay =
445 check_for_completed_raster_tasks_time_ - base::TimeTicks::Now();
447 // Post another delayed task if it is not yet time to check for completed
448 // raster tasks.
449 if (delay > base::TimeDelta()) {
450 task_runner_->PostDelayedTask(
451 FROM_HERE,
452 base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks,
453 weak_ptr_factory_.GetWeakPtr()),
454 delay);
455 return;
458 check_for_completed_raster_tasks_pending_ = false;
459 CheckForCompletedRasterTasks();
462 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
463 TRACE_EVENT0("cc",
464 "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
466 DCHECK(should_notify_client_if_no_tasks_are_pending_);
467 check_for_completed_raster_tasks_time_ = base::TimeTicks();
469 CheckForCompletedRasterizerTasks();
470 CheckForCompletedUploads();
471 FlushUploads();
473 // Determine what client notifications to generate.
474 bool will_notify_client_that_no_tasks_required_for_activation_are_pending =
475 (should_notify_client_if_no_tasks_required_for_activation_are_pending_ &&
476 !raster_required_for_activation_finished_task_pending_ &&
477 !HasPendingTasksRequiredForActivation());
478 bool will_notify_client_that_no_tasks_are_pending =
479 (should_notify_client_if_no_tasks_are_pending_ &&
480 !raster_required_for_activation_finished_task_pending_ &&
481 !raster_finished_task_pending_ && !HasPendingTasks());
483 // Adjust the need to generate notifications before scheduling more tasks.
484 should_notify_client_if_no_tasks_required_for_activation_are_pending_ &=
485 !will_notify_client_that_no_tasks_required_for_activation_are_pending;
486 should_notify_client_if_no_tasks_are_pending_ &=
487 !will_notify_client_that_no_tasks_are_pending;
489 scheduled_raster_task_count_ = 0;
490 if (PendingRasterTaskCount())
491 ScheduleMoreTasks();
493 TRACE_EVENT_ASYNC_STEP_INTO1(
494 "cc",
495 "ScheduledTasks",
496 this,
497 StateName(),
498 "state",
499 TracedValue::FromValue(StateAsValue().release()));
501 // Schedule another check for completed raster tasks while there are
502 // pending raster tasks or pending uploads.
503 if (HasPendingTasks())
504 ScheduleCheckForCompletedRasterTasks();
506 // Generate client notifications.
507 if (will_notify_client_that_no_tasks_required_for_activation_are_pending) {
508 DCHECK(!HasPendingTasksRequiredForActivation());
509 client_->DidFinishRunningTasksRequiredForActivation();
511 if (will_notify_client_that_no_tasks_are_pending) {
512 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
513 DCHECK(!HasPendingTasksRequiredForActivation());
514 client_->DidFinishRunningTasks();
518 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
519 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
521 RasterTaskVector tasks;
522 RasterTaskVector tasks_required_for_activation;
524 unsigned priority = kRasterTaskPriorityBase;
526 graph_.Reset();
528 size_t bytes_pending_upload = bytes_pending_upload_;
529 bool did_throttle_raster_tasks = false;
530 bool did_throttle_raster_tasks_required_for_activation = false;
532 for (RasterTaskQueue::Item::Vector::const_iterator it =
533 raster_tasks_.items.begin();
534 it != raster_tasks_.items.end();
535 ++it) {
536 const RasterTaskQueue::Item& item = *it;
537 RasterTask* task = item.task;
539 // |raster_task_states_| contains the state of all tasks that we have not
540 // yet run reply callbacks for.
541 RasterTaskState::Vector::iterator state_it =
542 std::find_if(raster_task_states_.begin(),
543 raster_task_states_.end(),
544 RasterTaskState::TaskComparator(task));
545 if (state_it == raster_task_states_.end())
546 continue;
548 RasterTaskState& state = *state_it;
550 // Skip task if completed.
551 if (state.type == RasterTaskState::COMPLETED) {
552 DCHECK(std::find(completed_raster_tasks_.begin(),
553 completed_raster_tasks_.end(),
554 task) != completed_raster_tasks_.end());
555 continue;
558 // All raster tasks need to be throttled by bytes of pending uploads.
559 size_t new_bytes_pending_upload = bytes_pending_upload;
560 new_bytes_pending_upload += task->resource()->bytes();
561 if (new_bytes_pending_upload > max_bytes_pending_upload_) {
562 did_throttle_raster_tasks = true;
563 if (item.required_for_activation)
564 did_throttle_raster_tasks_required_for_activation = true;
565 continue;
568 // If raster has finished, just update |bytes_pending_upload|.
569 if (state.type == RasterTaskState::UPLOADING) {
570 DCHECK(!task->HasCompleted());
571 bytes_pending_upload = new_bytes_pending_upload;
572 continue;
575 // Throttle raster tasks based on kMaxScheduledRasterTasks.
576 if (tasks.container().size() >= kMaxScheduledRasterTasks) {
577 did_throttle_raster_tasks = true;
578 if (item.required_for_activation)
579 did_throttle_raster_tasks_required_for_activation = true;
580 continue;
583 // Update |bytes_pending_upload| now that task has cleared all
584 // throttling limits.
585 bytes_pending_upload = new_bytes_pending_upload;
587 DCHECK(state.type == RasterTaskState::UNSCHEDULED ||
588 state.type == RasterTaskState::SCHEDULED);
589 state.type = RasterTaskState::SCHEDULED;
591 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
593 tasks.container().push_back(task);
594 if (item.required_for_activation)
595 tasks_required_for_activation.container().push_back(task);
598 // Cancel existing OnRasterFinished callbacks.
599 raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
601 scoped_refptr<RasterizerTask>
602 new_raster_required_for_activation_finished_task;
604 size_t scheduled_raster_task_required_for_activation_count =
605 tasks_required_for_activation.container().size();
606 DCHECK_LE(scheduled_raster_task_required_for_activation_count,
607 raster_tasks_required_for_activation_count_);
608 // Schedule OnRasterTasksRequiredForActivationFinished call only when
609 // notification is pending and throttling is not preventing all pending
610 // tasks required for activation from being scheduled.
611 if (!did_throttle_raster_tasks_required_for_activation &&
612 should_notify_client_if_no_tasks_required_for_activation_are_pending_) {
613 new_raster_required_for_activation_finished_task =
614 CreateRasterRequiredForActivationFinishedTask(
615 raster_tasks_.required_for_activation_count,
616 task_runner_.get(),
617 base::Bind(&PixelBufferRasterWorkerPool::
618 OnRasterRequiredForActivationFinished,
619 raster_finished_weak_ptr_factory_.GetWeakPtr()));
620 raster_required_for_activation_finished_task_pending_ = true;
621 InsertNodeForTask(&graph_,
622 new_raster_required_for_activation_finished_task.get(),
623 kRasterRequiredForActivationFinishedTaskPriority,
624 scheduled_raster_task_required_for_activation_count);
625 for (RasterTaskVector::ContainerType::const_iterator it =
626 tasks_required_for_activation.container().begin();
627 it != tasks_required_for_activation.container().end();
628 ++it) {
629 graph_.edges.push_back(TaskGraph::Edge(
630 *it, new_raster_required_for_activation_finished_task.get()));
634 scoped_refptr<RasterizerTask> new_raster_finished_task;
636 size_t scheduled_raster_task_count = tasks.container().size();
637 DCHECK_LE(scheduled_raster_task_count, PendingRasterTaskCount());
638 // Schedule OnRasterTasksFinished call only when notification is pending
639 // and throttling is not preventing all pending tasks from being scheduled.
640 if (!did_throttle_raster_tasks &&
641 should_notify_client_if_no_tasks_are_pending_) {
642 new_raster_finished_task = CreateRasterFinishedTask(
643 task_runner_.get(),
644 base::Bind(&PixelBufferRasterWorkerPool::OnRasterFinished,
645 raster_finished_weak_ptr_factory_.GetWeakPtr()));
646 raster_finished_task_pending_ = true;
647 InsertNodeForTask(&graph_,
648 new_raster_finished_task.get(),
649 kRasterFinishedTaskPriority,
650 scheduled_raster_task_count);
651 for (RasterTaskVector::ContainerType::const_iterator it =
652 tasks.container().begin();
653 it != tasks.container().end();
654 ++it) {
655 graph_.edges.push_back(
656 TaskGraph::Edge(*it, new_raster_finished_task.get()));
660 ScheduleTasksOnOriginThread(this, &graph_);
661 task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
663 scheduled_raster_task_count_ = scheduled_raster_task_count;
665 raster_finished_task_ = new_raster_finished_task;
666 raster_required_for_activation_finished_task_ =
667 new_raster_required_for_activation_finished_task;
670 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
671 unsigned num_completed_raster_tasks =
672 raster_tasks_with_pending_upload_.size() + completed_raster_tasks_.size();
673 DCHECK_GE(raster_task_states_.size(), num_completed_raster_tasks);
674 return raster_task_states_.size() - num_completed_raster_tasks;
677 bool PixelBufferRasterWorkerPool::HasPendingTasks() const {
678 return PendingRasterTaskCount() || !raster_tasks_with_pending_upload_.empty();
681 bool PixelBufferRasterWorkerPool::HasPendingTasksRequiredForActivation() const {
682 return !!raster_tasks_required_for_activation_count_;
685 const char* PixelBufferRasterWorkerPool::StateName() const {
686 if (scheduled_raster_task_count_)
687 return "rasterizing";
688 if (PendingRasterTaskCount())
689 return "throttled";
690 if (!raster_tasks_with_pending_upload_.empty())
691 return "waiting_for_uploads";
693 return "finishing";
696 void PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks() {
697 TRACE_EVENT0("cc",
698 "PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks");
700 task_graph_runner_->CollectCompletedTasks(namespace_token_,
701 &completed_tasks_);
702 for (Task::Vector::const_iterator it = completed_tasks_.begin();
703 it != completed_tasks_.end();
704 ++it) {
705 RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
707 RasterTask* raster_task = task->AsRasterTask();
708 if (!raster_task) {
709 task->WillComplete();
710 task->CompleteOnOriginThread(this);
711 task->DidComplete();
713 completed_image_decode_tasks_.push_back(task);
714 continue;
717 RasterTaskState::Vector::iterator state_it =
718 std::find_if(raster_task_states_.begin(),
719 raster_task_states_.end(),
720 RasterTaskState::TaskComparator(raster_task));
721 DCHECK(state_it != raster_task_states_.end());
723 RasterTaskState& state = *state_it;
724 DCHECK_EQ(RasterTaskState::SCHEDULED, state.type);
726 // Balanced with MapPixelRasterBuffer() call in AcquireCanvasForRaster().
727 bool content_has_changed = resource_provider_->UnmapPixelRasterBuffer(
728 raster_task->resource()->id());
730 // |content_has_changed| can be false as result of task being canceled or
731 // task implementation deciding not to modify bitmap (ie. analysis of raster
732 // commands detected content as a solid color).
733 if (!content_has_changed) {
734 raster_task->WillComplete();
735 raster_task->CompleteOnOriginThread(this);
736 raster_task->DidComplete();
738 if (!raster_task->HasFinishedRunning()) {
739 // When priorites change, a raster task can be canceled as a result of
740 // no longer being of high enough priority to fit in our throttled
741 // raster task budget. The task has not yet completed in this case.
742 RasterTaskQueue::Item::Vector::const_iterator item_it =
743 std::find_if(raster_tasks_.items.begin(),
744 raster_tasks_.items.end(),
745 RasterTaskQueue::Item::TaskComparator(raster_task));
746 if (item_it != raster_tasks_.items.end()) {
747 state.type = RasterTaskState::UNSCHEDULED;
748 continue;
752 DCHECK(std::find(completed_raster_tasks_.begin(),
753 completed_raster_tasks_.end(),
754 raster_task) == completed_raster_tasks_.end());
755 completed_raster_tasks_.push_back(raster_task);
756 state.type = RasterTaskState::COMPLETED;
757 DCHECK_LE(static_cast<size_t>(state.required_for_activation),
758 raster_tasks_required_for_activation_count_);
759 raster_tasks_required_for_activation_count_ -=
760 state.required_for_activation;
761 continue;
764 DCHECK(raster_task->HasFinishedRunning());
766 resource_provider_->BeginSetPixels(raster_task->resource()->id());
767 has_performed_uploads_since_last_flush_ = true;
769 bytes_pending_upload_ += raster_task->resource()->bytes();
770 raster_tasks_with_pending_upload_.push_back(raster_task);
771 state.type = RasterTaskState::UPLOADING;
773 completed_tasks_.clear();
776 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::StateAsValue() const {
777 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
779 state->SetInteger("completed_count", completed_raster_tasks_.size());
780 state->SetInteger("pending_count", raster_task_states_.size());
781 state->SetInteger("pending_upload_count",
782 raster_tasks_with_pending_upload_.size());
783 state->SetInteger("pending_required_for_activation_count",
784 raster_tasks_required_for_activation_count_);
785 state->Set("throttle_state", ThrottleStateAsValue().release());
786 return state.PassAs<base::Value>();
789 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::ThrottleStateAsValue()
790 const {
791 scoped_ptr<base::DictionaryValue> throttle_state(new base::DictionaryValue);
793 throttle_state->SetInteger("bytes_available_for_upload",
794 max_bytes_pending_upload_ - bytes_pending_upload_);
795 throttle_state->SetInteger("bytes_pending_upload", bytes_pending_upload_);
796 throttle_state->SetInteger("scheduled_raster_task_count",
797 scheduled_raster_task_count_);
798 return throttle_state.PassAs<base::Value>();
801 } // namespace cc