Disable WebContentsObserverAndroidTest#testDidFirstVisuallyNonEmptyPaint
[chromium-blink-merge.git] / cc / resources / raster_worker_pool.cc
blobd175141f3f6308c688637857702b0ab9d9e10275
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.
5 #include "cc/resources/raster_worker_pool.h"
7 #include <algorithm>
9 #include "base/debug/trace_event_synthetic_delay.h"
10 #include "base/lazy_instance.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/threading/simple_thread.h"
13 #include "cc/base/scoped_ptr_deque.h"
15 namespace cc {
16 namespace {
18 class RasterTaskGraphRunner : public TaskGraphRunner,
19 public base::DelegateSimpleThread::Delegate {
20 public:
21 RasterTaskGraphRunner()
22 : synthetic_delay_(base::debug::TraceEventSyntheticDelay::Lookup(
23 "cc.RasterRequiredForActivation")) {
24 size_t num_threads = RasterWorkerPool::GetNumRasterThreads();
25 while (workers_.size() < num_threads) {
26 scoped_ptr<base::DelegateSimpleThread> worker =
27 make_scoped_ptr(new base::DelegateSimpleThread(
28 this,
29 base::StringPrintf("CompositorRasterWorker%u",
30 static_cast<unsigned>(workers_.size() + 1))
31 .c_str()));
32 worker->Start();
33 #if defined(OS_ANDROID) || defined(OS_LINUX)
34 worker->SetThreadPriority(base::kThreadPriority_Background);
35 #endif
36 workers_.push_back(worker.Pass());
40 virtual ~RasterTaskGraphRunner() { NOTREACHED(); }
42 base::debug::TraceEventSyntheticDelay* synthetic_delay() {
43 return synthetic_delay_;
46 private:
47 // Overridden from base::DelegateSimpleThread::Delegate:
48 virtual void Run() OVERRIDE {
49 TaskGraphRunner::Run();
52 ScopedPtrDeque<base::DelegateSimpleThread> workers_;
53 base::debug::TraceEventSyntheticDelay* synthetic_delay_;
56 base::LazyInstance<RasterTaskGraphRunner>::Leaky g_task_graph_runner =
57 LAZY_INSTANCE_INITIALIZER;
59 const int kDefaultNumRasterThreads = 1;
61 int g_num_raster_threads = 0;
63 class RasterFinishedTaskImpl : public RasterizerTask {
64 public:
65 explicit RasterFinishedTaskImpl(
66 base::SequencedTaskRunner* task_runner,
67 const base::Closure& on_raster_finished_callback)
68 : task_runner_(task_runner),
69 on_raster_finished_callback_(on_raster_finished_callback) {}
71 // Overridden from Task:
72 virtual void RunOnWorkerThread() OVERRIDE {
73 TRACE_EVENT0("cc", "RasterFinishedTaskImpl::RunOnWorkerThread");
74 RasterFinished();
77 // Overridden from RasterizerTask:
78 virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {}
79 virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {}
80 virtual void RunReplyOnOriginThread() OVERRIDE {}
82 protected:
83 virtual ~RasterFinishedTaskImpl() {}
85 void RasterFinished() {
86 task_runner_->PostTask(FROM_HERE, on_raster_finished_callback_);
89 private:
90 scoped_refptr<base::SequencedTaskRunner> task_runner_;
91 const base::Closure on_raster_finished_callback_;
93 DISALLOW_COPY_AND_ASSIGN(RasterFinishedTaskImpl);
96 class RasterRequiredForActivationFinishedTaskImpl
97 : public RasterFinishedTaskImpl {
98 public:
99 RasterRequiredForActivationFinishedTaskImpl(
100 base::SequencedTaskRunner* task_runner,
101 const base::Closure& on_raster_finished_callback,
102 size_t tasks_required_for_activation_count)
103 : RasterFinishedTaskImpl(task_runner, on_raster_finished_callback),
104 tasks_required_for_activation_count_(
105 tasks_required_for_activation_count) {
106 if (tasks_required_for_activation_count_) {
107 g_task_graph_runner.Get().synthetic_delay()->BeginParallel(
108 &activation_delay_end_time_);
112 // Overridden from Task:
113 virtual void RunOnWorkerThread() OVERRIDE {
114 TRACE_EVENT0(
115 "cc", "RasterRequiredForActivationFinishedTaskImpl::RunOnWorkerThread");
117 if (tasks_required_for_activation_count_) {
118 g_task_graph_runner.Get().synthetic_delay()->EndParallel(
119 activation_delay_end_time_);
121 RasterFinished();
124 private:
125 virtual ~RasterRequiredForActivationFinishedTaskImpl() {}
127 base::TimeTicks activation_delay_end_time_;
128 const size_t tasks_required_for_activation_count_;
130 DISALLOW_COPY_AND_ASSIGN(RasterRequiredForActivationFinishedTaskImpl);
133 } // namespace
135 // This allows an external rasterize on-demand system to run raster tasks
136 // with highest priority using the same task graph runner instance.
137 unsigned RasterWorkerPool::kOnDemandRasterTaskPriority = 0u;
138 // This allows a micro benchmark system to run tasks with highest priority,
139 // since it should finish as quickly as possible.
140 unsigned RasterWorkerPool::kBenchmarkRasterTaskPriority = 0u;
141 // Task priorities that make sure raster finished tasks run before any
142 // remaining raster tasks.
143 unsigned RasterWorkerPool::kRasterFinishedTaskPriority = 2u;
144 unsigned RasterWorkerPool::kRasterRequiredForActivationFinishedTaskPriority =
146 unsigned RasterWorkerPool::kRasterTaskPriorityBase = 3u;
148 RasterWorkerPool::RasterWorkerPool() {}
150 RasterWorkerPool::~RasterWorkerPool() {}
152 // static
153 void RasterWorkerPool::SetNumRasterThreads(int num_threads) {
154 DCHECK_LT(0, num_threads);
155 DCHECK_EQ(0, g_num_raster_threads);
157 g_num_raster_threads = num_threads;
160 // static
161 int RasterWorkerPool::GetNumRasterThreads() {
162 if (!g_num_raster_threads)
163 g_num_raster_threads = kDefaultNumRasterThreads;
165 return g_num_raster_threads;
168 // static
169 TaskGraphRunner* RasterWorkerPool::GetTaskGraphRunner() {
170 return g_task_graph_runner.Pointer();
173 // static
174 scoped_refptr<RasterizerTask> RasterWorkerPool::CreateRasterFinishedTask(
175 base::SequencedTaskRunner* task_runner,
176 const base::Closure& on_raster_finished_callback) {
177 return make_scoped_refptr(
178 new RasterFinishedTaskImpl(task_runner, on_raster_finished_callback));
181 // static
182 scoped_refptr<RasterizerTask>
183 RasterWorkerPool::CreateRasterRequiredForActivationFinishedTask(
184 size_t tasks_required_for_activation_count,
185 base::SequencedTaskRunner* task_runner,
186 const base::Closure& on_raster_finished_callback) {
187 return make_scoped_refptr(new RasterRequiredForActivationFinishedTaskImpl(
188 task_runner,
189 on_raster_finished_callback,
190 tasks_required_for_activation_count));
193 // static
194 void RasterWorkerPool::ScheduleTasksOnOriginThread(RasterizerTaskClient* client,
195 TaskGraph* graph) {
196 TRACE_EVENT0("cc", "Rasterizer::ScheduleTasksOnOriginThread");
198 for (TaskGraph::Node::Vector::iterator it = graph->nodes.begin();
199 it != graph->nodes.end();
200 ++it) {
201 TaskGraph::Node& node = *it;
202 RasterizerTask* task = static_cast<RasterizerTask*>(node.task);
204 if (!task->HasBeenScheduled()) {
205 task->WillSchedule();
206 task->ScheduleOnOriginThread(client);
207 task->DidSchedule();
212 // static
213 void RasterWorkerPool::InsertNodeForTask(TaskGraph* graph,
214 RasterizerTask* task,
215 unsigned priority,
216 size_t dependencies) {
217 DCHECK(std::find_if(graph->nodes.begin(),
218 graph->nodes.end(),
219 TaskGraph::Node::TaskComparator(task)) ==
220 graph->nodes.end());
221 graph->nodes.push_back(TaskGraph::Node(task, priority, dependencies));
224 // static
225 void RasterWorkerPool::InsertNodesForRasterTask(
226 TaskGraph* graph,
227 RasterTask* raster_task,
228 const ImageDecodeTask::Vector& decode_tasks,
229 unsigned priority) {
230 size_t dependencies = 0u;
232 // Insert image decode tasks.
233 for (ImageDecodeTask::Vector::const_iterator it = decode_tasks.begin();
234 it != decode_tasks.end();
235 ++it) {
236 ImageDecodeTask* decode_task = it->get();
238 // Skip if already decoded.
239 if (decode_task->HasCompleted())
240 continue;
242 dependencies++;
244 // Add decode task if it doesn't already exists in graph.
245 TaskGraph::Node::Vector::iterator decode_it =
246 std::find_if(graph->nodes.begin(),
247 graph->nodes.end(),
248 TaskGraph::Node::TaskComparator(decode_task));
249 if (decode_it == graph->nodes.end())
250 InsertNodeForTask(graph, decode_task, priority, 0u);
252 graph->edges.push_back(TaskGraph::Edge(decode_task, raster_task));
255 InsertNodeForTask(graph, raster_task, priority, dependencies);
258 } // namespace cc