Home | History | Annotate | Download | only in resources
      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