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