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 <algorithm>
      8 
      9 #include "base/containers/stack_container.h"
     10 #include "base/debug/trace_event.h"
     11 #include "base/debug/trace_event_argument.h"
     12 #include "base/strings/stringprintf.h"
     13 #include "cc/debug/traced_value.h"
     14 #include "cc/resources/raster_buffer.h"
     15 #include "cc/resources/resource.h"
     16 #include "gpu/command_buffer/client/gles2_interface.h"
     17 #include "third_party/skia/include/utils/SkNullCanvas.h"
     18 
     19 namespace cc {
     20 namespace {
     21 
     22 class RasterBufferImpl : public RasterBuffer {
     23  public:
     24   RasterBufferImpl(ResourceProvider* resource_provider,
     25                    const Resource* resource)
     26       : resource_provider_(resource_provider),
     27         resource_(resource),
     28         buffer_(NULL),
     29         stride_(0) {
     30     resource_provider_->AcquirePixelBuffer(resource_->id());
     31     buffer_ = resource_provider_->MapPixelBuffer(resource_->id(), &stride_);
     32   }
     33 
     34   virtual ~RasterBufferImpl() {
     35     resource_provider_->ReleasePixelBuffer(resource_->id());
     36   }
     37 
     38   // Overridden from RasterBuffer:
     39   virtual skia::RefPtr<SkCanvas> AcquireSkCanvas() OVERRIDE {
     40     if (!buffer_)
     41       return skia::AdoptRef(SkCreateNullCanvas());
     42 
     43     RasterWorkerPool::AcquireBitmapForBuffer(
     44         &bitmap_, buffer_, resource_->format(), resource_->size(), stride_);
     45     return skia::AdoptRef(new SkCanvas(bitmap_));
     46   }
     47   virtual void ReleaseSkCanvas(const skia::RefPtr<SkCanvas>& canvas) OVERRIDE {
     48     if (!buffer_)
     49       return;
     50 
     51     RasterWorkerPool::ReleaseBitmapForBuffer(
     52         &bitmap_, buffer_, resource_->format());
     53   }
     54 
     55  private:
     56   ResourceProvider* resource_provider_;
     57   const Resource* resource_;
     58   uint8_t* buffer_;
     59   int stride_;
     60   SkBitmap bitmap_;
     61 
     62   DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
     63 };
     64 
     65 const int kCheckForCompletedRasterTasksDelayMs = 6;
     66 
     67 const size_t kMaxScheduledRasterTasks = 48;
     68 
     69 typedef base::StackVector<RasterTask*, kMaxScheduledRasterTasks>
     70     RasterTaskVector;
     71 
     72 TaskSetCollection NonEmptyTaskSetsFromTaskCounts(const size_t* task_counts) {
     73   TaskSetCollection task_sets;
     74   for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
     75     if (task_counts[task_set])
     76       task_sets[task_set] = true;
     77   }
     78   return task_sets;
     79 }
     80 
     81 void AddTaskSetsToTaskCounts(size_t* task_counts,
     82                              const TaskSetCollection& task_sets) {
     83   for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
     84     if (task_sets[task_set])
     85       task_counts[task_set]++;
     86   }
     87 }
     88 
     89 void RemoveTaskSetsFromTaskCounts(size_t* task_counts,
     90                                   const TaskSetCollection& task_sets) {
     91   for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
     92     if (task_sets[task_set])
     93       task_counts[task_set]--;
     94   }
     95 }
     96 
     97 }  // namespace
     98 
     99 PixelBufferRasterWorkerPool::RasterTaskState::RasterTaskState(
    100     RasterTask* task,
    101     const TaskSetCollection& task_sets)
    102     : type(UNSCHEDULED), task(task), task_sets(task_sets) {
    103 }
    104 
    105 // static
    106 scoped_ptr<RasterWorkerPool> PixelBufferRasterWorkerPool::Create(
    107     base::SequencedTaskRunner* task_runner,
    108     TaskGraphRunner* task_graph_runner,
    109     ContextProvider* context_provider,
    110     ResourceProvider* resource_provider,
    111     size_t max_transfer_buffer_usage_bytes) {
    112   return make_scoped_ptr<RasterWorkerPool>(
    113       new PixelBufferRasterWorkerPool(task_runner,
    114                                       task_graph_runner,
    115                                       context_provider,
    116                                       resource_provider,
    117                                       max_transfer_buffer_usage_bytes));
    118 }
    119 
    120 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
    121     base::SequencedTaskRunner* task_runner,
    122     TaskGraphRunner* task_graph_runner,
    123     ContextProvider* context_provider,
    124     ResourceProvider* resource_provider,
    125     size_t max_transfer_buffer_usage_bytes)
    126     : task_runner_(task_runner),
    127       task_graph_runner_(task_graph_runner),
    128       namespace_token_(task_graph_runner->GetNamespaceToken()),
    129       context_provider_(context_provider),
    130       resource_provider_(resource_provider),
    131       shutdown_(false),
    132       scheduled_raster_task_count_(0u),
    133       bytes_pending_upload_(0u),
    134       max_bytes_pending_upload_(max_transfer_buffer_usage_bytes),
    135       has_performed_uploads_since_last_flush_(false),
    136       check_for_completed_raster_task_notifier_(
    137           task_runner,
    138           base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks,
    139                      base::Unretained(this)),
    140           base::TimeDelta::FromMilliseconds(
    141               kCheckForCompletedRasterTasksDelayMs)),
    142       raster_finished_weak_ptr_factory_(this) {
    143   DCHECK(context_provider_);
    144   std::fill(task_counts_, task_counts_ + kNumberOfTaskSets, 0);
    145 }
    146 
    147 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
    148   DCHECK_EQ(0u, raster_task_states_.size());
    149   DCHECK_EQ(0u, raster_tasks_with_pending_upload_.size());
    150   DCHECK_EQ(0u, completed_raster_tasks_.size());
    151   DCHECK_EQ(0u, completed_image_decode_tasks_.size());
    152   DCHECK(NonEmptyTaskSetsFromTaskCounts(task_counts_).none());
    153 }
    154 
    155 Rasterizer* PixelBufferRasterWorkerPool::AsRasterizer() { return this; }
    156 
    157 void PixelBufferRasterWorkerPool::SetClient(RasterizerClient* client) {
    158   client_ = client;
    159 }
    160 
    161 void PixelBufferRasterWorkerPool::Shutdown() {
    162   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::Shutdown");
    163 
    164   shutdown_ = true;
    165 
    166   TaskGraph empty;
    167   task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
    168   task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
    169 
    170   CheckForCompletedRasterizerTasks();
    171   CheckForCompletedUploads();
    172 
    173   check_for_completed_raster_task_notifier_.Cancel();
    174 
    175   for (RasterTaskState::Vector::iterator it = raster_task_states_.begin();
    176        it != raster_task_states_.end();
    177        ++it) {
    178     RasterTaskState& state = *it;
    179 
    180     // All unscheduled tasks need to be canceled.
    181     if (state.type == RasterTaskState::UNSCHEDULED) {
    182       completed_raster_tasks_.push_back(state.task);
    183       state.type = RasterTaskState::COMPLETED;
    184     }
    185   }
    186   DCHECK_EQ(completed_raster_tasks_.size(), raster_task_states_.size());
    187 }
    188 
    189 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
    190   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
    191 
    192   if (should_notify_client_if_no_tasks_are_pending_.none())
    193     TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
    194 
    195   should_notify_client_if_no_tasks_are_pending_.set();
    196   std::fill(task_counts_, task_counts_ + kNumberOfTaskSets, 0);
    197 
    198   // Update raster task state and remove items from old queue.
    199   for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
    200        it != queue->items.end();
    201        ++it) {
    202     const RasterTaskQueue::Item& item = *it;
    203     RasterTask* task = item.task;
    204 
    205     // Remove any old items that are associated with this task. The result is
    206     // that the old queue is left with all items not present in this queue,
    207     // which we use below to determine what tasks need to be canceled.
    208     RasterTaskQueue::Item::Vector::iterator old_it =
    209         std::find_if(raster_tasks_.items.begin(),
    210                      raster_tasks_.items.end(),
    211                      RasterTaskQueue::Item::TaskComparator(task));
    212     if (old_it != raster_tasks_.items.end()) {
    213       std::swap(*old_it, raster_tasks_.items.back());
    214       raster_tasks_.items.pop_back();
    215     }
    216 
    217     RasterTaskState::Vector::iterator state_it =
    218         std::find_if(raster_task_states_.begin(),
    219                      raster_task_states_.end(),
    220                      RasterTaskState::TaskComparator(task));
    221     if (state_it != raster_task_states_.end()) {
    222       RasterTaskState& state = *state_it;
    223 
    224       state.task_sets = item.task_sets;
    225       // |raster_tasks_required_for_activation_count| accounts for all tasks
    226       // that need to complete before we can send a "ready to activate" signal.
    227       // Tasks that have already completed should not be part of this count.
    228       if (state.type != RasterTaskState::COMPLETED)
    229         AddTaskSetsToTaskCounts(task_counts_, item.task_sets);
    230 
    231       continue;
    232     }
    233 
    234     DCHECK(!task->HasBeenScheduled());
    235     raster_task_states_.push_back(RasterTaskState(task, item.task_sets));
    236     AddTaskSetsToTaskCounts(task_counts_, item.task_sets);
    237   }
    238 
    239   // Determine what tasks in old queue need to be canceled.
    240   for (RasterTaskQueue::Item::Vector::const_iterator it =
    241            raster_tasks_.items.begin();
    242        it != raster_tasks_.items.end();
    243        ++it) {
    244     const RasterTaskQueue::Item& item = *it;
    245     RasterTask* task = item.task;
    246 
    247     RasterTaskState::Vector::iterator state_it =
    248         std::find_if(raster_task_states_.begin(),
    249                      raster_task_states_.end(),
    250                      RasterTaskState::TaskComparator(task));
    251     // We've already processed completion if we can't find a RasterTaskState for
    252     // this task.
    253     if (state_it == raster_task_states_.end())
    254       continue;
    255 
    256     RasterTaskState& state = *state_it;
    257 
    258     // Unscheduled task can be canceled.
    259     if (state.type == RasterTaskState::UNSCHEDULED) {
    260       DCHECK(!task->HasBeenScheduled());
    261       DCHECK(std::find(completed_raster_tasks_.begin(),
    262                        completed_raster_tasks_.end(),
    263                        task) == completed_raster_tasks_.end());
    264       completed_raster_tasks_.push_back(task);
    265       state.type = RasterTaskState::COMPLETED;
    266     }
    267 
    268     // No longer in any task set.
    269     state.task_sets.reset();
    270   }
    271 
    272   raster_tasks_.Swap(queue);
    273 
    274   // Check for completed tasks when ScheduleTasks() is called as
    275   // priorities might have changed and this maximizes the number
    276   // of top priority tasks that are scheduled.
    277   CheckForCompletedRasterizerTasks();
    278   CheckForCompletedUploads();
    279   FlushUploads();
    280 
    281   // Schedule new tasks.
    282   ScheduleMoreTasks();
    283 
    284   // Reschedule check for completed raster tasks.
    285   check_for_completed_raster_task_notifier_.Schedule();
    286 
    287   TRACE_EVENT_ASYNC_STEP_INTO1(
    288       "cc", "ScheduledTasks", this, StateName(), "state", StateAsValue());
    289 }
    290 
    291 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
    292   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
    293 
    294   CheckForCompletedRasterizerTasks();
    295   CheckForCompletedUploads();
    296   FlushUploads();
    297 
    298   for (RasterizerTask::Vector::const_iterator it =
    299            completed_image_decode_tasks_.begin();
    300        it != completed_image_decode_tasks_.end();
    301        ++it) {
    302     RasterizerTask* task = it->get();
    303     task->RunReplyOnOriginThread();
    304   }
    305   completed_image_decode_tasks_.clear();
    306 
    307   for (RasterTask::Vector::const_iterator it = completed_raster_tasks_.begin();
    308        it != completed_raster_tasks_.end();
    309        ++it) {
    310     RasterTask* task = it->get();
    311     RasterTaskState::Vector::iterator state_it =
    312         std::find_if(raster_task_states_.begin(),
    313                      raster_task_states_.end(),
    314                      RasterTaskState::TaskComparator(task));
    315     DCHECK(state_it != raster_task_states_.end());
    316     DCHECK_EQ(RasterTaskState::COMPLETED, state_it->type);
    317 
    318     std::swap(*state_it, raster_task_states_.back());
    319     raster_task_states_.pop_back();
    320 
    321     task->RunReplyOnOriginThread();
    322   }
    323   completed_raster_tasks_.clear();
    324 }
    325 
    326 scoped_ptr<RasterBuffer> PixelBufferRasterWorkerPool::AcquireBufferForRaster(
    327     const Resource* resource) {
    328   return make_scoped_ptr<RasterBuffer>(
    329       new RasterBufferImpl(resource_provider_, resource));
    330 }
    331 
    332 void PixelBufferRasterWorkerPool::ReleaseBufferForRaster(
    333     scoped_ptr<RasterBuffer> buffer) {
    334   // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
    335 }
    336 
    337 void PixelBufferRasterWorkerPool::OnRasterFinished(TaskSet task_set) {
    338   TRACE_EVENT2("cc",
    339                "PixelBufferRasterWorkerPool::OnRasterFinished",
    340                "task_set",
    341                task_set,
    342                "should_notify_client_if_no_tasks_are_pending",
    343                should_notify_client_if_no_tasks_are_pending_[task_set]);
    344 
    345   // There's no need to call CheckForCompletedRasterTasks() if the client has
    346   // already been notified.
    347   if (!should_notify_client_if_no_tasks_are_pending_[task_set])
    348     return;
    349   raster_finished_tasks_pending_[task_set] = false;
    350 
    351   // This reduces latency between the time when all tasks required for
    352   // activation have finished running and the time when the client is
    353   // notified.
    354   CheckForCompletedRasterTasks();
    355 }
    356 
    357 void PixelBufferRasterWorkerPool::FlushUploads() {
    358   if (!has_performed_uploads_since_last_flush_)
    359     return;
    360 
    361   context_provider_->ContextGL()->ShallowFlushCHROMIUM();
    362   has_performed_uploads_since_last_flush_ = false;
    363 }
    364 
    365 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
    366   RasterTask::Vector tasks_with_completed_uploads;
    367 
    368   // First check if any have completed.
    369   while (!raster_tasks_with_pending_upload_.empty()) {
    370     RasterTask* task = raster_tasks_with_pending_upload_.front().get();
    371     DCHECK(std::find_if(raster_task_states_.begin(),
    372                         raster_task_states_.end(),
    373                         RasterTaskState::TaskComparator(task)) !=
    374            raster_task_states_.end());
    375     DCHECK_EQ(RasterTaskState::UPLOADING,
    376               std::find_if(raster_task_states_.begin(),
    377                            raster_task_states_.end(),
    378                            RasterTaskState::TaskComparator(task))->type);
    379 
    380     // Uploads complete in the order they are issued.
    381     if (!resource_provider_->DidSetPixelsComplete(task->resource()->id()))
    382       break;
    383 
    384     tasks_with_completed_uploads.push_back(task);
    385     raster_tasks_with_pending_upload_.pop_front();
    386   }
    387 
    388   DCHECK(client_);
    389   TaskSetCollection tasks_that_should_be_forced_to_complete =
    390       client_->TasksThatShouldBeForcedToComplete();
    391   bool should_force_some_uploads_to_complete =
    392       shutdown_ || tasks_that_should_be_forced_to_complete.any();
    393 
    394   if (should_force_some_uploads_to_complete) {
    395     RasterTask::Vector tasks_with_uploads_to_force;
    396     RasterTaskDeque::iterator it = raster_tasks_with_pending_upload_.begin();
    397     while (it != raster_tasks_with_pending_upload_.end()) {
    398       RasterTask* task = it->get();
    399       RasterTaskState::Vector::const_iterator state_it =
    400           std::find_if(raster_task_states_.begin(),
    401                        raster_task_states_.end(),
    402                        RasterTaskState::TaskComparator(task));
    403       DCHECK(state_it != raster_task_states_.end());
    404       const RasterTaskState& state = *state_it;
    405 
    406       // Force all uploads to complete for which the client requests to do so.
    407       // During shutdown, force all pending uploads to complete.
    408       if (shutdown_ ||
    409           (state.task_sets & tasks_that_should_be_forced_to_complete).any()) {
    410         tasks_with_uploads_to_force.push_back(task);
    411         tasks_with_completed_uploads.push_back(task);
    412         it = raster_tasks_with_pending_upload_.erase(it);
    413         continue;
    414       }
    415 
    416       ++it;
    417     }
    418 
    419     // Force uploads in reverse order. Since forcing can cause a wait on
    420     // all previous uploads, we would rather wait only once downstream.
    421     for (RasterTask::Vector::reverse_iterator it =
    422              tasks_with_uploads_to_force.rbegin();
    423          it != tasks_with_uploads_to_force.rend();
    424          ++it) {
    425       RasterTask* task = it->get();
    426 
    427       resource_provider_->ForceSetPixelsToComplete(task->resource()->id());
    428       has_performed_uploads_since_last_flush_ = true;
    429     }
    430   }
    431 
    432   // Release shared memory and move tasks with completed uploads
    433   // to |completed_raster_tasks_|.
    434   for (RasterTask::Vector::const_iterator it =
    435            tasks_with_completed_uploads.begin();
    436        it != tasks_with_completed_uploads.end();
    437        ++it) {
    438     RasterTask* task = it->get();
    439     RasterTaskState::Vector::iterator state_it =
    440         std::find_if(raster_task_states_.begin(),
    441                      raster_task_states_.end(),
    442                      RasterTaskState::TaskComparator(task));
    443     DCHECK(state_it != raster_task_states_.end());
    444     RasterTaskState& state = *state_it;
    445 
    446     bytes_pending_upload_ -= task->resource()->bytes();
    447 
    448     task->WillComplete();
    449     task->CompleteOnOriginThread(this);
    450     task->DidComplete();
    451 
    452     // Async set pixels commands are not necessarily processed in-sequence with
    453     // drawing commands. Read lock fences are required to ensure that async
    454     // commands don't access the resource while used for drawing.
    455     resource_provider_->EnableReadLockFences(task->resource()->id());
    456 
    457     DCHECK(std::find(completed_raster_tasks_.begin(),
    458                      completed_raster_tasks_.end(),
    459                      task) == completed_raster_tasks_.end());
    460     completed_raster_tasks_.push_back(task);
    461     state.type = RasterTaskState::COMPLETED;
    462     // Triggers if the current task belongs to a set that should be empty.
    463     DCHECK((state.task_sets & ~NonEmptyTaskSetsFromTaskCounts(task_counts_))
    464                .none());
    465     RemoveTaskSetsFromTaskCounts(task_counts_, state.task_sets);
    466   }
    467 }
    468 
    469 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
    470   TRACE_EVENT0("cc",
    471                "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
    472 
    473   // Since this function can be called directly, cancel any pending checks.
    474   check_for_completed_raster_task_notifier_.Cancel();
    475 
    476   DCHECK(should_notify_client_if_no_tasks_are_pending_.any());
    477 
    478   CheckForCompletedRasterizerTasks();
    479   CheckForCompletedUploads();
    480   FlushUploads();
    481 
    482   // Determine what client notifications to generate.
    483   TaskSetCollection will_notify_client_that_no_tasks_are_pending =
    484       should_notify_client_if_no_tasks_are_pending_ &
    485       ~raster_finished_tasks_pending_ & ~PendingTasks();
    486 
    487   // Adjust the need to generate notifications before scheduling more tasks.
    488   should_notify_client_if_no_tasks_are_pending_ &=
    489       ~will_notify_client_that_no_tasks_are_pending;
    490 
    491   scheduled_raster_task_count_ = 0;
    492   if (PendingRasterTaskCount())
    493     ScheduleMoreTasks();
    494 
    495   TRACE_EVENT_ASYNC_STEP_INTO1(
    496       "cc", "ScheduledTasks", this, StateName(), "state", StateAsValue());
    497 
    498   // Schedule another check for completed raster tasks while there are
    499   // pending raster tasks or pending uploads.
    500   if (PendingTasks().any())
    501     check_for_completed_raster_task_notifier_.Schedule();
    502 
    503   if (should_notify_client_if_no_tasks_are_pending_.none())
    504     TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
    505 
    506   // Generate client notifications.
    507   for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
    508     if (will_notify_client_that_no_tasks_are_pending[task_set]) {
    509       DCHECK(!PendingTasks()[task_set]);
    510       client_->DidFinishRunningTasks(task_set);
    511     }
    512   }
    513 }
    514 
    515 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
    516   TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
    517 
    518   RasterTaskVector tasks[kNumberOfTaskSets];
    519 
    520   unsigned priority = kRasterTaskPriorityBase;
    521 
    522   graph_.Reset();
    523 
    524   size_t bytes_pending_upload = bytes_pending_upload_;
    525   TaskSetCollection did_throttle_raster_tasks;
    526   size_t scheduled_raster_task_count = 0;
    527 
    528   for (RasterTaskQueue::Item::Vector::const_iterator it =
    529            raster_tasks_.items.begin();
    530        it != raster_tasks_.items.end();
    531        ++it) {
    532     const RasterTaskQueue::Item& item = *it;
    533     RasterTask* task = item.task;
    534     DCHECK(item.task_sets.any());
    535 
    536     // |raster_task_states_| contains the state of all tasks that we have not
    537     // yet run reply callbacks for.
    538     RasterTaskState::Vector::iterator state_it =
    539         std::find_if(raster_task_states_.begin(),
    540                      raster_task_states_.end(),
    541                      RasterTaskState::TaskComparator(task));
    542     if (state_it == raster_task_states_.end())
    543       continue;
    544 
    545     RasterTaskState& state = *state_it;
    546 
    547     // Skip task if completed.
    548     if (state.type == RasterTaskState::COMPLETED) {
    549       DCHECK(std::find(completed_raster_tasks_.begin(),
    550                        completed_raster_tasks_.end(),
    551                        task) != completed_raster_tasks_.end());
    552       continue;
    553     }
    554 
    555     // All raster tasks need to be throttled by bytes of pending uploads,
    556     // but if it's the only task allow it to complete no matter what its size,
    557     // to prevent starvation of the task queue.
    558     size_t new_bytes_pending_upload = bytes_pending_upload;
    559     new_bytes_pending_upload += task->resource()->bytes();
    560     if (new_bytes_pending_upload > max_bytes_pending_upload_ &&
    561         bytes_pending_upload) {
    562       did_throttle_raster_tasks |= item.task_sets;
    563       continue;
    564     }
    565 
    566     // If raster has finished, just update |bytes_pending_upload|.
    567     if (state.type == RasterTaskState::UPLOADING) {
    568       DCHECK(!task->HasCompleted());
    569       bytes_pending_upload = new_bytes_pending_upload;
    570       continue;
    571     }
    572 
    573     // Throttle raster tasks based on kMaxScheduledRasterTasks.
    574     if (scheduled_raster_task_count >= kMaxScheduledRasterTasks) {
    575       did_throttle_raster_tasks |= item.task_sets;
    576       continue;
    577     }
    578 
    579     // Update |bytes_pending_upload| now that task has cleared all
    580     // throttling limits.
    581     bytes_pending_upload = new_bytes_pending_upload;
    582 
    583     DCHECK(state.type == RasterTaskState::UNSCHEDULED ||
    584            state.type == RasterTaskState::SCHEDULED);
    585     state.type = RasterTaskState::SCHEDULED;
    586 
    587     InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
    588 
    589     ++scheduled_raster_task_count;
    590     for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
    591       if (item.task_sets[task_set])
    592         tasks[task_set].container().push_back(task);
    593     }
    594   }
    595 
    596   // Cancel existing OnRasterFinished callbacks.
    597   raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
    598 
    599   scoped_refptr<RasterizerTask> new_raster_finished_tasks[kNumberOfTaskSets];
    600   size_t scheduled_task_counts[kNumberOfTaskSets] = {0};
    601 
    602   for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
    603     scheduled_task_counts[task_set] = tasks[task_set].container().size();
    604     DCHECK_LE(scheduled_task_counts[task_set], task_counts_[task_set]);
    605     // Schedule OnRasterFinished call for task set only when notification is
    606     // pending and throttling is not preventing all pending tasks in the set
    607     // from being scheduled.
    608     if (!did_throttle_raster_tasks[task_set] &&
    609         should_notify_client_if_no_tasks_are_pending_[task_set]) {
    610       new_raster_finished_tasks[task_set] = CreateRasterFinishedTask(
    611           task_runner_.get(),
    612           base::Bind(&PixelBufferRasterWorkerPool::OnRasterFinished,
    613                      raster_finished_weak_ptr_factory_.GetWeakPtr(),
    614                      task_set));
    615       raster_finished_tasks_pending_[task_set] = true;
    616       InsertNodeForTask(&graph_,
    617                         new_raster_finished_tasks[task_set].get(),
    618                         kRasterFinishedTaskPriority,
    619                         scheduled_task_counts[task_set]);
    620       for (RasterTaskVector::ContainerType::const_iterator it =
    621                tasks[task_set].container().begin();
    622            it != tasks[task_set].container().end();
    623            ++it) {
    624         graph_.edges.push_back(
    625             TaskGraph::Edge(*it, new_raster_finished_tasks[task_set].get()));
    626       }
    627     }
    628   }
    629 
    630   DCHECK_LE(scheduled_raster_task_count, PendingRasterTaskCount());
    631 
    632   ScheduleTasksOnOriginThread(this, &graph_);
    633   task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
    634 
    635   scheduled_raster_task_count_ = scheduled_raster_task_count;
    636 
    637   std::copy(new_raster_finished_tasks,
    638             new_raster_finished_tasks + kNumberOfTaskSets,
    639             raster_finished_tasks_);
    640 }
    641 
    642 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
    643   unsigned num_completed_raster_tasks =
    644       raster_tasks_with_pending_upload_.size() + completed_raster_tasks_.size();
    645   DCHECK_GE(raster_task_states_.size(), num_completed_raster_tasks);
    646   return raster_task_states_.size() - num_completed_raster_tasks;
    647 }
    648 
    649 TaskSetCollection PixelBufferRasterWorkerPool::PendingTasks() const {
    650   return NonEmptyTaskSetsFromTaskCounts(task_counts_);
    651 }
    652 
    653 const char* PixelBufferRasterWorkerPool::StateName() const {
    654   if (scheduled_raster_task_count_)
    655     return "rasterizing";
    656   if (PendingRasterTaskCount())
    657     return "throttled";
    658   if (!raster_tasks_with_pending_upload_.empty())
    659     return "waiting_for_uploads";
    660 
    661   return "finishing";
    662 }
    663 
    664 void PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks() {
    665   TRACE_EVENT0("cc",
    666                "PixelBufferRasterWorkerPool::CheckForCompletedRasterizerTasks");
    667 
    668   task_graph_runner_->CollectCompletedTasks(namespace_token_,
    669                                             &completed_tasks_);
    670   for (Task::Vector::const_iterator it = completed_tasks_.begin();
    671        it != completed_tasks_.end();
    672        ++it) {
    673     RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
    674 
    675     RasterTask* raster_task = task->AsRasterTask();
    676     if (!raster_task) {
    677       task->WillComplete();
    678       task->CompleteOnOriginThread(this);
    679       task->DidComplete();
    680 
    681       completed_image_decode_tasks_.push_back(task);
    682       continue;
    683     }
    684 
    685     RasterTaskState::Vector::iterator state_it =
    686         std::find_if(raster_task_states_.begin(),
    687                      raster_task_states_.end(),
    688                      RasterTaskState::TaskComparator(raster_task));
    689     DCHECK(state_it != raster_task_states_.end());
    690 
    691     RasterTaskState& state = *state_it;
    692     DCHECK_EQ(RasterTaskState::SCHEDULED, state.type);
    693 
    694     resource_provider_->UnmapPixelBuffer(raster_task->resource()->id());
    695 
    696     if (!raster_task->HasFinishedRunning()) {
    697       // When priorites change, a raster task can be canceled as a result of
    698       // no longer being of high enough priority to fit in our throttled
    699       // raster task budget. The task has not yet completed in this case.
    700       raster_task->WillComplete();
    701       raster_task->CompleteOnOriginThread(this);
    702       raster_task->DidComplete();
    703 
    704       RasterTaskQueue::Item::Vector::const_iterator item_it =
    705           std::find_if(raster_tasks_.items.begin(),
    706                        raster_tasks_.items.end(),
    707                        RasterTaskQueue::Item::TaskComparator(raster_task));
    708       if (item_it != raster_tasks_.items.end()) {
    709         state.type = RasterTaskState::UNSCHEDULED;
    710         continue;
    711       }
    712 
    713       DCHECK(std::find(completed_raster_tasks_.begin(),
    714                        completed_raster_tasks_.end(),
    715                        raster_task) == completed_raster_tasks_.end());
    716       completed_raster_tasks_.push_back(raster_task);
    717       state.type = RasterTaskState::COMPLETED;
    718       // Triggers if the current task belongs to a set that should be empty.
    719       DCHECK((state.task_sets & ~NonEmptyTaskSetsFromTaskCounts(task_counts_))
    720                  .none());
    721       RemoveTaskSetsFromTaskCounts(task_counts_, state.task_sets);
    722       continue;
    723     }
    724 
    725     resource_provider_->BeginSetPixels(raster_task->resource()->id());
    726     has_performed_uploads_since_last_flush_ = true;
    727 
    728     bytes_pending_upload_ += raster_task->resource()->bytes();
    729     raster_tasks_with_pending_upload_.push_back(raster_task);
    730     state.type = RasterTaskState::UPLOADING;
    731   }
    732   completed_tasks_.clear();
    733 }
    734 
    735 scoped_refptr<base::debug::ConvertableToTraceFormat>
    736 PixelBufferRasterWorkerPool::StateAsValue() const {
    737   scoped_refptr<base::debug::TracedValue> state =
    738       new base::debug::TracedValue();
    739   state->SetInteger("completed_count", completed_raster_tasks_.size());
    740   state->BeginArray("pending_count");
    741   for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set)
    742     state->AppendInteger(task_counts_[task_set]);
    743   state->EndArray();
    744   state->SetInteger("pending_upload_count",
    745                     raster_tasks_with_pending_upload_.size());
    746   state->BeginDictionary("throttle_state");
    747   ThrottleStateAsValueInto(state.get());
    748   state->EndDictionary();
    749   return state;
    750 }
    751 
    752 void PixelBufferRasterWorkerPool::ThrottleStateAsValueInto(
    753     base::debug::TracedValue* throttle_state) const {
    754   throttle_state->SetInteger("bytes_available_for_upload",
    755                              max_bytes_pending_upload_ - bytes_pending_upload_);
    756   throttle_state->SetInteger("bytes_pending_upload", bytes_pending_upload_);
    757   throttle_state->SetInteger("scheduled_raster_task_count",
    758                              scheduled_raster_task_count_);
    759 }
    760 
    761 }  // namespace cc
    762