Upstream version 7.36.149.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 <algorithm>
8
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"
13
14 namespace cc {
15 namespace {
16
17 const int kCheckForCompletedRasterTasksDelayMs = 6;
18
19 const size_t kMaxScheduledRasterTasks = 48;
20
21 typedef base::StackVector<RasterTask*, kMaxScheduledRasterTasks>
22     RasterTaskVector;
23
24 }  // namespace
25
26 // static
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,
34                                       task_graph_runner,
35                                       resource_provider,
36                                       max_transfer_buffer_usage_bytes));
37 }
38
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),
48       shutdown_(false),
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_(
57           false),
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) {}
62
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_);
70 }
71
72 Rasterizer* PixelBufferRasterWorkerPool::AsRasterizer() { return this; }
73
74 void PixelBufferRasterWorkerPool::SetClient(RasterizerClient* client) {
75   client_ = client;
76 }
77
78 void PixelBufferRasterWorkerPool::Shutdown() {
79   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::Shutdown");
80
81   shutdown_ = true;
82
83   TaskGraph empty;
84   task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
85   task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
86
87   CheckForCompletedRasterizerTasks();
88   CheckForCompletedUploads();
89
90   check_for_completed_raster_tasks_pending_ = false;
91
92   for (RasterTaskState::Vector::iterator it = raster_task_states_.begin();
93        it != raster_task_states_.end();
94        ++it) {
95     RasterTaskState& state = *it;
96
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;
101     }
102   }
103   DCHECK_EQ(completed_raster_tasks_.size(), raster_task_states_.size());
104 }
105
106 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
107   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
108
109   DCHECK_EQ(queue->required_for_activation_count,
110             static_cast<size_t>(
111                 std::count_if(queue->items.begin(),
112                               queue->items.end(),
113                               RasterTaskQueue::Item::IsRequiredForActivation)));
114
115   if (!should_notify_client_if_no_tasks_are_pending_)
116     TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
117
118   should_notify_client_if_no_tasks_are_pending_ = true;
119   should_notify_client_if_no_tasks_required_for_activation_are_pending_ = true;
120
121   raster_tasks_required_for_activation_count_ = 0u;
122
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();
126        ++it) {
127     const RasterTaskQueue::Item& item = *it;
128     RasterTask* task = item.task;
129
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();
140     }
141
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;
148
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;
156       }
157       continue;
158     }
159
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;
164   }
165
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();
170        ++it) {
171     const RasterTaskQueue::Item& item = *it;
172     RasterTask* task = item.task;
173
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
179     // this task.
180     if (state_it == raster_task_states_.end())
181       continue;
182
183     RasterTaskState& state = *state_it;
184
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;
193     }
194
195     // No longer required for activation.
196     state.required_for_activation = false;
197   }
198
199   raster_tasks_.Swap(queue);
200
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();
206   FlushUploads();
207
208   // Schedule new tasks.
209   ScheduleMoreTasks();
210
211   // Cancel any pending check for completed raster tasks and schedule
212   // another check.
213   check_for_completed_raster_tasks_time_ = base::TimeTicks();
214   ScheduleCheckForCompletedRasterTasks();
215
216   TRACE_EVENT_ASYNC_STEP_INTO1(
217       "cc",
218       "ScheduledTasks",
219       this,
220       StateName(),
221       "state",
222       TracedValue::FromValue(StateAsValue().release()));
223 }
224
225 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
226   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
227
228   CheckForCompletedRasterizerTasks();
229   CheckForCompletedUploads();
230   FlushUploads();
231
232   for (RasterizerTask::Vector::const_iterator it =
233            completed_image_decode_tasks_.begin();
234        it != completed_image_decode_tasks_.end();
235        ++it) {
236     RasterizerTask* task = it->get();
237     task->RunReplyOnOriginThread();
238   }
239   completed_image_decode_tasks_.clear();
240
241   for (RasterTask::Vector::const_iterator it = completed_raster_tasks_.begin();
242        it != completed_raster_tasks_.end();
243        ++it) {
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);
251
252     std::swap(*state_it, raster_task_states_.back());
253     raster_task_states_.pop_back();
254
255     task->RunReplyOnOriginThread();
256   }
257   completed_raster_tasks_.clear();
258 }
259
260 SkCanvas* PixelBufferRasterWorkerPool::AcquireCanvasForRaster(
261     RasterTask* task) {
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());
268 }
269
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());
276 }
277
278 void PixelBufferRasterWorkerPool::OnRasterFinished() {
279   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::OnRasterFinished");
280
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_)
285     return;
286   raster_finished_task_pending_ = false;
287
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();
293 }
294
295 void PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished() {
296   TRACE_EVENT0(
297       "cc",
298       "PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished");
299
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_)
303     return;
304   raster_required_for_activation_finished_task_pending_ = false;
305
306   // This reduces latency between the time when all tasks required for
307   // activation have finished running and the time when the client is
308   // notified.
309   CheckForCompletedRasterTasks();
310 }
311
312 void PixelBufferRasterWorkerPool::FlushUploads() {
313   if (!has_performed_uploads_since_last_flush_)
314     return;
315
316   resource_provider_->ShallowFlushIfSupported();
317   has_performed_uploads_since_last_flush_ = false;
318 }
319
320 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
321   RasterTask::Vector tasks_with_completed_uploads;
322
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);
334
335     // Uploads complete in the order they are issued.
336     if (!resource_provider_->DidSetPixelsComplete(task->resource()->id()))
337       break;
338
339     tasks_with_completed_uploads.push_back(task);
340     raster_tasks_with_pending_upload_.pop_front();
341   }
342
343   DCHECK(client_);
344   bool should_force_some_uploads_to_complete =
345       shutdown_ || client_->ShouldForceTasksRequiredForActivationToComplete();
346
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;
358
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);
365         continue;
366       }
367
368       ++it;
369     }
370
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();
376          ++it) {
377       RasterTask* task = it->get();
378
379       resource_provider_->ForceSetPixelsToComplete(task->resource()->id());
380       has_performed_uploads_since_last_flush_ = true;
381     }
382   }
383
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();
389        ++it) {
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;
397
398     bytes_pending_upload_ -= task->resource()->bytes();
399
400     task->WillComplete();
401     task->CompleteOnOriginThread(this);
402     task->DidComplete();
403
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);
408
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;
418   }
419 }
420
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;
426
427   if (check_for_completed_raster_tasks_pending_)
428     return;
429
430   task_runner_->PostDelayedTask(
431       FROM_HERE,
432       base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks,
433                  weak_ptr_factory_.GetWeakPtr()),
434       delay);
435   check_for_completed_raster_tasks_pending_ = true;
436 }
437
438 void PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks() {
439   if (check_for_completed_raster_tasks_time_.is_null()) {
440     check_for_completed_raster_tasks_pending_ = false;
441     return;
442   }
443
444   base::TimeDelta delay =
445       check_for_completed_raster_tasks_time_ - base::TimeTicks::Now();
446
447   // Post another delayed task if it is not yet time to check for completed
448   // raster tasks.
449   if (delay > base::TimeDelta()) {
450     task_runner_->PostDelayedTask(
451         FROM_HERE,
452         base::Bind(&PixelBufferRasterWorkerPool::OnCheckForCompletedRasterTasks,
453                    weak_ptr_factory_.GetWeakPtr()),
454         delay);
455     return;
456   }
457
458   check_for_completed_raster_tasks_pending_ = false;
459   CheckForCompletedRasterTasks();
460 }
461
462 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
463   TRACE_EVENT0("cc",
464                "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
465
466   DCHECK(should_notify_client_if_no_tasks_are_pending_);
467   check_for_completed_raster_tasks_time_ = base::TimeTicks();
468
469   CheckForCompletedRasterizerTasks();
470   CheckForCompletedUploads();
471   FlushUploads();
472
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());
482
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;
488
489   scheduled_raster_task_count_ = 0;
490   if (PendingRasterTaskCount())
491     ScheduleMoreTasks();
492
493   TRACE_EVENT_ASYNC_STEP_INTO1(
494       "cc",
495       "ScheduledTasks",
496       this,
497       StateName(),
498       "state",
499       TracedValue::FromValue(StateAsValue().release()));
500
501   // Schedule another check for completed raster tasks while there are
502   // pending raster tasks or pending uploads.
503   if (HasPendingTasks())
504     ScheduleCheckForCompletedRasterTasks();
505
506   // Generate client notifications.
507   if (will_notify_client_that_no_tasks_required_for_activation_are_pending) {
508     DCHECK(!HasPendingTasksRequiredForActivation());
509     client_->DidFinishRunningTasksRequiredForActivation();
510   }
511   if (will_notify_client_that_no_tasks_are_pending) {
512     TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
513     DCHECK(!HasPendingTasksRequiredForActivation());
514     client_->DidFinishRunningTasks();
515   }
516 }
517
518 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
519   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
520
521   RasterTaskVector tasks;
522   RasterTaskVector tasks_required_for_activation;
523
524   unsigned priority = kRasterTaskPriorityBase;
525
526   graph_.Reset();
527
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;
531
532   for (RasterTaskQueue::Item::Vector::const_iterator it =
533            raster_tasks_.items.begin();
534        it != raster_tasks_.items.end();
535        ++it) {
536     const RasterTaskQueue::Item& item = *it;
537     RasterTask* task = item.task;
538
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())
546       continue;
547
548     RasterTaskState& state = *state_it;
549
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());
555       continue;
556     }
557
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;
565       continue;
566     }
567
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;
572       continue;
573     }
574
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;
580       continue;
581     }
582
583     // Update |bytes_pending_upload| now that task has cleared all
584     // throttling limits.
585     bytes_pending_upload = new_bytes_pending_upload;
586
587     DCHECK(state.type == RasterTaskState::UNSCHEDULED ||
588            state.type == RasterTaskState::SCHEDULED);
589     state.type = RasterTaskState::SCHEDULED;
590
591     InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
592
593     tasks.container().push_back(task);
594     if (item.required_for_activation)
595       tasks_required_for_activation.container().push_back(task);
596   }
597
598   // Cancel existing OnRasterFinished callbacks.
599   raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
600
601   scoped_refptr<RasterizerTask>
602       new_raster_required_for_activation_finished_task;
603
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,
616             task_runner_.get(),
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();
628          ++it) {
629       graph_.edges.push_back(TaskGraph::Edge(
630           *it, new_raster_required_for_activation_finished_task.get()));
631     }
632   }
633
634   scoped_refptr<RasterizerTask> new_raster_finished_task;
635
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(
643         task_runner_.get(),
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();
654          ++it) {
655       graph_.edges.push_back(
656           TaskGraph::Edge(*it, new_raster_finished_task.get()));
657     }
658   }
659
660   ScheduleTasksOnOriginThread(this, &graph_);
661   task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
662
663   scheduled_raster_task_count_ = scheduled_raster_task_count;
664
665   raster_finished_task_ = new_raster_finished_task;
666   raster_required_for_activation_finished_task_ =
667       new_raster_required_for_activation_finished_task;
668 }
669
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;
675 }
676
677 bool PixelBufferRasterWorkerPool::HasPendingTasks() const {
678   return PendingRasterTaskCount() || !raster_tasks_with_pending_upload_.empty();
679 }
680
681 bool PixelBufferRasterWorkerPool::HasPendingTasksRequiredForActivation() const {
682   return !!raster_tasks_required_for_activation_count_;
683 }
684
685 const char* PixelBufferRasterWorkerPool::StateName() const {
686   if (scheduled_raster_task_count_)
687     return "rasterizing";
688   if (PendingRasterTaskCount())
689     return "throttled";
690   if (!raster_tasks_with_pending_upload_.empty())
691     return "waiting_for_uploads";
692
693   return "finishing";
694 }
695
696 void PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks() {
697   TRACE_EVENT0("cc",
698                "PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks");
699
700   task_graph_runner_->CollectCompletedTasks(namespace_token_,
701                                             &completed_tasks_);
702   for (Task::Vector::const_iterator it = completed_tasks_.begin();
703        it != completed_tasks_.end();
704        ++it) {
705     RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
706
707     RasterTask* raster_task = task->AsRasterTask();
708     if (!raster_task) {
709       task->WillComplete();
710       task->CompleteOnOriginThread(this);
711       task->DidComplete();
712
713       completed_image_decode_tasks_.push_back(task);
714       continue;
715     }
716
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());
722
723     RasterTaskState& state = *state_it;
724     DCHECK_EQ(RasterTaskState::SCHEDULED, state.type);
725
726     // Balanced with MapPixelRasterBuffer() call in AcquireCanvasForRaster().
727     bool content_has_changed = resource_provider_->UnmapPixelRasterBuffer(
728         raster_task->resource()->id());
729
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();
737
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;
748           continue;
749         }
750       }
751
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;
761       continue;
762     }
763
764     DCHECK(raster_task->HasFinishedRunning());
765
766     resource_provider_->BeginSetPixels(raster_task->resource()->id());
767     has_performed_uploads_since_last_flush_ = true;
768
769     bytes_pending_upload_ += raster_task->resource()->bytes();
770     raster_tasks_with_pending_upload_.push_back(raster_task);
771     state.type = RasterTaskState::UPLOADING;
772   }
773   completed_tasks_.clear();
774 }
775
776 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::StateAsValue() const {
777   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
778
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>();
787 }
788
789 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::ThrottleStateAsValue()
790     const {
791   scoped_ptr<base::DictionaryValue> throttle_state(new base::DictionaryValue);
792
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>();
799 }
800
801 }  // namespace cc