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/direct_raster_worker_pool.h"
      6 
      7 #include "base/debug/trace_event.h"
      8 #include "cc/output/context_provider.h"
      9 #include "cc/resources/resource.h"
     10 #include "cc/resources/resource_provider.h"
     11 #include "gpu/command_buffer/client/gles2_interface.h"
     12 #include "third_party/skia/include/gpu/GrContext.h"
     13 
     14 namespace cc {
     15 
     16 // static
     17 scoped_ptr<RasterWorkerPool> DirectRasterWorkerPool::Create(
     18     base::SequencedTaskRunner* task_runner,
     19     ResourceProvider* resource_provider,
     20     ContextProvider* context_provider) {
     21   return make_scoped_ptr<RasterWorkerPool>(new DirectRasterWorkerPool(
     22       task_runner, resource_provider, context_provider));
     23 }
     24 
     25 DirectRasterWorkerPool::DirectRasterWorkerPool(
     26     base::SequencedTaskRunner* task_runner,
     27     ResourceProvider* resource_provider,
     28     ContextProvider* context_provider)
     29     : task_runner_(task_runner),
     30       task_graph_runner_(new TaskGraphRunner),
     31       namespace_token_(task_graph_runner_->GetNamespaceToken()),
     32       resource_provider_(resource_provider),
     33       context_provider_(context_provider),
     34       run_tasks_on_origin_thread_pending_(false),
     35       raster_tasks_pending_(false),
     36       raster_tasks_required_for_activation_pending_(false),
     37       raster_finished_weak_ptr_factory_(this),
     38       weak_ptr_factory_(this) {}
     39 
     40 DirectRasterWorkerPool::~DirectRasterWorkerPool() {
     41   DCHECK_EQ(0u, completed_tasks_.size());
     42 }
     43 
     44 Rasterizer* DirectRasterWorkerPool::AsRasterizer() { return this; }
     45 
     46 void DirectRasterWorkerPool::SetClient(RasterizerClient* client) {
     47   client_ = client;
     48 }
     49 
     50 void DirectRasterWorkerPool::Shutdown() {
     51   TRACE_EVENT0("cc", "DirectRasterWorkerPool::Shutdown");
     52 
     53   TaskGraph empty;
     54   task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
     55   task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
     56 }
     57 
     58 void DirectRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
     59   TRACE_EVENT0("cc", "DirectRasterWorkerPool::ScheduleTasks");
     60 
     61   DCHECK_EQ(queue->required_for_activation_count,
     62             static_cast<size_t>(
     63                 std::count_if(queue->items.begin(),
     64                               queue->items.end(),
     65                               RasterTaskQueue::Item::IsRequiredForActivation)));
     66 
     67   raster_tasks_pending_ = true;
     68   raster_tasks_required_for_activation_pending_ = true;
     69 
     70   unsigned priority = kRasterTaskPriorityBase;
     71 
     72   graph_.Reset();
     73 
     74   // Cancel existing OnRasterFinished callbacks.
     75   raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
     76 
     77   scoped_refptr<RasterizerTask>
     78       new_raster_required_for_activation_finished_task(
     79           CreateRasterRequiredForActivationFinishedTask(
     80               queue->required_for_activation_count,
     81               task_runner_.get(),
     82               base::Bind(&DirectRasterWorkerPool::
     83                              OnRasterRequiredForActivationFinished,
     84                          raster_finished_weak_ptr_factory_.GetWeakPtr())));
     85   scoped_refptr<RasterizerTask> new_raster_finished_task(
     86       CreateRasterFinishedTask(
     87           task_runner_.get(),
     88           base::Bind(&DirectRasterWorkerPool::OnRasterFinished,
     89                      raster_finished_weak_ptr_factory_.GetWeakPtr())));
     90 
     91   for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
     92        it != queue->items.end();
     93        ++it) {
     94     const RasterTaskQueue::Item& item = *it;
     95     RasterTask* task = item.task;
     96     DCHECK(!task->HasCompleted());
     97 
     98     if (item.required_for_activation) {
     99       graph_.edges.push_back(TaskGraph::Edge(
    100           task, new_raster_required_for_activation_finished_task.get()));
    101     }
    102 
    103     InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
    104 
    105     graph_.edges.push_back(
    106         TaskGraph::Edge(task, new_raster_finished_task.get()));
    107   }
    108 
    109   InsertNodeForTask(&graph_,
    110                     new_raster_required_for_activation_finished_task.get(),
    111                     kRasterRequiredForActivationFinishedTaskPriority,
    112                     queue->required_for_activation_count);
    113   InsertNodeForTask(&graph_,
    114                     new_raster_finished_task.get(),
    115                     kRasterFinishedTaskPriority,
    116                     queue->items.size());
    117 
    118   ScheduleTasksOnOriginThread(this, &graph_);
    119   task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
    120 
    121   ScheduleRunTasksOnOriginThread();
    122 
    123   raster_finished_task_ = new_raster_finished_task;
    124   raster_required_for_activation_finished_task_ =
    125       new_raster_required_for_activation_finished_task;
    126 }
    127 
    128 void DirectRasterWorkerPool::CheckForCompletedTasks() {
    129   TRACE_EVENT0("cc", "DirectRasterWorkerPool::CheckForCompletedTasks");
    130 
    131   task_graph_runner_->CollectCompletedTasks(namespace_token_,
    132                                             &completed_tasks_);
    133   for (Task::Vector::const_iterator it = completed_tasks_.begin();
    134        it != completed_tasks_.end();
    135        ++it) {
    136     RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
    137 
    138     task->WillComplete();
    139     task->CompleteOnOriginThread(this);
    140     task->DidComplete();
    141 
    142     task->RunReplyOnOriginThread();
    143   }
    144   completed_tasks_.clear();
    145 }
    146 
    147 SkCanvas* DirectRasterWorkerPool::AcquireCanvasForRaster(RasterTask* task) {
    148   return resource_provider_->MapDirectRasterBuffer(task->resource()->id());
    149 }
    150 
    151 void DirectRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) {
    152   resource_provider_->UnmapDirectRasterBuffer(task->resource()->id());
    153 }
    154 
    155 void DirectRasterWorkerPool::OnRasterFinished() {
    156   TRACE_EVENT0("cc", "DirectRasterWorkerPool::OnRasterFinished");
    157 
    158   DCHECK(raster_tasks_pending_);
    159   raster_tasks_pending_ = false;
    160   client_->DidFinishRunningTasks();
    161 }
    162 
    163 void DirectRasterWorkerPool::OnRasterRequiredForActivationFinished() {
    164   TRACE_EVENT0("cc",
    165                "DirectRasterWorkerPool::OnRasterRequiredForActivationFinished");
    166 
    167   DCHECK(raster_tasks_required_for_activation_pending_);
    168   raster_tasks_required_for_activation_pending_ = false;
    169   client_->DidFinishRunningTasksRequiredForActivation();
    170 }
    171 
    172 void DirectRasterWorkerPool::ScheduleRunTasksOnOriginThread() {
    173   if (run_tasks_on_origin_thread_pending_)
    174     return;
    175 
    176   task_runner_->PostTask(
    177       FROM_HERE,
    178       base::Bind(&DirectRasterWorkerPool::RunTasksOnOriginThread,
    179                  weak_ptr_factory_.GetWeakPtr()));
    180   run_tasks_on_origin_thread_pending_ = true;
    181 }
    182 
    183 void DirectRasterWorkerPool::RunTasksOnOriginThread() {
    184   TRACE_EVENT0("cc", "DirectRasterWorkerPool::RunTasksOnOriginThread");
    185 
    186   DCHECK(run_tasks_on_origin_thread_pending_);
    187   run_tasks_on_origin_thread_pending_ = false;
    188 
    189   if (context_provider_) {
    190     DCHECK(context_provider_->ContextGL());
    191     // TODO(alokp): Use a trace macro to push/pop markers.
    192     // Using push/pop functions directly incurs cost to evaluate function
    193     // arguments even when tracing is disabled.
    194     context_provider_->ContextGL()->PushGroupMarkerEXT(
    195         0, "DirectRasterWorkerPool::RunTasksOnOriginThread");
    196 
    197     GrContext* gr_context = context_provider_->GrContext();
    198     // TODO(alokp): Implement TestContextProvider::GrContext().
    199     if (gr_context)
    200       gr_context->resetContext();
    201   }
    202 
    203   task_graph_runner_->RunUntilIdle();
    204 
    205   if (context_provider_) {
    206     GrContext* gr_context = context_provider_->GrContext();
    207     // TODO(alokp): Implement TestContextProvider::GrContext().
    208     if (gr_context)
    209       gr_context->flush();
    210 
    211     context_provider_->ContextGL()->PopGroupMarkerEXT();
    212   }
    213 }
    214 
    215 }  // namespace cc
    216