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/image_raster_worker_pool.h"
      6 
      7 #include "base/debug/trace_event.h"
      8 #include "cc/debug/traced_value.h"
      9 #include "cc/resources/resource.h"
     10 
     11 namespace cc {
     12 
     13 // static
     14 scoped_ptr<RasterWorkerPool> ImageRasterWorkerPool::Create(
     15     base::SequencedTaskRunner* task_runner,
     16     TaskGraphRunner* task_graph_runner,
     17     ResourceProvider* resource_provider) {
     18   return make_scoped_ptr<RasterWorkerPool>(new ImageRasterWorkerPool(
     19       task_runner, task_graph_runner, resource_provider));
     20 }
     21 
     22 ImageRasterWorkerPool::ImageRasterWorkerPool(
     23     base::SequencedTaskRunner* task_runner,
     24     TaskGraphRunner* task_graph_runner,
     25     ResourceProvider* resource_provider)
     26     : task_runner_(task_runner),
     27       task_graph_runner_(task_graph_runner),
     28       namespace_token_(task_graph_runner->GetNamespaceToken()),
     29       resource_provider_(resource_provider),
     30       raster_tasks_pending_(false),
     31       raster_tasks_required_for_activation_pending_(false),
     32       raster_finished_weak_ptr_factory_(this) {}
     33 
     34 ImageRasterWorkerPool::~ImageRasterWorkerPool() {}
     35 
     36 Rasterizer* ImageRasterWorkerPool::AsRasterizer() { return this; }
     37 
     38 void ImageRasterWorkerPool::SetClient(RasterizerClient* client) {
     39   client_ = client;
     40 }
     41 
     42 void ImageRasterWorkerPool::Shutdown() {
     43   TRACE_EVENT0("cc", "ImageRasterWorkerPool::Shutdown");
     44 
     45   TaskGraph empty;
     46   task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
     47   task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
     48 }
     49 
     50 void ImageRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
     51   TRACE_EVENT0("cc", "ImageRasterWorkerPool::ScheduleTasks");
     52 
     53   DCHECK_EQ(queue->required_for_activation_count,
     54             static_cast<size_t>(
     55                 std::count_if(queue->items.begin(),
     56                               queue->items.end(),
     57                               RasterTaskQueue::Item::IsRequiredForActivation)));
     58 
     59   if (!raster_tasks_pending_)
     60     TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
     61 
     62   raster_tasks_pending_ = true;
     63   raster_tasks_required_for_activation_pending_ = true;
     64 
     65   unsigned priority = kRasterTaskPriorityBase;
     66 
     67   graph_.Reset();
     68 
     69   // Cancel existing OnRasterFinished callbacks.
     70   raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
     71 
     72   scoped_refptr<RasterizerTask>
     73       new_raster_required_for_activation_finished_task(
     74           CreateRasterRequiredForActivationFinishedTask(
     75               queue->required_for_activation_count,
     76               task_runner_.get(),
     77               base::Bind(
     78                   &ImageRasterWorkerPool::OnRasterRequiredForActivationFinished,
     79                   raster_finished_weak_ptr_factory_.GetWeakPtr())));
     80   scoped_refptr<RasterizerTask> new_raster_finished_task(
     81       CreateRasterFinishedTask(
     82           task_runner_.get(),
     83           base::Bind(&ImageRasterWorkerPool::OnRasterFinished,
     84                      raster_finished_weak_ptr_factory_.GetWeakPtr())));
     85 
     86   for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
     87        it != queue->items.end();
     88        ++it) {
     89     const RasterTaskQueue::Item& item = *it;
     90     RasterTask* task = item.task;
     91     DCHECK(!task->HasCompleted());
     92 
     93     if (item.required_for_activation) {
     94       graph_.edges.push_back(TaskGraph::Edge(
     95           task, new_raster_required_for_activation_finished_task.get()));
     96     }
     97 
     98     InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
     99 
    100     graph_.edges.push_back(
    101         TaskGraph::Edge(task, new_raster_finished_task.get()));
    102   }
    103 
    104   InsertNodeForTask(&graph_,
    105                     new_raster_required_for_activation_finished_task.get(),
    106                     kRasterRequiredForActivationFinishedTaskPriority,
    107                     queue->required_for_activation_count);
    108   InsertNodeForTask(&graph_,
    109                     new_raster_finished_task.get(),
    110                     kRasterFinishedTaskPriority,
    111                     queue->items.size());
    112 
    113   ScheduleTasksOnOriginThread(this, &graph_);
    114   task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
    115 
    116   raster_finished_task_ = new_raster_finished_task;
    117   raster_required_for_activation_finished_task_ =
    118       new_raster_required_for_activation_finished_task;
    119 
    120   TRACE_EVENT_ASYNC_STEP_INTO1(
    121       "cc",
    122       "ScheduledTasks",
    123       this,
    124       "rasterizing",
    125       "state",
    126       TracedValue::FromValue(StateAsValue().release()));
    127 }
    128 
    129 void ImageRasterWorkerPool::CheckForCompletedTasks() {
    130   TRACE_EVENT0("cc", "ImageRasterWorkerPool::CheckForCompletedTasks");
    131 
    132   task_graph_runner_->CollectCompletedTasks(namespace_token_,
    133                                             &completed_tasks_);
    134   for (Task::Vector::const_iterator it = completed_tasks_.begin();
    135        it != completed_tasks_.end();
    136        ++it) {
    137     RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
    138 
    139     task->WillComplete();
    140     task->CompleteOnOriginThread(this);
    141     task->DidComplete();
    142 
    143     task->RunReplyOnOriginThread();
    144   }
    145   completed_tasks_.clear();
    146 }
    147 
    148 SkCanvas* ImageRasterWorkerPool::AcquireCanvasForRaster(RasterTask* task) {
    149   return resource_provider_->MapImageRasterBuffer(task->resource()->id());
    150 }
    151 
    152 void ImageRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) {
    153   resource_provider_->UnmapImageRasterBuffer(task->resource()->id());
    154 
    155   // Map/UnmapImageRasterBuffer provides direct access to the memory used by the
    156   // GPU. Read lock fences are required to ensure that we're not trying to map a
    157   // resource that is currently in-use by the GPU.
    158   resource_provider_->EnableReadLockFences(task->resource()->id(), true);
    159 }
    160 
    161 void ImageRasterWorkerPool::OnRasterFinished() {
    162   TRACE_EVENT0("cc", "ImageRasterWorkerPool::OnRasterFinished");
    163 
    164   DCHECK(raster_tasks_pending_);
    165   raster_tasks_pending_ = false;
    166   TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
    167   client_->DidFinishRunningTasks();
    168 }
    169 
    170 void ImageRasterWorkerPool::OnRasterRequiredForActivationFinished() {
    171   TRACE_EVENT0("cc",
    172                "ImageRasterWorkerPool::OnRasterRequiredForActivationFinished");
    173 
    174   DCHECK(raster_tasks_required_for_activation_pending_);
    175   raster_tasks_required_for_activation_pending_ = false;
    176   TRACE_EVENT_ASYNC_STEP_INTO1(
    177       "cc",
    178       "ScheduledTasks",
    179       this,
    180       "rasterizing",
    181       "state",
    182       TracedValue::FromValue(StateAsValue().release()));
    183   client_->DidFinishRunningTasksRequiredForActivation();
    184 }
    185 
    186 scoped_ptr<base::Value> ImageRasterWorkerPool::StateAsValue() const {
    187   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
    188 
    189   state->SetBoolean("tasks_required_for_activation_pending",
    190                     raster_tasks_required_for_activation_pending_);
    191   return state.PassAs<base::Value>();
    192 }
    193 
    194 }  // namespace cc
    195