1 // Copyright 2015 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 "raster_worker_pool.h"
7 #include "base/strings/stringprintf.h"
11 // A sequenced task runner which posts tasks to a RasterWorkerPool.
12 class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner
13 : public base::SequencedTaskRunner
{
15 RasterWorkerPoolSequencedTaskRunner(cc::TaskGraphRunner
* task_graph_runner
)
16 : task_graph_runner_(task_graph_runner
),
17 namespace_token_(task_graph_runner
->GetNamespaceToken()) {}
19 // Overridden from base::TaskRunner:
20 bool PostDelayedTask(const tracked_objects::Location
& from_here
,
21 const base::Closure
& task
,
22 base::TimeDelta delay
) override
{
23 return PostNonNestableDelayedTask(from_here
, task
, delay
);
25 bool RunsTasksOnCurrentThread() const override
{ return true; }
27 // Overridden from base::SequencedTaskRunner:
28 bool PostNonNestableDelayedTask(const tracked_objects::Location
& from_here
,
29 const base::Closure
& task
,
30 base::TimeDelta delay
) override
{
31 base::AutoLock
lock(lock_
);
33 // Remove completed tasks.
34 DCHECK(completed_tasks_
.empty());
35 task_graph_runner_
->CollectCompletedTasks(namespace_token_
,
38 tasks_
.erase(tasks_
.begin(), tasks_
.begin() + completed_tasks_
.size());
40 tasks_
.push_back(make_scoped_refptr(new ClosureTask(task
)));
42 for (const auto& graph_task
: tasks_
) {
44 if (!graph_
.nodes
.empty())
47 cc::TaskGraph::Node
node(graph_task
.get(), 0, dependencies
);
49 graph_
.edges
.push_back(
50 cc::TaskGraph::Edge(graph_
.nodes
.back().task
, node
.task
));
52 graph_
.nodes
.push_back(node
);
54 task_graph_runner_
->ScheduleTasks(namespace_token_
, &graph_
);
55 completed_tasks_
.clear();
60 ~RasterWorkerPoolSequencedTaskRunner() override
{
61 task_graph_runner_
->WaitForTasksToFinishRunning(namespace_token_
);
62 task_graph_runner_
->CollectCompletedTasks(namespace_token_
,
66 cc::TaskGraphRunner
* const task_graph_runner_
;
68 // Lock to exclusively access all the following members that are used to
69 // implement the SequencedTaskRunner interfaces.
71 // Namespace used to schedule tasks in the task graph runner.
72 cc::NamespaceToken namespace_token_
;
73 // List of tasks currently queued up for execution.
74 cc::Task::Vector tasks_
;
75 // Graph object used for scheduling tasks.
77 // Cached vector to avoid allocation when getting the list of complete
79 cc::Task::Vector completed_tasks_
;
82 RasterWorkerPool::RasterWorkerPool()
83 : namespace_token_(task_graph_runner_
.GetNamespaceToken()) {}
85 void RasterWorkerPool::Start(
87 const base::SimpleThread::Options
& thread_options
) {
88 DCHECK(threads_
.empty());
89 while (threads_
.size() < static_cast<size_t>(num_threads
)) {
90 scoped_ptr
<base::DelegateSimpleThread
> thread(
91 new base::DelegateSimpleThread(
92 this, base::StringPrintf("CompositorTileWorker%u",
93 static_cast<unsigned>(threads_
.size() + 1))
97 threads_
.push_back(thread
.Pass());
101 void RasterWorkerPool::Shutdown() {
102 task_graph_runner_
.WaitForTasksToFinishRunning(namespace_token_
);
103 task_graph_runner_
.CollectCompletedTasks(namespace_token_
, &completed_tasks_
);
104 // Shutdown raster threads.
105 task_graph_runner_
.Shutdown();
106 while (!threads_
.empty()) {
107 threads_
.back()->Join();
112 // Overridden from base::TaskRunner:
113 bool RasterWorkerPool::PostDelayedTask(
114 const tracked_objects::Location
& from_here
,
115 const base::Closure
& task
,
116 base::TimeDelta delay
) {
117 base::AutoLock
lock(lock_
);
119 // Remove completed tasks.
120 DCHECK(completed_tasks_
.empty());
121 task_graph_runner_
.CollectCompletedTasks(namespace_token_
, &completed_tasks_
);
123 cc::Task::Vector::iterator end
= std::remove_if(
124 tasks_
.begin(), tasks_
.end(), [this](const scoped_refptr
<cc::Task
>& e
) {
125 return std::find(this->completed_tasks_
.begin(),
126 this->completed_tasks_
.end(),
127 e
) != this->completed_tasks_
.end();
129 tasks_
.erase(end
, tasks_
.end());
131 tasks_
.push_back(make_scoped_refptr(new ClosureTask(task
)));
133 for (const auto& graph_task
: tasks_
)
134 graph_
.nodes
.push_back(cc::TaskGraph::Node(graph_task
.get(), 0, 0));
136 task_graph_runner_
.ScheduleTasks(namespace_token_
, &graph_
);
137 completed_tasks_
.clear();
141 bool RasterWorkerPool::RunsTasksOnCurrentThread() const {
145 // Overridden from base::DelegateSimpleThread::Delegate:
146 void RasterWorkerPool::Run() {
147 task_graph_runner_
.Run();
150 scoped_refptr
<base::SequencedTaskRunner
>
151 RasterWorkerPool::CreateSequencedTaskRunner() {
152 return new RasterWorkerPoolSequencedTaskRunner(&task_graph_runner_
);
155 RasterWorkerPool::~RasterWorkerPool() {}
157 RasterWorkerPool::ClosureTask::ClosureTask(const base::Closure
& closure
)
158 : closure_(closure
) {}
160 // Overridden from cc::Task:
161 void RasterWorkerPool::ClosureTask::RunOnWorkerThread() {
166 RasterWorkerPool::ClosureTask::~ClosureTask() {}
168 } // namespace content