Revert "Fix broken channel icon in chrome://help on CrOS" and try again
[chromium-blink-merge.git] / cc / raster / tile_task_worker_pool_perftest.cc
blob76fc9c3c7343988c43e4d95f7e81929687d6242a
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 {}
136 void RunReplyOnOriginThread() override { Reset(); }
138 void Reset() {
139 did_run_ = false;
140 did_complete_ = false;
143 protected:
144 ~PerfImageDecodeTaskImpl() override {}
146 private:
147 DISALLOW_COPY_AND_ASSIGN(PerfImageDecodeTaskImpl);
150 class PerfRasterTaskImpl : public RasterTask {
151 public:
152 PerfRasterTaskImpl(scoped_ptr<ScopedResource> resource,
153 ImageDecodeTask::Vector* dependencies)
154 : RasterTask(resource.get(), dependencies), resource_(resource.Pass()) {}
156 // Overridden from Task:
157 void RunOnWorkerThread() override {}
159 // Overridden from TileTask:
160 void ScheduleOnOriginThread(TileTaskClient* client) override {
161 // No tile ids are given to support partial updates.
162 raster_buffer_ = client->AcquireBufferForRaster(resource(), 0, 0);
164 void CompleteOnOriginThread(TileTaskClient* client) override {
165 client->ReleaseBufferForRaster(raster_buffer_.Pass());
167 void RunReplyOnOriginThread() override { Reset(); }
169 void Reset() {
170 did_run_ = false;
171 did_complete_ = false;
174 protected:
175 ~PerfRasterTaskImpl() override {}
177 private:
178 scoped_ptr<ScopedResource> resource_;
179 scoped_ptr<RasterBuffer> raster_buffer_;
181 DISALLOW_COPY_AND_ASSIGN(PerfRasterTaskImpl);
184 class TileTaskWorkerPoolPerfTestBase {
185 public:
186 typedef std::vector<scoped_refptr<RasterTask>> RasterTaskVector;
188 enum NamedTaskSet { REQUIRED_FOR_ACTIVATION, REQUIRED_FOR_DRAW, ALL };
190 TileTaskWorkerPoolPerfTestBase()
191 : context_provider_(make_scoped_refptr(new PerfContextProvider)),
192 task_runner_(new base::TestSimpleTaskRunner),
193 task_graph_runner_(new TaskGraphRunner),
194 timer_(kWarmupRuns,
195 base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
196 kTimeCheckInterval) {}
198 void CreateImageDecodeTasks(unsigned num_image_decode_tasks,
199 ImageDecodeTask::Vector* image_decode_tasks) {
200 for (unsigned i = 0; i < num_image_decode_tasks; ++i)
201 image_decode_tasks->push_back(new PerfImageDecodeTaskImpl);
204 void CreateRasterTasks(unsigned num_raster_tasks,
205 const ImageDecodeTask::Vector& image_decode_tasks,
206 RasterTaskVector* raster_tasks) {
207 const gfx::Size size(1, 1);
209 for (unsigned i = 0; i < num_raster_tasks; ++i) {
210 scoped_ptr<ScopedResource> resource(
211 ScopedResource::Create(resource_provider_.get()));
212 resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
213 RGBA_8888);
215 ImageDecodeTask::Vector dependencies = image_decode_tasks;
216 raster_tasks->push_back(
217 new PerfRasterTaskImpl(resource.Pass(), &dependencies));
221 void BuildTileTaskQueue(TileTaskQueue* queue,
222 const RasterTaskVector& raster_tasks) {
223 for (size_t i = 0u; i < raster_tasks.size(); ++i) {
224 bool required_for_activation = (i % 2) == 0;
225 TaskSetCollection task_set_collection;
226 task_set_collection[ALL] = true;
227 task_set_collection[REQUIRED_FOR_ACTIVATION] = required_for_activation;
228 queue->items.push_back(
229 TileTaskQueue::Item(raster_tasks[i].get(), task_set_collection));
233 protected:
234 scoped_refptr<ContextProvider> context_provider_;
235 FakeOutputSurfaceClient output_surface_client_;
236 scoped_ptr<FakeOutputSurface> output_surface_;
237 scoped_ptr<ResourceProvider> resource_provider_;
238 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
239 scoped_ptr<TaskGraphRunner> task_graph_runner_;
240 LapTimer timer_;
243 class TileTaskWorkerPoolPerfTest
244 : public TileTaskWorkerPoolPerfTestBase,
245 public testing::TestWithParam<TileTaskWorkerPoolType>,
246 public TileTaskRunnerClient {
247 public:
248 // Overridden from testing::Test:
249 void SetUp() override {
250 switch (GetParam()) {
251 case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY:
252 Create3dOutputSurfaceAndResourceProvider();
253 tile_task_worker_pool_ = ZeroCopyTileTaskWorkerPool::Create(
254 task_runner_.get(), task_graph_runner_.get(),
255 resource_provider_.get());
256 break;
257 case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY:
258 Create3dOutputSurfaceAndResourceProvider();
259 tile_task_worker_pool_ = OneCopyTileTaskWorkerPool::Create(
260 task_runner_.get(), task_graph_runner_.get(),
261 context_provider_.get(), resource_provider_.get(),
262 std::numeric_limits<int>::max(), false,
263 std::numeric_limits<int>::max());
264 break;
265 case TILE_TASK_WORKER_POOL_TYPE_GPU:
266 Create3dOutputSurfaceAndResourceProvider();
267 tile_task_worker_pool_ = GpuTileTaskWorkerPool::Create(
268 task_runner_.get(), task_graph_runner_.get(),
269 context_provider_.get(), resource_provider_.get(), false, 0);
270 break;
271 case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
272 CreateSoftwareOutputSurfaceAndResourceProvider();
273 tile_task_worker_pool_ = BitmapTileTaskWorkerPool::Create(
274 task_runner_.get(), task_graph_runner_.get(),
275 resource_provider_.get());
276 break;
279 DCHECK(tile_task_worker_pool_);
280 tile_task_worker_pool_->AsTileTaskRunner()->SetClient(this);
282 void TearDown() override {
283 tile_task_worker_pool_->AsTileTaskRunner()->Shutdown();
284 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
287 // Overriden from TileTaskRunnerClient:
288 void DidFinishRunningTileTasks(TaskSet task_set) override {
289 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
291 TaskSetCollection TasksThatShouldBeForcedToComplete() const override {
292 return TaskSetCollection();
295 void RunMessageLoopUntilAllTasksHaveCompleted() {
296 task_graph_runner_->RunUntilIdle();
297 task_runner_->RunUntilIdle();
300 void RunScheduleTasksTest(const std::string& test_name,
301 unsigned num_raster_tasks,
302 unsigned num_image_decode_tasks) {
303 ImageDecodeTask::Vector image_decode_tasks;
304 RasterTaskVector raster_tasks;
305 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
306 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
308 // Avoid unnecessary heap allocations by reusing the same queue.
309 TileTaskQueue queue;
311 timer_.Reset();
312 do {
313 queue.Reset();
314 BuildTileTaskQueue(&queue, raster_tasks);
315 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
316 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
317 timer_.NextLap();
318 } while (!timer_.HasTimeLimitExpired());
320 TileTaskQueue empty;
321 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
322 RunMessageLoopUntilAllTasksHaveCompleted();
324 perf_test::PrintResult("schedule_tasks", TestModifierString(), test_name,
325 timer_.LapsPerSecond(), "runs/s", true);
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(num_raster_tasks, image_decode_tasks[i],
337 &raster_tasks[i]);
340 // Avoid unnecessary heap allocations by reusing the same queue.
341 TileTaskQueue queue;
343 size_t count = 0;
344 timer_.Reset();
345 do {
346 queue.Reset();
347 BuildTileTaskQueue(&queue, raster_tasks[count % kNumVersions]);
348 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
349 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
350 ++count;
351 timer_.NextLap();
352 } while (!timer_.HasTimeLimitExpired());
354 TileTaskQueue empty;
355 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
356 RunMessageLoopUntilAllTasksHaveCompleted();
358 perf_test::PrintResult("schedule_alternate_tasks", TestModifierString(),
359 test_name, timer_.LapsPerSecond(), "runs/s", true);
362 void RunScheduleAndExecuteTasksTest(const std::string& test_name,
363 unsigned num_raster_tasks,
364 unsigned num_image_decode_tasks) {
365 ImageDecodeTask::Vector image_decode_tasks;
366 RasterTaskVector raster_tasks;
367 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
368 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
370 // Avoid unnecessary heap allocations by reusing the same queue.
371 TileTaskQueue queue;
373 timer_.Reset();
374 do {
375 queue.Reset();
376 BuildTileTaskQueue(&queue, raster_tasks);
377 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
378 RunMessageLoopUntilAllTasksHaveCompleted();
379 timer_.NextLap();
380 } while (!timer_.HasTimeLimitExpired());
382 TileTaskQueue empty;
383 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
384 RunMessageLoopUntilAllTasksHaveCompleted();
386 perf_test::PrintResult("schedule_and_execute_tasks", TestModifierString(),
387 test_name, timer_.LapsPerSecond(), "runs/s", true);
390 private:
391 void Create3dOutputSurfaceAndResourceProvider() {
392 output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
393 CHECK(output_surface_->BindToClient(&output_surface_client_));
394 resource_provider_ = FakeResourceProvider::Create(
395 output_surface_.get(), nullptr, &gpu_memory_buffer_manager_);
398 void CreateSoftwareOutputSurfaceAndResourceProvider() {
399 output_surface_ = FakeOutputSurface::CreateSoftware(
400 make_scoped_ptr(new SoftwareOutputDevice));
401 CHECK(output_surface_->BindToClient(&output_surface_client_));
402 resource_provider_ = FakeResourceProvider::Create(
403 output_surface_.get(), &shared_bitmap_manager_, nullptr);
406 std::string TestModifierString() const {
407 switch (GetParam()) {
408 case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY:
409 return std::string("_zero_copy_tile_task_worker_pool");
410 case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY:
411 return std::string("_one_copy_tile_task_worker_pool");
412 case TILE_TASK_WORKER_POOL_TYPE_GPU:
413 return std::string("_gpu_tile_task_worker_pool");
414 case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
415 return std::string("_bitmap_tile_task_worker_pool");
417 NOTREACHED();
418 return std::string();
421 scoped_ptr<TileTaskWorkerPool> tile_task_worker_pool_;
422 TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
423 TestSharedBitmapManager shared_bitmap_manager_;
426 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleTasks) {
427 RunScheduleTasksTest("1_0", 1, 0);
428 RunScheduleTasksTest("32_0", 32, 0);
429 RunScheduleTasksTest("1_1", 1, 1);
430 RunScheduleTasksTest("32_1", 32, 1);
431 RunScheduleTasksTest("1_4", 1, 4);
432 RunScheduleTasksTest("32_4", 32, 4);
435 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAlternateTasks) {
436 RunScheduleAlternateTasksTest("1_0", 1, 0);
437 RunScheduleAlternateTasksTest("32_0", 32, 0);
438 RunScheduleAlternateTasksTest("1_1", 1, 1);
439 RunScheduleAlternateTasksTest("32_1", 32, 1);
440 RunScheduleAlternateTasksTest("1_4", 1, 4);
441 RunScheduleAlternateTasksTest("32_4", 32, 4);
444 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAndExecuteTasks) {
445 RunScheduleAndExecuteTasksTest("1_0", 1, 0);
446 RunScheduleAndExecuteTasksTest("32_0", 32, 0);
447 RunScheduleAndExecuteTasksTest("1_1", 1, 1);
448 RunScheduleAndExecuteTasksTest("32_1", 32, 1);
449 RunScheduleAndExecuteTasksTest("1_4", 1, 4);
450 RunScheduleAndExecuteTasksTest("32_4", 32, 4);
453 INSTANTIATE_TEST_CASE_P(TileTaskWorkerPoolPerfTests,
454 TileTaskWorkerPoolPerfTest,
455 ::testing::Values(TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
456 TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
457 TILE_TASK_WORKER_POOL_TYPE_GPU,
458 TILE_TASK_WORKER_POOL_TYPE_BITMAP));
460 class TileTaskWorkerPoolCommonPerfTest : public TileTaskWorkerPoolPerfTestBase,
461 public testing::Test {
462 public:
463 // Overridden from testing::Test:
464 void SetUp() override {
465 output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
466 CHECK(output_surface_->BindToClient(&output_surface_client_));
467 resource_provider_ =
468 FakeResourceProvider::Create(output_surface_.get(), nullptr);
471 void RunBuildTileTaskQueueTest(const std::string& test_name,
472 unsigned num_raster_tasks,
473 unsigned num_image_decode_tasks) {
474 ImageDecodeTask::Vector image_decode_tasks;
475 RasterTaskVector raster_tasks;
476 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
477 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
479 // Avoid unnecessary heap allocations by reusing the same queue.
480 TileTaskQueue queue;
482 timer_.Reset();
483 do {
484 queue.Reset();
485 BuildTileTaskQueue(&queue, raster_tasks);
486 timer_.NextLap();
487 } while (!timer_.HasTimeLimitExpired());
489 perf_test::PrintResult("build_raster_task_queue", "", test_name,
490 timer_.LapsPerSecond(), "runs/s", true);
494 TEST_F(TileTaskWorkerPoolCommonPerfTest, BuildTileTaskQueue) {
495 RunBuildTileTaskQueueTest("1_0", 1, 0);
496 RunBuildTileTaskQueueTest("32_0", 32, 0);
497 RunBuildTileTaskQueueTest("1_1", 1, 1);
498 RunBuildTileTaskQueueTest("32_1", 32, 1);
499 RunBuildTileTaskQueueTest("1_4", 1, 4);
500 RunBuildTileTaskQueueTest("32_4", 32, 4);
503 } // namespace
504 } // namespace cc