Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / cc / resources / raster_worker_pool_perftest.cc
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_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
31 namespace cc {
32 namespace {
33
34 class PerfGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
35   // Overridden from gpu::gles2::GLES2Interface:
36   GLuint CreateImageCHROMIUM(ClientBuffer buffer,
37                              GLsizei width,
38                              GLsizei height,
39                              GLenum internalformat) override {
40     return 1u;
41   }
42   void GenBuffers(GLsizei n, GLuint* buffers) override {
43     for (GLsizei i = 0; i < n; ++i)
44       buffers[i] = 1u;
45   }
46   void GenTextures(GLsizei n, GLuint* textures) override {
47     for (GLsizei i = 0; i < n; ++i)
48       textures[i] = 1u;
49   }
50   void GetIntegerv(GLenum pname, GLint* params) override {
51     if (pname == GL_MAX_TEXTURE_SIZE)
52       *params = INT_MAX;
53   }
54   void GenQueriesEXT(GLsizei n, GLuint* queries) override {
55     for (GLsizei i = 0; i < n; ++i)
56       queries[i] = 1u;
57   }
58   void GetQueryObjectuivEXT(GLuint query,
59                             GLenum pname,
60                             GLuint* params) override {
61     if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
62       *params = 1;
63   }
64 };
65
66 class PerfContextProvider : public ContextProvider {
67  public:
68   PerfContextProvider() : context_gl_(new PerfGLES2Interface) {}
69
70   bool BindToCurrentThread() override { return true; }
71   Capabilities ContextCapabilities() override {
72     Capabilities capabilities;
73     capabilities.gpu.image = true;
74     capabilities.gpu.sync_query = true;
75     return capabilities;
76   }
77   gpu::gles2::GLES2Interface* ContextGL() override { return context_gl_.get(); }
78   gpu::ContextSupport* ContextSupport() override { return &support_; }
79   class GrContext* GrContext() override {
80     return NULL;
81   }
82   bool IsContextLost() override { return false; }
83   void VerifyContexts() override {}
84   void DeleteCachedResources() override {}
85   bool DestroyedOnMainThread() override { return false; }
86   void SetLostContextCallback(const LostContextCallback& cb) override {}
87   void SetMemoryPolicyChangedCallback(
88       const MemoryPolicyChangedCallback& cb) override {}
89
90  private:
91   ~PerfContextProvider() override {}
92
93   scoped_ptr<PerfGLES2Interface> context_gl_;
94   TestContextSupport support_;
95 };
96
97 enum RasterWorkerPoolType {
98   RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
99   RASTER_WORKER_POOL_TYPE_ZERO_COPY,
100   RASTER_WORKER_POOL_TYPE_ONE_COPY,
101   RASTER_WORKER_POOL_TYPE_GPU,
102   RASTER_WORKER_POOL_TYPE_BITMAP
103 };
104
105 static const int kTimeLimitMillis = 2000;
106 static const int kWarmupRuns = 5;
107 static const int kTimeCheckInterval = 10;
108
109 class PerfImageDecodeTaskImpl : public ImageDecodeTask {
110  public:
111   PerfImageDecodeTaskImpl() {}
112
113   // Overridden from Task:
114   void RunOnWorkerThread() override {}
115
116   // Overridden from RasterizerTask:
117   void ScheduleOnOriginThread(RasterizerTaskClient* client) override {}
118   void CompleteOnOriginThread(RasterizerTaskClient* client) override {}
119   void RunReplyOnOriginThread() override { Reset(); }
120
121   void Reset() {
122     did_run_ = false;
123     did_complete_ = false;
124   }
125
126  protected:
127   ~PerfImageDecodeTaskImpl() override {}
128
129  private:
130   DISALLOW_COPY_AND_ASSIGN(PerfImageDecodeTaskImpl);
131 };
132
133 class PerfRasterTaskImpl : public RasterTask {
134  public:
135   PerfRasterTaskImpl(scoped_ptr<ScopedResource> resource,
136                      ImageDecodeTask::Vector* dependencies)
137       : RasterTask(resource.get(), dependencies), resource_(resource.Pass()) {}
138
139   // Overridden from Task:
140   void RunOnWorkerThread() override {}
141
142   // Overridden from RasterizerTask:
143   void ScheduleOnOriginThread(RasterizerTaskClient* client) override {
144     raster_buffer_ = client->AcquireBufferForRaster(resource());
145   }
146   void CompleteOnOriginThread(RasterizerTaskClient* client) override {
147     client->ReleaseBufferForRaster(raster_buffer_.Pass());
148   }
149   void RunReplyOnOriginThread() override { Reset(); }
150
151   void Reset() {
152     did_run_ = false;
153     did_complete_ = false;
154   }
155
156  protected:
157   ~PerfRasterTaskImpl() override {}
158
159  private:
160   scoped_ptr<ScopedResource> resource_;
161   scoped_ptr<RasterBuffer> raster_buffer_;
162
163   DISALLOW_COPY_AND_ASSIGN(PerfRasterTaskImpl);
164 };
165
166 class RasterWorkerPoolPerfTestBase {
167  public:
168   typedef std::vector<scoped_refptr<RasterTask>> RasterTaskVector;
169
170   enum NamedTaskSet { REQUIRED_FOR_ACTIVATION = 0, ALL = 1 };
171
172   RasterWorkerPoolPerfTestBase()
173       : context_provider_(make_scoped_refptr(new PerfContextProvider)),
174         task_runner_(new base::TestSimpleTaskRunner),
175         task_graph_runner_(new TaskGraphRunner),
176         timer_(kWarmupRuns,
177                base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
178                kTimeCheckInterval) {}
179
180   void CreateImageDecodeTasks(unsigned num_image_decode_tasks,
181                               ImageDecodeTask::Vector* image_decode_tasks) {
182     for (unsigned i = 0; i < num_image_decode_tasks; ++i)
183       image_decode_tasks->push_back(new PerfImageDecodeTaskImpl);
184   }
185
186   void CreateRasterTasks(unsigned num_raster_tasks,
187                          const ImageDecodeTask::Vector& image_decode_tasks,
188                          RasterTaskVector* raster_tasks) {
189     const gfx::Size size(1, 1);
190
191     for (unsigned i = 0; i < num_raster_tasks; ++i) {
192       scoped_ptr<ScopedResource> resource(
193           ScopedResource::Create(resource_provider_.get()));
194       resource->Allocate(
195           size, ResourceProvider::TextureHintImmutable, RGBA_8888);
196
197       ImageDecodeTask::Vector dependencies = image_decode_tasks;
198       raster_tasks->push_back(
199           new PerfRasterTaskImpl(resource.Pass(), &dependencies));
200     }
201   }
202
203   void BuildRasterTaskQueue(RasterTaskQueue* queue,
204                             const RasterTaskVector& raster_tasks) {
205     for (size_t i = 0u; i < raster_tasks.size(); ++i) {
206       bool required_for_activation = (i % 2) == 0;
207       TaskSetCollection task_set_collection;
208       task_set_collection[ALL] = true;
209       task_set_collection[REQUIRED_FOR_ACTIVATION] = required_for_activation;
210       queue->items.push_back(
211           RasterTaskQueue::Item(raster_tasks[i].get(), task_set_collection));
212     }
213   }
214
215  protected:
216   scoped_refptr<ContextProvider> context_provider_;
217   FakeOutputSurfaceClient output_surface_client_;
218   scoped_ptr<FakeOutputSurface> output_surface_;
219   scoped_ptr<ResourceProvider> resource_provider_;
220   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
221   scoped_ptr<TaskGraphRunner> task_graph_runner_;
222   LapTimer timer_;
223 };
224
225 class RasterWorkerPoolPerfTest
226     : public RasterWorkerPoolPerfTestBase,
227       public testing::TestWithParam<RasterWorkerPoolType>,
228       public RasterizerClient {
229  public:
230   // Overridden from testing::Test:
231   virtual void SetUp() override {
232     switch (GetParam()) {
233       case RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER:
234         Create3dOutputSurfaceAndResourceProvider();
235         raster_worker_pool_ = PixelBufferRasterWorkerPool::Create(
236             task_runner_.get(),
237             task_graph_runner_.get(),
238             context_provider_.get(),
239             resource_provider_.get(),
240             std::numeric_limits<size_t>::max());
241         break;
242       case RASTER_WORKER_POOL_TYPE_ZERO_COPY:
243         Create3dOutputSurfaceAndResourceProvider();
244         raster_worker_pool_ =
245             ZeroCopyRasterWorkerPool::Create(task_runner_.get(),
246                                              task_graph_runner_.get(),
247                                              resource_provider_.get());
248         break;
249       case RASTER_WORKER_POOL_TYPE_ONE_COPY:
250         Create3dOutputSurfaceAndResourceProvider();
251         staging_resource_pool_ = ResourcePool::Create(
252             resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
253         raster_worker_pool_ =
254             OneCopyRasterWorkerPool::Create(task_runner_.get(),
255                                             task_graph_runner_.get(),
256                                             context_provider_.get(),
257                                             resource_provider_.get(),
258                                             staging_resource_pool_.get());
259         break;
260       case RASTER_WORKER_POOL_TYPE_GPU:
261         Create3dOutputSurfaceAndResourceProvider();
262         raster_worker_pool_ =
263             GpuRasterWorkerPool::Create(task_runner_.get(),
264                                         context_provider_.get(),
265                                         resource_provider_.get(),
266                                         false);
267         break;
268       case RASTER_WORKER_POOL_TYPE_BITMAP:
269         CreateSoftwareOutputSurfaceAndResourceProvider();
270         raster_worker_pool_ =
271             BitmapRasterWorkerPool::Create(task_runner_.get(),
272                                            task_graph_runner_.get(),
273                                            resource_provider_.get());
274         break;
275     }
276
277     DCHECK(raster_worker_pool_);
278     raster_worker_pool_->AsRasterizer()->SetClient(this);
279   }
280   virtual void TearDown() override {
281     raster_worker_pool_->AsRasterizer()->Shutdown();
282     raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
283   }
284
285   // Overriden from RasterizerClient:
286   void DidFinishRunningTasks(TaskSet task_set) override {
287     raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
288   }
289   TaskSetCollection TasksThatShouldBeForcedToComplete() const override {
290     return TaskSetCollection();
291   }
292
293   void RunMessageLoopUntilAllTasksHaveCompleted() {
294     task_graph_runner_->RunUntilIdle();
295     task_runner_->RunUntilIdle();
296   }
297
298   void RunScheduleTasksTest(const std::string& test_name,
299                             unsigned num_raster_tasks,
300                             unsigned num_image_decode_tasks) {
301     ImageDecodeTask::Vector image_decode_tasks;
302     RasterTaskVector raster_tasks;
303     CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
304     CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
305
306     // Avoid unnecessary heap allocations by reusing the same queue.
307     RasterTaskQueue queue;
308
309     timer_.Reset();
310     do {
311       queue.Reset();
312       BuildRasterTaskQueue(&queue, raster_tasks);
313       raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
314       raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
315       timer_.NextLap();
316     } while (!timer_.HasTimeLimitExpired());
317
318     RasterTaskQueue empty;
319     raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty);
320     RunMessageLoopUntilAllTasksHaveCompleted();
321
322     perf_test::PrintResult("schedule_tasks",
323                            TestModifierString(),
324                            test_name,
325                            timer_.LapsPerSecond(),
326                            "runs/s",
327                            true);
328   }
329
330   void RunScheduleAlternateTasksTest(const std::string& test_name,
331                                      unsigned num_raster_tasks,
332                                      unsigned num_image_decode_tasks) {
333     const size_t kNumVersions = 2;
334     ImageDecodeTask::Vector image_decode_tasks[kNumVersions];
335     RasterTaskVector raster_tasks[kNumVersions];
336     for (size_t i = 0; i < kNumVersions; ++i) {
337       CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks[i]);
338       CreateRasterTasks(
339           num_raster_tasks, image_decode_tasks[i], &raster_tasks[i]);
340     }
341
342     // Avoid unnecessary heap allocations by reusing the same queue.
343     RasterTaskQueue queue;
344
345     size_t count = 0;
346     timer_.Reset();
347     do {
348       queue.Reset();
349       BuildRasterTaskQueue(&queue, raster_tasks[count % kNumVersions]);
350       raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
351       raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
352       ++count;
353       timer_.NextLap();
354     } while (!timer_.HasTimeLimitExpired());
355
356     RasterTaskQueue empty;
357     raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty);
358     RunMessageLoopUntilAllTasksHaveCompleted();
359
360     perf_test::PrintResult("schedule_alternate_tasks",
361                            TestModifierString(),
362                            test_name,
363                            timer_.LapsPerSecond(),
364                            "runs/s",
365                            true);
366   }
367
368   void RunScheduleAndExecuteTasksTest(const std::string& test_name,
369                                       unsigned num_raster_tasks,
370                                       unsigned num_image_decode_tasks) {
371     ImageDecodeTask::Vector image_decode_tasks;
372     RasterTaskVector raster_tasks;
373     CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
374     CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
375
376     // Avoid unnecessary heap allocations by reusing the same queue.
377     RasterTaskQueue queue;
378
379     timer_.Reset();
380     do {
381       queue.Reset();
382       BuildRasterTaskQueue(&queue, raster_tasks);
383       raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
384       RunMessageLoopUntilAllTasksHaveCompleted();
385       timer_.NextLap();
386     } while (!timer_.HasTimeLimitExpired());
387
388     RasterTaskQueue empty;
389     raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty);
390     RunMessageLoopUntilAllTasksHaveCompleted();
391
392     perf_test::PrintResult("schedule_and_execute_tasks",
393                            TestModifierString(),
394                            test_name,
395                            timer_.LapsPerSecond(),
396                            "runs/s",
397                            true);
398   }
399
400  private:
401   void Create3dOutputSurfaceAndResourceProvider() {
402     output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
403     CHECK(output_surface_->BindToClient(&output_surface_client_));
404     resource_provider_ = ResourceProvider::Create(output_surface_.get(),
405                                                   NULL,
406                                                   &gpu_memory_buffer_manager_,
407                                                   NULL,
408                                                   0,
409                                                   false,
410                                                   1).Pass();
411   }
412
413   void CreateSoftwareOutputSurfaceAndResourceProvider() {
414     output_surface_ = FakeOutputSurface::CreateSoftware(
415         make_scoped_ptr(new SoftwareOutputDevice));
416     CHECK(output_surface_->BindToClient(&output_surface_client_));
417     resource_provider_ = ResourceProvider::Create(output_surface_.get(),
418                                                   &shared_bitmap_manager_,
419                                                   NULL,
420                                                   NULL,
421                                                   0,
422                                                   false,
423                                                   1).Pass();
424   }
425
426   std::string TestModifierString() const {
427     switch (GetParam()) {
428       case RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER:
429         return std::string("_pixel_raster_worker_pool");
430       case RASTER_WORKER_POOL_TYPE_ZERO_COPY:
431         return std::string("_zero_copy_raster_worker_pool");
432       case RASTER_WORKER_POOL_TYPE_ONE_COPY:
433         return std::string("_one_copy_raster_worker_pool");
434       case RASTER_WORKER_POOL_TYPE_GPU:
435         return std::string("_gpu_raster_worker_pool");
436       case RASTER_WORKER_POOL_TYPE_BITMAP:
437         return std::string("_bitmap_raster_worker_pool");
438     }
439     NOTREACHED();
440     return std::string();
441   }
442
443   scoped_ptr<ResourcePool> staging_resource_pool_;
444   scoped_ptr<RasterWorkerPool> raster_worker_pool_;
445   TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
446   TestSharedBitmapManager shared_bitmap_manager_;
447 };
448
449 TEST_P(RasterWorkerPoolPerfTest, ScheduleTasks) {
450   RunScheduleTasksTest("1_0", 1, 0);
451   RunScheduleTasksTest("32_0", 32, 0);
452   RunScheduleTasksTest("1_1", 1, 1);
453   RunScheduleTasksTest("32_1", 32, 1);
454   RunScheduleTasksTest("1_4", 1, 4);
455   RunScheduleTasksTest("32_4", 32, 4);
456 }
457
458 TEST_P(RasterWorkerPoolPerfTest, ScheduleAlternateTasks) {
459   RunScheduleAlternateTasksTest("1_0", 1, 0);
460   RunScheduleAlternateTasksTest("32_0", 32, 0);
461   RunScheduleAlternateTasksTest("1_1", 1, 1);
462   RunScheduleAlternateTasksTest("32_1", 32, 1);
463   RunScheduleAlternateTasksTest("1_4", 1, 4);
464   RunScheduleAlternateTasksTest("32_4", 32, 4);
465 }
466
467 TEST_P(RasterWorkerPoolPerfTest, ScheduleAndExecuteTasks) {
468   RunScheduleAndExecuteTasksTest("1_0", 1, 0);
469   RunScheduleAndExecuteTasksTest("32_0", 32, 0);
470   RunScheduleAndExecuteTasksTest("1_1", 1, 1);
471   RunScheduleAndExecuteTasksTest("32_1", 32, 1);
472   RunScheduleAndExecuteTasksTest("1_4", 1, 4);
473   RunScheduleAndExecuteTasksTest("32_4", 32, 4);
474 }
475
476 INSTANTIATE_TEST_CASE_P(RasterWorkerPoolPerfTests,
477                         RasterWorkerPoolPerfTest,
478                         ::testing::Values(RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
479                                           RASTER_WORKER_POOL_TYPE_ZERO_COPY,
480                                           RASTER_WORKER_POOL_TYPE_ONE_COPY,
481                                           RASTER_WORKER_POOL_TYPE_GPU,
482                                           RASTER_WORKER_POOL_TYPE_BITMAP));
483
484 class RasterWorkerPoolCommonPerfTest : public RasterWorkerPoolPerfTestBase,
485                                        public testing::Test {
486  public:
487   // Overridden from testing::Test:
488   virtual void SetUp() override {
489     output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
490     CHECK(output_surface_->BindToClient(&output_surface_client_));
491     resource_provider_ =
492         ResourceProvider::Create(
493             output_surface_.get(), NULL, NULL, NULL, 0, false, 1).Pass();
494   }
495
496   void RunBuildRasterTaskQueueTest(const std::string& test_name,
497                                    unsigned num_raster_tasks,
498                                    unsigned num_image_decode_tasks) {
499     ImageDecodeTask::Vector image_decode_tasks;
500     RasterTaskVector raster_tasks;
501     CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
502     CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
503
504     // Avoid unnecessary heap allocations by reusing the same queue.
505     RasterTaskQueue queue;
506
507     timer_.Reset();
508     do {
509       queue.Reset();
510       BuildRasterTaskQueue(&queue, raster_tasks);
511       timer_.NextLap();
512     } while (!timer_.HasTimeLimitExpired());
513
514     perf_test::PrintResult("build_raster_task_queue",
515                            "",
516                            test_name,
517                            timer_.LapsPerSecond(),
518                            "runs/s",
519                            true);
520   }
521 };
522
523 TEST_F(RasterWorkerPoolCommonPerfTest, BuildRasterTaskQueue) {
524   RunBuildRasterTaskQueueTest("1_0", 1, 0);
525   RunBuildRasterTaskQueueTest("32_0", 32, 0);
526   RunBuildRasterTaskQueueTest("1_1", 1, 1);
527   RunBuildRasterTaskQueueTest("32_1", 32, 1);
528   RunBuildRasterTaskQueueTest("1_4", 1, 4);
529   RunBuildRasterTaskQueueTest("32_4", 32, 4);
530 }
531
532 }  // namespace
533 }  // namespace cc