Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / cc / resources / pixel_buffer_raster_worker_pool.cc
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.
4
5 #include "cc/resources/pixel_buffer_raster_worker_pool.h"
6
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
13 namespace cc {
14 namespace {
15
16 const int kCheckForCompletedRasterTasksDelayMs = 6;
17
18 const size_t kMaxScheduledRasterTasks = 48;
19
20 typedef base::StackVector<internal::WorkerPoolTask*, kMaxScheduledRasterTasks>
21     WorkerPoolTaskVector;
22
23 // Only used as std::find_if predicate for DCHECKs.
24 bool WasCanceled(const internal::RasterWorkerPoolTask* task) {
25   return !task->HasFinishedRunning();
26 }
27
28 }  // namespace
29
30 // static
31 scoped_ptr<RasterWorkerPool> PixelBufferRasterWorkerPool::Create(
32     ResourceProvider* resource_provider,
33     size_t max_transfer_buffer_usage_bytes) {
34   return make_scoped_ptr<RasterWorkerPool>(
35       new PixelBufferRasterWorkerPool(GetTaskGraphRunner(),
36                                       resource_provider,
37                                       max_transfer_buffer_usage_bytes));
38 }
39
40 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
41     internal::TaskGraphRunner* task_graph_runner,
42     ResourceProvider* resource_provider,
43     size_t max_transfer_buffer_usage_bytes)
44     : RasterWorkerPool(task_graph_runner, resource_provider),
45       shutdown_(false),
46       scheduled_raster_task_count_(0),
47       bytes_pending_upload_(0),
48       max_bytes_pending_upload_(max_transfer_buffer_usage_bytes),
49       has_performed_uploads_since_last_flush_(false),
50       check_for_completed_raster_tasks_pending_(false),
51       should_notify_client_if_no_tasks_are_pending_(false),
52       should_notify_client_if_no_tasks_required_for_activation_are_pending_(
53           false),
54       raster_finished_task_pending_(false),
55       raster_required_for_activation_finished_task_pending_(false),
56       weak_factory_(this) {}
57
58 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
59   DCHECK(shutdown_);
60   DCHECK(!check_for_completed_raster_tasks_pending_);
61   DCHECK_EQ(0u, raster_task_states_.size());
62   DCHECK_EQ(0u, raster_tasks_with_pending_upload_.size());
63   DCHECK_EQ(0u, completed_raster_tasks_.size());
64   DCHECK_EQ(0u, completed_image_decode_tasks_.size());
65 }
66
67 void PixelBufferRasterWorkerPool::Shutdown() {
68   shutdown_ = true;
69   RasterWorkerPool::Shutdown();
70
71   CheckForCompletedWorkerPoolTasks();
72   CheckForCompletedUploads();
73
74   weak_factory_.InvalidateWeakPtrs();
75   check_for_completed_raster_tasks_pending_ = false;
76
77   for (RasterTaskStateMap::iterator it = raster_task_states_.begin();
78        it != raster_task_states_.end();
79        ++it) {
80     internal::RasterWorkerPoolTask* task = it->first;
81
82     // All unscheduled tasks need to be canceled.
83     if (it->second == UNSCHEDULED) {
84       completed_raster_tasks_.push_back(task);
85       it->second = COMPLETED;
86     }
87   }
88   DCHECK_EQ(completed_raster_tasks_.size(), raster_task_states_.size());
89 }
90
91 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) {
92   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
93
94   if (!should_notify_client_if_no_tasks_are_pending_)
95     TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
96
97   should_notify_client_if_no_tasks_are_pending_ = true;
98   should_notify_client_if_no_tasks_required_for_activation_are_pending_ = true;
99
100   raster_tasks_required_for_activation_.clear();
101
102   // Build new raster task state map.
103   RasterTaskStateMap new_raster_task_states;
104   for (RasterTaskQueueIterator it(queue); it; ++it) {
105     internal::RasterWorkerPoolTask* task = *it;
106     DCHECK(new_raster_task_states.find(task) == new_raster_task_states.end());
107
108     RasterTaskStateMap::iterator state_it = raster_task_states_.find(task);
109     if (state_it != raster_task_states_.end()) {
110       RasterTaskState state = state_it->second;
111
112       new_raster_task_states[task] = state;
113       // |raster_tasks_required_for_activation_| contains all tasks that need to
114       // complete before we can send a "ready to activate" signal. Tasks that
115       // have already completed should not be part of this set.
116       if (state != COMPLETED && it.required_for_activation())
117         raster_tasks_required_for_activation_.insert(task);
118
119       raster_task_states_.erase(state_it);
120     } else {
121       DCHECK(!task->HasBeenScheduled());
122       new_raster_task_states[task] = UNSCHEDULED;
123       if (it.required_for_activation())
124         raster_tasks_required_for_activation_.insert(task);
125     }
126   }
127
128   // Transfer old raster task state to |new_raster_task_states| and cancel all
129   // remaining unscheduled tasks.
130   for (RasterTaskStateMap::iterator it = raster_task_states_.begin();
131        it != raster_task_states_.end();
132        ++it) {
133     internal::RasterWorkerPoolTask* task = it->first;
134     DCHECK(new_raster_task_states.find(task) == new_raster_task_states.end());
135
136     // Unscheduled task can be canceled.
137     if (it->second == UNSCHEDULED) {
138       DCHECK(!task->HasBeenScheduled());
139       DCHECK(std::find(completed_raster_tasks_.begin(),
140                        completed_raster_tasks_.end(),
141                        task) == completed_raster_tasks_.end());
142       completed_raster_tasks_.push_back(task);
143       new_raster_task_states[task] = COMPLETED;
144       continue;
145     }
146
147     // Move state to |new_raster_task_states|.
148     new_raster_task_states[task] = it->second;
149   }
150
151   raster_tasks_.Swap(queue);
152   raster_task_states_.swap(new_raster_task_states);
153
154   // Check for completed tasks when ScheduleTasks() is called as
155   // priorities might have changed and this maximizes the number
156   // of top priority tasks that are scheduled.
157   CheckForCompletedWorkerPoolTasks();
158   CheckForCompletedUploads();
159   FlushUploads();
160
161   // Schedule new tasks.
162   ScheduleMoreTasks();
163
164   // Cancel any pending check for completed raster tasks and schedule
165   // another check.
166   check_for_completed_raster_tasks_time_ = base::TimeTicks();
167   ScheduleCheckForCompletedRasterTasks();
168
169   TRACE_EVENT_ASYNC_STEP_INTO1(
170       "cc",
171       "ScheduledTasks",
172       this,
173       StateName(),
174       "state",
175       TracedValue::FromValue(StateAsValue().release()));
176 }
177
178 unsigned PixelBufferRasterWorkerPool::GetResourceTarget() const {
179   return GL_TEXTURE_2D;
180 }
181
182 ResourceFormat PixelBufferRasterWorkerPool::GetResourceFormat() const {
183   return resource_provider()->memory_efficient_texture_format();
184 }
185
186 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
187   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
188
189   CheckForCompletedWorkerPoolTasks();
190   CheckForCompletedUploads();
191   FlushUploads();
192
193   while (!completed_image_decode_tasks_.empty()) {
194     internal::WorkerPoolTask* task =
195         completed_image_decode_tasks_.front().get();
196
197     task->RunReplyOnOriginThread();
198
199     completed_image_decode_tasks_.pop_front();
200   }
201
202   while (!completed_raster_tasks_.empty()) {
203     internal::RasterWorkerPoolTask* task =
204         completed_raster_tasks_.front().get();
205     DCHECK(raster_task_states_.find(task) != raster_task_states_.end());
206     DCHECK_EQ(COMPLETED, raster_task_states_[task]);
207
208     raster_task_states_.erase(task);
209
210     task->RunReplyOnOriginThread();
211
212     completed_raster_tasks_.pop_front();
213   }
214 }
215
216 SkCanvas* PixelBufferRasterWorkerPool::AcquireCanvasForRaster(
217     internal::RasterWorkerPoolTask* task) {
218   resource_provider()->AcquirePixelRasterBuffer(task->resource()->id());
219   return resource_provider()->MapPixelRasterBuffer(task->resource()->id());
220 }
221
222 void PixelBufferRasterWorkerPool::OnRasterCompleted(
223     internal::RasterWorkerPoolTask* task,
224     const PicturePileImpl::Analysis& analysis) {
225   TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc"),
226                "PixelBufferRasterWorkerPool::OnRasterCompleted",
227                "was_canceled",
228                !task->HasFinishedRunning(),
229                "needs_upload",
230                task->HasFinishedRunning() && !analysis.is_solid_color);
231
232   DCHECK(raster_task_states_.find(task) != raster_task_states_.end());
233   DCHECK_EQ(SCHEDULED, raster_task_states_[task]);
234
235   // Balanced with MapPixelRasterBuffer() call in AcquireCanvasForRaster().
236   resource_provider()->UnmapPixelRasterBuffer(task->resource()->id());
237
238   if (!task->HasFinishedRunning() || analysis.is_solid_color) {
239     resource_provider()->ReleasePixelRasterBuffer(task->resource()->id());
240
241     if (!task->HasFinishedRunning()) {
242       // When priorites change, a raster task can be canceled as a result of
243       // no longer being of high enough priority to fit in our throttled
244       // raster task budget. The task has not yet completed in this case.
245       for (RasterTaskQueueIterator it(&raster_tasks_); it; ++it) {
246         if (*it == task) {
247           raster_task_states_[task] = UNSCHEDULED;
248           return;
249         }
250       }
251     }
252
253     DCHECK(std::find(completed_raster_tasks_.begin(),
254                      completed_raster_tasks_.end(),
255                      task) == completed_raster_tasks_.end());
256     completed_raster_tasks_.push_back(task);
257     raster_task_states_[task] = COMPLETED;
258     raster_tasks_required_for_activation_.erase(task);
259     return;
260   }
261
262   DCHECK(task->HasFinishedRunning());
263
264   resource_provider()->BeginSetPixels(task->resource()->id());
265   has_performed_uploads_since_last_flush_ = true;
266
267   bytes_pending_upload_ += task->resource()->bytes();
268   raster_tasks_with_pending_upload_.push_back(task);
269   raster_task_states_[task] = UPLOADING;
270 }
271
272 void PixelBufferRasterWorkerPool::OnImageDecodeCompleted(
273     internal::WorkerPoolTask* task) {
274   completed_image_decode_tasks_.push_back(task);
275 }
276
277 void PixelBufferRasterWorkerPool::OnRasterTasksFinished() {
278   // |should_notify_client_if_no_tasks_are_pending_| can be set to false as
279   // a result of a scheduled CheckForCompletedRasterTasks() call. No need to
280   // perform another check in that case as we've already notified the client.
281   if (!should_notify_client_if_no_tasks_are_pending_)
282     return;
283   raster_finished_task_pending_ = false;
284
285   // Call CheckForCompletedRasterTasks() when we've finished running all
286   // raster tasks needed since last time ScheduleTasks() was called.
287   // This reduces latency between the time when all tasks have finished
288   // running and the time when the client is notified.
289   CheckForCompletedRasterTasks();
290 }
291
292 void PixelBufferRasterWorkerPool::OnRasterTasksRequiredForActivationFinished() {
293   // Analogous to OnRasterTasksFinished(), there's no need to call
294   // CheckForCompletedRasterTasks() if the client has already been notified.
295   if (!should_notify_client_if_no_tasks_required_for_activation_are_pending_)
296     return;
297   raster_required_for_activation_finished_task_pending_ = false;
298
299   // This reduces latency between the time when all tasks required for
300   // activation have finished running and the time when the client is
301   // notified.
302   CheckForCompletedRasterTasks();
303 }
304
305 void PixelBufferRasterWorkerPool::FlushUploads() {
306   if (!has_performed_uploads_since_last_flush_)
307     return;
308
309   resource_provider()->ShallowFlushIfSupported();
310   has_performed_uploads_since_last_flush_ = false;
311 }
312
313 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
314   RasterTaskDeque tasks_with_completed_uploads;
315
316   // First check if any have completed.
317   while (!raster_tasks_with_pending_upload_.empty()) {
318     internal::RasterWorkerPoolTask* task =
319         raster_tasks_with_pending_upload_.front().get();
320     DCHECK(raster_task_states_.find(task) != raster_task_states_.end());
321     DCHECK_EQ(UPLOADING, raster_task_states_[task]);
322
323     // Uploads complete in the order they are issued.
324     if (!resource_provider()->DidSetPixelsComplete(task->resource()->id()))
325       break;
326
327     tasks_with_completed_uploads.push_back(task);
328     raster_tasks_with_pending_upload_.pop_front();
329   }
330
331   DCHECK(client());
332   bool should_force_some_uploads_to_complete =
333       shutdown_ || client()->ShouldForceTasksRequiredForActivationToComplete();
334
335   if (should_force_some_uploads_to_complete) {
336     RasterTaskDeque tasks_with_uploads_to_force;
337     RasterTaskDeque::iterator it = raster_tasks_with_pending_upload_.begin();
338     while (it != raster_tasks_with_pending_upload_.end()) {
339       internal::RasterWorkerPoolTask* task = it->get();
340       DCHECK(raster_task_states_.find(task) != raster_task_states_.end());
341
342       // Force all uploads required for activation to complete.
343       // During shutdown, force all pending uploads to complete.
344       if (shutdown_ || IsRasterTaskRequiredForActivation(task)) {
345         tasks_with_uploads_to_force.push_back(task);
346         tasks_with_completed_uploads.push_back(task);
347         it = raster_tasks_with_pending_upload_.erase(it);
348         continue;
349       }
350
351       ++it;
352     }
353
354     // Force uploads in reverse order. Since forcing can cause a wait on
355     // all previous uploads, we would rather wait only once downstream.
356     for (RasterTaskDeque::reverse_iterator it =
357              tasks_with_uploads_to_force.rbegin();
358          it != tasks_with_uploads_to_force.rend();
359          ++it) {
360       resource_provider()->ForceSetPixelsToComplete((*it)->resource()->id());
361       has_performed_uploads_since_last_flush_ = true;
362     }
363   }
364
365   // Release shared memory and move tasks with completed uploads
366   // to |completed_raster_tasks_|.
367   while (!tasks_with_completed_uploads.empty()) {
368     internal::RasterWorkerPoolTask* task =
369         tasks_with_completed_uploads.front().get();
370
371     // It's now safe to release the pixel buffer and the shared memory.
372     resource_provider()->ReleasePixelRasterBuffer(task->resource()->id());
373
374     bytes_pending_upload_ -= task->resource()->bytes();
375
376     DCHECK(std::find(completed_raster_tasks_.begin(),
377                      completed_raster_tasks_.end(),
378                      task) == completed_raster_tasks_.end());
379     completed_raster_tasks_.push_back(task);
380     raster_task_states_[task] = COMPLETED;
381
382     raster_tasks_required_for_activation_.erase(task);
383
384     tasks_with_completed_uploads.pop_front();
385   }
386 }
387
388 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() {
389   base::TimeDelta delay =
390       base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs);
391   if (check_for_completed_raster_tasks_time_.is_null())
392     check_for_completed_raster_tasks_time_ = base::TimeTicks::Now() + delay;
393
394   if (check_for_completed_raster_tasks_pending_)
395     return;
396
397   base::MessageLoopProxy::current()->PostDelayedTask(
398       FROM_HERE,
399       base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks,
400                  weak_factory_.GetWeakPtr()),
401       delay);
402   check_for_completed_raster_tasks_pending_ = true;
403 }
404
405 void PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks() {
406   if (check_for_completed_raster_tasks_time_.is_null()) {
407     check_for_completed_raster_tasks_pending_ = false;
408     return;
409   }
410
411   base::TimeDelta delay =
412       check_for_completed_raster_tasks_time_ - base::TimeTicks::Now();
413
414   // Post another delayed task if it is not yet time to check for completed
415   // raster tasks.
416   if (delay > base::TimeDelta()) {
417     base::MessageLoopProxy::current()->PostDelayedTask(
418         FROM_HERE,
419         base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks,
420                    weak_factory_.GetWeakPtr()),
421         delay);
422     return;
423   }
424
425   check_for_completed_raster_tasks_pending_ = false;
426   CheckForCompletedRasterTasks();
427 }
428
429 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
430   TRACE_EVENT0("cc",
431                "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
432
433   DCHECK(should_notify_client_if_no_tasks_are_pending_);
434   check_for_completed_raster_tasks_time_ = base::TimeTicks();
435
436   CheckForCompletedWorkerPoolTasks();
437   CheckForCompletedUploads();
438   FlushUploads();
439
440   // Determine what client notifications to generate.
441   bool will_notify_client_that_no_tasks_required_for_activation_are_pending =
442       (should_notify_client_if_no_tasks_required_for_activation_are_pending_ &&
443        !raster_required_for_activation_finished_task_pending_ &&
444        !HasPendingTasksRequiredForActivation());
445   bool will_notify_client_that_no_tasks_are_pending =
446       (should_notify_client_if_no_tasks_are_pending_ &&
447        !raster_required_for_activation_finished_task_pending_ &&
448        !raster_finished_task_pending_ && !HasPendingTasks());
449
450   // Adjust the need to generate notifications before scheduling more tasks.
451   should_notify_client_if_no_tasks_required_for_activation_are_pending_ &=
452       !will_notify_client_that_no_tasks_required_for_activation_are_pending;
453   should_notify_client_if_no_tasks_are_pending_ &=
454       !will_notify_client_that_no_tasks_are_pending;
455
456   scheduled_raster_task_count_ = 0;
457   if (PendingRasterTaskCount())
458     ScheduleMoreTasks();
459
460   TRACE_EVENT_ASYNC_STEP_INTO1(
461       "cc",
462       "ScheduledTasks",
463       this,
464       StateName(),
465       "state",
466       TracedValue::FromValue(StateAsValue().release()));
467
468   // Schedule another check for completed raster tasks while there are
469   // pending raster tasks or pending uploads.
470   if (HasPendingTasks())
471     ScheduleCheckForCompletedRasterTasks();
472
473   // Generate client notifications.
474   if (will_notify_client_that_no_tasks_required_for_activation_are_pending) {
475     DCHECK(std::find_if(raster_tasks_required_for_activation_.begin(),
476                         raster_tasks_required_for_activation_.end(),
477                         WasCanceled) ==
478            raster_tasks_required_for_activation_.end());
479     client()->DidFinishRunningTasksRequiredForActivation();
480   }
481   if (will_notify_client_that_no_tasks_are_pending) {
482     TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
483     DCHECK(!HasPendingTasksRequiredForActivation());
484     client()->DidFinishRunningTasks();
485   }
486 }
487
488 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
489   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
490
491   WorkerPoolTaskVector tasks;
492   WorkerPoolTaskVector tasks_required_for_activation;
493
494   unsigned priority = kRasterTaskPriorityBase;
495
496   graph_.Reset();
497
498   size_t bytes_pending_upload = bytes_pending_upload_;
499   bool did_throttle_raster_tasks = false;
500
501   for (RasterTaskQueueIterator it(&raster_tasks_); it; ++it) {
502     internal::RasterWorkerPoolTask* task = *it;
503
504     // |raster_task_states_| contains the state of all tasks that we have not
505     // yet run reply callbacks for.
506     RasterTaskStateMap::iterator state_it = raster_task_states_.find(task);
507     if (state_it == raster_task_states_.end())
508       continue;
509
510     // Skip task if completed.
511     if (state_it->second == COMPLETED) {
512       DCHECK(std::find(completed_raster_tasks_.begin(),
513                        completed_raster_tasks_.end(),
514                        task) != completed_raster_tasks_.end());
515       continue;
516     }
517
518     // All raster tasks need to be throttled by bytes of pending uploads.
519     size_t new_bytes_pending_upload = bytes_pending_upload;
520     new_bytes_pending_upload += task->resource()->bytes();
521     if (new_bytes_pending_upload > max_bytes_pending_upload_) {
522       did_throttle_raster_tasks = true;
523       break;
524     }
525
526     // If raster has finished, just update |bytes_pending_upload|.
527     if (state_it->second == UPLOADING) {
528       DCHECK(task->HasCompleted());
529       bytes_pending_upload = new_bytes_pending_upload;
530       continue;
531     }
532
533     // Throttle raster tasks based on kMaxScheduledRasterTasks.
534     if (tasks.container().size() >= kMaxScheduledRasterTasks) {
535       did_throttle_raster_tasks = true;
536       break;
537     }
538
539     // Update |bytes_pending_upload| now that task has cleared all
540     // throttling limits.
541     bytes_pending_upload = new_bytes_pending_upload;
542
543     DCHECK(state_it->second == UNSCHEDULED || state_it->second == SCHEDULED);
544     state_it->second = SCHEDULED;
545
546     InsertNodeForRasterTask(&graph_, task, task->dependencies(), priority++);
547
548     tasks.container().push_back(task);
549     if (it.required_for_activation())
550       tasks_required_for_activation.container().push_back(task);
551   }
552
553   scoped_refptr<internal::WorkerPoolTask>
554       new_raster_required_for_activation_finished_task;
555
556   size_t scheduled_raster_task_required_for_activation_count =
557       tasks_required_for_activation.container().size();
558   DCHECK_LE(scheduled_raster_task_required_for_activation_count,
559             raster_tasks_required_for_activation_.size());
560   // Schedule OnRasterTasksRequiredForActivationFinished call only when
561   // notification is pending and throttling is not preventing all pending
562   // tasks required for activation from being scheduled.
563   if (scheduled_raster_task_required_for_activation_count ==
564           raster_tasks_required_for_activation_.size() &&
565       should_notify_client_if_no_tasks_required_for_activation_are_pending_) {
566     new_raster_required_for_activation_finished_task =
567         CreateRasterRequiredForActivationFinishedTask(
568             raster_tasks_required_for_activation_.size());
569     raster_required_for_activation_finished_task_pending_ = true;
570     InsertNodeForTask(&graph_,
571                       new_raster_required_for_activation_finished_task.get(),
572                       kRasterRequiredForActivationFinishedTaskPriority,
573                       scheduled_raster_task_required_for_activation_count);
574     for (WorkerPoolTaskVector::ContainerType::const_iterator it =
575              tasks_required_for_activation.container().begin();
576          it != tasks_required_for_activation.container().end();
577          ++it) {
578       graph_.edges.push_back(internal::TaskGraph::Edge(
579           *it, new_raster_required_for_activation_finished_task.get()));
580     }
581   }
582
583   scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task;
584
585   size_t scheduled_raster_task_count = tasks.container().size();
586   DCHECK_LE(scheduled_raster_task_count, PendingRasterTaskCount());
587   // Schedule OnRasterTasksFinished call only when notification is pending
588   // and throttling is not preventing all pending tasks from being scheduled.
589   if (!did_throttle_raster_tasks &&
590       should_notify_client_if_no_tasks_are_pending_) {
591     new_raster_finished_task = CreateRasterFinishedTask();
592     raster_finished_task_pending_ = true;
593     InsertNodeForTask(&graph_,
594                       new_raster_finished_task.get(),
595                       kRasterFinishedTaskPriority,
596                       scheduled_raster_task_count);
597     for (WorkerPoolTaskVector::ContainerType::const_iterator it =
598              tasks.container().begin();
599          it != tasks.container().end();
600          ++it) {
601       graph_.edges.push_back(
602           internal::TaskGraph::Edge(*it, new_raster_finished_task.get()));
603     }
604   }
605
606   SetTaskGraph(&graph_);
607
608   scheduled_raster_task_count_ = scheduled_raster_task_count;
609
610   set_raster_finished_task(new_raster_finished_task);
611   set_raster_required_for_activation_finished_task(
612       new_raster_required_for_activation_finished_task);
613 }
614
615 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
616   unsigned num_completed_raster_tasks =
617       raster_tasks_with_pending_upload_.size() + completed_raster_tasks_.size();
618   DCHECK_GE(raster_task_states_.size(), num_completed_raster_tasks);
619   return raster_task_states_.size() - num_completed_raster_tasks;
620 }
621
622 bool PixelBufferRasterWorkerPool::HasPendingTasks() const {
623   return PendingRasterTaskCount() || !raster_tasks_with_pending_upload_.empty();
624 }
625
626 bool PixelBufferRasterWorkerPool::HasPendingTasksRequiredForActivation() const {
627   return !raster_tasks_required_for_activation_.empty();
628 }
629
630 const char* PixelBufferRasterWorkerPool::StateName() const {
631   if (scheduled_raster_task_count_)
632     return "rasterizing";
633   if (PendingRasterTaskCount())
634     return "throttled";
635   if (!raster_tasks_with_pending_upload_.empty())
636     return "waiting_for_uploads";
637
638   return "finishing";
639 }
640
641 void PixelBufferRasterWorkerPool::CheckForCompletedWorkerPoolTasks() {
642   CollectCompletedWorkerPoolTasks(&completed_tasks_);
643   for (internal::Task::Vector::const_iterator it = completed_tasks_.begin();
644        it != completed_tasks_.end();
645        ++it) {
646     internal::WorkerPoolTask* task =
647         static_cast<internal::WorkerPoolTask*>(it->get());
648
649     task->WillComplete();
650     task->CompleteOnOriginThread(this);
651     task->DidComplete();
652   }
653   completed_tasks_.clear();
654 }
655
656 bool PixelBufferRasterWorkerPool::IsRasterTaskRequiredForActivation(
657     internal::RasterWorkerPoolTask* task) const {
658   return raster_tasks_required_for_activation_.find(task) !=
659          raster_tasks_required_for_activation_.end();
660 }
661
662 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::StateAsValue() const {
663   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
664
665   state->SetInteger("completed_count", completed_raster_tasks_.size());
666   state->SetInteger("pending_count", raster_task_states_.size());
667   state->SetInteger("pending_upload_count",
668                     raster_tasks_with_pending_upload_.size());
669   state->SetInteger("pending_required_for_activation_count",
670                     raster_tasks_required_for_activation_.size());
671   state->Set("throttle_state", ThrottleStateAsValue().release());
672   return state.PassAs<base::Value>();
673 }
674
675 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::ThrottleStateAsValue()
676     const {
677   scoped_ptr<base::DictionaryValue> throttle_state(new base::DictionaryValue);
678
679   throttle_state->SetInteger("bytes_available_for_upload",
680                              max_bytes_pending_upload_ - bytes_pending_upload_);
681   throttle_state->SetInteger("bytes_pending_upload", bytes_pending_upload_);
682   throttle_state->SetInteger("scheduled_raster_task_count",
683                              scheduled_raster_task_count_);
684   return throttle_state.PassAs<base::Value>();
685 }
686
687 }  // namespace cc