Enable right clicking on the applist doodle web contents and log the data.
[chromium-blink-merge.git] / cc / resources / tile_task_worker_pool_perftest.cc
blob71da7b11bfe605b125251030904f9fc1a2ee0e30
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.
5 #include "cc/resources/tile_task_worker_pool.h"
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_tile_task_worker_pool.h"
12 #include "cc/resources/gpu_rasterizer.h"
13 #include "cc/resources/gpu_tile_task_worker_pool.h"
14 #include "cc/resources/one_copy_tile_task_worker_pool.h"
15 #include "cc/resources/pixel_buffer_tile_task_worker_pool.h"
16 #include "cc/resources/raster_buffer.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/tile_task_runner.h"
21 #include "cc/resources/zero_copy_tile_task_worker_pool.h"
22 #include "cc/test/fake_output_surface.h"
23 #include "cc/test/fake_output_surface_client.h"
24 #include "cc/test/test_context_support.h"
25 #include "cc/test/test_gpu_memory_buffer_manager.h"
26 #include "cc/test/test_shared_bitmap_manager.h"
27 #include "cc/test/test_web_graphics_context_3d.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 #include "testing/perf/perf_test.h"
30 #include "third_party/khronos/GLES2/gl2.h"
31 #include "third_party/skia/include/gpu/GrContext.h"
32 #include "third_party/skia/include/gpu/gl/GrGLInterface.h"
34 namespace cc {
35 namespace {
37 class PerfGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
38 // Overridden from gpu::gles2::GLES2Interface:
39 GLuint CreateImageCHROMIUM(ClientBuffer buffer,
40 GLsizei width,
41 GLsizei height,
42 GLenum internalformat) override {
43 return 1u;
45 void GenBuffers(GLsizei n, GLuint* buffers) override {
46 for (GLsizei i = 0; i < n; ++i)
47 buffers[i] = 1u;
49 void GenTextures(GLsizei n, GLuint* textures) override {
50 for (GLsizei i = 0; i < n; ++i)
51 textures[i] = 1u;
53 void GetIntegerv(GLenum pname, GLint* params) override {
54 if (pname == GL_MAX_TEXTURE_SIZE)
55 *params = INT_MAX;
57 void GenQueriesEXT(GLsizei n, GLuint* queries) override {
58 for (GLsizei i = 0; i < n; ++i)
59 queries[i] = 1u;
61 void GetQueryObjectuivEXT(GLuint query,
62 GLenum pname,
63 GLuint* params) override {
64 if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
65 *params = 1;
69 class PerfContextProvider : public ContextProvider {
70 public:
71 PerfContextProvider() : context_gl_(new PerfGLES2Interface) {}
73 bool BindToCurrentThread() override { return true; }
74 Capabilities ContextCapabilities() override {
75 Capabilities capabilities;
76 capabilities.gpu.image = true;
77 capabilities.gpu.sync_query = true;
78 return capabilities;
80 gpu::gles2::GLES2Interface* ContextGL() override { return context_gl_.get(); }
81 gpu::ContextSupport* ContextSupport() override { return &support_; }
82 class GrContext* GrContext() override {
83 if (gr_context_)
84 return gr_context_.get();
86 skia::RefPtr<const GrGLInterface> null_interface =
87 skia::AdoptRef(GrGLCreateNullInterface());
88 gr_context_ = skia::AdoptRef(GrContext::Create(
89 kOpenGL_GrBackend,
90 reinterpret_cast<GrBackendContext>(null_interface.get())));
91 return gr_context_.get();
93 void SetupLock() override {}
94 base::Lock* GetLock() override { return &context_lock_; }
95 bool IsContextLost() override { return false; }
96 void VerifyContexts() override {}
97 void DeleteCachedResources() override {}
98 bool DestroyedOnMainThread() override { return false; }
99 void SetLostContextCallback(const LostContextCallback& cb) override {}
100 void SetMemoryPolicyChangedCallback(
101 const MemoryPolicyChangedCallback& cb) override {}
103 private:
104 ~PerfContextProvider() override {}
106 scoped_ptr<PerfGLES2Interface> context_gl_;
107 skia::RefPtr<class GrContext> gr_context_;
108 TestContextSupport support_;
109 base::Lock context_lock_;
112 enum TileTaskWorkerPoolType {
113 TILE_TASK_WORKER_POOL_TYPE_PIXEL_BUFFER,
114 TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
115 TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
116 TILE_TASK_WORKER_POOL_TYPE_GPU,
117 TILE_TASK_WORKER_POOL_TYPE_BITMAP
120 static const int kTimeLimitMillis = 2000;
121 static const int kWarmupRuns = 5;
122 static const int kTimeCheckInterval = 10;
124 class PerfImageDecodeTaskImpl : public ImageDecodeTask {
125 public:
126 PerfImageDecodeTaskImpl() {}
128 // Overridden from Task:
129 void RunOnWorkerThread() override {}
131 // Overridden from TileTask:
132 void ScheduleOnOriginThread(TileTaskClient* client) override {}
133 void CompleteOnOriginThread(TileTaskClient* client) override {}
134 void RunReplyOnOriginThread() override { Reset(); }
136 void Reset() {
137 did_run_ = false;
138 did_complete_ = false;
141 protected:
142 ~PerfImageDecodeTaskImpl() override {}
144 private:
145 DISALLOW_COPY_AND_ASSIGN(PerfImageDecodeTaskImpl);
148 class PerfRasterTaskImpl : public RasterTask {
149 public:
150 PerfRasterTaskImpl(scoped_ptr<ScopedResource> resource,
151 ImageDecodeTask::Vector* dependencies)
152 : RasterTask(resource.get(), dependencies), resource_(resource.Pass()) {}
154 // Overridden from Task:
155 void RunOnWorkerThread() override {}
157 // Overridden from TileTask:
158 void ScheduleOnOriginThread(TileTaskClient* client) override {
159 raster_buffer_ = client->AcquireBufferForRaster(resource());
161 void CompleteOnOriginThread(TileTaskClient* client) override {
162 client->ReleaseBufferForRaster(raster_buffer_.Pass());
164 void RunReplyOnOriginThread() override { Reset(); }
166 void Reset() {
167 did_run_ = false;
168 did_complete_ = false;
171 protected:
172 ~PerfRasterTaskImpl() override {}
174 private:
175 scoped_ptr<ScopedResource> resource_;
176 scoped_ptr<RasterBuffer> raster_buffer_;
178 DISALLOW_COPY_AND_ASSIGN(PerfRasterTaskImpl);
181 class TileTaskWorkerPoolPerfTestBase {
182 public:
183 typedef std::vector<scoped_refptr<RasterTask>> RasterTaskVector;
185 enum NamedTaskSet { REQUIRED_FOR_ACTIVATION, REQUIRED_FOR_DRAW, ALL };
187 TileTaskWorkerPoolPerfTestBase()
188 : context_provider_(make_scoped_refptr(new PerfContextProvider)),
189 task_runner_(new base::TestSimpleTaskRunner),
190 task_graph_runner_(new TaskGraphRunner),
191 timer_(kWarmupRuns,
192 base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
193 kTimeCheckInterval) {}
195 void CreateImageDecodeTasks(unsigned num_image_decode_tasks,
196 ImageDecodeTask::Vector* image_decode_tasks) {
197 for (unsigned i = 0; i < num_image_decode_tasks; ++i)
198 image_decode_tasks->push_back(new PerfImageDecodeTaskImpl);
201 void CreateRasterTasks(unsigned num_raster_tasks,
202 const ImageDecodeTask::Vector& image_decode_tasks,
203 RasterTaskVector* raster_tasks) {
204 const gfx::Size size(1, 1);
206 for (unsigned i = 0; i < num_raster_tasks; ++i) {
207 scoped_ptr<ScopedResource> resource(
208 ScopedResource::Create(resource_provider_.get()));
209 resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
210 RGBA_8888);
212 ImageDecodeTask::Vector dependencies = image_decode_tasks;
213 raster_tasks->push_back(
214 new PerfRasterTaskImpl(resource.Pass(), &dependencies));
218 void BuildTileTaskQueue(TileTaskQueue* queue,
219 const RasterTaskVector& raster_tasks) {
220 for (size_t i = 0u; i < raster_tasks.size(); ++i) {
221 bool required_for_activation = (i % 2) == 0;
222 TaskSetCollection task_set_collection;
223 task_set_collection[ALL] = true;
224 task_set_collection[REQUIRED_FOR_ACTIVATION] = required_for_activation;
225 queue->items.push_back(
226 TileTaskQueue::Item(raster_tasks[i].get(), task_set_collection));
230 protected:
231 scoped_refptr<ContextProvider> context_provider_;
232 FakeOutputSurfaceClient output_surface_client_;
233 scoped_ptr<FakeOutputSurface> output_surface_;
234 scoped_ptr<ResourceProvider> resource_provider_;
235 scoped_ptr<Rasterizer> rasterizer_;
236 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
237 scoped_ptr<TaskGraphRunner> task_graph_runner_;
238 LapTimer timer_;
241 class TileTaskWorkerPoolPerfTest
242 : public TileTaskWorkerPoolPerfTestBase,
243 public testing::TestWithParam<TileTaskWorkerPoolType>,
244 public TileTaskRunnerClient {
245 public:
246 // Overridden from testing::Test:
247 void SetUp() override {
248 switch (GetParam()) {
249 case TILE_TASK_WORKER_POOL_TYPE_PIXEL_BUFFER:
250 Create3dOutputSurfaceAndResourceProvider();
251 tile_task_worker_pool_ = PixelBufferTileTaskWorkerPool::Create(
252 task_runner_.get(), task_graph_runner_.get(),
253 context_provider_.get(), resource_provider_.get(),
254 std::numeric_limits<size_t>::max());
255 break;
256 case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY:
257 Create3dOutputSurfaceAndResourceProvider();
258 tile_task_worker_pool_ = ZeroCopyTileTaskWorkerPool::Create(
259 task_runner_.get(), task_graph_runner_.get(),
260 resource_provider_.get());
261 break;
262 case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY:
263 Create3dOutputSurfaceAndResourceProvider();
264 staging_resource_pool_ = ResourcePool::Create(resource_provider_.get(),
265 GL_TEXTURE_2D);
266 tile_task_worker_pool_ = OneCopyTileTaskWorkerPool::Create(
267 task_runner_.get(), task_graph_runner_.get(),
268 context_provider_.get(), resource_provider_.get(),
269 staging_resource_pool_.get());
270 break;
271 case TILE_TASK_WORKER_POOL_TYPE_GPU:
272 Create3dOutputSurfaceAndResourceProvider();
273 rasterizer_ = GpuRasterizer::Create(
274 context_provider_.get(), resource_provider_.get(), false, false, 0);
275 tile_task_worker_pool_ = GpuTileTaskWorkerPool::Create(
276 task_runner_.get(), task_graph_runner_.get(),
277 static_cast<GpuRasterizer*>(rasterizer_.get()));
278 break;
279 case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
280 CreateSoftwareOutputSurfaceAndResourceProvider();
281 tile_task_worker_pool_ = BitmapTileTaskWorkerPool::Create(
282 task_runner_.get(), task_graph_runner_.get(),
283 resource_provider_.get());
284 break;
287 DCHECK(tile_task_worker_pool_);
288 tile_task_worker_pool_->AsTileTaskRunner()->SetClient(this);
290 void TearDown() override {
291 tile_task_worker_pool_->AsTileTaskRunner()->Shutdown();
292 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
295 // Overriden from TileTaskRunnerClient:
296 void DidFinishRunningTileTasks(TaskSet task_set) override {
297 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
299 TaskSetCollection TasksThatShouldBeForcedToComplete() const override {
300 return TaskSetCollection();
303 void RunMessageLoopUntilAllTasksHaveCompleted() {
304 task_graph_runner_->RunUntilIdle();
305 task_runner_->RunUntilIdle();
308 void RunScheduleTasksTest(const std::string& test_name,
309 unsigned num_raster_tasks,
310 unsigned num_image_decode_tasks) {
311 ImageDecodeTask::Vector image_decode_tasks;
312 RasterTaskVector raster_tasks;
313 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
314 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
316 // Avoid unnecessary heap allocations by reusing the same queue.
317 TileTaskQueue queue;
319 timer_.Reset();
320 do {
321 queue.Reset();
322 BuildTileTaskQueue(&queue, raster_tasks);
323 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
324 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
325 timer_.NextLap();
326 } while (!timer_.HasTimeLimitExpired());
328 TileTaskQueue empty;
329 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
330 RunMessageLoopUntilAllTasksHaveCompleted();
332 perf_test::PrintResult("schedule_tasks", TestModifierString(), test_name,
333 timer_.LapsPerSecond(), "runs/s", true);
336 void RunScheduleAlternateTasksTest(const std::string& test_name,
337 unsigned num_raster_tasks,
338 unsigned num_image_decode_tasks) {
339 const size_t kNumVersions = 2;
340 ImageDecodeTask::Vector image_decode_tasks[kNumVersions];
341 RasterTaskVector raster_tasks[kNumVersions];
342 for (size_t i = 0; i < kNumVersions; ++i) {
343 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks[i]);
344 CreateRasterTasks(num_raster_tasks, image_decode_tasks[i],
345 &raster_tasks[i]);
348 // Avoid unnecessary heap allocations by reusing the same queue.
349 TileTaskQueue queue;
351 size_t count = 0;
352 timer_.Reset();
353 do {
354 queue.Reset();
355 BuildTileTaskQueue(&queue, raster_tasks[count % kNumVersions]);
356 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
357 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
358 ++count;
359 timer_.NextLap();
360 } while (!timer_.HasTimeLimitExpired());
362 TileTaskQueue empty;
363 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
364 RunMessageLoopUntilAllTasksHaveCompleted();
366 perf_test::PrintResult("schedule_alternate_tasks", TestModifierString(),
367 test_name, timer_.LapsPerSecond(), "runs/s", true);
370 void RunScheduleAndExecuteTasksTest(const std::string& test_name,
371 unsigned num_raster_tasks,
372 unsigned num_image_decode_tasks) {
373 ImageDecodeTask::Vector image_decode_tasks;
374 RasterTaskVector raster_tasks;
375 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
376 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
378 // Avoid unnecessary heap allocations by reusing the same queue.
379 TileTaskQueue queue;
381 timer_.Reset();
382 do {
383 queue.Reset();
384 BuildTileTaskQueue(&queue, raster_tasks);
385 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
386 RunMessageLoopUntilAllTasksHaveCompleted();
387 timer_.NextLap();
388 } while (!timer_.HasTimeLimitExpired());
390 TileTaskQueue empty;
391 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
392 RunMessageLoopUntilAllTasksHaveCompleted();
394 perf_test::PrintResult("schedule_and_execute_tasks", TestModifierString(),
395 test_name, timer_.LapsPerSecond(), "runs/s", true);
398 private:
399 void Create3dOutputSurfaceAndResourceProvider() {
400 output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
401 CHECK(output_surface_->BindToClient(&output_surface_client_));
402 resource_provider_ = ResourceProvider::Create(output_surface_.get(), NULL,
403 &gpu_memory_buffer_manager_,
404 NULL, 0, false, 1).Pass();
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_ =
412 ResourceProvider::Create(output_surface_.get(), &shared_bitmap_manager_,
413 NULL, NULL, 0, false, 1).Pass();
416 std::string TestModifierString() const {
417 switch (GetParam()) {
418 case TILE_TASK_WORKER_POOL_TYPE_PIXEL_BUFFER:
419 return std::string("_pixel_tile_task_worker_pool");
420 case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY:
421 return std::string("_zero_copy_tile_task_worker_pool");
422 case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY:
423 return std::string("_one_copy_tile_task_worker_pool");
424 case TILE_TASK_WORKER_POOL_TYPE_GPU:
425 return std::string("_gpu_tile_task_worker_pool");
426 case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
427 return std::string("_bitmap_tile_task_worker_pool");
429 NOTREACHED();
430 return std::string();
433 scoped_ptr<ResourcePool> staging_resource_pool_;
434 scoped_ptr<TileTaskWorkerPool> tile_task_worker_pool_;
435 TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
436 TestSharedBitmapManager shared_bitmap_manager_;
439 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleTasks) {
440 RunScheduleTasksTest("1_0", 1, 0);
441 RunScheduleTasksTest("32_0", 32, 0);
442 RunScheduleTasksTest("1_1", 1, 1);
443 RunScheduleTasksTest("32_1", 32, 1);
444 RunScheduleTasksTest("1_4", 1, 4);
445 RunScheduleTasksTest("32_4", 32, 4);
448 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAlternateTasks) {
449 RunScheduleAlternateTasksTest("1_0", 1, 0);
450 RunScheduleAlternateTasksTest("32_0", 32, 0);
451 RunScheduleAlternateTasksTest("1_1", 1, 1);
452 RunScheduleAlternateTasksTest("32_1", 32, 1);
453 RunScheduleAlternateTasksTest("1_4", 1, 4);
454 RunScheduleAlternateTasksTest("32_4", 32, 4);
457 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAndExecuteTasks) {
458 RunScheduleAndExecuteTasksTest("1_0", 1, 0);
459 RunScheduleAndExecuteTasksTest("32_0", 32, 0);
460 RunScheduleAndExecuteTasksTest("1_1", 1, 1);
461 RunScheduleAndExecuteTasksTest("32_1", 32, 1);
462 RunScheduleAndExecuteTasksTest("1_4", 1, 4);
463 RunScheduleAndExecuteTasksTest("32_4", 32, 4);
466 INSTANTIATE_TEST_CASE_P(
467 TileTaskWorkerPoolPerfTests,
468 TileTaskWorkerPoolPerfTest,
469 ::testing::Values(TILE_TASK_WORKER_POOL_TYPE_PIXEL_BUFFER,
470 TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
471 TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
472 TILE_TASK_WORKER_POOL_TYPE_GPU,
473 TILE_TASK_WORKER_POOL_TYPE_BITMAP));
475 class TileTaskWorkerPoolCommonPerfTest : public TileTaskWorkerPoolPerfTestBase,
476 public testing::Test {
477 public:
478 // Overridden from testing::Test:
479 void SetUp() override {
480 output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
481 CHECK(output_surface_->BindToClient(&output_surface_client_));
482 resource_provider_ =
483 ResourceProvider::Create(output_surface_.get(), NULL, NULL, NULL, 0,
484 false, 1).Pass();
487 void RunBuildTileTaskQueueTest(const std::string& test_name,
488 unsigned num_raster_tasks,
489 unsigned num_image_decode_tasks) {
490 ImageDecodeTask::Vector image_decode_tasks;
491 RasterTaskVector raster_tasks;
492 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
493 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
495 // Avoid unnecessary heap allocations by reusing the same queue.
496 TileTaskQueue queue;
498 timer_.Reset();
499 do {
500 queue.Reset();
501 BuildTileTaskQueue(&queue, raster_tasks);
502 timer_.NextLap();
503 } while (!timer_.HasTimeLimitExpired());
505 perf_test::PrintResult("build_raster_task_queue", "", test_name,
506 timer_.LapsPerSecond(), "runs/s", true);
510 TEST_F(TileTaskWorkerPoolCommonPerfTest, BuildTileTaskQueue) {
511 RunBuildTileTaskQueueTest("1_0", 1, 0);
512 RunBuildTileTaskQueueTest("32_0", 32, 0);
513 RunBuildTileTaskQueueTest("1_1", 1, 1);
514 RunBuildTileTaskQueueTest("32_1", 32, 1);
515 RunBuildTileTaskQueueTest("1_4", 1, 4);
516 RunBuildTileTaskQueueTest("32_4", 32, 4);
519 } // namespace
520 } // namespace cc