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