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/raster_worker_pool.h"
6
7 #include "base/time/time.h"
8 #include "cc/test/lap_timer.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "testing/perf/perf_test.h"
11
12 namespace cc {
13
14 namespace {
15
16 static const int kTimeLimitMillis = 2000;
17 static const int kWarmupRuns = 5;
18 static const int kTimeCheckInterval = 10;
19
20 class PerfWorkerPoolTaskImpl : public internal::WorkerPoolTask {
21 public:
22 // Overridden from internal::WorkerPoolTask:
RunOnWorkerThread(unsigned thread_index)23 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {}
CompleteOnOriginThread()24 virtual void CompleteOnOriginThread() OVERRIDE {}
25
26 private:
~PerfWorkerPoolTaskImpl()27 virtual ~PerfWorkerPoolTaskImpl() {}
28 };
29
30 class PerfRasterWorkerPool : public RasterWorkerPool {
31 public:
PerfRasterWorkerPool()32 PerfRasterWorkerPool() : RasterWorkerPool(NULL, 1) {}
~PerfRasterWorkerPool()33 virtual ~PerfRasterWorkerPool() {}
34
Create()35 static scoped_ptr<PerfRasterWorkerPool> Create() {
36 return make_scoped_ptr(new PerfRasterWorkerPool);
37 }
38
39 // Overridden from RasterWorkerPool:
ScheduleTasks(RasterTask::Queue * queue)40 virtual void ScheduleTasks(RasterTask::Queue* queue) OVERRIDE {
41 NOTREACHED();
42 }
GetResourceTarget() const43 virtual GLenum GetResourceTarget() const OVERRIDE {
44 NOTREACHED();
45 return GL_TEXTURE_2D;
46 }
GetResourceFormat() const47 virtual ResourceFormat GetResourceFormat() const OVERRIDE {
48 NOTREACHED();
49 return RGBA_8888;
50 }
OnRasterTasksFinished()51 virtual void OnRasterTasksFinished() OVERRIDE {
52 NOTREACHED();
53 }
OnRasterTasksRequiredForActivationFinished()54 virtual void OnRasterTasksRequiredForActivationFinished() OVERRIDE {
55 NOTREACHED();
56 }
57
SetRasterTasks(RasterTask::Queue * queue)58 void SetRasterTasks(RasterTask::Queue* queue) {
59 RasterWorkerPool::SetRasterTasks(queue);
60
61 TaskMap perf_tasks;
62 for (RasterTaskVector::const_iterator it = raster_tasks().begin();
63 it != raster_tasks().end(); ++it) {
64 internal::RasterWorkerPoolTask* task = it->get();
65
66 scoped_refptr<internal::WorkerPoolTask> new_perf_task(
67 new PerfWorkerPoolTaskImpl);
68 perf_tasks[task] = new_perf_task;
69 }
70
71 perf_tasks_.swap(perf_tasks);
72 }
73
BuildTaskGraph()74 void BuildTaskGraph() {
75 unsigned priority = 0;
76 TaskGraph graph;
77
78 scoped_refptr<internal::WorkerPoolTask>
79 raster_required_for_activation_finished_task(
80 CreateRasterRequiredForActivationFinishedTask());
81 internal::GraphNode* raster_required_for_activation_finished_node =
82 CreateGraphNodeForTask(
83 raster_required_for_activation_finished_task.get(),
84 priority++,
85 &graph);
86
87 scoped_refptr<internal::WorkerPoolTask> raster_finished_task(
88 CreateRasterFinishedTask());
89 internal::GraphNode* raster_finished_node =
90 CreateGraphNodeForTask(raster_finished_task.get(),
91 priority++,
92 &graph);
93
94 for (RasterTaskVector::const_iterator it = raster_tasks().begin();
95 it != raster_tasks().end(); ++it) {
96 internal::RasterWorkerPoolTask* task = it->get();
97
98 TaskMap::iterator perf_it = perf_tasks_.find(task);
99 DCHECK(perf_it != perf_tasks_.end());
100 if (perf_it != perf_tasks_.end()) {
101 internal::WorkerPoolTask* perf_task = perf_it->second.get();
102
103 internal::GraphNode* perf_node =
104 CreateGraphNodeForRasterTask(perf_task,
105 task->dependencies(),
106 priority++,
107 &graph);
108
109 if (IsRasterTaskRequiredForActivation(task)) {
110 raster_required_for_activation_finished_node->add_dependency();
111 perf_node->add_dependent(
112 raster_required_for_activation_finished_node);
113 }
114
115 raster_finished_node->add_dependency();
116 perf_node->add_dependent(raster_finished_node);
117 }
118 }
119 }
120
121 private:
122 TaskMap perf_tasks_;
123
124 DISALLOW_COPY_AND_ASSIGN(PerfRasterWorkerPool);
125 };
126
127 class RasterWorkerPoolPerfTest : public testing::Test {
128 public:
RasterWorkerPoolPerfTest()129 RasterWorkerPoolPerfTest()
130 : timer_(kWarmupRuns,
131 base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
132 kTimeCheckInterval) {}
133
134 // Overridden from testing::Test:
SetUp()135 virtual void SetUp() OVERRIDE {
136 raster_worker_pool_ = PerfRasterWorkerPool::Create();
137 }
TearDown()138 virtual void TearDown() OVERRIDE {
139 raster_worker_pool_->Shutdown();
140 }
141
CreateTasks(RasterWorkerPool::RasterTask::Queue * tasks,unsigned num_raster_tasks,unsigned num_image_decode_tasks)142 void CreateTasks(RasterWorkerPool::RasterTask::Queue* tasks,
143 unsigned num_raster_tasks,
144 unsigned num_image_decode_tasks) {
145 typedef std::vector<RasterWorkerPool::Task> TaskVector;
146 TaskVector image_decode_tasks;
147
148 for (unsigned i = 0; i < num_image_decode_tasks; ++i) {
149 image_decode_tasks.push_back(
150 RasterWorkerPool::CreateImageDecodeTask(
151 NULL,
152 0,
153 NULL,
154 base::Bind(
155 &RasterWorkerPoolPerfTest::OnImageDecodeTaskCompleted)));
156 }
157
158 for (unsigned i = 0; i < num_raster_tasks; ++i) {
159 RasterWorkerPool::Task::Set decode_tasks;
160 for (TaskVector::iterator it = image_decode_tasks.begin();
161 it != image_decode_tasks.end(); ++it)
162 decode_tasks.Insert(*it);
163
164 tasks->Append(
165 RasterWorkerPool::CreateRasterTask(
166 NULL,
167 NULL,
168 gfx::Rect(),
169 1.0,
170 HIGH_QUALITY_RASTER_MODE,
171 TileResolution(),
172 1,
173 NULL,
174 1,
175 NULL,
176 base::Bind(&RasterWorkerPoolPerfTest::OnRasterTaskCompleted),
177 &decode_tasks),
178 false);
179 }
180 }
181
RunBuildTaskGraphTest(const std::string & test_name,unsigned num_raster_tasks,unsigned num_image_decode_tasks)182 void RunBuildTaskGraphTest(const std::string& test_name,
183 unsigned num_raster_tasks,
184 unsigned num_image_decode_tasks) {
185 timer_.Reset();
186 RasterWorkerPool::RasterTask::Queue tasks;
187 CreateTasks(&tasks, num_raster_tasks, num_image_decode_tasks);
188 raster_worker_pool_->SetRasterTasks(&tasks);
189 do {
190 raster_worker_pool_->BuildTaskGraph();
191 timer_.NextLap();
192 } while (!timer_.HasTimeLimitExpired());
193
194 perf_test::PrintResult("build_task_graph", "", test_name,
195 timer_.LapsPerSecond(), "runs/s", true);
196 }
197
198 protected:
OnRasterTaskCompleted(const PicturePileImpl::Analysis & analysis,bool was_canceled)199 static void OnRasterTaskCompleted(const PicturePileImpl::Analysis& analysis,
200 bool was_canceled) {}
OnImageDecodeTaskCompleted(bool was_canceled)201 static void OnImageDecodeTaskCompleted(bool was_canceled) {}
202
203 scoped_ptr<PerfRasterWorkerPool> raster_worker_pool_;
204 LapTimer timer_;
205 };
206
TEST_F(RasterWorkerPoolPerfTest,BuildTaskGraph)207 TEST_F(RasterWorkerPoolPerfTest, BuildTaskGraph) {
208 RunBuildTaskGraphTest("10_0", 10, 0);
209 RunBuildTaskGraphTest("100_0", 100, 0);
210 RunBuildTaskGraphTest("1000_0", 1000, 0);
211 RunBuildTaskGraphTest("10_1", 10, 1);
212 RunBuildTaskGraphTest("100_1", 100, 1);
213 RunBuildTaskGraphTest("1000_1", 1000, 1);
214 RunBuildTaskGraphTest("10_4", 10, 4);
215 RunBuildTaskGraphTest("100_4", 100, 4);
216 RunBuildTaskGraphTest("1000_4", 1000, 4);
217 RunBuildTaskGraphTest("10_16", 10, 16);
218 RunBuildTaskGraphTest("100_16", 100, 16);
219 RunBuildTaskGraphTest("1000_16", 1000, 16);
220 }
221
222 } // namespace
223
224 } // namespace cc
225