ash: Add missing include to test from r236852.
[chromium-blink-merge.git] / cc / resources / pixel_buffer_raster_worker_pool.cc
blobedd7d6c99d69119a7c84544c0c2b7a0f612fc078
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 "base/containers/stack_container.h"
8 #include "base/debug/trace_event.h"
9 #include "base/values.h"
10 #include "cc/debug/traced_value.h"
11 #include "cc/resources/resource.h"
12 #include "third_party/skia/include/core/SkBitmapDevice.h"
14 #if defined(OS_ANDROID)
15 #include "base/android/sys_utils.h"
16 #endif
18 namespace cc {
20 namespace {
22 class PixelBufferWorkerPoolTaskImpl : public internal::WorkerPoolTask {
23 public:
24 typedef base::Callback<void(bool was_canceled, bool needs_upload)> Reply;
26 PixelBufferWorkerPoolTaskImpl(internal::RasterWorkerPoolTask* task,
27 uint8_t* buffer,
28 const Reply& reply)
29 : task_(task),
30 buffer_(buffer),
31 reply_(reply),
32 needs_upload_(false) {
35 // Overridden from internal::WorkerPoolTask:
36 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {
37 // |buffer_| can be NULL in lost context situations.
38 if (!buffer_) {
39 // |needs_upload_| still needs to be true as task has not
40 // been canceled.
41 needs_upload_ = true;
42 return;
44 needs_upload_ = task_->RunOnWorkerThread(thread_index,
45 buffer_,
46 task_->resource()->size(),
47 0);
49 virtual void CompleteOnOriginThread() OVERRIDE {
50 // |needs_upload_| must be be false if task didn't run.
51 DCHECK(HasFinishedRunning() || !needs_upload_);
52 reply_.Run(!HasFinishedRunning(), needs_upload_);
55 private:
56 virtual ~PixelBufferWorkerPoolTaskImpl() {}
58 scoped_refptr<internal::RasterWorkerPoolTask> task_;
59 uint8_t* buffer_;
60 const Reply reply_;
61 bool needs_upload_;
63 DISALLOW_COPY_AND_ASSIGN(PixelBufferWorkerPoolTaskImpl);
66 const int kCheckForCompletedRasterTasksDelayMs = 6;
68 const size_t kMaxScheduledRasterTasks = 48;
70 typedef base::StackVector<internal::GraphNode*,
71 kMaxScheduledRasterTasks> NodeVector;
73 void AddDependenciesToGraphNode(
74 internal::GraphNode* node,
75 const NodeVector::ContainerType& dependencies) {
76 for (NodeVector::ContainerType::const_iterator it = dependencies.begin();
77 it != dependencies.end(); ++it) {
78 internal::GraphNode* dependency = *it;
80 node->add_dependency();
81 dependency->add_dependent(node);
85 // Only used as std::find_if predicate for DCHECKs.
86 bool WasCanceled(const internal::RasterWorkerPoolTask* task) {
87 return task->WasCanceled();
90 } // namespace
92 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
93 ResourceProvider* resource_provider,
94 size_t num_threads,
95 size_t max_transfer_buffer_usage_bytes)
96 : RasterWorkerPool(resource_provider, num_threads),
97 shutdown_(false),
98 scheduled_raster_task_count_(0),
99 bytes_pending_upload_(0),
100 max_bytes_pending_upload_(max_transfer_buffer_usage_bytes),
101 has_performed_uploads_since_last_flush_(false),
102 check_for_completed_raster_tasks_pending_(false),
103 should_notify_client_if_no_tasks_are_pending_(false),
104 should_notify_client_if_no_tasks_required_for_activation_are_pending_(
105 false) {
108 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
109 DCHECK(shutdown_);
110 DCHECK(!check_for_completed_raster_tasks_pending_);
111 DCHECK_EQ(0u, pixel_buffer_tasks_.size());
112 DCHECK_EQ(0u, tasks_with_pending_upload_.size());
113 DCHECK_EQ(0u, completed_tasks_.size());
116 void PixelBufferRasterWorkerPool::Shutdown() {
117 shutdown_ = true;
118 RasterWorkerPool::Shutdown();
119 RasterWorkerPool::CheckForCompletedTasks();
120 CheckForCompletedUploads();
121 check_for_completed_raster_tasks_callback_.Cancel();
122 check_for_completed_raster_tasks_pending_ = false;
123 for (TaskMap::iterator it = pixel_buffer_tasks_.begin();
124 it != pixel_buffer_tasks_.end(); ++it) {
125 internal::RasterWorkerPoolTask* task = it->first;
126 internal::WorkerPoolTask* pixel_buffer_task = it->second.get();
128 // All inactive tasks needs to be canceled.
129 if (!pixel_buffer_task && !task->HasFinishedRunning()) {
130 task->DidRun(true);
131 completed_tasks_.push_back(task);
134 DCHECK_EQ(completed_tasks_.size(), pixel_buffer_tasks_.size());
137 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) {
138 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
140 RasterWorkerPool::SetRasterTasks(queue);
142 if (!should_notify_client_if_no_tasks_are_pending_)
143 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
145 should_notify_client_if_no_tasks_are_pending_ = true;
146 should_notify_client_if_no_tasks_required_for_activation_are_pending_ = true;
148 tasks_required_for_activation_.clear();
150 // Build new pixel buffer task set.
151 TaskMap new_pixel_buffer_tasks;
152 for (RasterTaskVector::const_iterator it = raster_tasks().begin();
153 it != raster_tasks().end(); ++it) {
154 internal::RasterWorkerPoolTask* task = it->get();
155 DCHECK(new_pixel_buffer_tasks.find(task) == new_pixel_buffer_tasks.end());
156 DCHECK(!task->HasCompleted());
157 DCHECK(!task->WasCanceled());
159 new_pixel_buffer_tasks[task] = pixel_buffer_tasks_[task];
160 pixel_buffer_tasks_.erase(task);
162 if (IsRasterTaskRequiredForActivation(task))
163 tasks_required_for_activation_.insert(task);
166 // Transfer remaining pixel buffer tasks to |new_pixel_buffer_tasks|
167 // and cancel all remaining inactive tasks.
168 for (TaskMap::iterator it = pixel_buffer_tasks_.begin();
169 it != pixel_buffer_tasks_.end(); ++it) {
170 internal::RasterWorkerPoolTask* task = it->first;
171 internal::WorkerPoolTask* pixel_buffer_task = it->second.get();
173 // Move task to |new_pixel_buffer_tasks|
174 new_pixel_buffer_tasks[task] = pixel_buffer_task;
176 // Inactive task can be canceled.
177 if (!pixel_buffer_task && !task->HasFinishedRunning()) {
178 task->DidRun(true);
179 DCHECK(std::find(completed_tasks_.begin(),
180 completed_tasks_.end(),
181 task) == completed_tasks_.end());
182 completed_tasks_.push_back(task);
183 } else if (IsRasterTaskRequiredForActivation(task)) {
184 tasks_required_for_activation_.insert(task);
188 // |tasks_required_for_activation_| contains all tasks that need to
189 // complete before we can send a "ready to activate" signal. Tasks
190 // that have already completed should not be part of this set.
191 for (TaskDeque::const_iterator it = completed_tasks_.begin();
192 it != completed_tasks_.end() && !tasks_required_for_activation_.empty();
193 ++it) {
194 tasks_required_for_activation_.erase(*it);
197 pixel_buffer_tasks_.swap(new_pixel_buffer_tasks);
199 // Check for completed tasks when ScheduleTasks() is called as
200 // priorities might have changed and this maximizes the number
201 // of top priority tasks that are scheduled.
202 RasterWorkerPool::CheckForCompletedTasks();
203 CheckForCompletedUploads();
204 FlushUploads();
206 // Schedule new tasks.
207 ScheduleMoreTasks();
209 // Cancel any pending check for completed raster tasks and schedule
210 // another check.
211 check_for_completed_raster_tasks_callback_.Cancel();
212 check_for_completed_raster_tasks_pending_ = false;
213 ScheduleCheckForCompletedRasterTasks();
215 TRACE_EVENT_ASYNC_STEP_INTO1(
216 "cc", "ScheduledTasks", this, StateName(),
217 "state", TracedValue::FromValue(StateAsValue().release()));
220 ResourceFormat PixelBufferRasterWorkerPool::GetResourceFormat() const {
221 return resource_provider()->memory_efficient_texture_format();
224 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
225 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
227 RasterWorkerPool::CheckForCompletedTasks();
228 CheckForCompletedUploads();
229 FlushUploads();
231 TaskDeque completed_tasks;
232 completed_tasks_.swap(completed_tasks);
234 while (!completed_tasks.empty()) {
235 internal::RasterWorkerPoolTask* task = completed_tasks.front().get();
236 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end());
238 pixel_buffer_tasks_.erase(task);
240 task->WillComplete();
241 task->CompleteOnOriginThread();
242 task->DidComplete();
244 completed_tasks.pop_front();
248 void PixelBufferRasterWorkerPool::OnRasterTasksFinished() {
249 // |should_notify_client_if_no_tasks_are_pending_| can be set to false as
250 // a result of a scheduled CheckForCompletedRasterTasks() call. No need to
251 // perform another check in that case as we've already notified the client.
252 if (!should_notify_client_if_no_tasks_are_pending_)
253 return;
255 // Call CheckForCompletedRasterTasks() when we've finished running all
256 // raster tasks needed since last time ScheduleTasks() was called.
257 // This reduces latency between the time when all tasks have finished
258 // running and the time when the client is notified.
259 CheckForCompletedRasterTasks();
262 void PixelBufferRasterWorkerPool::OnRasterTasksRequiredForActivationFinished() {
263 // Analogous to OnRasterTasksFinished(), there's no need to call
264 // CheckForCompletedRasterTasks() if the client has already been notified.
265 if (!should_notify_client_if_no_tasks_required_for_activation_are_pending_)
266 return;
268 // This reduces latency between the time when all tasks required for
269 // activation have finished running and the time when the client is
270 // notified.
271 CheckForCompletedRasterTasks();
274 void PixelBufferRasterWorkerPool::FlushUploads() {
275 if (!has_performed_uploads_since_last_flush_)
276 return;
278 resource_provider()->ShallowFlushIfSupported();
279 has_performed_uploads_since_last_flush_ = false;
282 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
283 TaskDeque tasks_with_completed_uploads;
285 // First check if any have completed.
286 while (!tasks_with_pending_upload_.empty()) {
287 internal::RasterWorkerPoolTask* task =
288 tasks_with_pending_upload_.front().get();
290 // Uploads complete in the order they are issued.
291 if (!resource_provider()->DidSetPixelsComplete(task->resource()->id()))
292 break;
294 tasks_with_completed_uploads.push_back(task);
295 tasks_with_pending_upload_.pop_front();
298 DCHECK(client());
299 bool should_force_some_uploads_to_complete =
300 shutdown_ || client()->ShouldForceTasksRequiredForActivationToComplete();
302 if (should_force_some_uploads_to_complete) {
303 TaskDeque tasks_with_uploads_to_force;
304 TaskDeque::iterator it = tasks_with_pending_upload_.begin();
305 while (it != tasks_with_pending_upload_.end()) {
306 internal::RasterWorkerPoolTask* task = it->get();
307 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end());
309 // Force all uploads required for activation to complete.
310 // During shutdown, force all pending uploads to complete.
311 if (shutdown_ || IsRasterTaskRequiredForActivation(task)) {
312 tasks_with_uploads_to_force.push_back(task);
313 tasks_with_completed_uploads.push_back(task);
314 it = tasks_with_pending_upload_.erase(it);
315 continue;
318 ++it;
321 // Force uploads in reverse order. Since forcing can cause a wait on
322 // all previous uploads, we would rather wait only once downstream.
323 for (TaskDeque::reverse_iterator it = tasks_with_uploads_to_force.rbegin();
324 it != tasks_with_uploads_to_force.rend();
325 ++it) {
326 resource_provider()->ForceSetPixelsToComplete((*it)->resource()->id());
327 has_performed_uploads_since_last_flush_ = true;
331 // Release shared memory and move tasks with completed uploads
332 // to |completed_tasks_|.
333 while (!tasks_with_completed_uploads.empty()) {
334 internal::RasterWorkerPoolTask* task =
335 tasks_with_completed_uploads.front().get();
337 // It's now safe to release the pixel buffer and the shared memory.
338 resource_provider()->ReleasePixelBuffer(task->resource()->id());
340 bytes_pending_upload_ -= task->resource()->bytes();
342 task->DidRun(false);
344 DCHECK(std::find(completed_tasks_.begin(),
345 completed_tasks_.end(),
346 task) == completed_tasks_.end());
347 completed_tasks_.push_back(task);
349 tasks_required_for_activation_.erase(task);
351 tasks_with_completed_uploads.pop_front();
355 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() {
356 if (check_for_completed_raster_tasks_pending_)
357 return;
359 check_for_completed_raster_tasks_callback_.Reset(
360 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks,
361 base::Unretained(this)));
362 base::MessageLoopProxy::current()->PostDelayedTask(
363 FROM_HERE,
364 check_for_completed_raster_tasks_callback_.callback(),
365 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs));
366 check_for_completed_raster_tasks_pending_ = true;
369 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
370 TRACE_EVENT0(
371 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
373 DCHECK(should_notify_client_if_no_tasks_are_pending_);
375 check_for_completed_raster_tasks_callback_.Cancel();
376 check_for_completed_raster_tasks_pending_ = false;
378 RasterWorkerPool::CheckForCompletedTasks();
379 CheckForCompletedUploads();
380 FlushUploads();
382 // Determine what client notifications to generate.
383 bool will_notify_client_that_no_tasks_required_for_activation_are_pending =
384 (should_notify_client_if_no_tasks_required_for_activation_are_pending_ &&
385 !HasPendingTasksRequiredForActivation());
386 bool will_notify_client_that_no_tasks_are_pending =
387 (should_notify_client_if_no_tasks_are_pending_ &&
388 !HasPendingTasks());
390 // Adjust the need to generate notifications before scheduling more tasks.
391 should_notify_client_if_no_tasks_required_for_activation_are_pending_ &=
392 !will_notify_client_that_no_tasks_required_for_activation_are_pending;
393 should_notify_client_if_no_tasks_are_pending_ &=
394 !will_notify_client_that_no_tasks_are_pending;
396 scheduled_raster_task_count_ = 0;
397 if (PendingRasterTaskCount())
398 ScheduleMoreTasks();
400 TRACE_EVENT_ASYNC_STEP_INTO1(
401 "cc", "ScheduledTasks", this, StateName(),
402 "state", TracedValue::FromValue(StateAsValue().release()));
404 // Schedule another check for completed raster tasks while there are
405 // pending raster tasks or pending uploads.
406 if (HasPendingTasks())
407 ScheduleCheckForCompletedRasterTasks();
409 // Generate client notifications.
410 if (will_notify_client_that_no_tasks_required_for_activation_are_pending) {
411 DCHECK(std::find_if(raster_tasks_required_for_activation().begin(),
412 raster_tasks_required_for_activation().end(),
413 WasCanceled) ==
414 raster_tasks_required_for_activation().end());
415 client()->DidFinishRunningTasksRequiredForActivation();
417 if (will_notify_client_that_no_tasks_are_pending) {
418 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
419 DCHECK(!HasPendingTasksRequiredForActivation());
420 client()->DidFinishRunningTasks();
424 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
425 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
427 enum RasterTaskType {
428 PREPAINT_TYPE = 0,
429 REQUIRED_FOR_ACTIVATION_TYPE = 1,
430 NUM_TYPES = 2
432 NodeVector tasks[NUM_TYPES];
433 unsigned priority = 2u; // 0-1 reserved for RasterFinished tasks.
434 TaskGraph graph;
436 size_t bytes_pending_upload = bytes_pending_upload_;
438 for (RasterTaskVector::const_iterator it = raster_tasks().begin();
439 it != raster_tasks().end(); ++it) {
440 internal::RasterWorkerPoolTask* task = it->get();
442 // |pixel_buffer_tasks_| contains all tasks that have not yet completed.
443 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task);
444 if (pixel_buffer_it == pixel_buffer_tasks_.end())
445 continue;
447 // HasFinishedRunning() will return true when set pixels has completed.
448 if (task->HasFinishedRunning()) {
449 DCHECK(std::find(completed_tasks_.begin(),
450 completed_tasks_.end(),
451 task) != completed_tasks_.end());
452 continue;
455 // All raster tasks need to be throttled by bytes of pending uploads.
456 size_t new_bytes_pending_upload = bytes_pending_upload;
457 new_bytes_pending_upload += task->resource()->bytes();
458 if (new_bytes_pending_upload > max_bytes_pending_upload_)
459 break;
461 internal::WorkerPoolTask* pixel_buffer_task = pixel_buffer_it->second.get();
463 // If raster has finished, just update |bytes_pending_upload|.
464 if (pixel_buffer_task && pixel_buffer_task->HasCompleted()) {
465 bytes_pending_upload = new_bytes_pending_upload;
466 continue;
469 // Throttle raster tasks based on kMaxScheduledRasterTasks.
470 size_t scheduled_raster_task_count =
471 tasks[PREPAINT_TYPE].container().size() +
472 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size();
473 if (scheduled_raster_task_count >= kMaxScheduledRasterTasks)
474 break;
476 // Update |bytes_pending_upload| now that task has cleared all
477 // throttling limits.
478 bytes_pending_upload = new_bytes_pending_upload;
480 RasterTaskType type = IsRasterTaskRequiredForActivation(task) ?
481 REQUIRED_FOR_ACTIVATION_TYPE :
482 PREPAINT_TYPE;
484 // Use existing pixel buffer task if available.
485 if (pixel_buffer_task) {
486 tasks[type].container().push_back(
487 CreateGraphNodeForRasterTask(pixel_buffer_task,
488 task->dependencies(),
489 priority++,
490 &graph));
491 continue;
494 // Request a pixel buffer. This will reserve shared memory.
495 resource_provider()->AcquirePixelBuffer(task->resource()->id());
497 // MapPixelBuffer() returns NULL if context was lost at the time
498 // AcquirePixelBuffer() was called. For simplicity we still post
499 // a raster task that is essentially a noop in these situations.
500 uint8* buffer = resource_provider()->MapPixelBuffer(
501 task->resource()->id());
503 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task(
504 new PixelBufferWorkerPoolTaskImpl(
505 task,
506 buffer,
507 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted,
508 base::Unretained(this),
509 make_scoped_refptr(task))));
510 pixel_buffer_tasks_[task] = new_pixel_buffer_task;
511 tasks[type].container().push_back(
512 CreateGraphNodeForRasterTask(new_pixel_buffer_task.get(),
513 task->dependencies(),
514 priority++,
515 &graph));
518 scoped_refptr<internal::WorkerPoolTask>
519 new_raster_required_for_activation_finished_task;
521 size_t scheduled_raster_task_required_for_activation_count =
522 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size();
523 DCHECK_LE(scheduled_raster_task_required_for_activation_count,
524 tasks_required_for_activation_.size());
525 // Schedule OnRasterTasksRequiredForActivationFinished call only when
526 // notification is pending and throttling is not preventing all pending
527 // tasks required for activation from being scheduled.
528 if (scheduled_raster_task_required_for_activation_count ==
529 tasks_required_for_activation_.size() &&
530 should_notify_client_if_no_tasks_required_for_activation_are_pending_) {
531 new_raster_required_for_activation_finished_task =
532 CreateRasterRequiredForActivationFinishedTask();
533 internal::GraphNode* raster_required_for_activation_finished_node =
534 CreateGraphNodeForTask(
535 new_raster_required_for_activation_finished_task.get(),
536 0u, // Priority 0
537 &graph);
538 AddDependenciesToGraphNode(
539 raster_required_for_activation_finished_node,
540 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container());
543 scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task;
545 size_t scheduled_raster_task_count =
546 tasks[PREPAINT_TYPE].container().size() +
547 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size();
548 DCHECK_LE(scheduled_raster_task_count, PendingRasterTaskCount());
549 // Schedule OnRasterTasksFinished call only when notification is pending
550 // and throttling is not preventing all pending tasks from being scheduled.
551 if (scheduled_raster_task_count == PendingRasterTaskCount() &&
552 should_notify_client_if_no_tasks_are_pending_) {
553 new_raster_finished_task = CreateRasterFinishedTask();
554 internal::GraphNode* raster_finished_node =
555 CreateGraphNodeForTask(new_raster_finished_task.get(),
556 1u, // Priority 1
557 &graph);
558 for (unsigned type = 0; type < NUM_TYPES; ++type) {
559 AddDependenciesToGraphNode(
560 raster_finished_node,
561 tasks[type].container());
565 SetTaskGraph(&graph);
567 scheduled_raster_task_count_ = scheduled_raster_task_count;
569 set_raster_finished_task(new_raster_finished_task);
570 set_raster_required_for_activation_finished_task(
571 new_raster_required_for_activation_finished_task);
574 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted(
575 scoped_refptr<internal::RasterWorkerPoolTask> task,
576 bool was_canceled,
577 bool needs_upload) {
578 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc"),
579 "PixelBufferRasterWorkerPool::OnRasterTaskCompleted",
580 "was_canceled", was_canceled,
581 "needs_upload", needs_upload);
583 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end());
585 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks().
586 resource_provider()->UnmapPixelBuffer(task->resource()->id());
588 if (!needs_upload) {
589 resource_provider()->ReleasePixelBuffer(task->resource()->id());
591 if (was_canceled) {
592 // When priorites change, a raster task can be canceled as a result of
593 // no longer being of high enough priority to fit in our throttled
594 // raster task budget. The task has not yet completed in this case.
595 RasterTaskVector::const_iterator it = std::find(raster_tasks().begin(),
596 raster_tasks().end(),
597 task);
598 if (it != raster_tasks().end()) {
599 pixel_buffer_tasks_[task.get()] = NULL;
600 return;
604 task->DidRun(was_canceled);
605 DCHECK(std::find(completed_tasks_.begin(),
606 completed_tasks_.end(),
607 task) == completed_tasks_.end());
608 completed_tasks_.push_back(task);
609 tasks_required_for_activation_.erase(task);
610 return;
613 DCHECK(!was_canceled);
615 resource_provider()->BeginSetPixels(task->resource()->id());
616 has_performed_uploads_since_last_flush_ = true;
618 bytes_pending_upload_ += task->resource()->bytes();
619 tasks_with_pending_upload_.push_back(task);
622 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
623 unsigned num_completed_raster_tasks =
624 tasks_with_pending_upload_.size() + completed_tasks_.size();
625 DCHECK_GE(pixel_buffer_tasks_.size(), num_completed_raster_tasks);
626 return pixel_buffer_tasks_.size() - num_completed_raster_tasks;
629 bool PixelBufferRasterWorkerPool::HasPendingTasks() const {
630 return PendingRasterTaskCount() || !tasks_with_pending_upload_.empty();
633 bool PixelBufferRasterWorkerPool::HasPendingTasksRequiredForActivation() const {
634 return !tasks_required_for_activation_.empty();
637 const char* PixelBufferRasterWorkerPool::StateName() const {
638 if (scheduled_raster_task_count_)
639 return "rasterizing";
640 if (PendingRasterTaskCount())
641 return "throttled";
642 if (!tasks_with_pending_upload_.empty())
643 return "waiting_for_uploads";
645 return "finishing";
648 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::StateAsValue() const {
649 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
651 state->SetInteger("completed_count", completed_tasks_.size());
652 state->SetInteger("pending_count", pixel_buffer_tasks_.size());
653 state->SetInteger("pending_upload_count", tasks_with_pending_upload_.size());
654 state->SetInteger("required_for_activation_count",
655 tasks_required_for_activation_.size());
656 state->Set("scheduled_state", ScheduledStateAsValue().release());
657 state->Set("throttle_state", ThrottleStateAsValue().release());
658 return state.PassAs<base::Value>();
661 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::ThrottleStateAsValue()
662 const {
663 scoped_ptr<base::DictionaryValue> throttle_state(new base::DictionaryValue);
665 throttle_state->SetInteger("bytes_available_for_upload",
666 max_bytes_pending_upload_ - bytes_pending_upload_);
667 throttle_state->SetInteger("bytes_pending_upload", bytes_pending_upload_);
668 throttle_state->SetInteger("scheduled_raster_task_count",
669 scheduled_raster_task_count_);
670 return throttle_state.PassAs<base::Value>();
673 } // namespace cc