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 "cc/debug/traced_value.h"
12 #include "cc/resources/resource.h"
17 const int kCheckForCompletedRasterTasksDelayMs
= 6;
19 const size_t kMaxScheduledRasterTasks
= 48;
21 typedef base::StackVector
<RasterTask
*, kMaxScheduledRasterTasks
>
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
,
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
),
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_(
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
) {
78 void PixelBufferRasterWorkerPool::Shutdown() {
79 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::Shutdown");
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();
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
,
111 std::count_if(queue
->items
.begin(),
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();
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
;
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();
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
180 if (state_it
== raster_task_states_
.end())
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();
208 // Schedule new tasks.
211 // Cancel any pending check for completed raster tasks and schedule
213 check_for_completed_raster_tasks_time_
= base::TimeTicks();
214 ScheduleCheckForCompletedRasterTasks();
216 TRACE_EVENT_ASYNC_STEP_INTO1(
222 TracedValue::FromValue(StateAsValue().release()));
225 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
226 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
228 CheckForCompletedRasterizerTasks();
229 CheckForCompletedUploads();
232 for (RasterizerTask::Vector::const_iterator it
=
233 completed_image_decode_tasks_
.begin();
234 it
!= completed_image_decode_tasks_
.end();
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();
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(
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_
)
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() {
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_
)
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
309 CheckForCompletedRasterTasks();
312 void PixelBufferRasterWorkerPool::FlushUploads() {
313 if (!has_performed_uploads_since_last_flush_
)
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()))
339 tasks_with_completed_uploads
.push_back(task
);
340 raster_tasks_with_pending_upload_
.pop_front();
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
);
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();
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();
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);
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_
)
430 task_runner_
->PostDelayedTask(
432 base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks
,
433 weak_ptr_factory_
.GetWeakPtr()),
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;
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
449 if (delay
> base::TimeDelta()) {
450 task_runner_
->PostDelayedTask(
452 base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks
,
453 weak_ptr_factory_
.GetWeakPtr()),
458 check_for_completed_raster_tasks_pending_
= false;
459 CheckForCompletedRasterTasks();
462 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
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();
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())
493 TRACE_EVENT_ASYNC_STEP_INTO1(
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
;
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();
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())
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());
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;
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
;
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;
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
,
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();
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(
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();
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())
690 if (!raster_tasks_with_pending_upload_
.empty())
691 return "waiting_for_uploads";
696 void PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks() {
698 "PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks");
700 task_graph_runner_
->CollectCompletedTasks(namespace_token_
,
702 for (Task::Vector::const_iterator it
= completed_tasks_
.begin();
703 it
!= completed_tasks_
.end();
705 RasterizerTask
* task
= static_cast<RasterizerTask
*>(it
->get());
707 RasterTask
* raster_task
= task
->AsRasterTask();
709 task
->WillComplete();
710 task
->CompleteOnOriginThread(this);
713 completed_image_decode_tasks_
.push_back(task
);
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
;
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
;
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()
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
>();