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: 23 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE {} 24 virtual void CompleteOnOriginThread() OVERRIDE {} 25 26 private: 27 virtual ~PerfWorkerPoolTaskImpl() {} 28 }; 29 30 class PerfRasterWorkerPool : public RasterWorkerPool { 31 public: 32 PerfRasterWorkerPool() : RasterWorkerPool(NULL, 1) {} 33 virtual ~PerfRasterWorkerPool() {} 34 35 static scoped_ptr<PerfRasterWorkerPool> Create() { 36 return make_scoped_ptr(new PerfRasterWorkerPool); 37 } 38 39 // Overridden from RasterWorkerPool: 40 virtual void ScheduleTasks(RasterTask::Queue* queue) OVERRIDE { 41 NOTREACHED(); 42 } 43 virtual GLenum GetResourceTarget() const OVERRIDE { 44 NOTREACHED(); 45 return GL_TEXTURE_2D; 46 } 47 virtual ResourceFormat GetResourceFormat() const OVERRIDE { 48 NOTREACHED(); 49 return RGBA_8888; 50 } 51 virtual void OnRasterTasksFinished() OVERRIDE { 52 NOTREACHED(); 53 } 54 virtual void OnRasterTasksRequiredForActivationFinished() OVERRIDE { 55 NOTREACHED(); 56 } 57 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 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: 129 RasterWorkerPoolPerfTest() 130 : timer_(kWarmupRuns, 131 base::TimeDelta::FromMilliseconds(kTimeLimitMillis), 132 kTimeCheckInterval) {} 133 134 // Overridden from testing::Test: 135 virtual void SetUp() OVERRIDE { 136 raster_worker_pool_ = PerfRasterWorkerPool::Create(); 137 } 138 virtual void TearDown() OVERRIDE { 139 raster_worker_pool_->Shutdown(); 140 } 141 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 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: 199 static void OnRasterTaskCompleted(const PicturePileImpl::Analysis& analysis, 200 bool was_canceled) {} 201 static void OnImageDecodeTaskCompleted(bool was_canceled) {} 202 203 scoped_ptr<PerfRasterWorkerPool> raster_worker_pool_; 204 LapTimer timer_; 205 }; 206 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