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 "base/strings/stringprintf.h"
13 #include "cc/debug/traced_value.h"
14 #include "cc/resources/raster_buffer.h"
15 #include "cc/resources/resource.h"
16 #include "gpu/command_buffer/client/gles2_interface.h"
21 class RasterBufferImpl
: public RasterBuffer
{
23 RasterBufferImpl(ResourceProvider
* resource_provider
,
24 const Resource
* resource
)
25 : resource_provider_(resource_provider
),
29 resource_provider_
->AcquirePixelBuffer(resource_
->id());
30 memory_
= resource_provider_
->MapPixelBuffer(resource_
->id(), &stride_
);
33 ~RasterBufferImpl() override
{
34 resource_provider_
->ReleasePixelBuffer(resource_
->id());
37 // Overridden from RasterBuffer:
38 void Playback(const RasterSource
* raster_source
,
39 const gfx::Rect
& rect
,
40 float scale
) override
{
44 RasterWorkerPool::PlaybackToMemory(memory_
, resource_
->format(),
45 resource_
->size(), stride_
,
46 raster_source
, rect
, scale
);
50 ResourceProvider
* resource_provider_
;
51 const Resource
* resource_
;
55 DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl
);
58 const int kCheckForCompletedRasterTasksDelayMs
= 6;
60 const size_t kMaxScheduledRasterTasks
= 48;
62 typedef base::StackVector
<RasterTask
*, kMaxScheduledRasterTasks
>
65 TaskSetCollection
NonEmptyTaskSetsFromTaskCounts(const size_t* task_counts
) {
66 TaskSetCollection task_sets
;
67 for (TaskSet task_set
= 0; task_set
< kNumberOfTaskSets
; ++task_set
) {
68 if (task_counts
[task_set
])
69 task_sets
[task_set
] = true;
74 void AddTaskSetsToTaskCounts(size_t* task_counts
,
75 const TaskSetCollection
& task_sets
) {
76 for (TaskSet task_set
= 0; task_set
< kNumberOfTaskSets
; ++task_set
) {
77 if (task_sets
[task_set
])
78 task_counts
[task_set
]++;
82 void RemoveTaskSetsFromTaskCounts(size_t* task_counts
,
83 const TaskSetCollection
& task_sets
) {
84 for (TaskSet task_set
= 0; task_set
< kNumberOfTaskSets
; ++task_set
) {
85 if (task_sets
[task_set
])
86 task_counts
[task_set
]--;
92 PixelBufferRasterWorkerPool::RasterTaskState::RasterTaskState(
94 const TaskSetCollection
& task_sets
)
95 : type(UNSCHEDULED
), task(task
), task_sets(task_sets
) {
99 scoped_ptr
<RasterWorkerPool
> PixelBufferRasterWorkerPool::Create(
100 base::SequencedTaskRunner
* task_runner
,
101 TaskGraphRunner
* task_graph_runner
,
102 ContextProvider
* context_provider
,
103 ResourceProvider
* resource_provider
,
104 size_t max_transfer_buffer_usage_bytes
) {
105 return make_scoped_ptr
<RasterWorkerPool
>(
106 new PixelBufferRasterWorkerPool(task_runner
,
110 max_transfer_buffer_usage_bytes
));
113 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
114 base::SequencedTaskRunner
* task_runner
,
115 TaskGraphRunner
* task_graph_runner
,
116 ContextProvider
* context_provider
,
117 ResourceProvider
* resource_provider
,
118 size_t max_transfer_buffer_usage_bytes
)
119 : task_runner_(task_runner
),
120 task_graph_runner_(task_graph_runner
),
121 namespace_token_(task_graph_runner
->GetNamespaceToken()),
122 context_provider_(context_provider
),
123 resource_provider_(resource_provider
),
125 scheduled_raster_task_count_(0u),
126 bytes_pending_upload_(0u),
127 max_bytes_pending_upload_(max_transfer_buffer_usage_bytes
),
128 has_performed_uploads_since_last_flush_(false),
129 check_for_completed_raster_task_notifier_(
131 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks
,
132 base::Unretained(this)),
133 base::TimeDelta::FromMilliseconds(
134 kCheckForCompletedRasterTasksDelayMs
)),
135 raster_finished_weak_ptr_factory_(this) {
136 DCHECK(context_provider_
);
137 std::fill(task_counts_
, task_counts_
+ kNumberOfTaskSets
, 0);
140 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
141 DCHECK_EQ(0u, raster_task_states_
.size());
142 DCHECK_EQ(0u, raster_tasks_with_pending_upload_
.size());
143 DCHECK_EQ(0u, completed_raster_tasks_
.size());
144 DCHECK_EQ(0u, completed_image_decode_tasks_
.size());
145 DCHECK(NonEmptyTaskSetsFromTaskCounts(task_counts_
).none());
148 Rasterizer
* PixelBufferRasterWorkerPool::AsRasterizer() { return this; }
150 void PixelBufferRasterWorkerPool::SetClient(RasterizerClient
* client
) {
154 void PixelBufferRasterWorkerPool::Shutdown() {
155 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::Shutdown");
160 task_graph_runner_
->ScheduleTasks(namespace_token_
, &empty
);
161 task_graph_runner_
->WaitForTasksToFinishRunning(namespace_token_
);
163 CheckForCompletedRasterizerTasks();
164 CheckForCompletedUploads();
166 check_for_completed_raster_task_notifier_
.Shutdown();
168 for (RasterTaskState::Vector::iterator it
= raster_task_states_
.begin();
169 it
!= raster_task_states_
.end();
171 RasterTaskState
& state
= *it
;
173 // All unscheduled tasks need to be canceled.
174 if (state
.type
== RasterTaskState::UNSCHEDULED
) {
175 completed_raster_tasks_
.push_back(state
.task
);
176 state
.type
= RasterTaskState::COMPLETED
;
179 DCHECK_EQ(completed_raster_tasks_
.size(), raster_task_states_
.size());
182 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue
* queue
) {
183 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
185 if (should_notify_client_if_no_tasks_are_pending_
.none())
186 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
188 should_notify_client_if_no_tasks_are_pending_
.set();
189 std::fill(task_counts_
, task_counts_
+ kNumberOfTaskSets
, 0);
191 // Update raster task state and remove items from old queue.
192 for (RasterTaskQueue::Item::Vector::const_iterator it
= queue
->items
.begin();
193 it
!= queue
->items
.end();
195 const RasterTaskQueue::Item
& item
= *it
;
196 RasterTask
* task
= item
.task
;
198 // Remove any old items that are associated with this task. The result is
199 // that the old queue is left with all items not present in this queue,
200 // which we use below to determine what tasks need to be canceled.
201 RasterTaskQueue::Item::Vector::iterator old_it
=
202 std::find_if(raster_tasks_
.items
.begin(),
203 raster_tasks_
.items
.end(),
204 RasterTaskQueue::Item::TaskComparator(task
));
205 if (old_it
!= raster_tasks_
.items
.end()) {
206 std::swap(*old_it
, raster_tasks_
.items
.back());
207 raster_tasks_
.items
.pop_back();
210 RasterTaskState::Vector::iterator state_it
=
211 std::find_if(raster_task_states_
.begin(),
212 raster_task_states_
.end(),
213 RasterTaskState::TaskComparator(task
));
214 if (state_it
!= raster_task_states_
.end()) {
215 RasterTaskState
& state
= *state_it
;
217 state
.task_sets
= item
.task_sets
;
218 // |raster_tasks_required_for_activation_count| accounts for all tasks
219 // that need to complete before we can send a "ready to activate" signal.
220 // Tasks that have already completed should not be part of this count.
221 if (state
.type
!= RasterTaskState::COMPLETED
)
222 AddTaskSetsToTaskCounts(task_counts_
, item
.task_sets
);
227 DCHECK(!task
->HasBeenScheduled());
228 raster_task_states_
.push_back(RasterTaskState(task
, item
.task_sets
));
229 AddTaskSetsToTaskCounts(task_counts_
, item
.task_sets
);
232 // Determine what tasks in old queue need to be canceled.
233 for (RasterTaskQueue::Item::Vector::const_iterator it
=
234 raster_tasks_
.items
.begin();
235 it
!= raster_tasks_
.items
.end();
237 const RasterTaskQueue::Item
& item
= *it
;
238 RasterTask
* task
= item
.task
;
240 RasterTaskState::Vector::iterator state_it
=
241 std::find_if(raster_task_states_
.begin(),
242 raster_task_states_
.end(),
243 RasterTaskState::TaskComparator(task
));
244 // We've already processed completion if we can't find a RasterTaskState for
246 if (state_it
== raster_task_states_
.end())
249 RasterTaskState
& state
= *state_it
;
251 // Unscheduled task can be canceled.
252 if (state
.type
== RasterTaskState::UNSCHEDULED
) {
253 DCHECK(!task
->HasBeenScheduled());
254 DCHECK(std::find(completed_raster_tasks_
.begin(),
255 completed_raster_tasks_
.end(),
256 task
) == completed_raster_tasks_
.end());
257 completed_raster_tasks_
.push_back(task
);
258 state
.type
= RasterTaskState::COMPLETED
;
261 // No longer in any task set.
262 state
.task_sets
.reset();
265 raster_tasks_
.Swap(queue
);
267 // Check for completed tasks when ScheduleTasks() is called as
268 // priorities might have changed and this maximizes the number
269 // of top priority tasks that are scheduled.
270 CheckForCompletedRasterizerTasks();
271 CheckForCompletedUploads();
274 // Schedule new tasks.
277 // Reschedule check for completed raster tasks.
278 check_for_completed_raster_task_notifier_
.Schedule();
280 TRACE_EVENT_ASYNC_STEP_INTO1(
281 "cc", "ScheduledTasks", this, StateName(), "state", StateAsValue());
284 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
285 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
287 CheckForCompletedRasterizerTasks();
288 CheckForCompletedUploads();
291 for (RasterizerTask::Vector::const_iterator it
=
292 completed_image_decode_tasks_
.begin();
293 it
!= completed_image_decode_tasks_
.end();
295 RasterizerTask
* task
= it
->get();
296 task
->RunReplyOnOriginThread();
298 completed_image_decode_tasks_
.clear();
300 for (RasterTask::Vector::const_iterator it
= completed_raster_tasks_
.begin();
301 it
!= completed_raster_tasks_
.end();
303 RasterTask
* task
= it
->get();
304 RasterTaskState::Vector::iterator state_it
=
305 std::find_if(raster_task_states_
.begin(),
306 raster_task_states_
.end(),
307 RasterTaskState::TaskComparator(task
));
308 DCHECK(state_it
!= raster_task_states_
.end());
309 DCHECK_EQ(RasterTaskState::COMPLETED
, state_it
->type
);
311 std::swap(*state_it
, raster_task_states_
.back());
312 raster_task_states_
.pop_back();
314 task
->RunReplyOnOriginThread();
316 completed_raster_tasks_
.clear();
319 scoped_ptr
<RasterBuffer
> PixelBufferRasterWorkerPool::AcquireBufferForRaster(
320 const Resource
* resource
) {
321 return make_scoped_ptr
<RasterBuffer
>(
322 new RasterBufferImpl(resource_provider_
, resource
));
325 void PixelBufferRasterWorkerPool::ReleaseBufferForRaster(
326 scoped_ptr
<RasterBuffer
> buffer
) {
327 // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
330 void PixelBufferRasterWorkerPool::OnRasterFinished(TaskSet task_set
) {
332 "PixelBufferRasterWorkerPool::OnRasterFinished",
335 "should_notify_client_if_no_tasks_are_pending",
336 should_notify_client_if_no_tasks_are_pending_
[task_set
]);
338 // There's no need to call CheckForCompletedRasterTasks() if the client has
339 // already been notified.
340 if (!should_notify_client_if_no_tasks_are_pending_
[task_set
])
342 raster_finished_tasks_pending_
[task_set
] = false;
344 // This reduces latency between the time when all tasks required for
345 // activation have finished running and the time when the client is
347 CheckForCompletedRasterTasks();
350 void PixelBufferRasterWorkerPool::FlushUploads() {
351 if (!has_performed_uploads_since_last_flush_
)
354 context_provider_
->ContextGL()->ShallowFlushCHROMIUM();
355 has_performed_uploads_since_last_flush_
= false;
358 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
359 RasterTask::Vector tasks_with_completed_uploads
;
361 // First check if any have completed.
362 while (!raster_tasks_with_pending_upload_
.empty()) {
363 RasterTask
* task
= raster_tasks_with_pending_upload_
.front().get();
364 DCHECK(std::find_if(raster_task_states_
.begin(),
365 raster_task_states_
.end(),
366 RasterTaskState::TaskComparator(task
)) !=
367 raster_task_states_
.end());
368 DCHECK_EQ(RasterTaskState::UPLOADING
,
369 std::find_if(raster_task_states_
.begin(),
370 raster_task_states_
.end(),
371 RasterTaskState::TaskComparator(task
))->type
);
373 // Uploads complete in the order they are issued.
374 if (!resource_provider_
->DidSetPixelsComplete(task
->resource()->id()))
377 tasks_with_completed_uploads
.push_back(task
);
378 raster_tasks_with_pending_upload_
.pop_front();
382 TaskSetCollection tasks_that_should_be_forced_to_complete
=
383 client_
->TasksThatShouldBeForcedToComplete();
384 bool should_force_some_uploads_to_complete
=
385 shutdown_
|| tasks_that_should_be_forced_to_complete
.any();
387 if (should_force_some_uploads_to_complete
) {
388 RasterTask::Vector tasks_with_uploads_to_force
;
389 RasterTaskDeque::iterator it
= raster_tasks_with_pending_upload_
.begin();
390 while (it
!= raster_tasks_with_pending_upload_
.end()) {
391 RasterTask
* task
= it
->get();
392 RasterTaskState::Vector::const_iterator state_it
=
393 std::find_if(raster_task_states_
.begin(),
394 raster_task_states_
.end(),
395 RasterTaskState::TaskComparator(task
));
396 DCHECK(state_it
!= raster_task_states_
.end());
397 const RasterTaskState
& state
= *state_it
;
399 // Force all uploads to complete for which the client requests to do so.
400 // During shutdown, force all pending uploads to complete.
402 (state
.task_sets
& tasks_that_should_be_forced_to_complete
).any()) {
403 tasks_with_uploads_to_force
.push_back(task
);
404 tasks_with_completed_uploads
.push_back(task
);
405 it
= raster_tasks_with_pending_upload_
.erase(it
);
412 // Force uploads in reverse order. Since forcing can cause a wait on
413 // all previous uploads, we would rather wait only once downstream.
414 for (RasterTask::Vector::reverse_iterator it
=
415 tasks_with_uploads_to_force
.rbegin();
416 it
!= tasks_with_uploads_to_force
.rend();
418 RasterTask
* task
= it
->get();
420 resource_provider_
->ForceSetPixelsToComplete(task
->resource()->id());
421 has_performed_uploads_since_last_flush_
= true;
425 // Release shared memory and move tasks with completed uploads
426 // to |completed_raster_tasks_|.
427 for (RasterTask::Vector::const_iterator it
=
428 tasks_with_completed_uploads
.begin();
429 it
!= tasks_with_completed_uploads
.end();
431 RasterTask
* task
= it
->get();
432 RasterTaskState::Vector::iterator state_it
=
433 std::find_if(raster_task_states_
.begin(),
434 raster_task_states_
.end(),
435 RasterTaskState::TaskComparator(task
));
436 DCHECK(state_it
!= raster_task_states_
.end());
437 RasterTaskState
& state
= *state_it
;
439 bytes_pending_upload_
-= task
->resource()->bytes();
441 task
->WillComplete();
442 task
->CompleteOnOriginThread(this);
445 DCHECK(std::find(completed_raster_tasks_
.begin(),
446 completed_raster_tasks_
.end(),
447 task
) == completed_raster_tasks_
.end());
448 completed_raster_tasks_
.push_back(task
);
449 state
.type
= RasterTaskState::COMPLETED
;
450 // Triggers if the current task belongs to a set that should be empty.
451 DCHECK((state
.task_sets
& ~NonEmptyTaskSetsFromTaskCounts(task_counts_
))
453 RemoveTaskSetsFromTaskCounts(task_counts_
, state
.task_sets
);
457 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
459 "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
461 // Since this function can be called directly, cancel any pending checks.
462 check_for_completed_raster_task_notifier_
.Cancel();
464 DCHECK(should_notify_client_if_no_tasks_are_pending_
.any());
466 CheckForCompletedRasterizerTasks();
467 CheckForCompletedUploads();
470 // Determine what client notifications to generate.
471 TaskSetCollection will_notify_client_that_no_tasks_are_pending
=
472 should_notify_client_if_no_tasks_are_pending_
&
473 ~raster_finished_tasks_pending_
& ~PendingTasks();
475 // Adjust the need to generate notifications before scheduling more tasks.
476 should_notify_client_if_no_tasks_are_pending_
&=
477 ~will_notify_client_that_no_tasks_are_pending
;
479 scheduled_raster_task_count_
= 0;
480 if (PendingRasterTaskCount())
483 TRACE_EVENT_ASYNC_STEP_INTO1(
484 "cc", "ScheduledTasks", this, StateName(), "state", StateAsValue());
486 // Schedule another check for completed raster tasks while there are
487 // pending raster tasks or pending uploads.
488 if (PendingTasks().any())
489 check_for_completed_raster_task_notifier_
.Schedule();
491 if (should_notify_client_if_no_tasks_are_pending_
.none())
492 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
494 // Generate client notifications.
495 for (TaskSet task_set
= 0; task_set
< kNumberOfTaskSets
; ++task_set
) {
496 if (will_notify_client_that_no_tasks_are_pending
[task_set
]) {
497 DCHECK(!PendingTasks()[task_set
]);
498 client_
->DidFinishRunningTasks(task_set
);
503 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
504 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
506 RasterTaskVector tasks
[kNumberOfTaskSets
];
508 unsigned priority
= kRasterTaskPriorityBase
;
512 size_t bytes_pending_upload
= bytes_pending_upload_
;
513 TaskSetCollection did_throttle_raster_tasks
;
514 size_t scheduled_raster_task_count
= 0;
516 for (RasterTaskQueue::Item::Vector::const_iterator it
=
517 raster_tasks_
.items
.begin();
518 it
!= raster_tasks_
.items
.end();
520 const RasterTaskQueue::Item
& item
= *it
;
521 RasterTask
* task
= item
.task
;
522 DCHECK(item
.task_sets
.any());
524 // |raster_task_states_| contains the state of all tasks that we have not
525 // yet run reply callbacks for.
526 RasterTaskState::Vector::iterator state_it
=
527 std::find_if(raster_task_states_
.begin(),
528 raster_task_states_
.end(),
529 RasterTaskState::TaskComparator(task
));
530 if (state_it
== raster_task_states_
.end())
533 RasterTaskState
& state
= *state_it
;
535 // Skip task if completed.
536 if (state
.type
== RasterTaskState::COMPLETED
) {
537 DCHECK(std::find(completed_raster_tasks_
.begin(),
538 completed_raster_tasks_
.end(),
539 task
) != completed_raster_tasks_
.end());
543 // All raster tasks need to be throttled by bytes of pending uploads,
544 // but if it's the only task allow it to complete no matter what its size,
545 // to prevent starvation of the task queue.
546 size_t new_bytes_pending_upload
= bytes_pending_upload
;
547 new_bytes_pending_upload
+= task
->resource()->bytes();
548 if (new_bytes_pending_upload
> max_bytes_pending_upload_
&&
549 bytes_pending_upload
) {
550 did_throttle_raster_tasks
|= item
.task_sets
;
554 // If raster has finished, just update |bytes_pending_upload|.
555 if (state
.type
== RasterTaskState::UPLOADING
) {
556 DCHECK(!task
->HasCompleted());
557 bytes_pending_upload
= new_bytes_pending_upload
;
561 // Throttle raster tasks based on kMaxScheduledRasterTasks.
562 if (scheduled_raster_task_count
>= kMaxScheduledRasterTasks
) {
563 did_throttle_raster_tasks
|= item
.task_sets
;
567 // Update |bytes_pending_upload| now that task has cleared all
568 // throttling limits.
569 bytes_pending_upload
= new_bytes_pending_upload
;
571 DCHECK(state
.type
== RasterTaskState::UNSCHEDULED
||
572 state
.type
== RasterTaskState::SCHEDULED
);
573 state
.type
= RasterTaskState::SCHEDULED
;
575 InsertNodesForRasterTask(&graph_
, task
, task
->dependencies(), priority
++);
577 ++scheduled_raster_task_count
;
578 for (TaskSet task_set
= 0; task_set
< kNumberOfTaskSets
; ++task_set
) {
579 if (item
.task_sets
[task_set
])
580 tasks
[task_set
].container().push_back(task
);
584 // Cancel existing OnRasterFinished callbacks.
585 raster_finished_weak_ptr_factory_
.InvalidateWeakPtrs();
587 scoped_refptr
<RasterizerTask
> new_raster_finished_tasks
[kNumberOfTaskSets
];
588 size_t scheduled_task_counts
[kNumberOfTaskSets
] = {0};
590 for (TaskSet task_set
= 0; task_set
< kNumberOfTaskSets
; ++task_set
) {
591 scheduled_task_counts
[task_set
] = tasks
[task_set
].container().size();
592 DCHECK_LE(scheduled_task_counts
[task_set
], task_counts_
[task_set
]);
593 // Schedule OnRasterFinished call for task set only when notification is
594 // pending and throttling is not preventing all pending tasks in the set
595 // from being scheduled.
596 if (!did_throttle_raster_tasks
[task_set
] &&
597 should_notify_client_if_no_tasks_are_pending_
[task_set
]) {
598 new_raster_finished_tasks
[task_set
] = CreateRasterFinishedTask(
600 base::Bind(&PixelBufferRasterWorkerPool::OnRasterFinished
,
601 raster_finished_weak_ptr_factory_
.GetWeakPtr(),
603 raster_finished_tasks_pending_
[task_set
] = true;
604 InsertNodeForTask(&graph_
,
605 new_raster_finished_tasks
[task_set
].get(),
606 kRasterFinishedTaskPriority
,
607 scheduled_task_counts
[task_set
]);
608 for (RasterTaskVector::ContainerType::const_iterator it
=
609 tasks
[task_set
].container().begin();
610 it
!= tasks
[task_set
].container().end();
612 graph_
.edges
.push_back(
613 TaskGraph::Edge(*it
, new_raster_finished_tasks
[task_set
].get()));
618 DCHECK_LE(scheduled_raster_task_count
, PendingRasterTaskCount());
620 ScheduleTasksOnOriginThread(this, &graph_
);
621 task_graph_runner_
->ScheduleTasks(namespace_token_
, &graph_
);
623 scheduled_raster_task_count_
= scheduled_raster_task_count
;
625 std::copy(new_raster_finished_tasks
,
626 new_raster_finished_tasks
+ kNumberOfTaskSets
,
627 raster_finished_tasks_
);
630 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
631 unsigned num_completed_raster_tasks
=
632 raster_tasks_with_pending_upload_
.size() + completed_raster_tasks_
.size();
633 DCHECK_GE(raster_task_states_
.size(), num_completed_raster_tasks
);
634 return raster_task_states_
.size() - num_completed_raster_tasks
;
637 TaskSetCollection
PixelBufferRasterWorkerPool::PendingTasks() const {
638 return NonEmptyTaskSetsFromTaskCounts(task_counts_
);
641 const char* PixelBufferRasterWorkerPool::StateName() const {
642 if (scheduled_raster_task_count_
)
643 return "rasterizing";
644 if (PendingRasterTaskCount())
646 if (!raster_tasks_with_pending_upload_
.empty())
647 return "waiting_for_uploads";
652 void PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks() {
654 "PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks");
656 task_graph_runner_
->CollectCompletedTasks(namespace_token_
,
658 for (Task::Vector::const_iterator it
= completed_tasks_
.begin();
659 it
!= completed_tasks_
.end();
661 RasterizerTask
* task
= static_cast<RasterizerTask
*>(it
->get());
663 RasterTask
* raster_task
= task
->AsRasterTask();
665 task
->WillComplete();
666 task
->CompleteOnOriginThread(this);
669 completed_image_decode_tasks_
.push_back(task
);
673 RasterTaskState::Vector::iterator state_it
=
674 std::find_if(raster_task_states_
.begin(),
675 raster_task_states_
.end(),
676 RasterTaskState::TaskComparator(raster_task
));
677 DCHECK(state_it
!= raster_task_states_
.end());
679 RasterTaskState
& state
= *state_it
;
680 DCHECK_EQ(RasterTaskState::SCHEDULED
, state
.type
);
682 resource_provider_
->UnmapPixelBuffer(raster_task
->resource()->id());
684 if (!raster_task
->HasFinishedRunning()) {
685 // When priorites change, a raster task can be canceled as a result of
686 // no longer being of high enough priority to fit in our throttled
687 // raster task budget. The task has not yet completed in this case.
688 raster_task
->WillComplete();
689 raster_task
->CompleteOnOriginThread(this);
690 raster_task
->DidComplete();
692 RasterTaskQueue::Item::Vector::const_iterator item_it
=
693 std::find_if(raster_tasks_
.items
.begin(),
694 raster_tasks_
.items
.end(),
695 RasterTaskQueue::Item::TaskComparator(raster_task
));
696 if (item_it
!= raster_tasks_
.items
.end()) {
697 state
.type
= RasterTaskState::UNSCHEDULED
;
701 DCHECK(std::find(completed_raster_tasks_
.begin(),
702 completed_raster_tasks_
.end(),
703 raster_task
) == completed_raster_tasks_
.end());
704 completed_raster_tasks_
.push_back(raster_task
);
705 state
.type
= RasterTaskState::COMPLETED
;
706 // Triggers if the current task belongs to a set that should be empty.
707 DCHECK((state
.task_sets
& ~NonEmptyTaskSetsFromTaskCounts(task_counts_
))
709 RemoveTaskSetsFromTaskCounts(task_counts_
, state
.task_sets
);
713 resource_provider_
->BeginSetPixels(raster_task
->resource()->id());
714 has_performed_uploads_since_last_flush_
= true;
716 bytes_pending_upload_
+= raster_task
->resource()->bytes();
717 raster_tasks_with_pending_upload_
.push_back(raster_task
);
718 state
.type
= RasterTaskState::UPLOADING
;
720 completed_tasks_
.clear();
723 scoped_refptr
<base::debug::ConvertableToTraceFormat
>
724 PixelBufferRasterWorkerPool::StateAsValue() const {
725 scoped_refptr
<base::debug::TracedValue
> state
=
726 new base::debug::TracedValue();
727 state
->SetInteger("completed_count", completed_raster_tasks_
.size());
728 state
->BeginArray("pending_count");
729 for (TaskSet task_set
= 0; task_set
< kNumberOfTaskSets
; ++task_set
)
730 state
->AppendInteger(task_counts_
[task_set
]);
732 state
->SetInteger("pending_upload_count",
733 raster_tasks_with_pending_upload_
.size());
734 state
->BeginDictionary("throttle_state");
735 ThrottleStateAsValueInto(state
.get());
736 state
->EndDictionary();
740 void PixelBufferRasterWorkerPool::ThrottleStateAsValueInto(
741 base::debug::TracedValue
* throttle_state
) const {
742 throttle_state
->SetInteger("bytes_available_for_upload",
743 max_bytes_pending_upload_
- bytes_pending_upload_
);
744 throttle_state
->SetInteger("bytes_pending_upload", bytes_pending_upload_
);
745 throttle_state
->SetInteger("scheduled_raster_task_count",
746 scheduled_raster_task_count_
);