11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "cc/resources/bitmap_raster_worker_pool.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <algorithm>
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/debug/trace_event.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/debug/trace_event_argument.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/stringprintf.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "cc/debug/traced_value.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "cc/resources/raster_buffer.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "cc/resources/resource.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace cc {
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass RasterBufferImpl : public RasterBuffer {
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RasterBufferImpl(ResourceProvider* resource_provider,
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   const Resource* resource)
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : lock_(resource_provider, resource->id()) {}
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Overridden from RasterBuffer:
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual skia::RefPtr<SkCanvas> AcquireSkCanvas() OVERRIDE {
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return skia::SharePtr(lock_.sk_canvas());
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void ReleaseSkCanvas(const skia::RefPtr<SkCanvas>& canvas) OVERRIDE {}
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ResourceProvider::ScopedWriteLockSoftware lock_;
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl);
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<RasterWorkerPool> BitmapRasterWorkerPool::Create(
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::SequencedTaskRunner* task_runner,
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TaskGraphRunner* task_graph_runner,
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ResourceProvider* resource_provider) {
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return make_scoped_ptr<RasterWorkerPool>(new BitmapRasterWorkerPool(
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_runner, task_graph_runner, resource_provider));
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBitmapRasterWorkerPool::BitmapRasterWorkerPool(
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::SequencedTaskRunner* task_runner,
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TaskGraphRunner* task_graph_runner,
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ResourceProvider* resource_provider)
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : task_runner_(task_runner),
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      task_graph_runner_(task_graph_runner),
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      namespace_token_(task_graph_runner->GetNamespaceToken()),
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      resource_provider_(resource_provider),
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      raster_finished_weak_ptr_factory_(this) {
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBitmapRasterWorkerPool::~BitmapRasterWorkerPool() {
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciRasterizer* BitmapRasterWorkerPool::AsRasterizer() {
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return this;
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BitmapRasterWorkerPool::SetClient(RasterizerClient* client) {
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client_ = client;
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BitmapRasterWorkerPool::Shutdown() {
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("cc", "BitmapRasterWorkerPool::Shutdown");
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TaskGraph empty;
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  task_graph_runner_->ScheduleTasks(namespace_token_, &empty);
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_);
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BitmapRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) {
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("cc", "BitmapRasterWorkerPool::ScheduleTasks");
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (raster_pending_.none())
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Mark all task sets as pending.
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  raster_pending_.set();
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  unsigned priority = kRasterTaskPriorityBase;
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  graph_.Reset();
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Cancel existing OnRasterFinished callbacks.
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  raster_finished_weak_ptr_factory_.InvalidateWeakPtrs();
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<RasterizerTask> new_raster_finished_tasks[kNumberOfTaskSets];
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t task_count[kNumberOfTaskSets] = {0};
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    new_raster_finished_tasks[task_set] = CreateRasterFinishedTask(
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        task_runner_.get(),
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::Bind(&BitmapRasterWorkerPool::OnRasterFinished,
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   raster_finished_weak_ptr_factory_.GetWeakPtr(),
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   task_set));
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin();
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != queue->items.end();
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++it) {
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const RasterTaskQueue::Item& item = *it;
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RasterTask* task = item.task;
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    DCHECK(!task->HasCompleted());
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (!item.task_sets[task_set])
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        continue;
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ++task_count[task_set];
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      graph_.edges.push_back(
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          TaskGraph::Edge(task, new_raster_finished_tasks[task_set].get()));
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++);
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) {
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    InsertNodeForTask(&graph_,
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      new_raster_finished_tasks[task_set].get(),
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      kRasterFinishedTaskPriority,
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      task_count[task_set]);
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ScheduleTasksOnOriginThread(this, &graph_);
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  task_graph_runner_->ScheduleTasks(namespace_token_, &graph_);
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::copy(new_raster_finished_tasks,
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            new_raster_finished_tasks + kNumberOfTaskSets,
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            raster_finished_tasks_);
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT_ASYNC_STEP_INTO1(
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue());
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BitmapRasterWorkerPool::CheckForCompletedTasks() {
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("cc", "BitmapRasterWorkerPool::CheckForCompletedTasks");
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  task_graph_runner_->CollectCompletedTasks(namespace_token_,
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            &completed_tasks_);
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (Task::Vector::const_iterator it = completed_tasks_.begin();
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       it != completed_tasks_.end();
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++it) {
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    RasterizerTask* task = static_cast<RasterizerTask*>(it->get());
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    task->WillComplete();
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    task->CompleteOnOriginThread(this);
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    task->DidComplete();
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    task->RunReplyOnOriginThread();
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  completed_tasks_.clear();
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<RasterBuffer> BitmapRasterWorkerPool::AcquireBufferForRaster(
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const Resource* resource) {
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return make_scoped_ptr<RasterBuffer>(
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new RasterBufferImpl(resource_provider_, resource));
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BitmapRasterWorkerPool::ReleaseBufferForRaster(
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<RasterBuffer> buffer) {
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Nothing to do here. RasterBufferImpl destructor cleans up after itself.
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid BitmapRasterWorkerPool::OnRasterFinished(TaskSet task_set) {
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT1(
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "cc", "BitmapRasterWorkerPool::OnRasterFinished", "task_set", task_set);
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(raster_pending_[task_set]);
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  raster_pending_[task_set] = false;
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (raster_pending_.any()) {
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TRACE_EVENT_ASYNC_STEP_INTO1(
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue());
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client_->DidFinishRunningTasks(task_set);
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_refptr<base::debug::ConvertableToTraceFormat>
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBitmapRasterWorkerPool::StateAsValue() const {
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<base::debug::TracedValue> state =
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new base::debug::TracedValue();
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  state->BeginArray("tasks_pending");
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set)
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    state->AppendBoolean(raster_pending_[task_set]);
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  state->EndArray();
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return state;
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace cc
202