Home | History | Annotate | Download | only in resources
      1 // Copyright 2014 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/bitmap_raster_worker_pool.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/debug/trace_event.h"
     10 #include "base/debug/trace_event_argument.h"
     11 #include "base/strings/stringprintf.h"
     12 #include "cc/debug/traced_value.h"
     13 #include "cc/resources/raster_buffer.h"
     14 #include "cc/resources/resource.h"
     15 
     16 namespace cc {
     17 namespace {
     18 
     19 class RasterBufferImpl : public RasterBuffer {
     20  public:
     21   RasterBufferImpl(ResourceProvider* resource_provider,
     22                    const Resource* resource)
     23       : lock_(resource_provider, resource->id()) {}
     24 
     25   // Overridden from RasterBuffer:
     26   virtual skia::RefPtr<SkCanvas> AcquireSkCanvas() OVERRIDE {
     27     return skia::SharePtr(lock_.sk_canvas());
     28   }
     29   virtual void ReleaseSkCanvas(const skia::RefPtr<SkCanvas>& canvas) OVERRIDE {}
     30 
     31  private:
     32   ResourceProvider::ScopedWriteLockSoftware lock_;
     33 
     34   DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
     35 };
     36 
     37 }  // namespace
     38 
     39 // static
     40 scoped_ptr<RasterWorkerPool> BitmapRasterWorkerPool::Create(
     41     base::SequencedTaskRunner* task_runner,
     42     TaskGraphRunner* task_graph_runner,
     43     ResourceProvider* resource_provider) {
     44   return make_scoped_ptr<RasterWorkerPool>(new BitmapRasterWorkerPool(
     45       task_runner, task_graph_runner, resource_provider));
     46 }
     47 
     48 BitmapRasterWorkerPool::BitmapRasterWorkerPool(
     49     base::SequencedTaskRunner* task_runner,
     50     TaskGraphRunner* task_graph_runner,
     51     ResourceProvider* resource_provider)
     52     : task_runner_(task_runner),
     53       task_graph_runner_(task_graph_runner),
     54       namespace_token_(task_graph_runner->GetNamespaceToken()),
     55       resource_provider_(resource_provider),
     56       raster_finished_weak_ptr_factory_(this) {
     57 }
     58 
     59 BitmapRasterWorkerPool::~BitmapRasterWorkerPool() {
     60 }
     61 
     62 Rasterizer* BitmapRasterWorkerPool::AsRasterizer() {
     63   return this;
     64 }
     65 
     66 void BitmapRasterWorkerPool::SetClient(RasterizerClient* client) {
     67   client_ = client;
     68 }
     69 
     70 void BitmapRasterWorkerPool::Shutdown() {
     71   TRACE_EVENT0("cc", "BitmapRasterWorkerPool::Shutdown");
     72 
     73   TaskGraph empty;
     74   task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
     75   task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
     76 }
     77 
     78 void BitmapRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
     79   TRACE_EVENT0("cc", "BitmapRasterWorkerPool::ScheduleTasks");
     80 
     81   if (raster_pending_.none())
     82     TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
     83 
     84   // Mark all task sets as pending.
     85   raster_pending_.set();
     86 
     87   unsigned priority = kRasterTaskPriorityBase;
     88 
     89   graph_.Reset();
     90 
     91   // Cancel existing OnRasterFinished callbacks.
     92   raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
     93 
     94   scoped_refptr<RasterizerTask> new_raster_finished_tasks[kNumberOfTaskSets];
     95 
     96   size_t task_count[kNumberOfTaskSets] = {0};
     97 
     98   for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
     99     new_raster_finished_tasks[task_set] = CreateRasterFinishedTask(
    100         task_runner_.get(),
    101         base::Bind(&BitmapRasterWorkerPool::OnRasterFinished,
    102                    raster_finished_weak_ptr_factory_.GetWeakPtr(),
    103                    task_set));
    104   }
    105 
    106   for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
    107        it != queue->items.end();
    108        ++it) {
    109     const RasterTaskQueue::Item& item = *it;
    110     RasterTask* task = item.task;
    111     DCHECK(!task->HasCompleted());
    112 
    113     for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
    114       if (!item.task_sets[task_set])
    115         continue;
    116 
    117       ++task_count[task_set];
    118 
    119       graph_.edges.push_back(
    120           TaskGraph::Edge(task, new_raster_finished_tasks[task_set].get()));
    121     }
    122 
    123     InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
    124   }
    125 
    126   for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
    127     InsertNodeForTask(&graph_,
    128                       new_raster_finished_tasks[task_set].get(),
    129                       kRasterFinishedTaskPriority,
    130                       task_count[task_set]);
    131   }
    132 
    133   ScheduleTasksOnOriginThread(this, &graph_);
    134   task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
    135 
    136   std::copy(new_raster_finished_tasks,
    137             new_raster_finished_tasks + kNumberOfTaskSets,
    138             raster_finished_tasks_);
    139 
    140   TRACE_EVENT_ASYNC_STEP_INTO1(
    141       "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue());
    142 }
    143 
    144 void BitmapRasterWorkerPool::CheckForCompletedTasks() {
    145   TRACE_EVENT0("cc", "BitmapRasterWorkerPool::CheckForCompletedTasks");
    146 
    147   task_graph_runner_->CollectCompletedTasks(namespace_token_,
    148                                             &completed_tasks_);
    149   for (Task::Vector::const_iterator it = completed_tasks_.begin();
    150        it != completed_tasks_.end();
    151        ++it) {
    152     RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
    153 
    154     task->WillComplete();
    155     task->CompleteOnOriginThread(this);
    156     task->DidComplete();
    157 
    158     task->RunReplyOnOriginThread();
    159   }
    160   completed_tasks_.clear();
    161 }
    162 
    163 scoped_ptr<RasterBuffer> BitmapRasterWorkerPool::AcquireBufferForRaster(
    164     const Resource* resource) {
    165   return make_scoped_ptr<RasterBuffer>(
    166       new RasterBufferImpl(resource_provider_, resource));
    167 }
    168 
    169 void BitmapRasterWorkerPool::ReleaseBufferForRaster(
    170     scoped_ptr<RasterBuffer> buffer) {
    171   // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
    172 }
    173 
    174 void BitmapRasterWorkerPool::OnRasterFinished(TaskSet task_set) {
    175   TRACE_EVENT1(
    176       "cc", "BitmapRasterWorkerPool::OnRasterFinished", "task_set", task_set);
    177 
    178   DCHECK(raster_pending_[task_set]);
    179   raster_pending_[task_set] = false;
    180   if (raster_pending_.any()) {
    181     TRACE_EVENT_ASYNC_STEP_INTO1(
    182         "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue());
    183   } else {
    184     TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
    185   }
    186   client_->DidFinishRunningTasks(task_set);
    187 }
    188 
    189 scoped_refptr<base::debug::ConvertableToTraceFormat>
    190 BitmapRasterWorkerPool::StateAsValue() const {
    191   scoped_refptr<base::debug::TracedValue> state =
    192       new base::debug::TracedValue();
    193 
    194   state->BeginArray("tasks_pending");
    195   for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set)
    196     state->AppendBoolean(raster_pending_[task_set]);
    197   state->EndArray();
    198   return state;
    199 }
    200 
    201 }  // namespace cc
    202