• 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/test/test_simple_task_runner.h"
8 #include "base/time/time.h"
9 #include "cc/debug/lap_timer.h"
10 #include "cc/output/context_provider.h"
11 #include "cc/resources/bitmap_raster_worker_pool.h"
12 #include "cc/resources/gpu_raster_worker_pool.h"
13 #include "cc/resources/one_copy_raster_worker_pool.h"
14 #include "cc/resources/pixel_buffer_raster_worker_pool.h"
15 #include "cc/resources/raster_buffer.h"
16 #include "cc/resources/rasterizer.h"
17 #include "cc/resources/resource_pool.h"
18 #include "cc/resources/resource_provider.h"
19 #include "cc/resources/scoped_resource.h"
20 #include "cc/resources/zero_copy_raster_worker_pool.h"
21 #include "cc/test/fake_output_surface.h"
22 #include "cc/test/fake_output_surface_client.h"
23 #include "cc/test/test_context_support.h"
24 #include "cc/test/test_shared_bitmap_manager.h"
25 #include "cc/test/test_web_graphics_context_3d.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "testing/perf/perf_test.h"
28 #include "third_party/khronos/GLES2/gl2.h"
29 
30 namespace cc {
31 namespace {
32 
33 class PerfGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
34   // Overridden from gpu::gles2::GLES2Interface:
CreateImageCHROMIUM(GLsizei width,GLsizei height,GLenum internalformat,GLenum usage)35   virtual GLuint CreateImageCHROMIUM(GLsizei width,
36                                      GLsizei height,
37                                      GLenum internalformat,
38                                      GLenum usage) OVERRIDE {
39     return 1u;
40   }
GenBuffers(GLsizei n,GLuint * buffers)41   virtual void GenBuffers(GLsizei n, GLuint* buffers) OVERRIDE {
42     for (GLsizei i = 0; i < n; ++i)
43       buffers[i] = 1u;
44   }
GenTextures(GLsizei n,GLuint * textures)45   virtual void GenTextures(GLsizei n, GLuint* textures) OVERRIDE {
46     for (GLsizei i = 0; i < n; ++i)
47       textures[i] = 1u;
48   }
GetIntegerv(GLenum pname,GLint * params)49   virtual void GetIntegerv(GLenum pname, GLint* params) OVERRIDE {
50     if (pname == GL_MAX_TEXTURE_SIZE)
51       *params = INT_MAX;
52   }
GenQueriesEXT(GLsizei n,GLuint * queries)53   virtual void GenQueriesEXT(GLsizei n, GLuint* queries) OVERRIDE {
54     for (GLsizei i = 0; i < n; ++i)
55       queries[i] = 1u;
56   }
GetQueryObjectuivEXT(GLuint query,GLenum pname,GLuint * params)57   virtual void GetQueryObjectuivEXT(GLuint query,
58                                     GLenum pname,
59                                     GLuint* params) OVERRIDE {
60     if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
61       *params = 1;
62   }
63 };
64 
65 class PerfContextProvider : public ContextProvider {
66  public:
PerfContextProvider()67   PerfContextProvider() : context_gl_(new PerfGLES2Interface) {}
68 
BindToCurrentThread()69   virtual bool BindToCurrentThread() OVERRIDE { return true; }
ContextCapabilities()70   virtual Capabilities ContextCapabilities() OVERRIDE {
71     Capabilities capabilities;
72     capabilities.gpu.map_image = true;
73     capabilities.gpu.sync_query = true;
74     return capabilities;
75   }
ContextGL()76   virtual gpu::gles2::GLES2Interface* ContextGL() OVERRIDE {
77     return context_gl_.get();
78   }
ContextSupport()79   virtual gpu::ContextSupport* ContextSupport() OVERRIDE { return &support_; }
GrContext()80   virtual class GrContext* GrContext() OVERRIDE { return NULL; }
IsContextLost()81   virtual bool IsContextLost() OVERRIDE { return false; }
VerifyContexts()82   virtual void VerifyContexts() OVERRIDE {}
DeleteCachedResources()83   virtual void DeleteCachedResources() OVERRIDE {}
DestroyedOnMainThread()84   virtual bool DestroyedOnMainThread() OVERRIDE { return false; }
SetLostContextCallback(const LostContextCallback & cb)85   virtual void SetLostContextCallback(const LostContextCallback& cb) OVERRIDE {}
SetMemoryPolicyChangedCallback(const MemoryPolicyChangedCallback & cb)86   virtual void SetMemoryPolicyChangedCallback(
87       const MemoryPolicyChangedCallback& cb) OVERRIDE {}
88 
89  private:
~PerfContextProvider()90   virtual ~PerfContextProvider() {}
91 
92   scoped_ptr<PerfGLES2Interface> context_gl_;
93   TestContextSupport support_;
94 };
95 
96 enum RasterWorkerPoolType {
97   RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
98   RASTER_WORKER_POOL_TYPE_ZERO_COPY,
99   RASTER_WORKER_POOL_TYPE_ONE_COPY,
100   RASTER_WORKER_POOL_TYPE_GPU,
101   RASTER_WORKER_POOL_TYPE_BITMAP
102 };
103 
104 static const int kTimeLimitMillis = 2000;
105 static const int kWarmupRuns = 5;
106 static const int kTimeCheckInterval = 10;
107 
108 class PerfImageDecodeTaskImpl : public ImageDecodeTask {
109  public:
PerfImageDecodeTaskImpl()110   PerfImageDecodeTaskImpl() {}
111 
112   // Overridden from Task:
RunOnWorkerThread()113   virtual void RunOnWorkerThread() OVERRIDE {}
114 
115   // Overridden from RasterizerTask:
ScheduleOnOriginThread(RasterizerTaskClient * client)116   virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {}
CompleteOnOriginThread(RasterizerTaskClient * client)117   virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {}
RunReplyOnOriginThread()118   virtual void RunReplyOnOriginThread() OVERRIDE { Reset(); }
119 
Reset()120   void Reset() {
121     did_run_ = false;
122     did_complete_ = false;
123   }
124 
125  protected:
~PerfImageDecodeTaskImpl()126   virtual ~PerfImageDecodeTaskImpl() {}
127 
128  private:
129   DISALLOW_COPY_AND_ASSIGN(PerfImageDecodeTaskImpl);
130 };
131 
132 class PerfRasterTaskImpl : public RasterTask {
133  public:
PerfRasterTaskImpl(scoped_ptr<ScopedResource> resource,ImageDecodeTask::Vector * dependencies)134   PerfRasterTaskImpl(scoped_ptr<ScopedResource> resource,
135                      ImageDecodeTask::Vector* dependencies)
136       : RasterTask(resource.get(), dependencies), resource_(resource.Pass()) {}
137 
138   // Overridden from Task:
RunOnWorkerThread()139   virtual void RunOnWorkerThread() OVERRIDE {}
140 
141   // Overridden from RasterizerTask:
ScheduleOnOriginThread(RasterizerTaskClient * client)142   virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {
143     raster_buffer_ = client->AcquireBufferForRaster(resource());
144   }
CompleteOnOriginThread(RasterizerTaskClient * client)145   virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {
146     client->ReleaseBufferForRaster(raster_buffer_.Pass());
147   }
RunReplyOnOriginThread()148   virtual void RunReplyOnOriginThread() OVERRIDE { Reset(); }
149 
Reset()150   void Reset() {
151     did_run_ = false;
152     did_complete_ = false;
153   }
154 
155  protected:
~PerfRasterTaskImpl()156   virtual ~PerfRasterTaskImpl() {}
157 
158  private:
159   scoped_ptr<ScopedResource> resource_;
160   scoped_ptr<RasterBuffer> raster_buffer_;
161 
162   DISALLOW_COPY_AND_ASSIGN(PerfRasterTaskImpl);
163 };
164 
165 class RasterWorkerPoolPerfTestBase {
166  public:
167   typedef std::vector<scoped_refptr<RasterTask> > RasterTaskVector;
168 
169   enum NamedTaskSet { REQUIRED_FOR_ACTIVATION = 0, ALL = 1 };
170 
RasterWorkerPoolPerfTestBase()171   RasterWorkerPoolPerfTestBase()
172       : context_provider_(make_scoped_refptr(new PerfContextProvider)),
173         task_runner_(new base::TestSimpleTaskRunner),
174         task_graph_runner_(new TaskGraphRunner),
175         timer_(kWarmupRuns,
176                base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
177                kTimeCheckInterval) {}
178 
CreateImageDecodeTasks(unsigned num_image_decode_tasks,ImageDecodeTask::Vector * image_decode_tasks)179   void CreateImageDecodeTasks(unsigned num_image_decode_tasks,
180                               ImageDecodeTask::Vector* image_decode_tasks) {
181     for (unsigned i = 0; i < num_image_decode_tasks; ++i)
182       image_decode_tasks->push_back(new PerfImageDecodeTaskImpl);
183   }
184 
CreateRasterTasks(unsigned num_raster_tasks,const ImageDecodeTask::Vector & image_decode_tasks,RasterTaskVector * raster_tasks)185   void CreateRasterTasks(unsigned num_raster_tasks,
186                          const ImageDecodeTask::Vector& image_decode_tasks,
187                          RasterTaskVector* raster_tasks) {
188     const gfx::Size size(1, 1);
189 
190     for (unsigned i = 0; i < num_raster_tasks; ++i) {
191       scoped_ptr<ScopedResource> resource(
192           ScopedResource::Create(resource_provider_.get()));
193       resource->Allocate(
194           size, ResourceProvider::TextureHintImmutable, RGBA_8888);
195 
196       ImageDecodeTask::Vector dependencies = image_decode_tasks;
197       raster_tasks->push_back(
198           new PerfRasterTaskImpl(resource.Pass(), &dependencies));
199     }
200   }
201 
BuildRasterTaskQueue(RasterTaskQueue * queue,const RasterTaskVector & raster_tasks)202   void BuildRasterTaskQueue(RasterTaskQueue* queue,
203                             const RasterTaskVector& raster_tasks) {
204     for (size_t i = 0u; i < raster_tasks.size(); ++i) {
205       bool required_for_activation = (i % 2) == 0;
206       TaskSetCollection task_set_collection;
207       task_set_collection[ALL] = true;
208       task_set_collection[REQUIRED_FOR_ACTIVATION] = required_for_activation;
209       queue->items.push_back(
210           RasterTaskQueue::Item(raster_tasks[i].get(), task_set_collection));
211     }
212   }
213 
214  protected:
215   scoped_refptr<ContextProvider> context_provider_;
216   FakeOutputSurfaceClient output_surface_client_;
217   scoped_ptr<FakeOutputSurface> output_surface_;
218   scoped_ptr<ResourceProvider> resource_provider_;
219   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
220   scoped_ptr<TaskGraphRunner> task_graph_runner_;
221   LapTimer timer_;
222 };
223 
224 class RasterWorkerPoolPerfTest
225     : public RasterWorkerPoolPerfTestBase,
226       public testing::TestWithParam<RasterWorkerPoolType>,
227       public RasterizerClient {
228  public:
229   // Overridden from testing::Test:
SetUp()230   virtual void SetUp() OVERRIDE {
231     switch (GetParam()) {
232       case RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER:
233         Create3dOutputSurfaceAndResourceProvider();
234         raster_worker_pool_ = PixelBufferRasterWorkerPool::Create(
235             task_runner_.get(),
236             task_graph_runner_.get(),
237             context_provider_.get(),
238             resource_provider_.get(),
239             std::numeric_limits<size_t>::max());
240         break;
241       case RASTER_WORKER_POOL_TYPE_ZERO_COPY:
242         Create3dOutputSurfaceAndResourceProvider();
243         raster_worker_pool_ =
244             ZeroCopyRasterWorkerPool::Create(task_runner_.get(),
245                                              task_graph_runner_.get(),
246                                              resource_provider_.get());
247         break;
248       case RASTER_WORKER_POOL_TYPE_ONE_COPY:
249         Create3dOutputSurfaceAndResourceProvider();
250         staging_resource_pool_ = ResourcePool::Create(
251             resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
252         raster_worker_pool_ =
253             OneCopyRasterWorkerPool::Create(task_runner_.get(),
254                                             task_graph_runner_.get(),
255                                             context_provider_.get(),
256                                             resource_provider_.get(),
257                                             staging_resource_pool_.get());
258         break;
259       case RASTER_WORKER_POOL_TYPE_GPU:
260         Create3dOutputSurfaceAndResourceProvider();
261         raster_worker_pool_ =
262             GpuRasterWorkerPool::Create(task_runner_.get(),
263                                         context_provider_.get(),
264                                         resource_provider_.get());
265         break;
266       case RASTER_WORKER_POOL_TYPE_BITMAP:
267         CreateSoftwareOutputSurfaceAndResourceProvider();
268         raster_worker_pool_ =
269             BitmapRasterWorkerPool::Create(task_runner_.get(),
270                                            task_graph_runner_.get(),
271                                            resource_provider_.get());
272         break;
273     }
274 
275     DCHECK(raster_worker_pool_);
276     raster_worker_pool_->AsRasterizer()->SetClient(this);
277   }
TearDown()278   virtual void TearDown() OVERRIDE {
279     raster_worker_pool_->AsRasterizer()->Shutdown();
280     raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
281   }
282 
283   // Overriden from RasterizerClient:
DidFinishRunningTasks(TaskSet task_set)284   virtual void DidFinishRunningTasks(TaskSet task_set) OVERRIDE {
285     raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
286   }
TasksThatShouldBeForcedToComplete() const287   virtual TaskSetCollection TasksThatShouldBeForcedToComplete() const OVERRIDE {
288     return TaskSetCollection();
289   }
290 
RunMessageLoopUntilAllTasksHaveCompleted()291   void RunMessageLoopUntilAllTasksHaveCompleted() {
292     task_graph_runner_->RunUntilIdle();
293     task_runner_->RunUntilIdle();
294   }
295 
RunScheduleTasksTest(const std::string & test_name,unsigned num_raster_tasks,unsigned num_image_decode_tasks)296   void RunScheduleTasksTest(const std::string& test_name,
297                             unsigned num_raster_tasks,
298                             unsigned num_image_decode_tasks) {
299     ImageDecodeTask::Vector image_decode_tasks;
300     RasterTaskVector raster_tasks;
301     CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
302     CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
303 
304     // Avoid unnecessary heap allocations by reusing the same queue.
305     RasterTaskQueue queue;
306 
307     timer_.Reset();
308     do {
309       queue.Reset();
310       BuildRasterTaskQueue(&queue, raster_tasks);
311       raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
312       raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
313       timer_.NextLap();
314     } while (!timer_.HasTimeLimitExpired());
315 
316     RasterTaskQueue empty;
317     raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty);
318     RunMessageLoopUntilAllTasksHaveCompleted();
319 
320     perf_test::PrintResult("schedule_tasks",
321                            TestModifierString(),
322                            test_name,
323                            timer_.LapsPerSecond(),
324                            "runs/s",
325                            true);
326   }
327 
RunScheduleAlternateTasksTest(const std::string & test_name,unsigned num_raster_tasks,unsigned num_image_decode_tasks)328   void RunScheduleAlternateTasksTest(const std::string& test_name,
329                                      unsigned num_raster_tasks,
330                                      unsigned num_image_decode_tasks) {
331     const size_t kNumVersions = 2;
332     ImageDecodeTask::Vector image_decode_tasks[kNumVersions];
333     RasterTaskVector raster_tasks[kNumVersions];
334     for (size_t i = 0; i < kNumVersions; ++i) {
335       CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks[i]);
336       CreateRasterTasks(
337           num_raster_tasks, image_decode_tasks[i], &raster_tasks[i]);
338     }
339 
340     // Avoid unnecessary heap allocations by reusing the same queue.
341     RasterTaskQueue queue;
342 
343     size_t count = 0;
344     timer_.Reset();
345     do {
346       queue.Reset();
347       BuildRasterTaskQueue(&queue, raster_tasks[count % kNumVersions]);
348       raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
349       raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
350       ++count;
351       timer_.NextLap();
352     } while (!timer_.HasTimeLimitExpired());
353 
354     RasterTaskQueue empty;
355     raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty);
356     RunMessageLoopUntilAllTasksHaveCompleted();
357 
358     perf_test::PrintResult("schedule_alternate_tasks",
359                            TestModifierString(),
360                            test_name,
361                            timer_.LapsPerSecond(),
362                            "runs/s",
363                            true);
364   }
365 
RunScheduleAndExecuteTasksTest(const std::string & test_name,unsigned num_raster_tasks,unsigned num_image_decode_tasks)366   void RunScheduleAndExecuteTasksTest(const std::string& test_name,
367                                       unsigned num_raster_tasks,
368                                       unsigned num_image_decode_tasks) {
369     ImageDecodeTask::Vector image_decode_tasks;
370     RasterTaskVector raster_tasks;
371     CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
372     CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
373 
374     // Avoid unnecessary heap allocations by reusing the same queue.
375     RasterTaskQueue queue;
376 
377     timer_.Reset();
378     do {
379       queue.Reset();
380       BuildRasterTaskQueue(&queue, raster_tasks);
381       raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
382       RunMessageLoopUntilAllTasksHaveCompleted();
383       timer_.NextLap();
384     } while (!timer_.HasTimeLimitExpired());
385 
386     RasterTaskQueue empty;
387     raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty);
388     RunMessageLoopUntilAllTasksHaveCompleted();
389 
390     perf_test::PrintResult("schedule_and_execute_tasks",
391                            TestModifierString(),
392                            test_name,
393                            timer_.LapsPerSecond(),
394                            "runs/s",
395                            true);
396   }
397 
398  private:
Create3dOutputSurfaceAndResourceProvider()399   void Create3dOutputSurfaceAndResourceProvider() {
400     output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
401     CHECK(output_surface_->BindToClient(&output_surface_client_));
402     resource_provider_ =
403         ResourceProvider::Create(
404             output_surface_.get(), NULL, NULL, 0, false, 1, false).Pass();
405   }
406 
CreateSoftwareOutputSurfaceAndResourceProvider()407   void CreateSoftwareOutputSurfaceAndResourceProvider() {
408     output_surface_ = FakeOutputSurface::CreateSoftware(
409         make_scoped_ptr(new SoftwareOutputDevice));
410     CHECK(output_surface_->BindToClient(&output_surface_client_));
411     resource_provider_ = ResourceProvider::Create(output_surface_.get(),
412                                                   &shared_bitmap_manager_,
413                                                   NULL,
414                                                   0,
415                                                   false,
416                                                   1,
417                                                   false).Pass();
418   }
419 
TestModifierString() const420   std::string TestModifierString() const {
421     switch (GetParam()) {
422       case RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER:
423         return std::string("_pixel_raster_worker_pool");
424       case RASTER_WORKER_POOL_TYPE_ZERO_COPY:
425         return std::string("_zero_copy_raster_worker_pool");
426       case RASTER_WORKER_POOL_TYPE_ONE_COPY:
427         return std::string("_one_copy_raster_worker_pool");
428       case RASTER_WORKER_POOL_TYPE_GPU:
429         return std::string("_gpu_raster_worker_pool");
430       case RASTER_WORKER_POOL_TYPE_BITMAP:
431         return std::string("_bitmap_raster_worker_pool");
432     }
433     NOTREACHED();
434     return std::string();
435   }
436 
437   scoped_ptr<ResourcePool> staging_resource_pool_;
438   scoped_ptr<RasterWorkerPool> raster_worker_pool_;
439   TestSharedBitmapManager shared_bitmap_manager_;
440 };
441 
TEST_P(RasterWorkerPoolPerfTest,ScheduleTasks)442 TEST_P(RasterWorkerPoolPerfTest, ScheduleTasks) {
443   RunScheduleTasksTest("1_0", 1, 0);
444   RunScheduleTasksTest("32_0", 32, 0);
445   RunScheduleTasksTest("1_1", 1, 1);
446   RunScheduleTasksTest("32_1", 32, 1);
447   RunScheduleTasksTest("1_4", 1, 4);
448   RunScheduleTasksTest("32_4", 32, 4);
449 }
450 
TEST_P(RasterWorkerPoolPerfTest,ScheduleAlternateTasks)451 TEST_P(RasterWorkerPoolPerfTest, ScheduleAlternateTasks) {
452   RunScheduleAlternateTasksTest("1_0", 1, 0);
453   RunScheduleAlternateTasksTest("32_0", 32, 0);
454   RunScheduleAlternateTasksTest("1_1", 1, 1);
455   RunScheduleAlternateTasksTest("32_1", 32, 1);
456   RunScheduleAlternateTasksTest("1_4", 1, 4);
457   RunScheduleAlternateTasksTest("32_4", 32, 4);
458 }
459 
TEST_P(RasterWorkerPoolPerfTest,ScheduleAndExecuteTasks)460 TEST_P(RasterWorkerPoolPerfTest, ScheduleAndExecuteTasks) {
461   RunScheduleAndExecuteTasksTest("1_0", 1, 0);
462   RunScheduleAndExecuteTasksTest("32_0", 32, 0);
463   RunScheduleAndExecuteTasksTest("1_1", 1, 1);
464   RunScheduleAndExecuteTasksTest("32_1", 32, 1);
465   RunScheduleAndExecuteTasksTest("1_4", 1, 4);
466   RunScheduleAndExecuteTasksTest("32_4", 32, 4);
467 }
468 
469 INSTANTIATE_TEST_CASE_P(RasterWorkerPoolPerfTests,
470                         RasterWorkerPoolPerfTest,
471                         ::testing::Values(RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
472                                           RASTER_WORKER_POOL_TYPE_ZERO_COPY,
473                                           RASTER_WORKER_POOL_TYPE_ONE_COPY,
474                                           RASTER_WORKER_POOL_TYPE_GPU,
475                                           RASTER_WORKER_POOL_TYPE_BITMAP));
476 
477 class RasterWorkerPoolCommonPerfTest : public RasterWorkerPoolPerfTestBase,
478                                        public testing::Test {
479  public:
480   // Overridden from testing::Test:
SetUp()481   virtual void SetUp() OVERRIDE {
482     output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
483     CHECK(output_surface_->BindToClient(&output_surface_client_));
484     resource_provider_ =
485         ResourceProvider::Create(
486             output_surface_.get(), NULL, NULL, 0, false, 1, false).Pass();
487   }
488 
RunBuildRasterTaskQueueTest(const std::string & test_name,unsigned num_raster_tasks,unsigned num_image_decode_tasks)489   void RunBuildRasterTaskQueueTest(const std::string& test_name,
490                                    unsigned num_raster_tasks,
491                                    unsigned num_image_decode_tasks) {
492     ImageDecodeTask::Vector image_decode_tasks;
493     RasterTaskVector raster_tasks;
494     CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
495     CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
496 
497     // Avoid unnecessary heap allocations by reusing the same queue.
498     RasterTaskQueue queue;
499 
500     timer_.Reset();
501     do {
502       queue.Reset();
503       BuildRasterTaskQueue(&queue, raster_tasks);
504       timer_.NextLap();
505     } while (!timer_.HasTimeLimitExpired());
506 
507     perf_test::PrintResult("build_raster_task_queue",
508                            "",
509                            test_name,
510                            timer_.LapsPerSecond(),
511                            "runs/s",
512                            true);
513   }
514 };
515 
TEST_F(RasterWorkerPoolCommonPerfTest,BuildRasterTaskQueue)516 TEST_F(RasterWorkerPoolCommonPerfTest, BuildRasterTaskQueue) {
517   RunBuildRasterTaskQueueTest("1_0", 1, 0);
518   RunBuildRasterTaskQueueTest("32_0", 32, 0);
519   RunBuildRasterTaskQueueTest("1_1", 1, 1);
520   RunBuildRasterTaskQueueTest("32_1", 32, 1);
521   RunBuildRasterTaskQueueTest("1_4", 1, 4);
522   RunBuildRasterTaskQueueTest("32_4", 32, 4);
523 }
524 
525 }  // namespace
526 }  // namespace cc
527