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"
9 #include "base/containers/stack_container.h"
10 #include "base/debug/trace_event.h"
11 #include "base/debug/trace_event_argument.h"
12 #include "cc/debug/traced_value.h"
13 #include "cc/resources/resource.h"
14 #include "gpu/command_buffer/client/gles2_interface.h"
19 const int kCheckForCompletedRasterTasksDelayMs = 6;
21 const size_t kMaxScheduledRasterTasks = 48;
23 typedef base::StackVector<RasterTask*, kMaxScheduledRasterTasks>
29 scoped_ptr<RasterWorkerPool> PixelBufferRasterWorkerPool::Create(
30 base::SequencedTaskRunner* task_runner,
31 TaskGraphRunner* task_graph_runner,
32 ContextProvider* context_provider,
33 ResourceProvider* resource_provider,
34 size_t max_transfer_buffer_usage_bytes) {
35 return make_scoped_ptr<RasterWorkerPool>(
36 new PixelBufferRasterWorkerPool(task_runner,
40 max_transfer_buffer_usage_bytes));
43 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
44 base::SequencedTaskRunner* task_runner,
45 TaskGraphRunner* task_graph_runner,
46 ContextProvider* context_provider,
47 ResourceProvider* resource_provider,
48 size_t max_transfer_buffer_usage_bytes)
49 : task_runner_(task_runner),
50 task_graph_runner_(task_graph_runner),
51 namespace_token_(task_graph_runner->GetNamespaceToken()),
52 context_provider_(context_provider),
53 resource_provider_(resource_provider),
55 scheduled_raster_task_count_(0u),
56 raster_tasks_required_for_activation_count_(0u),
57 bytes_pending_upload_(0u),
58 max_bytes_pending_upload_(max_transfer_buffer_usage_bytes),
59 has_performed_uploads_since_last_flush_(false),
60 should_notify_client_if_no_tasks_are_pending_(false),
61 should_notify_client_if_no_tasks_required_for_activation_are_pending_(
63 raster_finished_task_pending_(false),
64 raster_required_for_activation_finished_task_pending_(false),
65 check_for_completed_raster_task_notifier_(
67 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks,
68 base::Unretained(this)),
69 base::TimeDelta::FromMilliseconds(
70 kCheckForCompletedRasterTasksDelayMs)),
71 raster_finished_weak_ptr_factory_(this) {
72 DCHECK(context_provider_);
75 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
76 DCHECK_EQ(0u, raster_task_states_.size());
77 DCHECK_EQ(0u, raster_tasks_with_pending_upload_.size());
78 DCHECK_EQ(0u, completed_raster_tasks_.size());
79 DCHECK_EQ(0u, completed_image_decode_tasks_.size());
80 DCHECK_EQ(0u, raster_tasks_required_for_activation_count_);
83 Rasterizer* PixelBufferRasterWorkerPool::AsRasterizer() { return this; }
85 void PixelBufferRasterWorkerPool::SetClient(RasterizerClient* client) {
89 void PixelBufferRasterWorkerPool::Shutdown() {
90 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::Shutdown");
95 task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
96 task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
98 CheckForCompletedRasterizerTasks();
99 CheckForCompletedUploads();
101 check_for_completed_raster_task_notifier_.Cancel();
103 for (RasterTaskState::Vector::iterator it = raster_task_states_.begin();
104 it != raster_task_states_.end();
106 RasterTaskState& state = *it;
108 // All unscheduled tasks need to be canceled.
109 if (state.type == RasterTaskState::UNSCHEDULED) {
110 completed_raster_tasks_.push_back(state.task);
111 state.type = RasterTaskState::COMPLETED;
114 DCHECK_EQ(completed_raster_tasks_.size(), raster_task_states_.size());
117 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
118 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
120 DCHECK_EQ(queue->required_for_activation_count,
122 std::count_if(queue->items.begin(),
124 RasterTaskQueue::Item::IsRequiredForActivation)));
126 if (!should_notify_client_if_no_tasks_are_pending_)
127 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
129 should_notify_client_if_no_tasks_are_pending_ = true;
130 should_notify_client_if_no_tasks_required_for_activation_are_pending_ = true;
132 raster_tasks_required_for_activation_count_ = 0u;
134 // Update raster task state and remove items from old queue.
135 for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
136 it != queue->items.end();
138 const RasterTaskQueue::Item& item = *it;
139 RasterTask* task = item.task;
141 // Remove any old items that are associated with this task. The result is
142 // that the old queue is left with all items not present in this queue,
143 // which we use below to determine what tasks need to be canceled.
144 RasterTaskQueue::Item::Vector::iterator old_it =
145 std::find_if(raster_tasks_.items.begin(),
146 raster_tasks_.items.end(),
147 RasterTaskQueue::Item::TaskComparator(task));
148 if (old_it != raster_tasks_.items.end()) {
149 std::swap(*old_it, raster_tasks_.items.back());
150 raster_tasks_.items.pop_back();
153 RasterTaskState::Vector::iterator state_it =
154 std::find_if(raster_task_states_.begin(),
155 raster_task_states_.end(),
156 RasterTaskState::TaskComparator(task));
157 if (state_it != raster_task_states_.end()) {
158 RasterTaskState& state = *state_it;
160 state.required_for_activation = item.required_for_activation;
161 // |raster_tasks_required_for_activation_count| accounts for all tasks
162 // that need to complete before we can send a "ready to activate" signal.
163 // Tasks that have already completed should not be part of this count.
164 if (state.type != RasterTaskState::COMPLETED) {
165 raster_tasks_required_for_activation_count_ +=
166 item.required_for_activation;
171 DCHECK(!task->HasBeenScheduled());
172 raster_task_states_.push_back(
173 RasterTaskState(task, item.required_for_activation));
174 raster_tasks_required_for_activation_count_ += item.required_for_activation;
177 // Determine what tasks in old queue need to be canceled.
178 for (RasterTaskQueue::Item::Vector::const_iterator it =
179 raster_tasks_.items.begin();
180 it != raster_tasks_.items.end();
182 const RasterTaskQueue::Item& item = *it;
183 RasterTask* task = item.task;
185 RasterTaskState::Vector::iterator state_it =
186 std::find_if(raster_task_states_.begin(),
187 raster_task_states_.end(),
188 RasterTaskState::TaskComparator(task));
189 // We've already processed completion if we can't find a RasterTaskState for
191 if (state_it == raster_task_states_.end())
194 RasterTaskState& state = *state_it;
196 // Unscheduled task can be canceled.
197 if (state.type == RasterTaskState::UNSCHEDULED) {
198 DCHECK(!task->HasBeenScheduled());
199 DCHECK(std::find(completed_raster_tasks_.begin(),
200 completed_raster_tasks_.end(),
201 task) == completed_raster_tasks_.end());
202 completed_raster_tasks_.push_back(task);
203 state.type = RasterTaskState::COMPLETED;
206 // No longer required for activation.
207 state.required_for_activation = false;
210 raster_tasks_.Swap(queue);
212 // Check for completed tasks when ScheduleTasks() is called as
213 // priorities might have changed and this maximizes the number
214 // of top priority tasks that are scheduled.
215 CheckForCompletedRasterizerTasks();
216 CheckForCompletedUploads();
219 // Schedule new tasks.
222 // Reschedule check for completed raster tasks.
223 check_for_completed_raster_task_notifier_.Schedule();
225 TRACE_EVENT_ASYNC_STEP_INTO1(
226 "cc", "ScheduledTasks", this, StateName(), "state", StateAsValue());
229 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
230 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
232 CheckForCompletedRasterizerTasks();
233 CheckForCompletedUploads();
236 for (RasterizerTask::Vector::const_iterator it =
237 completed_image_decode_tasks_.begin();
238 it != completed_image_decode_tasks_.end();
240 RasterizerTask* task = it->get();
241 task->RunReplyOnOriginThread();
243 completed_image_decode_tasks_.clear();
245 for (RasterTask::Vector::const_iterator it = completed_raster_tasks_.begin();
246 it != completed_raster_tasks_.end();
248 RasterTask* task = it->get();
249 RasterTaskState::Vector::iterator state_it =
250 std::find_if(raster_task_states_.begin(),
251 raster_task_states_.end(),
252 RasterTaskState::TaskComparator(task));
253 DCHECK(state_it != raster_task_states_.end());
254 DCHECK_EQ(RasterTaskState::COMPLETED, state_it->type);
256 std::swap(*state_it, raster_task_states_.back());
257 raster_task_states_.pop_back();
259 task->RunReplyOnOriginThread();
261 completed_raster_tasks_.clear();
264 SkCanvas* PixelBufferRasterWorkerPool::AcquireCanvasForRaster(
266 DCHECK(std::find_if(raster_task_states_.begin(),
267 raster_task_states_.end(),
268 RasterTaskState::TaskComparator(task)) !=
269 raster_task_states_.end());
270 resource_provider_->AcquirePixelRasterBuffer(task->resource()->id());
271 return resource_provider_->MapPixelRasterBuffer(task->resource()->id());
274 void PixelBufferRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) {
275 DCHECK(std::find_if(raster_task_states_.begin(),
276 raster_task_states_.end(),
277 RasterTaskState::TaskComparator(task)) !=
278 raster_task_states_.end());
279 resource_provider_->ReleasePixelRasterBuffer(task->resource()->id());
282 void PixelBufferRasterWorkerPool::OnRasterFinished() {
283 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::OnRasterFinished");
285 // |should_notify_client_if_no_tasks_are_pending_| can be set to false as
286 // a result of a scheduled CheckForCompletedRasterTasks() call. No need to
287 // perform another check in that case as we've already notified the client.
288 if (!should_notify_client_if_no_tasks_are_pending_)
290 raster_finished_task_pending_ = false;
292 // Call CheckForCompletedRasterTasks() when we've finished running all
293 // raster tasks needed since last time ScheduleTasks() was called.
294 // This reduces latency between the time when all tasks have finished
295 // running and the time when the client is notified.
296 CheckForCompletedRasterTasks();
299 void PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished() {
302 "PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished");
304 // Analogous to OnRasterTasksFinished(), there's no need to call
305 // CheckForCompletedRasterTasks() if the client has already been notified.
306 if (!should_notify_client_if_no_tasks_required_for_activation_are_pending_)
308 raster_required_for_activation_finished_task_pending_ = false;
310 // This reduces latency between the time when all tasks required for
311 // activation have finished running and the time when the client is
313 CheckForCompletedRasterTasks();
316 void PixelBufferRasterWorkerPool::FlushUploads() {
317 if (!has_performed_uploads_since_last_flush_)
320 context_provider_->ContextGL()->ShallowFlushCHROMIUM();
321 has_performed_uploads_since_last_flush_ = false;
324 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
325 RasterTask::Vector tasks_with_completed_uploads;
327 // First check if any have completed.
328 while (!raster_tasks_with_pending_upload_.empty()) {
329 RasterTask* task = raster_tasks_with_pending_upload_.front().get();
330 DCHECK(std::find_if(raster_task_states_.begin(),
331 raster_task_states_.end(),
332 RasterTaskState::TaskComparator(task)) !=
333 raster_task_states_.end());
334 DCHECK_EQ(RasterTaskState::UPLOADING,
335 std::find_if(raster_task_states_.begin(),
336 raster_task_states_.end(),
337 RasterTaskState::TaskComparator(task))->type);
339 // Uploads complete in the order they are issued.
340 if (!resource_provider_->DidSetPixelsComplete(task->resource()->id()))
343 tasks_with_completed_uploads.push_back(task);
344 raster_tasks_with_pending_upload_.pop_front();
348 bool should_force_some_uploads_to_complete =
349 shutdown_ || client_->ShouldForceTasksRequiredForActivationToComplete();
351 if (should_force_some_uploads_to_complete) {
352 RasterTask::Vector tasks_with_uploads_to_force;
353 RasterTaskDeque::iterator it = raster_tasks_with_pending_upload_.begin();
354 while (it != raster_tasks_with_pending_upload_.end()) {
355 RasterTask* task = it->get();
356 RasterTaskState::Vector::const_iterator state_it =
357 std::find_if(raster_task_states_.begin(),
358 raster_task_states_.end(),
359 RasterTaskState::TaskComparator(task));
360 DCHECK(state_it != raster_task_states_.end());
361 const RasterTaskState& state = *state_it;
363 // Force all uploads required for activation to complete.
364 // During shutdown, force all pending uploads to complete.
365 if (shutdown_ || state.required_for_activation) {
366 tasks_with_uploads_to_force.push_back(task);
367 tasks_with_completed_uploads.push_back(task);
368 it = raster_tasks_with_pending_upload_.erase(it);
375 // Force uploads in reverse order. Since forcing can cause a wait on
376 // all previous uploads, we would rather wait only once downstream.
377 for (RasterTask::Vector::reverse_iterator it =
378 tasks_with_uploads_to_force.rbegin();
379 it != tasks_with_uploads_to_force.rend();
381 RasterTask* task = it->get();
383 resource_provider_->ForceSetPixelsToComplete(task->resource()->id());
384 has_performed_uploads_since_last_flush_ = true;
388 // Release shared memory and move tasks with completed uploads
389 // to |completed_raster_tasks_|.
390 for (RasterTask::Vector::const_iterator it =
391 tasks_with_completed_uploads.begin();
392 it != tasks_with_completed_uploads.end();
394 RasterTask* task = it->get();
395 RasterTaskState::Vector::iterator state_it =
396 std::find_if(raster_task_states_.begin(),
397 raster_task_states_.end(),
398 RasterTaskState::TaskComparator(task));
399 DCHECK(state_it != raster_task_states_.end());
400 RasterTaskState& state = *state_it;
402 bytes_pending_upload_ -= task->resource()->bytes();
404 task->WillComplete();
405 task->CompleteOnOriginThread(this);
408 // Async set pixels commands are not necessarily processed in-sequence with
409 // drawing commands. Read lock fences are required to ensure that async
410 // commands don't access the resource while used for drawing.
411 resource_provider_->EnableReadLockFences(task->resource()->id());
413 DCHECK(std::find(completed_raster_tasks_.begin(),
414 completed_raster_tasks_.end(),
415 task) == completed_raster_tasks_.end());
416 completed_raster_tasks_.push_back(task);
417 state.type = RasterTaskState::COMPLETED;
418 DCHECK_LE(static_cast<size_t>(state.required_for_activation),
419 raster_tasks_required_for_activation_count_);
420 raster_tasks_required_for_activation_count_ -=
421 state.required_for_activation;
425 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
427 "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
429 // Since this function can be called directly, cancel any pending checks.
430 check_for_completed_raster_task_notifier_.Cancel();
432 DCHECK(should_notify_client_if_no_tasks_are_pending_);
434 CheckForCompletedRasterizerTasks();
435 CheckForCompletedUploads();
438 // Determine what client notifications to generate.
439 bool will_notify_client_that_no_tasks_required_for_activation_are_pending =
440 (should_notify_client_if_no_tasks_required_for_activation_are_pending_ &&
441 !raster_required_for_activation_finished_task_pending_ &&
442 !HasPendingTasksRequiredForActivation());
443 bool will_notify_client_that_no_tasks_are_pending =
444 (should_notify_client_if_no_tasks_are_pending_ &&
445 !raster_required_for_activation_finished_task_pending_ &&
446 !raster_finished_task_pending_ && !HasPendingTasks());
448 // Adjust the need to generate notifications before scheduling more tasks.
449 should_notify_client_if_no_tasks_required_for_activation_are_pending_ &=
450 !will_notify_client_that_no_tasks_required_for_activation_are_pending;
451 should_notify_client_if_no_tasks_are_pending_ &=
452 !will_notify_client_that_no_tasks_are_pending;
454 scheduled_raster_task_count_ = 0;
455 if (PendingRasterTaskCount())
458 TRACE_EVENT_ASYNC_STEP_INTO1(
459 "cc", "ScheduledTasks", this, StateName(), "state", StateAsValue());
461 // Schedule another check for completed raster tasks while there are
462 // pending raster tasks or pending uploads.
463 if (HasPendingTasks())
464 check_for_completed_raster_task_notifier_.Schedule();
466 // Generate client notifications.
467 if (will_notify_client_that_no_tasks_required_for_activation_are_pending) {
468 DCHECK(!HasPendingTasksRequiredForActivation());
469 client_->DidFinishRunningTasksRequiredForActivation();
471 if (will_notify_client_that_no_tasks_are_pending) {
472 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
473 DCHECK(!HasPendingTasksRequiredForActivation());
474 client_->DidFinishRunningTasks();
478 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
479 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
481 RasterTaskVector tasks;
482 RasterTaskVector tasks_required_for_activation;
484 unsigned priority = kRasterTaskPriorityBase;
488 size_t bytes_pending_upload = bytes_pending_upload_;
489 bool did_throttle_raster_tasks = false;
490 bool did_throttle_raster_tasks_required_for_activation = false;
492 for (RasterTaskQueue::Item::Vector::const_iterator it =
493 raster_tasks_.items.begin();
494 it != raster_tasks_.items.end();
496 const RasterTaskQueue::Item& item = *it;
497 RasterTask* task = item.task;
499 // |raster_task_states_| contains the state of all tasks that we have not
500 // yet run reply callbacks for.
501 RasterTaskState::Vector::iterator state_it =
502 std::find_if(raster_task_states_.begin(),
503 raster_task_states_.end(),
504 RasterTaskState::TaskComparator(task));
505 if (state_it == raster_task_states_.end())
508 RasterTaskState& state = *state_it;
510 // Skip task if completed.
511 if (state.type == RasterTaskState::COMPLETED) {
512 DCHECK(std::find(completed_raster_tasks_.begin(),
513 completed_raster_tasks_.end(),
514 task) != completed_raster_tasks_.end());
518 // All raster tasks need to be throttled by bytes of pending uploads,
519 // but if it's the only task allow it to complete no matter what its size,
520 // to prevent starvation of the task queue.
521 size_t new_bytes_pending_upload = bytes_pending_upload;
522 new_bytes_pending_upload += task->resource()->bytes();
523 if (new_bytes_pending_upload > max_bytes_pending_upload_ &&
524 bytes_pending_upload) {
525 did_throttle_raster_tasks = true;
526 if (item.required_for_activation)
527 did_throttle_raster_tasks_required_for_activation = true;
531 // If raster has finished, just update |bytes_pending_upload|.
532 if (state.type == RasterTaskState::UPLOADING) {
533 DCHECK(!task->HasCompleted());
534 bytes_pending_upload = new_bytes_pending_upload;
538 // Throttle raster tasks based on kMaxScheduledRasterTasks.
539 if (tasks.container().size() >= kMaxScheduledRasterTasks) {
540 did_throttle_raster_tasks = true;
541 if (item.required_for_activation)
542 did_throttle_raster_tasks_required_for_activation = true;
546 // Update |bytes_pending_upload| now that task has cleared all
547 // throttling limits.
548 bytes_pending_upload = new_bytes_pending_upload;
550 DCHECK(state.type == RasterTaskState::UNSCHEDULED ||
551 state.type == RasterTaskState::SCHEDULED);
552 state.type = RasterTaskState::SCHEDULED;
554 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
556 tasks.container().push_back(task);
557 if (item.required_for_activation)
558 tasks_required_for_activation.container().push_back(task);
561 // Cancel existing OnRasterFinished callbacks.
562 raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
564 scoped_refptr<RasterizerTask>
565 new_raster_required_for_activation_finished_task;
567 size_t scheduled_raster_task_required_for_activation_count =
568 tasks_required_for_activation.container().size();
569 DCHECK_LE(scheduled_raster_task_required_for_activation_count,
570 raster_tasks_required_for_activation_count_);
571 // Schedule OnRasterTasksRequiredForActivationFinished call only when
572 // notification is pending and throttling is not preventing all pending
573 // tasks required for activation from being scheduled.
574 if (!did_throttle_raster_tasks_required_for_activation &&
575 should_notify_client_if_no_tasks_required_for_activation_are_pending_) {
576 new_raster_required_for_activation_finished_task =
577 CreateRasterRequiredForActivationFinishedTask(
578 raster_tasks_.required_for_activation_count,
580 base::Bind(&PixelBufferRasterWorkerPool::
581 OnRasterRequiredForActivationFinished,
582 raster_finished_weak_ptr_factory_.GetWeakPtr()));
583 raster_required_for_activation_finished_task_pending_ = true;
584 InsertNodeForTask(&graph_,
585 new_raster_required_for_activation_finished_task.get(),
586 kRasterRequiredForActivationFinishedTaskPriority,
587 scheduled_raster_task_required_for_activation_count);
588 for (RasterTaskVector::ContainerType::const_iterator it =
589 tasks_required_for_activation.container().begin();
590 it != tasks_required_for_activation.container().end();
592 graph_.edges.push_back(TaskGraph::Edge(
593 *it, new_raster_required_for_activation_finished_task.get()));
597 scoped_refptr<RasterizerTask> new_raster_finished_task;
599 size_t scheduled_raster_task_count = tasks.container().size();
600 DCHECK_LE(scheduled_raster_task_count, PendingRasterTaskCount());
601 // Schedule OnRasterTasksFinished call only when notification is pending
602 // and throttling is not preventing all pending tasks from being scheduled.
603 if (!did_throttle_raster_tasks &&
604 should_notify_client_if_no_tasks_are_pending_) {
605 new_raster_finished_task = CreateRasterFinishedTask(
607 base::Bind(&PixelBufferRasterWorkerPool::OnRasterFinished,
608 raster_finished_weak_ptr_factory_.GetWeakPtr()));
609 raster_finished_task_pending_ = true;
610 InsertNodeForTask(&graph_,
611 new_raster_finished_task.get(),
612 kRasterFinishedTaskPriority,
613 scheduled_raster_task_count);
614 for (RasterTaskVector::ContainerType::const_iterator it =
615 tasks.container().begin();
616 it != tasks.container().end();
618 graph_.edges.push_back(
619 TaskGraph::Edge(*it, new_raster_finished_task.get()));
623 ScheduleTasksOnOriginThread(this, &graph_);
624 task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
626 scheduled_raster_task_count_ = scheduled_raster_task_count;
628 raster_finished_task_ = new_raster_finished_task;
629 raster_required_for_activation_finished_task_ =
630 new_raster_required_for_activation_finished_task;
633 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
634 unsigned num_completed_raster_tasks =
635 raster_tasks_with_pending_upload_.size() + completed_raster_tasks_.size();
636 DCHECK_GE(raster_task_states_.size(), num_completed_raster_tasks);
637 return raster_task_states_.size() - num_completed_raster_tasks;
640 bool PixelBufferRasterWorkerPool::HasPendingTasks() const {
641 return PendingRasterTaskCount() || !raster_tasks_with_pending_upload_.empty();
644 bool PixelBufferRasterWorkerPool::HasPendingTasksRequiredForActivation() const {
645 return !!raster_tasks_required_for_activation_count_;
648 const char* PixelBufferRasterWorkerPool::StateName() const {
649 if (scheduled_raster_task_count_)
650 return "rasterizing";
651 if (PendingRasterTaskCount())
653 if (!raster_tasks_with_pending_upload_.empty())
654 return "waiting_for_uploads";
659 void PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks() {
661 "PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks");
663 task_graph_runner_->CollectCompletedTasks(namespace_token_,
665 for (Task::Vector::const_iterator it = completed_tasks_.begin();
666 it != completed_tasks_.end();
668 RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
670 RasterTask* raster_task = task->AsRasterTask();
672 task->WillComplete();
673 task->CompleteOnOriginThread(this);
676 completed_image_decode_tasks_.push_back(task);
680 RasterTaskState::Vector::iterator state_it =
681 std::find_if(raster_task_states_.begin(),
682 raster_task_states_.end(),
683 RasterTaskState::TaskComparator(raster_task));
684 DCHECK(state_it != raster_task_states_.end());
686 RasterTaskState& state = *state_it;
687 DCHECK_EQ(RasterTaskState::SCHEDULED, state.type);
689 // Balanced with MapPixelRasterBuffer() call in AcquireCanvasForRaster().
690 bool content_has_changed = resource_provider_->UnmapPixelRasterBuffer(
691 raster_task->resource()->id());
693 // |content_has_changed| can be false as result of task being canceled or
694 // task implementation deciding not to modify bitmap (ie. analysis of raster
695 // commands detected content as a solid color).
696 if (!content_has_changed) {
697 raster_task->WillComplete();
698 raster_task->CompleteOnOriginThread(this);
699 raster_task->DidComplete();
701 if (!raster_task->HasFinishedRunning()) {
702 // When priorites change, a raster task can be canceled as a result of
703 // no longer being of high enough priority to fit in our throttled
704 // raster task budget. The task has not yet completed in this case.
705 RasterTaskQueue::Item::Vector::const_iterator item_it =
706 std::find_if(raster_tasks_.items.begin(),
707 raster_tasks_.items.end(),
708 RasterTaskQueue::Item::TaskComparator(raster_task));
709 if (item_it != raster_tasks_.items.end()) {
710 state.type = RasterTaskState::UNSCHEDULED;
715 DCHECK(std::find(completed_raster_tasks_.begin(),
716 completed_raster_tasks_.end(),
717 raster_task) == completed_raster_tasks_.end());
718 completed_raster_tasks_.push_back(raster_task);
719 state.type = RasterTaskState::COMPLETED;
720 DCHECK_LE(static_cast<size_t>(state.required_for_activation),
721 raster_tasks_required_for_activation_count_);
722 raster_tasks_required_for_activation_count_ -=
723 state.required_for_activation;
727 DCHECK(raster_task->HasFinishedRunning());
729 resource_provider_->BeginSetPixels(raster_task->resource()->id());
730 has_performed_uploads_since_last_flush_ = true;
732 bytes_pending_upload_ += raster_task->resource()->bytes();
733 raster_tasks_with_pending_upload_.push_back(raster_task);
734 state.type = RasterTaskState::UPLOADING;
736 completed_tasks_.clear();
739 scoped_refptr<base::debug::ConvertableToTraceFormat>
740 PixelBufferRasterWorkerPool::StateAsValue() const {
741 scoped_refptr<base::debug::TracedValue> state =
742 new base::debug::TracedValue();
743 state->SetInteger("completed_count", completed_raster_tasks_.size());
744 state->SetInteger("pending_count", raster_task_states_.size());
745 state->SetInteger("pending_upload_count",
746 raster_tasks_with_pending_upload_.size());
747 state->SetInteger("pending_required_for_activation_count",
748 raster_tasks_required_for_activation_count_);
749 state->BeginDictionary("throttle_state");
750 ThrottleStateAsValueInto(state.get());
751 state->EndDictionary();
755 void PixelBufferRasterWorkerPool::ThrottleStateAsValueInto(
756 base::debug::TracedValue* throttle_state) const {
757 throttle_state->SetInteger("bytes_available_for_upload",
758 max_bytes_pending_upload_ - bytes_pending_upload_);
759 throttle_state->SetInteger("bytes_pending_upload", bytes_pending_upload_);
760 throttle_state->SetInteger("scheduled_raster_task_count",
761 scheduled_raster_task_count_);