Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / cc / raster / tile_task_worker_pool_perftest.cc
blob12b7464883603a01a2a36b37b04f818724de8c7b
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/raster/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/raster/bitmap_tile_task_worker_pool.h"
12 #include "cc/raster/gpu_rasterizer.h"
13 #include "cc/raster/gpu_tile_task_worker_pool.h"
14 #include "cc/raster/one_copy_tile_task_worker_pool.h"
15 #include "cc/raster/raster_buffer.h"
16 #include "cc/raster/tile_task_runner.h"
17 #include "cc/raster/zero_copy_tile_task_worker_pool.h"
18 #include "cc/resources/resource_pool.h"
19 #include "cc/resources/resource_provider.h"
20 #include "cc/resources/scoped_resource.h"
21 #include "cc/test/fake_output_surface.h"
22 #include "cc/test/fake_output_surface_client.h"
23 #include "cc/test/fake_resource_provider.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 InvalidateGrContext(uint32_t state) override {
94 if (gr_context_)
95 gr_context_.get()->resetContext(state);
97 void SetupLock() override {}
98 base::Lock* GetLock() override { return &context_lock_; }
99 void VerifyContexts() override {}
100 void DeleteCachedResources() override {}
101 bool DestroyedOnMainThread() override { return false; }
102 void SetLostContextCallback(const LostContextCallback& cb) override {}
103 void SetMemoryPolicyChangedCallback(
104 const MemoryPolicyChangedCallback& cb) override {}
106 private:
107 ~PerfContextProvider() override {}
109 scoped_ptr<PerfGLES2Interface> context_gl_;
110 skia::RefPtr<class GrContext> gr_context_;
111 TestContextSupport support_;
112 base::Lock context_lock_;
115 enum TileTaskWorkerPoolType {
116 TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
117 TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
118 TILE_TASK_WORKER_POOL_TYPE_GPU,
119 TILE_TASK_WORKER_POOL_TYPE_BITMAP
122 static const int kTimeLimitMillis = 2000;
123 static const int kWarmupRuns = 5;
124 static const int kTimeCheckInterval = 10;
126 class PerfImageDecodeTaskImpl : public ImageDecodeTask {
127 public:
128 PerfImageDecodeTaskImpl() {}
130 // Overridden from Task:
131 void RunOnWorkerThread() override {}
133 // Overridden from TileTask:
134 void ScheduleOnOriginThread(TileTaskClient* client) override {}
135 void CompleteOnOriginThread(TileTaskClient* client) override { Reset(); }
137 void Reset() {
138 did_run_ = false;
139 did_complete_ = false;
142 protected:
143 ~PerfImageDecodeTaskImpl() override {}
145 private:
146 DISALLOW_COPY_AND_ASSIGN(PerfImageDecodeTaskImpl);
149 class PerfRasterTaskImpl : public RasterTask {
150 public:
151 PerfRasterTaskImpl(scoped_ptr<ScopedResource> resource,
152 ImageDecodeTask::Vector* dependencies)
153 : RasterTask(dependencies), resource_(resource.Pass()) {}
155 // Overridden from Task:
156 void RunOnWorkerThread() override {}
158 // Overridden from TileTask:
159 void ScheduleOnOriginThread(TileTaskClient* client) override {
160 // No tile ids are given to support partial updates.
161 raster_buffer_ = client->AcquireBufferForRaster(resource_.get(), 0, 0);
163 void CompleteOnOriginThread(TileTaskClient* client) override {
164 client->ReleaseBufferForRaster(raster_buffer_.Pass());
165 Reset();
168 void Reset() {
169 did_run_ = false;
170 did_complete_ = false;
173 protected:
174 ~PerfRasterTaskImpl() override {}
176 private:
177 scoped_ptr<ScopedResource> resource_;
178 scoped_ptr<RasterBuffer> raster_buffer_;
180 DISALLOW_COPY_AND_ASSIGN(PerfRasterTaskImpl);
183 class TileTaskWorkerPoolPerfTestBase {
184 public:
185 typedef std::vector<scoped_refptr<RasterTask>> RasterTaskVector;
187 enum NamedTaskSet { REQUIRED_FOR_ACTIVATION, REQUIRED_FOR_DRAW, ALL };
189 TileTaskWorkerPoolPerfTestBase()
190 : context_provider_(make_scoped_refptr(new PerfContextProvider)),
191 task_runner_(new base::TestSimpleTaskRunner),
192 task_graph_runner_(new TaskGraphRunner),
193 timer_(kWarmupRuns,
194 base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
195 kTimeCheckInterval) {}
197 void CreateImageDecodeTasks(unsigned num_image_decode_tasks,
198 ImageDecodeTask::Vector* image_decode_tasks) {
199 for (unsigned i = 0; i < num_image_decode_tasks; ++i)
200 image_decode_tasks->push_back(new PerfImageDecodeTaskImpl);
203 void CreateRasterTasks(unsigned num_raster_tasks,
204 const ImageDecodeTask::Vector& image_decode_tasks,
205 RasterTaskVector* raster_tasks) {
206 const gfx::Size size(1, 1);
208 for (unsigned i = 0; i < num_raster_tasks; ++i) {
209 scoped_ptr<ScopedResource> resource(
210 ScopedResource::Create(resource_provider_.get()));
211 resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
212 RGBA_8888);
214 ImageDecodeTask::Vector dependencies = image_decode_tasks;
215 raster_tasks->push_back(
216 new PerfRasterTaskImpl(resource.Pass(), &dependencies));
220 void BuildTileTaskQueue(TileTaskQueue* queue,
221 const RasterTaskVector& raster_tasks) {
222 for (size_t i = 0u; i < raster_tasks.size(); ++i) {
223 bool required_for_activation = (i % 2) == 0;
224 TaskSetCollection task_set_collection;
225 task_set_collection[ALL] = true;
226 task_set_collection[REQUIRED_FOR_ACTIVATION] = required_for_activation;
227 queue->items.push_back(
228 TileTaskQueue::Item(raster_tasks[i].get(), task_set_collection));
232 protected:
233 scoped_refptr<ContextProvider> context_provider_;
234 FakeOutputSurfaceClient output_surface_client_;
235 scoped_ptr<FakeOutputSurface> output_surface_;
236 scoped_ptr<ResourceProvider> resource_provider_;
237 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
238 scoped_ptr<TaskGraphRunner> task_graph_runner_;
239 LapTimer timer_;
242 class TileTaskWorkerPoolPerfTest
243 : public TileTaskWorkerPoolPerfTestBase,
244 public testing::TestWithParam<TileTaskWorkerPoolType>,
245 public TileTaskRunnerClient {
246 public:
247 // Overridden from testing::Test:
248 void SetUp() override {
249 switch (GetParam()) {
250 case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY:
251 Create3dOutputSurfaceAndResourceProvider();
252 tile_task_worker_pool_ = ZeroCopyTileTaskWorkerPool::Create(
253 task_runner_.get(), task_graph_runner_.get(),
254 resource_provider_.get());
255 break;
256 case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY:
257 Create3dOutputSurfaceAndResourceProvider();
258 tile_task_worker_pool_ = OneCopyTileTaskWorkerPool::Create(
259 task_runner_.get(), task_graph_runner_.get(),
260 context_provider_.get(), resource_provider_.get(),
261 std::numeric_limits<int>::max(), false,
262 std::numeric_limits<int>::max());
263 break;
264 case TILE_TASK_WORKER_POOL_TYPE_GPU:
265 Create3dOutputSurfaceAndResourceProvider();
266 tile_task_worker_pool_ = GpuTileTaskWorkerPool::Create(
267 task_runner_.get(), task_graph_runner_.get(),
268 context_provider_.get(), resource_provider_.get(), false, 0);
269 break;
270 case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
271 CreateSoftwareOutputSurfaceAndResourceProvider();
272 tile_task_worker_pool_ = BitmapTileTaskWorkerPool::Create(
273 task_runner_.get(), task_graph_runner_.get(),
274 resource_provider_.get());
275 break;
278 DCHECK(tile_task_worker_pool_);
279 tile_task_worker_pool_->AsTileTaskRunner()->SetClient(this);
281 void TearDown() override {
282 tile_task_worker_pool_->AsTileTaskRunner()->Shutdown();
283 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
286 // Overriden from TileTaskRunnerClient:
287 void DidFinishRunningTileTasks(TaskSet task_set) override {
288 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
291 void RunMessageLoopUntilAllTasksHaveCompleted() {
292 task_graph_runner_->RunUntilIdle();
293 task_runner_->RunUntilIdle();
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);
304 // Avoid unnecessary heap allocations by reusing the same queue.
305 TileTaskQueue queue;
307 timer_.Reset();
308 do {
309 queue.Reset();
310 BuildTileTaskQueue(&queue, raster_tasks);
311 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
312 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
313 timer_.NextLap();
314 } while (!timer_.HasTimeLimitExpired());
316 TileTaskQueue empty;
317 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
318 RunMessageLoopUntilAllTasksHaveCompleted();
320 perf_test::PrintResult("schedule_tasks", TestModifierString(), test_name,
321 timer_.LapsPerSecond(), "runs/s", true);
324 void RunScheduleAlternateTasksTest(const std::string& test_name,
325 unsigned num_raster_tasks,
326 unsigned num_image_decode_tasks) {
327 const size_t kNumVersions = 2;
328 ImageDecodeTask::Vector image_decode_tasks[kNumVersions];
329 RasterTaskVector raster_tasks[kNumVersions];
330 for (size_t i = 0; i < kNumVersions; ++i) {
331 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks[i]);
332 CreateRasterTasks(num_raster_tasks, image_decode_tasks[i],
333 &raster_tasks[i]);
336 // Avoid unnecessary heap allocations by reusing the same queue.
337 TileTaskQueue queue;
339 size_t count = 0;
340 timer_.Reset();
341 do {
342 queue.Reset();
343 BuildTileTaskQueue(&queue, raster_tasks[count % kNumVersions]);
344 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
345 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
346 ++count;
347 timer_.NextLap();
348 } while (!timer_.HasTimeLimitExpired());
350 TileTaskQueue empty;
351 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
352 RunMessageLoopUntilAllTasksHaveCompleted();
354 perf_test::PrintResult("schedule_alternate_tasks", TestModifierString(),
355 test_name, timer_.LapsPerSecond(), "runs/s", true);
358 void RunScheduleAndExecuteTasksTest(const std::string& test_name,
359 unsigned num_raster_tasks,
360 unsigned num_image_decode_tasks) {
361 ImageDecodeTask::Vector image_decode_tasks;
362 RasterTaskVector raster_tasks;
363 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
364 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
366 // Avoid unnecessary heap allocations by reusing the same queue.
367 TileTaskQueue queue;
369 timer_.Reset();
370 do {
371 queue.Reset();
372 BuildTileTaskQueue(&queue, raster_tasks);
373 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
374 RunMessageLoopUntilAllTasksHaveCompleted();
375 timer_.NextLap();
376 } while (!timer_.HasTimeLimitExpired());
378 TileTaskQueue empty;
379 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
380 RunMessageLoopUntilAllTasksHaveCompleted();
382 perf_test::PrintResult("schedule_and_execute_tasks", TestModifierString(),
383 test_name, timer_.LapsPerSecond(), "runs/s", true);
386 private:
387 void Create3dOutputSurfaceAndResourceProvider() {
388 output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
389 CHECK(output_surface_->BindToClient(&output_surface_client_));
390 resource_provider_ = FakeResourceProvider::Create(
391 output_surface_.get(), nullptr, &gpu_memory_buffer_manager_);
394 void CreateSoftwareOutputSurfaceAndResourceProvider() {
395 output_surface_ = FakeOutputSurface::CreateSoftware(
396 make_scoped_ptr(new SoftwareOutputDevice));
397 CHECK(output_surface_->BindToClient(&output_surface_client_));
398 resource_provider_ = FakeResourceProvider::Create(
399 output_surface_.get(), &shared_bitmap_manager_, nullptr);
402 std::string TestModifierString() const {
403 switch (GetParam()) {
404 case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY:
405 return std::string("_zero_copy_tile_task_worker_pool");
406 case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY:
407 return std::string("_one_copy_tile_task_worker_pool");
408 case TILE_TASK_WORKER_POOL_TYPE_GPU:
409 return std::string("_gpu_tile_task_worker_pool");
410 case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
411 return std::string("_bitmap_tile_task_worker_pool");
413 NOTREACHED();
414 return std::string();
417 scoped_ptr<TileTaskWorkerPool> tile_task_worker_pool_;
418 TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
419 TestSharedBitmapManager shared_bitmap_manager_;
422 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleTasks) {
423 RunScheduleTasksTest("1_0", 1, 0);
424 RunScheduleTasksTest("32_0", 32, 0);
425 RunScheduleTasksTest("1_1", 1, 1);
426 RunScheduleTasksTest("32_1", 32, 1);
427 RunScheduleTasksTest("1_4", 1, 4);
428 RunScheduleTasksTest("32_4", 32, 4);
431 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAlternateTasks) {
432 RunScheduleAlternateTasksTest("1_0", 1, 0);
433 RunScheduleAlternateTasksTest("32_0", 32, 0);
434 RunScheduleAlternateTasksTest("1_1", 1, 1);
435 RunScheduleAlternateTasksTest("32_1", 32, 1);
436 RunScheduleAlternateTasksTest("1_4", 1, 4);
437 RunScheduleAlternateTasksTest("32_4", 32, 4);
440 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAndExecuteTasks) {
441 RunScheduleAndExecuteTasksTest("1_0", 1, 0);
442 RunScheduleAndExecuteTasksTest("32_0", 32, 0);
443 RunScheduleAndExecuteTasksTest("1_1", 1, 1);
444 RunScheduleAndExecuteTasksTest("32_1", 32, 1);
445 RunScheduleAndExecuteTasksTest("1_4", 1, 4);
446 RunScheduleAndExecuteTasksTest("32_4", 32, 4);
449 INSTANTIATE_TEST_CASE_P(TileTaskWorkerPoolPerfTests,
450 TileTaskWorkerPoolPerfTest,
451 ::testing::Values(TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
452 TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
453 TILE_TASK_WORKER_POOL_TYPE_GPU,
454 TILE_TASK_WORKER_POOL_TYPE_BITMAP));
456 class TileTaskWorkerPoolCommonPerfTest : public TileTaskWorkerPoolPerfTestBase,
457 public testing::Test {
458 public:
459 // Overridden from testing::Test:
460 void SetUp() override {
461 output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
462 CHECK(output_surface_->BindToClient(&output_surface_client_));
463 resource_provider_ =
464 FakeResourceProvider::Create(output_surface_.get(), nullptr);
467 void RunBuildTileTaskQueueTest(const std::string& test_name,
468 unsigned num_raster_tasks,
469 unsigned num_image_decode_tasks) {
470 ImageDecodeTask::Vector image_decode_tasks;
471 RasterTaskVector raster_tasks;
472 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
473 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
475 // Avoid unnecessary heap allocations by reusing the same queue.
476 TileTaskQueue queue;
478 timer_.Reset();
479 do {
480 queue.Reset();
481 BuildTileTaskQueue(&queue, raster_tasks);
482 timer_.NextLap();
483 } while (!timer_.HasTimeLimitExpired());
485 perf_test::PrintResult("build_raster_task_queue", "", test_name,
486 timer_.LapsPerSecond(), "runs/s", true);
490 TEST_F(TileTaskWorkerPoolCommonPerfTest, BuildTileTaskQueue) {
491 RunBuildTileTaskQueueTest("1_0", 1, 0);
492 RunBuildTileTaskQueueTest("32_0", 32, 0);
493 RunBuildTileTaskQueueTest("1_1", 1, 1);
494 RunBuildTileTaskQueueTest("32_1", 32, 1);
495 RunBuildTileTaskQueueTest("1_4", 1, 4);
496 RunBuildTileTaskQueueTest("32_4", 32, 4);
499 } // namespace
500 } // namespace cc