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 <vector> 8 9 #include "cc/resources/image_raster_worker_pool.h" 10 #include "cc/resources/picture_pile.h" 11 #include "cc/resources/picture_pile_impl.h" 12 #include "cc/resources/pixel_buffer_raster_worker_pool.h" 13 #include "cc/resources/resource_provider.h" 14 #include "cc/resources/scoped_resource.h" 15 #include "cc/test/fake_output_surface.h" 16 #include "testing/gtest/include/gtest/gtest.h" 17 18 namespace cc { 19 20 class TestRasterWorkerPoolTaskImpl : public internal::RasterWorkerPoolTask { 21 public: 22 typedef base::Callback<void(const PicturePileImpl::Analysis& analysis, 23 bool was_canceled, 24 bool did_raster)> Reply; 25 26 TestRasterWorkerPoolTaskImpl( 27 const Resource* resource, 28 const Reply& reply, 29 TaskVector* dependencies) 30 : internal::RasterWorkerPoolTask(resource, dependencies), 31 reply_(reply), 32 did_raster_(false) {} 33 34 // Overridden from internal::WorkerPoolTask: 35 virtual bool RunOnWorkerThread(SkDevice* device, unsigned thread_index) 36 OVERRIDE { 37 did_raster_ = true; 38 return true; 39 } 40 virtual void CompleteOnOriginThread() OVERRIDE { 41 reply_.Run(PicturePileImpl::Analysis(), !HasFinishedRunning(), did_raster_); 42 } 43 44 protected: 45 virtual ~TestRasterWorkerPoolTaskImpl() {} 46 47 private: 48 const Reply reply_; 49 bool did_raster_; 50 51 DISALLOW_COPY_AND_ASSIGN(TestRasterWorkerPoolTaskImpl); 52 }; 53 54 class RasterWorkerPoolTest : public testing::Test, 55 public RasterWorkerPoolClient { 56 public: 57 RasterWorkerPoolTest() 58 : output_surface_(FakeOutputSurface::Create3d()), 59 resource_provider_( 60 ResourceProvider::Create(output_surface_.get(), 0)), 61 check_interval_milliseconds_(1), 62 timeout_seconds_(5), 63 timed_out_(false) { 64 } 65 virtual ~RasterWorkerPoolTest() { 66 resource_provider_.reset(); 67 } 68 69 // Overridden from testing::Test: 70 virtual void TearDown() OVERRIDE { 71 if (!raster_worker_pool_) 72 return; 73 raster_worker_pool_->Shutdown(); 74 raster_worker_pool_->CheckForCompletedTasks(); 75 } 76 77 // Overriden from RasterWorkerPoolClient: 78 virtual bool ShouldForceTasksRequiredForActivationToComplete() const 79 OVERRIDE { 80 return false; 81 } 82 virtual void DidFinishRunningTasks() OVERRIDE {} 83 virtual void DidFinishRunningTasksRequiredForActivation() OVERRIDE {} 84 85 virtual void BeginTest() = 0; 86 virtual void AfterTest() = 0; 87 88 ResourceProvider* resource_provider() const { 89 return resource_provider_.get(); 90 } 91 92 RasterWorkerPool* worker_pool() { 93 return raster_worker_pool_.get(); 94 } 95 96 void RunTest(bool use_map_image) { 97 if (use_map_image) { 98 raster_worker_pool_ = ImageRasterWorkerPool::Create( 99 resource_provider(), 1); 100 } else { 101 raster_worker_pool_ = PixelBufferRasterWorkerPool::Create( 102 resource_provider(), 1); 103 } 104 105 raster_worker_pool_->SetClient(this); 106 107 BeginTest(); 108 109 ScheduleCheckForCompletedTasks(); 110 111 if (timeout_seconds_) { 112 timeout_.Reset(base::Bind(&RasterWorkerPoolTest::OnTimeout, 113 base::Unretained(this))); 114 base::MessageLoopProxy::current()->PostDelayedTask( 115 FROM_HERE, 116 timeout_.callback(), 117 base::TimeDelta::FromSeconds(timeout_seconds_)); 118 } 119 120 base::MessageLoop::current()->Run(); 121 122 check_.Cancel(); 123 timeout_.Cancel(); 124 125 if (timed_out_) { 126 FAIL() << "Test timed out"; 127 return; 128 } 129 AfterTest(); 130 } 131 132 void EndTest() { 133 base::MessageLoop::current()->Quit(); 134 } 135 136 void ScheduleTasks() { 137 RasterWorkerPool::RasterTask::Queue tasks; 138 139 for (std::vector<RasterWorkerPool::RasterTask>::iterator it = 140 tasks_.begin(); 141 it != tasks_.end(); ++it) 142 tasks.Append(*it, false); 143 144 worker_pool()->ScheduleTasks(&tasks); 145 } 146 147 void AppendTask(unsigned id) { 148 const gfx::Size size(1, 1); 149 150 scoped_ptr<ScopedResource> resource( 151 ScopedResource::create(resource_provider())); 152 resource->Allocate(size, GL_RGBA, ResourceProvider::TextureUsageAny); 153 const Resource* const_resource = resource.get(); 154 155 RasterWorkerPool::Task::Set empty; 156 tasks_.push_back( 157 RasterWorkerPool::RasterTask(new TestRasterWorkerPoolTaskImpl( 158 const_resource, 159 base::Bind(&RasterWorkerPoolTest::OnTaskCompleted, 160 base::Unretained(this), 161 base::Passed(&resource), 162 id), 163 &empty.tasks_))); 164 } 165 166 virtual void OnTaskCompleted(scoped_ptr<ScopedResource> resource, 167 unsigned id, 168 const PicturePileImpl::Analysis& analysis, 169 bool was_canceled, 170 bool did_raster) {} 171 172 private: 173 void ScheduleCheckForCompletedTasks() { 174 check_.Reset(base::Bind(&RasterWorkerPoolTest::OnCheckForCompletedTasks, 175 base::Unretained(this))); 176 base::MessageLoopProxy::current()->PostDelayedTask( 177 FROM_HERE, 178 check_.callback(), 179 base::TimeDelta::FromMilliseconds(check_interval_milliseconds_)); 180 } 181 182 void OnCheckForCompletedTasks() { 183 raster_worker_pool_->CheckForCompletedTasks(); 184 ScheduleCheckForCompletedTasks(); 185 } 186 187 void OnTimeout() { 188 timed_out_ = true; 189 base::MessageLoop::current()->Quit(); 190 } 191 192 protected: 193 scoped_ptr<FakeOutputSurface> output_surface_; 194 scoped_ptr<ResourceProvider> resource_provider_; 195 scoped_ptr<RasterWorkerPool> raster_worker_pool_; 196 base::CancelableClosure check_; 197 int check_interval_milliseconds_; 198 base::CancelableClosure timeout_; 199 int timeout_seconds_; 200 bool timed_out_; 201 std::vector<RasterWorkerPool::RasterTask> tasks_; 202 }; 203 204 namespace { 205 206 #define PIXEL_BUFFER_TEST_F(TEST_FIXTURE_NAME) \ 207 TEST_F(TEST_FIXTURE_NAME, RunPixelBuffer) { \ 208 RunTest(false); \ 209 } 210 211 #define IMAGE_TEST_F(TEST_FIXTURE_NAME) \ 212 TEST_F(TEST_FIXTURE_NAME, RunImage) { \ 213 RunTest(true); \ 214 } 215 216 #define PIXEL_BUFFER_AND_IMAGE_TEST_F(TEST_FIXTURE_NAME) \ 217 PIXEL_BUFFER_TEST_F(TEST_FIXTURE_NAME); \ 218 IMAGE_TEST_F(TEST_FIXTURE_NAME) 219 220 class BasicRasterWorkerPoolTest : public RasterWorkerPoolTest { 221 public: 222 virtual void OnTaskCompleted(scoped_ptr<ScopedResource> resource, 223 unsigned id, 224 const PicturePileImpl::Analysis& analysis, 225 bool was_canceled, 226 bool did_raster) OVERRIDE { 227 EXPECT_TRUE(did_raster); 228 on_task_completed_ids_.push_back(id); 229 if (on_task_completed_ids_.size() == 2) 230 EndTest(); 231 } 232 233 // Overridden from RasterWorkerPoolTest: 234 virtual void BeginTest() OVERRIDE { 235 AppendTask(0u); 236 AppendTask(1u); 237 ScheduleTasks(); 238 } 239 virtual void AfterTest() OVERRIDE { 240 EXPECT_EQ(2u, on_task_completed_ids_.size()); 241 tasks_.clear(); 242 } 243 244 std::vector<unsigned> on_task_completed_ids_; 245 }; 246 247 PIXEL_BUFFER_AND_IMAGE_TEST_F(BasicRasterWorkerPoolTest); 248 249 class RasterWorkerPoolTestFailedMapResource : public RasterWorkerPoolTest { 250 public: 251 virtual void OnTaskCompleted(scoped_ptr<ScopedResource> resource, 252 unsigned id, 253 const PicturePileImpl::Analysis& analysis, 254 bool was_canceled, 255 bool did_raster) OVERRIDE { 256 EXPECT_FALSE(did_raster); 257 EndTest(); 258 } 259 260 // Overridden from RasterWorkerPoolTest: 261 virtual void BeginTest() OVERRIDE { 262 TestWebGraphicsContext3D* context3d = 263 static_cast<TestWebGraphicsContext3D*>(output_surface_->context3d()); 264 context3d->set_times_map_image_chromium_succeeds(0); 265 context3d->set_times_map_buffer_chromium_succeeds(0); 266 AppendTask(0u); 267 ScheduleTasks(); 268 } 269 270 virtual void AfterTest() OVERRIDE { 271 ASSERT_EQ(1u, tasks_.size()); 272 tasks_.clear(); 273 } 274 }; 275 276 PIXEL_BUFFER_AND_IMAGE_TEST_F(RasterWorkerPoolTestFailedMapResource); 277 278 } // namespace 279 280 } // namespace cc 281