• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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