Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / cc / resources / raster_worker_pool_perftest.cc
blobee3f359cc2f45819de0444333b1586271529b3d2
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/raster_worker_pool.h"
7 #include "base/time/time.h"
8 #include "cc/output/context_provider.h"
9 #include "cc/resources/direct_raster_worker_pool.h"
10 #include "cc/resources/image_copy_raster_worker_pool.h"
11 #include "cc/resources/image_raster_worker_pool.h"
12 #include "cc/resources/pixel_buffer_raster_worker_pool.h"
13 #include "cc/resources/rasterizer.h"
14 #include "cc/resources/resource_pool.h"
15 #include "cc/resources/resource_provider.h"
16 #include "cc/resources/scoped_resource.h"
17 #include "cc/test/fake_output_surface.h"
18 #include "cc/test/fake_output_surface_client.h"
19 #include "cc/test/lap_timer.h"
20 #include "cc/test/test_context_support.h"
21 #include "cc/test/test_shared_bitmap_manager.h"
22 #include "cc/test/test_web_graphics_context_3d.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "testing/perf/perf_test.h"
25 #include "third_party/khronos/GLES2/gl2.h"
27 namespace cc {
28 namespace {
30 class PerfGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
31 // Overridden from gpu::gles2::GLES2Interface:
32 virtual GLuint CreateImageCHROMIUM(GLsizei width,
33 GLsizei height,
34 GLenum internalformat) OVERRIDE {
35 return 1u;
37 virtual void GenBuffers(GLsizei n, GLuint* buffers) OVERRIDE {
38 for (GLsizei i = 0; i < n; ++i)
39 buffers[i] = 1u;
41 virtual void GenTextures(GLsizei n, GLuint* textures) OVERRIDE {
42 for (GLsizei i = 0; i < n; ++i)
43 textures[i] = 1u;
45 virtual void GetIntegerv(GLenum pname, GLint* params) OVERRIDE {
46 if (pname == GL_MAX_TEXTURE_SIZE)
47 *params = INT_MAX;
51 class PerfContextProvider : public ContextProvider {
52 public:
53 PerfContextProvider() : context_gl_(new PerfGLES2Interface) {}
55 virtual bool BindToCurrentThread() OVERRIDE { return true; }
56 virtual Capabilities ContextCapabilities() OVERRIDE { return Capabilities(); }
57 virtual gpu::gles2::GLES2Interface* ContextGL() OVERRIDE {
58 return context_gl_.get();
60 virtual gpu::ContextSupport* ContextSupport() OVERRIDE { return &support_; }
61 virtual class GrContext* GrContext() OVERRIDE { return NULL; }
62 virtual bool IsContextLost() OVERRIDE { return false; }
63 virtual void VerifyContexts() OVERRIDE {}
64 virtual void DeleteCachedResources() OVERRIDE {}
65 virtual bool DestroyedOnMainThread() OVERRIDE { return false; }
66 virtual void SetLostContextCallback(const LostContextCallback& cb) OVERRIDE {}
67 virtual void SetMemoryPolicyChangedCallback(
68 const MemoryPolicyChangedCallback& cb) OVERRIDE {}
70 private:
71 virtual ~PerfContextProvider() {}
73 scoped_ptr<PerfGLES2Interface> context_gl_;
74 TestContextSupport support_;
77 enum RasterWorkerPoolType {
78 RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
79 RASTER_WORKER_POOL_TYPE_IMAGE,
80 RASTER_WORKER_POOL_TYPE_IMAGE_COPY,
81 RASTER_WORKER_POOL_TYPE_DIRECT
84 static const int kTimeLimitMillis = 2000;
85 static const int kWarmupRuns = 5;
86 static const int kTimeCheckInterval = 10;
88 class PerfImageDecodeTaskImpl : public ImageDecodeTask {
89 public:
90 PerfImageDecodeTaskImpl() {}
92 // Overridden from Task:
93 virtual void RunOnWorkerThread() OVERRIDE {}
95 // Overridden from RasterizerTask:
96 virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {}
97 virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {}
98 virtual void RunReplyOnOriginThread() OVERRIDE { Reset(); }
100 void Reset() {
101 did_run_ = false;
102 did_complete_ = false;
105 protected:
106 virtual ~PerfImageDecodeTaskImpl() {}
108 private:
109 DISALLOW_COPY_AND_ASSIGN(PerfImageDecodeTaskImpl);
112 class PerfRasterTaskImpl : public RasterTask {
113 public:
114 PerfRasterTaskImpl(scoped_ptr<ScopedResource> resource,
115 ImageDecodeTask::Vector* dependencies)
116 : RasterTask(resource.get(), dependencies), resource_(resource.Pass()) {}
118 // Overridden from Task:
119 virtual void RunOnWorkerThread() OVERRIDE {}
121 // Overridden from RasterizerTask:
122 virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {
123 client->AcquireCanvasForRaster(this);
125 virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {
126 client->ReleaseCanvasForRaster(this);
128 virtual void RunReplyOnOriginThread() OVERRIDE { Reset(); }
130 void Reset() {
131 did_run_ = false;
132 did_complete_ = false;
135 protected:
136 virtual ~PerfRasterTaskImpl() {}
138 private:
139 scoped_ptr<ScopedResource> resource_;
141 DISALLOW_COPY_AND_ASSIGN(PerfRasterTaskImpl);
144 class RasterWorkerPoolPerfTestBase {
145 public:
146 typedef std::vector<scoped_refptr<RasterTask> > RasterTaskVector;
148 RasterWorkerPoolPerfTestBase()
149 : context_provider_(make_scoped_refptr(new PerfContextProvider)),
150 task_graph_runner_(new TaskGraphRunner),
151 timer_(kWarmupRuns,
152 base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
153 kTimeCheckInterval) {
154 output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
155 CHECK(output_surface_->BindToClient(&output_surface_client_));
157 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
158 resource_provider_ =
159 ResourceProvider::Create(
160 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1)
161 .Pass();
162 staging_resource_pool_ = ResourcePool::Create(
163 resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
166 void CreateImageDecodeTasks(unsigned num_image_decode_tasks,
167 ImageDecodeTask::Vector* image_decode_tasks) {
168 for (unsigned i = 0; i < num_image_decode_tasks; ++i)
169 image_decode_tasks->push_back(new PerfImageDecodeTaskImpl);
172 void CreateRasterTasks(unsigned num_raster_tasks,
173 const ImageDecodeTask::Vector& image_decode_tasks,
174 RasterTaskVector* raster_tasks) {
175 const gfx::Size size(1, 1);
177 for (unsigned i = 0; i < num_raster_tasks; ++i) {
178 scoped_ptr<ScopedResource> resource(
179 ScopedResource::Create(resource_provider_.get()));
180 resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888);
182 ImageDecodeTask::Vector dependencies = image_decode_tasks;
183 raster_tasks->push_back(
184 new PerfRasterTaskImpl(resource.Pass(), &dependencies));
188 void BuildRasterTaskQueue(RasterTaskQueue* queue,
189 const RasterTaskVector& raster_tasks) {
190 for (size_t i = 0u; i < raster_tasks.size(); ++i) {
191 bool required_for_activation = (i % 2) == 0;
192 queue->items.push_back(RasterTaskQueue::Item(raster_tasks[i].get(),
193 required_for_activation));
194 queue->required_for_activation_count += required_for_activation;
198 protected:
199 scoped_refptr<ContextProvider> context_provider_;
200 FakeOutputSurfaceClient output_surface_client_;
201 scoped_ptr<FakeOutputSurface> output_surface_;
202 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
203 scoped_ptr<ResourceProvider> resource_provider_;
204 scoped_ptr<ResourcePool> staging_resource_pool_;
205 scoped_ptr<TaskGraphRunner> task_graph_runner_;
206 LapTimer timer_;
209 class RasterWorkerPoolPerfTest
210 : public RasterWorkerPoolPerfTestBase,
211 public testing::TestWithParam<RasterWorkerPoolType>,
212 public RasterizerClient {
213 public:
214 RasterWorkerPoolPerfTest() {
215 switch (GetParam()) {
216 case RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER:
217 raster_worker_pool_ = PixelBufferRasterWorkerPool::Create(
218 base::MessageLoopProxy::current().get(),
219 task_graph_runner_.get(),
220 resource_provider_.get(),
221 std::numeric_limits<size_t>::max());
222 break;
223 case RASTER_WORKER_POOL_TYPE_IMAGE:
224 raster_worker_pool_ = ImageRasterWorkerPool::Create(
225 base::MessageLoopProxy::current().get(),
226 task_graph_runner_.get(),
227 resource_provider_.get());
228 break;
229 case RASTER_WORKER_POOL_TYPE_IMAGE_COPY:
230 raster_worker_pool_ = ImageCopyRasterWorkerPool::Create(
231 base::MessageLoopProxy::current().get(),
232 task_graph_runner_.get(),
233 resource_provider_.get(),
234 staging_resource_pool_.get());
235 break;
236 case RASTER_WORKER_POOL_TYPE_DIRECT:
237 raster_worker_pool_ = DirectRasterWorkerPool::Create(
238 base::MessageLoopProxy::current().get(),
239 resource_provider_.get(),
240 context_provider_.get());
241 break;
244 DCHECK(raster_worker_pool_);
245 raster_worker_pool_->AsRasterizer()->SetClient(this);
248 // Overridden from testing::Test:
249 virtual void TearDown() OVERRIDE {
250 raster_worker_pool_->AsRasterizer()->Shutdown();
251 raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
254 // Overriden from RasterizerClient:
255 virtual bool ShouldForceTasksRequiredForActivationToComplete() const
256 OVERRIDE {
257 return false;
259 virtual void DidFinishRunningTasks() OVERRIDE {
260 raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
261 base::MessageLoop::current()->Quit();
263 virtual void DidFinishRunningTasksRequiredForActivation() OVERRIDE {}
265 void RunMessageLoopUntilAllTasksHaveCompleted() {
266 task_graph_runner_->RunUntilIdle();
267 base::MessageLoop::current()->Run();
270 void RunScheduleTasksTest(const std::string& test_name,
271 unsigned num_raster_tasks,
272 unsigned num_image_decode_tasks) {
273 ImageDecodeTask::Vector image_decode_tasks;
274 RasterTaskVector raster_tasks;
275 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
276 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
278 // Avoid unnecessary heap allocations by reusing the same queue.
279 RasterTaskQueue queue;
281 timer_.Reset();
282 do {
283 queue.Reset();
284 BuildRasterTaskQueue(&queue, raster_tasks);
285 raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
286 raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
287 timer_.NextLap();
288 } while (!timer_.HasTimeLimitExpired());
290 RasterTaskQueue empty;
291 raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty);
292 RunMessageLoopUntilAllTasksHaveCompleted();
294 perf_test::PrintResult("schedule_tasks",
295 TestModifierString(),
296 test_name,
297 timer_.LapsPerSecond(),
298 "runs/s",
299 true);
302 void RunScheduleAlternateTasksTest(const std::string& test_name,
303 unsigned num_raster_tasks,
304 unsigned num_image_decode_tasks) {
305 const size_t kNumVersions = 2;
306 ImageDecodeTask::Vector image_decode_tasks[kNumVersions];
307 RasterTaskVector raster_tasks[kNumVersions];
308 for (size_t i = 0; i < kNumVersions; ++i) {
309 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks[i]);
310 CreateRasterTasks(
311 num_raster_tasks, image_decode_tasks[i], &raster_tasks[i]);
314 // Avoid unnecessary heap allocations by reusing the same queue.
315 RasterTaskQueue queue;
317 size_t count = 0;
318 timer_.Reset();
319 do {
320 queue.Reset();
321 BuildRasterTaskQueue(&queue, raster_tasks[count % kNumVersions]);
322 raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
323 raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
324 ++count;
325 timer_.NextLap();
326 } while (!timer_.HasTimeLimitExpired());
328 RasterTaskQueue empty;
329 raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty);
330 RunMessageLoopUntilAllTasksHaveCompleted();
332 perf_test::PrintResult("schedule_alternate_tasks",
333 TestModifierString(),
334 test_name,
335 timer_.LapsPerSecond(),
336 "runs/s",
337 true);
340 void RunScheduleAndExecuteTasksTest(const std::string& test_name,
341 unsigned num_raster_tasks,
342 unsigned num_image_decode_tasks) {
343 ImageDecodeTask::Vector image_decode_tasks;
344 RasterTaskVector raster_tasks;
345 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
346 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
348 // Avoid unnecessary heap allocations by reusing the same queue.
349 RasterTaskQueue queue;
351 timer_.Reset();
352 do {
353 queue.Reset();
354 BuildRasterTaskQueue(&queue, raster_tasks);
355 raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
356 RunMessageLoopUntilAllTasksHaveCompleted();
357 timer_.NextLap();
358 } while (!timer_.HasTimeLimitExpired());
360 RasterTaskQueue empty;
361 raster_worker_pool_->AsRasterizer()->ScheduleTasks(&empty);
362 RunMessageLoopUntilAllTasksHaveCompleted();
364 perf_test::PrintResult("schedule_and_execute_tasks",
365 TestModifierString(),
366 test_name,
367 timer_.LapsPerSecond(),
368 "runs/s",
369 true);
372 private:
373 std::string TestModifierString() const {
374 switch (GetParam()) {
375 case RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER:
376 return std::string("_pixel_raster_worker_pool");
377 case RASTER_WORKER_POOL_TYPE_IMAGE:
378 return std::string("_image_raster_worker_pool");
379 case RASTER_WORKER_POOL_TYPE_IMAGE_COPY:
380 return std::string("_image_copy_raster_worker_pool");
381 case RASTER_WORKER_POOL_TYPE_DIRECT:
382 return std::string("_direct_raster_worker_pool");
384 NOTREACHED();
385 return std::string();
388 scoped_ptr<RasterWorkerPool> raster_worker_pool_;
391 TEST_P(RasterWorkerPoolPerfTest, ScheduleTasks) {
392 RunScheduleTasksTest("1_0", 1, 0);
393 RunScheduleTasksTest("32_0", 32, 0);
394 RunScheduleTasksTest("1_1", 1, 1);
395 RunScheduleTasksTest("32_1", 32, 1);
396 RunScheduleTasksTest("1_4", 1, 4);
397 RunScheduleTasksTest("32_4", 32, 4);
400 TEST_P(RasterWorkerPoolPerfTest, ScheduleAlternateTasks) {
401 RunScheduleAlternateTasksTest("1_0", 1, 0);
402 RunScheduleAlternateTasksTest("32_0", 32, 0);
403 RunScheduleAlternateTasksTest("1_1", 1, 1);
404 RunScheduleAlternateTasksTest("32_1", 32, 1);
405 RunScheduleAlternateTasksTest("1_4", 1, 4);
406 RunScheduleAlternateTasksTest("32_4", 32, 4);
409 TEST_P(RasterWorkerPoolPerfTest, ScheduleAndExecuteTasks) {
410 RunScheduleAndExecuteTasksTest("1_0", 1, 0);
411 RunScheduleAndExecuteTasksTest("32_0", 32, 0);
412 RunScheduleAndExecuteTasksTest("1_1", 1, 1);
413 RunScheduleAndExecuteTasksTest("32_1", 32, 1);
414 RunScheduleAndExecuteTasksTest("1_4", 1, 4);
415 RunScheduleAndExecuteTasksTest("32_4", 32, 4);
418 INSTANTIATE_TEST_CASE_P(RasterWorkerPoolPerfTests,
419 RasterWorkerPoolPerfTest,
420 ::testing::Values(RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
421 RASTER_WORKER_POOL_TYPE_IMAGE,
422 RASTER_WORKER_POOL_TYPE_IMAGE_COPY,
423 RASTER_WORKER_POOL_TYPE_DIRECT));
425 class RasterWorkerPoolCommonPerfTest : public RasterWorkerPoolPerfTestBase,
426 public testing::Test {
427 public:
428 void RunBuildRasterTaskQueueTest(const std::string& test_name,
429 unsigned num_raster_tasks,
430 unsigned num_image_decode_tasks) {
431 ImageDecodeTask::Vector image_decode_tasks;
432 RasterTaskVector raster_tasks;
433 CreateImageDecodeTasks(num_image_decode_tasks, &image_decode_tasks);
434 CreateRasterTasks(num_raster_tasks, image_decode_tasks, &raster_tasks);
436 // Avoid unnecessary heap allocations by reusing the same queue.
437 RasterTaskQueue queue;
439 timer_.Reset();
440 do {
441 queue.Reset();
442 BuildRasterTaskQueue(&queue, raster_tasks);
443 timer_.NextLap();
444 } while (!timer_.HasTimeLimitExpired());
446 perf_test::PrintResult("build_raster_task_queue",
448 test_name,
449 timer_.LapsPerSecond(),
450 "runs/s",
451 true);
455 TEST_F(RasterWorkerPoolCommonPerfTest, BuildRasterTaskQueue) {
456 RunBuildRasterTaskQueueTest("1_0", 1, 0);
457 RunBuildRasterTaskQueueTest("32_0", 32, 0);
458 RunBuildRasterTaskQueueTest("1_1", 1, 1);
459 RunBuildRasterTaskQueueTest("32_1", 32, 1);
460 RunBuildRasterTaskQueueTest("1_4", 1, 4);
461 RunBuildRasterTaskQueueTest("32_4", 32, 4);
464 } // namespace
465 } // namespace cc