Revert of Linux MSan: enable swarming/sharding for browser_tests. (patchset #1 id...
[chromium-blink-merge.git] / cc / resources / tile_task_worker_pool_perftest.cc
blob483b71f3add5593dfbc719cc91cfb1ae3cbd85ee
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_tile_task_worker_pool.h"
13 #include "cc/resources/one_copy_tile_task_worker_pool.h"
14 #include "cc/resources/pixel_buffer_tile_task_worker_pool.h"
15 #include "cc/resources/raster_buffer.h"
16 #include "cc/resources/resource_pool.h"
17 #include "cc/resources/resource_provider.h"
18 #include "cc/resources/scoped_resource.h"
19 #include "cc/resources/tile_task_runner.h"
20 #include "cc/resources/zero_copy_tile_task_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_gpu_memory_buffer_manager.h"
25 #include "cc/test/test_shared_bitmap_manager.h"
26 #include "cc/test/test_web_graphics_context_3d.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "testing/perf/perf_test.h"
29 #include "third_party/khronos/GLES2/gl2.h"
30 #include "third_party/skia/include/gpu/GrContext.h"
31 #include "third_party/skia/include/gpu/gl/GrGLInterface.h"
33 namespace cc {
34 namespace {
36 class PerfGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
37 // Overridden from gpu::gles2::GLES2Interface:
38 GLuint CreateImageCHROMIUM(ClientBuffer buffer,
39 GLsizei width,
40 GLsizei height,
41 GLenum internalformat) override {
42 return 1u;
44 void GenBuffers(GLsizei n, GLuint* buffers) override {
45 for (GLsizei i = 0; i < n; ++i)
46 buffers[i] = 1u;
48 void GenTextures(GLsizei n, GLuint* textures) override {
49 for (GLsizei i = 0; i < n; ++i)
50 textures[i] = 1u;
52 void GetIntegerv(GLenum pname, GLint* params) override {
53 if (pname == GL_MAX_TEXTURE_SIZE)
54 *params = INT_MAX;
56 void GenQueriesEXT(GLsizei n, GLuint* queries) override {
57 for (GLsizei i = 0; i < n; ++i)
58 queries[i] = 1u;
60 void GetQueryObjectuivEXT(GLuint query,
61 GLenum pname,
62 GLuint* params) override {
63 if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
64 *params = 1;
68 class PerfContextProvider : public ContextProvider {
69 public:
70 PerfContextProvider() : context_gl_(new PerfGLES2Interface) {}
72 bool BindToCurrentThread() override { return true; }
73 Capabilities ContextCapabilities() override {
74 Capabilities capabilities;
75 capabilities.gpu.image = true;
76 capabilities.gpu.sync_query = true;
77 return capabilities;
79 gpu::gles2::GLES2Interface* ContextGL() override { return context_gl_.get(); }
80 gpu::ContextSupport* ContextSupport() override { return &support_; }
81 class GrContext* GrContext() override {
82 if (gr_context_)
83 return gr_context_.get();
85 skia::RefPtr<const GrGLInterface> null_interface =
86 skia::AdoptRef(GrGLCreateNullInterface());
87 gr_context_ = skia::AdoptRef(GrContext::Create(
88 kOpenGL_GrBackend,
89 reinterpret_cast<GrBackendContext>(null_interface.get())));
90 return gr_context_.get();
92 bool IsContextLost() override { return false; }
93 void VerifyContexts() override {}
94 void DeleteCachedResources() override {}
95 bool DestroyedOnMainThread() override { return false; }
96 void SetLostContextCallback(const LostContextCallback& cb) override {}
97 void SetMemoryPolicyChangedCallback(
98 const MemoryPolicyChangedCallback& cb) override {}
100 private:
101 ~PerfContextProvider() override {}
103 scoped_ptr<PerfGLES2Interface> context_gl_;
104 skia::RefPtr<class GrContext> gr_context_;
105 TestContextSupport support_;
108 enum TileTaskWorkerPoolType {
109 TILE_TASK_WORKER_POOL_TYPE_PIXEL_BUFFER,
110 TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
111 TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
112 TILE_TASK_WORKER_POOL_TYPE_GPU,
113 TILE_TASK_WORKER_POOL_TYPE_BITMAP
116 static const int kTimeLimitMillis = 2000;
117 static const int kWarmupRuns = 5;
118 static const int kTimeCheckInterval = 10;
120 class PerfImageDecodeTaskImpl : public ImageDecodeTask {
121 public:
122 PerfImageDecodeTaskImpl() {}
124 // Overridden from Task:
125 void RunOnWorkerThread() override {}
127 // Overridden from TileTask:
128 void ScheduleOnOriginThread(TileTaskClient* client) override {}
129 void CompleteOnOriginThread(TileTaskClient* client) override {}
130 void RunReplyOnOriginThread() override { Reset(); }
132 void Reset() {
133 did_run_ = false;
134 did_complete_ = false;
137 protected:
138 ~PerfImageDecodeTaskImpl() override {}
140 private:
141 DISALLOW_COPY_AND_ASSIGN(PerfImageDecodeTaskImpl);
144 class PerfRasterTaskImpl : public RasterTask {
145 public:
146 PerfRasterTaskImpl(scoped_ptr<ScopedResource> resource,
147 ImageDecodeTask::Vector* dependencies)
148 : RasterTask(resource.get(), dependencies), resource_(resource.Pass()) {}
150 // Overridden from Task:
151 void RunOnWorkerThread() override {}
153 // Overridden from TileTask:
154 void ScheduleOnOriginThread(TileTaskClient* client) override {
155 raster_buffer_ = client->AcquireBufferForRaster(resource());
157 void CompleteOnOriginThread(TileTaskClient* client) override {
158 client->ReleaseBufferForRaster(raster_buffer_.Pass());
160 void RunReplyOnOriginThread() override { Reset(); }
162 void Reset() {
163 did_run_ = false;
164 did_complete_ = false;
167 protected:
168 ~PerfRasterTaskImpl() override {}
170 private:
171 scoped_ptr<ScopedResource> resource_;
172 scoped_ptr<RasterBuffer> raster_buffer_;
174 DISALLOW_COPY_AND_ASSIGN(PerfRasterTaskImpl);
177 class TileTaskWorkerPoolPerfTestBase {
178 public:
179 typedef std::vector<scoped_refptr<RasterTask>> RasterTaskVector;
181 enum NamedTaskSet { REQUIRED_FOR_ACTIVATION, REQUIRED_FOR_DRAW, ALL };
183 TileTaskWorkerPoolPerfTestBase()
184 : context_provider_(make_scoped_refptr(new PerfContextProvider)),
185 task_runner_(new base::TestSimpleTaskRunner),
186 task_graph_runner_(new TaskGraphRunner),
187 timer_(kWarmupRuns,
188 base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
189 kTimeCheckInterval) {}
191 void CreateImageDecodeTasks(unsigned num_image_decode_tasks,
192 ImageDecodeTask::Vector* image_decode_tasks) {
193 for (unsigned i = 0; i < num_image_decode_tasks; ++i)
194 image_decode_tasks->push_back(new PerfImageDecodeTaskImpl);
197 void CreateRasterTasks(unsigned num_raster_tasks,
198 const ImageDecodeTask::Vector& image_decode_tasks,
199 RasterTaskVector* raster_tasks) {
200 const gfx::Size size(1, 1);
202 for (unsigned i = 0; i < num_raster_tasks; ++i) {
203 scoped_ptr<ScopedResource> resource(
204 ScopedResource::Create(resource_provider_.get()));
205 resource->Allocate(size, ResourceProvider::TextureHintImmutable,
206 RGBA_8888);
208 ImageDecodeTask::Vector dependencies = image_decode_tasks;
209 raster_tasks->push_back(
210 new PerfRasterTaskImpl(resource.Pass(), &dependencies));
214 void BuildTileTaskQueue(TileTaskQueue* queue,
215 const RasterTaskVector& raster_tasks) {
216 for (size_t i = 0u; i < raster_tasks.size(); ++i) {
217 bool required_for_activation = (i % 2) == 0;
218 TaskSetCollection task_set_collection;
219 task_set_collection[ALL] = true;
220 task_set_collection[REQUIRED_FOR_ACTIVATION] = required_for_activation;
221 queue->items.push_back(
222 TileTaskQueue::Item(raster_tasks[i].get(), task_set_collection));
226 protected:
227 scoped_refptr<ContextProvider> context_provider_;
228 FakeOutputSurfaceClient output_surface_client_;
229 scoped_ptr<FakeOutputSurface> output_surface_;
230 scoped_ptr<ResourceProvider> resource_provider_;
231 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
232 scoped_ptr<TaskGraphRunner> task_graph_runner_;
233 LapTimer timer_;
236 class TileTaskWorkerPoolPerfTest
237 : public TileTaskWorkerPoolPerfTestBase,
238 public testing::TestWithParam<TileTaskWorkerPoolType>,
239 public TileTaskRunnerClient {
240 public:
241 // Overridden from testing::Test:
242 void SetUp() override {
243 switch (GetParam()) {
244 case TILE_TASK_WORKER_POOL_TYPE_PIXEL_BUFFER:
245 Create3dOutputSurfaceAndResourceProvider();
246 tile_task_worker_pool_ = PixelBufferTileTaskWorkerPool::Create(
247 task_runner_.get(), task_graph_runner_.get(),
248 context_provider_.get(), resource_provider_.get(),
249 std::numeric_limits<size_t>::max());
250 break;
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 staging_resource_pool_ = ResourcePool::Create(resource_provider_.get(),
260 GL_TEXTURE_2D);
261 tile_task_worker_pool_ = OneCopyTileTaskWorkerPool::Create(
262 task_runner_.get(), task_graph_runner_.get(),
263 context_provider_.get(), resource_provider_.get(),
264 staging_resource_pool_.get());
265 break;
266 case TILE_TASK_WORKER_POOL_TYPE_GPU:
267 Create3dOutputSurfaceAndResourceProvider();
268 tile_task_worker_pool_ = GpuTileTaskWorkerPool::Create(
269 task_runner_.get(), task_graph_runner_.get(),
270 resource_provider_.get());
271 break;
272 case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
273 CreateSoftwareOutputSurfaceAndResourceProvider();
274 tile_task_worker_pool_ = BitmapTileTaskWorkerPool::Create(
275 task_runner_.get(), task_graph_runner_.get(),
276 resource_provider_.get());
277 break;
280 DCHECK(tile_task_worker_pool_);
281 tile_task_worker_pool_->AsTileTaskRunner()->SetClient(this);
283 void TearDown() override {
284 tile_task_worker_pool_->AsTileTaskRunner()->Shutdown();
285 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
288 // Overriden from TileTaskRunnerClient:
289 void DidFinishRunningTileTasks(TaskSet task_set) override {
290 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
292 TaskSetCollection TasksThatShouldBeForcedToComplete() const override {
293 return TaskSetCollection();
296 void RunMessageLoopUntilAllTasksHaveCompleted() {
297 task_graph_runner_->RunUntilIdle();
298 task_runner_->RunUntilIdle();
301 void RunScheduleTasksTest(const std::string& test_name,
302 unsigned num_raster_tasks,
303 unsigned num_image_decode_tasks) {
304 ImageDecodeTask::Vector image_decode_tasks;
305 RasterTaskVector raster_tasks;
306 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
307 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
309 // Avoid unnecessary heap allocations by reusing the same queue.
310 TileTaskQueue queue;
312 timer_.Reset();
313 do {
314 queue.Reset();
315 BuildTileTaskQueue(&queue, raster_tasks);
316 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
317 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
318 timer_.NextLap();
319 } while (!timer_.HasTimeLimitExpired());
321 TileTaskQueue empty;
322 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
323 RunMessageLoopUntilAllTasksHaveCompleted();
325 perf_test::PrintResult("schedule_tasks", TestModifierString(), test_name,
326 timer_.LapsPerSecond(), "runs/s", true);
329 void RunScheduleAlternateTasksTest(const std::string& test_name,
330 unsigned num_raster_tasks,
331 unsigned num_image_decode_tasks) {
332 const size_t kNumVersions = 2;
333 ImageDecodeTask::Vector image_decode_tasks[kNumVersions];
334 RasterTaskVector raster_tasks[kNumVersions];
335 for (size_t i = 0; i < kNumVersions; ++i) {
336 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks[i]);
337 CreateRasterTasks(num_raster_tasks, image_decode_tasks[i],
338 &raster_tasks[i]);
341 // Avoid unnecessary heap allocations by reusing the same queue.
342 TileTaskQueue queue;
344 size_t count = 0;
345 timer_.Reset();
346 do {
347 queue.Reset();
348 BuildTileTaskQueue(&queue, raster_tasks[count % kNumVersions]);
349 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
350 tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
351 ++count;
352 timer_.NextLap();
353 } while (!timer_.HasTimeLimitExpired());
355 TileTaskQueue empty;
356 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
357 RunMessageLoopUntilAllTasksHaveCompleted();
359 perf_test::PrintResult("schedule_alternate_tasks", TestModifierString(),
360 test_name, timer_.LapsPerSecond(), "runs/s", true);
363 void RunScheduleAndExecuteTasksTest(const std::string& test_name,
364 unsigned num_raster_tasks,
365 unsigned num_image_decode_tasks) {
366 ImageDecodeTask::Vector image_decode_tasks;
367 RasterTaskVector raster_tasks;
368 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
369 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
371 // Avoid unnecessary heap allocations by reusing the same queue.
372 TileTaskQueue queue;
374 timer_.Reset();
375 do {
376 queue.Reset();
377 BuildTileTaskQueue(&queue, raster_tasks);
378 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
379 RunMessageLoopUntilAllTasksHaveCompleted();
380 timer_.NextLap();
381 } while (!timer_.HasTimeLimitExpired());
383 TileTaskQueue empty;
384 tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&empty);
385 RunMessageLoopUntilAllTasksHaveCompleted();
387 perf_test::PrintResult("schedule_and_execute_tasks", TestModifierString(),
388 test_name, timer_.LapsPerSecond(), "runs/s", true);
391 private:
392 void Create3dOutputSurfaceAndResourceProvider() {
393 output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
394 CHECK(output_surface_->BindToClient(&output_surface_client_));
395 resource_provider_ = ResourceProvider::Create(output_surface_.get(), NULL,
396 &gpu_memory_buffer_manager_,
397 NULL, 0, false, 1).Pass();
400 void CreateSoftwareOutputSurfaceAndResourceProvider() {
401 output_surface_ = FakeOutputSurface::CreateSoftware(
402 make_scoped_ptr(new SoftwareOutputDevice));
403 CHECK(output_surface_->BindToClient(&output_surface_client_));
404 resource_provider_ =
405 ResourceProvider::Create(output_surface_.get(), &shared_bitmap_manager_,
406 NULL, NULL, 0, false, 1).Pass();
409 std::string TestModifierString() const {
410 switch (GetParam()) {
411 case TILE_TASK_WORKER_POOL_TYPE_PIXEL_BUFFER:
412 return std::string("_pixel_tile_task_worker_pool");
413 case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY:
414 return std::string("_zero_copy_tile_task_worker_pool");
415 case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY:
416 return std::string("_one_copy_tile_task_worker_pool");
417 case TILE_TASK_WORKER_POOL_TYPE_GPU:
418 return std::string("_gpu_tile_task_worker_pool");
419 case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
420 return std::string("_bitmap_tile_task_worker_pool");
422 NOTREACHED();
423 return std::string();
426 scoped_ptr<ResourcePool> staging_resource_pool_;
427 scoped_ptr<TileTaskWorkerPool> tile_task_worker_pool_;
428 TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
429 TestSharedBitmapManager shared_bitmap_manager_;
432 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleTasks) {
433 RunScheduleTasksTest("1_0", 1, 0);
434 RunScheduleTasksTest("32_0", 32, 0);
435 RunScheduleTasksTest("1_1", 1, 1);
436 RunScheduleTasksTest("32_1", 32, 1);
437 RunScheduleTasksTest("1_4", 1, 4);
438 RunScheduleTasksTest("32_4", 32, 4);
441 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAlternateTasks) {
442 RunScheduleAlternateTasksTest("1_0", 1, 0);
443 RunScheduleAlternateTasksTest("32_0", 32, 0);
444 RunScheduleAlternateTasksTest("1_1", 1, 1);
445 RunScheduleAlternateTasksTest("32_1", 32, 1);
446 RunScheduleAlternateTasksTest("1_4", 1, 4);
447 RunScheduleAlternateTasksTest("32_4", 32, 4);
450 TEST_P(TileTaskWorkerPoolPerfTest, ScheduleAndExecuteTasks) {
451 RunScheduleAndExecuteTasksTest("1_0", 1, 0);
452 RunScheduleAndExecuteTasksTest("32_0", 32, 0);
453 RunScheduleAndExecuteTasksTest("1_1", 1, 1);
454 RunScheduleAndExecuteTasksTest("32_1", 32, 1);
455 RunScheduleAndExecuteTasksTest("1_4", 1, 4);
456 RunScheduleAndExecuteTasksTest("32_4", 32, 4);
459 INSTANTIATE_TEST_CASE_P(
460 TileTaskWorkerPoolPerfTests,
461 TileTaskWorkerPoolPerfTest,
462 ::testing::Values(TILE_TASK_WORKER_POOL_TYPE_PIXEL_BUFFER,
463 TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
464 TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
465 TILE_TASK_WORKER_POOL_TYPE_GPU,
466 TILE_TASK_WORKER_POOL_TYPE_BITMAP));
468 class TileTaskWorkerPoolCommonPerfTest : public TileTaskWorkerPoolPerfTestBase,
469 public testing::Test {
470 public:
471 // Overridden from testing::Test:
472 void SetUp() override {
473 output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
474 CHECK(output_surface_->BindToClient(&output_surface_client_));
475 resource_provider_ =
476 ResourceProvider::Create(output_surface_.get(), NULL, NULL, NULL, 0,
477 false, 1).Pass();
480 void RunBuildTileTaskQueueTest(const std::string& test_name,
481 unsigned num_raster_tasks,
482 unsigned num_image_decode_tasks) {
483 ImageDecodeTask::Vector image_decode_tasks;
484 RasterTaskVector raster_tasks;
485 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
486 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
488 // Avoid unnecessary heap allocations by reusing the same queue.
489 TileTaskQueue queue;
491 timer_.Reset();
492 do {
493 queue.Reset();
494 BuildTileTaskQueue(&queue, raster_tasks);
495 timer_.NextLap();
496 } while (!timer_.HasTimeLimitExpired());
498 perf_test::PrintResult("build_raster_task_queue", "", test_name,
499 timer_.LapsPerSecond(), "runs/s", true);
503 TEST_F(TileTaskWorkerPoolCommonPerfTest, BuildTileTaskQueue) {
504 RunBuildTileTaskQueueTest("1_0", 1, 0);
505 RunBuildTileTaskQueueTest("32_0", 32, 0);
506 RunBuildTileTaskQueueTest("1_1", 1, 1);
507 RunBuildTileTaskQueueTest("32_1", 32, 1);
508 RunBuildTileTaskQueueTest("1_4", 1, 4);
509 RunBuildTileTaskQueueTest("32_4", 32, 4);
512 } // namespace
513 } // namespace cc