Temporarily re-enabling SizeAfterPrefChange test with traces.
[chromium-blink-merge.git] / cc / resources / raster_worker_pool_unittest.cc
blob7a5f324e39f84c35c0368304ddf188aacff114aa
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 <limits>
8 #include <vector>
10 #include "base/cancelable_callback.h"
11 #include "cc/resources/direct_raster_worker_pool.h"
12 #include "cc/resources/image_copy_raster_worker_pool.h"
13 #include "cc/resources/image_raster_worker_pool.h"
14 #include "cc/resources/picture_pile.h"
15 #include "cc/resources/picture_pile_impl.h"
16 #include "cc/resources/pixel_buffer_raster_worker_pool.h"
17 #include "cc/resources/rasterizer.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/test_shared_bitmap_manager.h"
24 #include "cc/test/test_web_graphics_context_3d.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 namespace cc {
28 namespace {
30 enum RasterWorkerPoolType {
31 RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
32 RASTER_WORKER_POOL_TYPE_IMAGE,
33 RASTER_WORKER_POOL_TYPE_IMAGE_COPY,
34 RASTER_WORKER_POOL_TYPE_DIRECT
37 class TestRasterTaskImpl : public RasterTask {
38 public:
39 typedef base::Callback<
40 void(const PicturePileImpl::Analysis& analysis, bool was_canceled)> Reply;
42 TestRasterTaskImpl(const Resource* resource,
43 const Reply& reply,
44 ImageDecodeTask::Vector* dependencies)
45 : RasterTask(resource, dependencies), reply_(reply) {}
47 // Overridden from Task:
48 virtual void RunOnWorkerThread() OVERRIDE {}
50 // Overridden from RasterizerTask:
51 virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {
52 client->AcquireCanvasForRaster(this);
54 virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {
55 client->ReleaseCanvasForRaster(this);
57 virtual void RunReplyOnOriginThread() OVERRIDE {
58 reply_.Run(PicturePileImpl::Analysis(), !HasFinishedRunning());
61 protected:
62 virtual ~TestRasterTaskImpl() {}
64 private:
65 const Reply reply_;
67 DISALLOW_COPY_AND_ASSIGN(TestRasterTaskImpl);
70 class BlockingTestRasterTaskImpl : public TestRasterTaskImpl {
71 public:
72 BlockingTestRasterTaskImpl(const Resource* resource,
73 const Reply& reply,
74 base::Lock* lock,
75 ImageDecodeTask::Vector* dependencies)
76 : TestRasterTaskImpl(resource, reply, dependencies), lock_(lock) {}
78 // Overridden from Task:
79 virtual void RunOnWorkerThread() OVERRIDE {
80 base::AutoLock lock(*lock_);
81 TestRasterTaskImpl::RunOnWorkerThread();
84 // Overridden from RasterizerTask:
85 virtual void RunReplyOnOriginThread() OVERRIDE {}
87 protected:
88 virtual ~BlockingTestRasterTaskImpl() {}
90 private:
91 base::Lock* lock_;
93 DISALLOW_COPY_AND_ASSIGN(BlockingTestRasterTaskImpl);
96 class RasterWorkerPoolTest
97 : public testing::TestWithParam<RasterWorkerPoolType>,
98 public RasterizerClient {
99 public:
100 struct RasterTaskResult {
101 unsigned id;
102 bool canceled;
105 typedef std::vector<scoped_refptr<RasterTask> > RasterTaskVector;
107 RasterWorkerPoolTest()
108 : context_provider_(TestContextProvider::Create()),
109 timeout_seconds_(5),
110 timed_out_(false) {
111 output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
112 CHECK(output_surface_->BindToClient(&output_surface_client_));
114 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
115 resource_provider_ =
116 ResourceProvider::Create(
117 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
118 false).Pass();
119 staging_resource_pool_ = ResourcePool::Create(
120 resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
122 switch (GetParam()) {
123 case RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER:
124 raster_worker_pool_ = PixelBufferRasterWorkerPool::Create(
125 base::MessageLoopProxy::current().get(),
126 RasterWorkerPool::GetTaskGraphRunner(),
127 resource_provider_.get(),
128 std::numeric_limits<size_t>::max());
129 break;
130 case RASTER_WORKER_POOL_TYPE_IMAGE:
131 raster_worker_pool_ = ImageRasterWorkerPool::Create(
132 base::MessageLoopProxy::current().get(),
133 RasterWorkerPool::GetTaskGraphRunner(),
134 resource_provider_.get());
135 break;
136 case RASTER_WORKER_POOL_TYPE_IMAGE_COPY:
137 raster_worker_pool_ = ImageCopyRasterWorkerPool::Create(
138 base::MessageLoopProxy::current().get(),
139 RasterWorkerPool::GetTaskGraphRunner(),
140 resource_provider_.get(),
141 staging_resource_pool_.get());
142 break;
143 case RASTER_WORKER_POOL_TYPE_DIRECT:
144 raster_worker_pool_ = DirectRasterWorkerPool::Create(
145 base::MessageLoopProxy::current().get(),
146 resource_provider_.get(),
147 context_provider_.get());
148 break;
151 DCHECK(raster_worker_pool_);
152 raster_worker_pool_->AsRasterizer()->SetClient(this);
154 virtual ~RasterWorkerPoolTest() {
155 staging_resource_pool_.reset();
156 resource_provider_.reset();
159 // Overridden from testing::Test:
160 virtual void TearDown() OVERRIDE {
161 raster_worker_pool_->AsRasterizer()->Shutdown();
162 raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
165 // Overriden from RasterWorkerPoolClient:
166 virtual bool ShouldForceTasksRequiredForActivationToComplete() const
167 OVERRIDE {
168 return false;
170 virtual void DidFinishRunningTasks() OVERRIDE {
171 raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
172 base::MessageLoop::current()->Quit();
174 virtual void DidFinishRunningTasksRequiredForActivation() OVERRIDE {}
176 void RunMessageLoopUntilAllTasksHaveCompleted() {
177 if (timeout_seconds_) {
178 timeout_.Reset(
179 base::Bind(&RasterWorkerPoolTest::OnTimeout, base::Unretained(this)));
180 base::MessageLoopProxy::current()->PostDelayedTask(
181 FROM_HERE,
182 timeout_.callback(),
183 base::TimeDelta::FromSeconds(timeout_seconds_));
186 base::MessageLoop::current()->Run();
188 timeout_.Cancel();
190 ASSERT_FALSE(timed_out_) << "Test timed out";
193 void ScheduleTasks() {
194 RasterTaskQueue queue;
196 for (RasterTaskVector::const_iterator it = tasks_.begin();
197 it != tasks_.end();
198 ++it)
199 queue.items.push_back(RasterTaskQueue::Item(*it, false));
201 raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
204 void AppendTask(unsigned id) {
205 const gfx::Size size(1, 1);
207 scoped_ptr<ScopedResource> resource(
208 ScopedResource::Create(resource_provider_.get()));
209 resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888);
210 const Resource* const_resource = resource.get();
212 ImageDecodeTask::Vector empty;
213 tasks_.push_back(new TestRasterTaskImpl(
214 const_resource,
215 base::Bind(&RasterWorkerPoolTest::OnTaskCompleted,
216 base::Unretained(this),
217 base::Passed(&resource),
218 id),
219 &empty));
222 void AppendBlockingTask(unsigned id, base::Lock* lock) {
223 const gfx::Size size(1, 1);
225 scoped_ptr<ScopedResource> resource(
226 ScopedResource::Create(resource_provider_.get()));
227 resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888);
228 const Resource* const_resource = resource.get();
230 ImageDecodeTask::Vector empty;
231 tasks_.push_back(new BlockingTestRasterTaskImpl(
232 const_resource,
233 base::Bind(&RasterWorkerPoolTest::OnTaskCompleted,
234 base::Unretained(this),
235 base::Passed(&resource),
236 id),
237 lock,
238 &empty));
241 const std::vector<RasterTaskResult>& completed_tasks() const {
242 return completed_tasks_;
245 private:
246 void OnTaskCompleted(scoped_ptr<ScopedResource> resource,
247 unsigned id,
248 const PicturePileImpl::Analysis& analysis,
249 bool was_canceled) {
250 RasterTaskResult result;
251 result.id = id;
252 result.canceled = was_canceled;
253 completed_tasks_.push_back(result);
256 void OnTimeout() {
257 timed_out_ = true;
258 base::MessageLoop::current()->Quit();
261 protected:
262 scoped_refptr<TestContextProvider> context_provider_;
263 FakeOutputSurfaceClient output_surface_client_;
264 scoped_ptr<FakeOutputSurface> output_surface_;
265 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
266 scoped_ptr<ResourceProvider> resource_provider_;
267 scoped_ptr<ResourcePool> staging_resource_pool_;
268 scoped_ptr<RasterWorkerPool> raster_worker_pool_;
269 base::CancelableClosure timeout_;
270 int timeout_seconds_;
271 bool timed_out_;
272 RasterTaskVector tasks_;
273 std::vector<RasterTaskResult> completed_tasks_;
276 TEST_P(RasterWorkerPoolTest, Basic) {
277 AppendTask(0u);
278 AppendTask(1u);
279 ScheduleTasks();
281 RunMessageLoopUntilAllTasksHaveCompleted();
283 ASSERT_EQ(2u, completed_tasks().size());
284 EXPECT_FALSE(completed_tasks()[0].canceled);
285 EXPECT_FALSE(completed_tasks()[1].canceled);
288 TEST_P(RasterWorkerPoolTest, FailedMapResource) {
289 TestWebGraphicsContext3D* context3d = context_provider_->TestContext3d();
290 context3d->set_times_map_image_chromium_succeeds(0);
291 context3d->set_times_map_buffer_chromium_succeeds(0);
292 AppendTask(0u);
293 ScheduleTasks();
295 RunMessageLoopUntilAllTasksHaveCompleted();
297 ASSERT_EQ(1u, completed_tasks().size());
298 EXPECT_FALSE(completed_tasks()[0].canceled);
301 // This test checks that replacing a pending raster task with another does
302 // not prevent the DidFinishRunningTasks notification from being sent.
303 TEST_P(RasterWorkerPoolTest, FalseThrottling) {
304 base::Lock lock;
306 // Schedule a task that is prevented from completing with a lock.
307 lock.Acquire();
308 AppendBlockingTask(0u, &lock);
309 ScheduleTasks();
311 // Schedule another task to replace the still-pending task. Because the old
312 // task is not a throttled task in the new task set, it should not prevent
313 // DidFinishRunningTasks from getting signaled.
314 RasterTaskVector tasks;
315 tasks.swap(tasks_);
316 AppendTask(1u);
317 ScheduleTasks();
319 // Unblock the first task to allow the second task to complete.
320 lock.Release();
322 RunMessageLoopUntilAllTasksHaveCompleted();
325 INSTANTIATE_TEST_CASE_P(RasterWorkerPoolTests,
326 RasterWorkerPoolTest,
327 ::testing::Values(RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
328 RASTER_WORKER_POOL_TYPE_IMAGE,
329 RASTER_WORKER_POOL_TYPE_IMAGE_COPY,
330 RASTER_WORKER_POOL_TYPE_DIRECT));
332 } // namespace
333 } // namespace cc