1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file.
4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/resources/raster_worker_pool.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <limits>
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include <vector>
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/cancelable_callback.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "cc/resources/direct_raster_worker_pool.h"
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "cc/resources/image_copy_raster_worker_pool.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/resources/image_raster_worker_pool.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/resources/picture_pile.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/resources/picture_pile_impl.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/resources/pixel_buffer_raster_worker_pool.h"
17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "cc/resources/rasterizer.h"
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "cc/resources/resource_pool.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/resources/resource_provider.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/resources/scoped_resource.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "cc/test/fake_output_surface.h"
223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "cc/test/fake_output_surface_client.h"
2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "cc/test/test_shared_bitmap_manager.h"
240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "cc/test/test_web_graphics_context_3d.h"
25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace cc {
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
30f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)const size_t kMaxTransferBufferUsageBytes = 10000U;
31f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)// A resource of this dimension^2 * 4 must be greater than the above transfer
32f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)// buffer constant.
33f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)const size_t kLargeResourceDimension = 1000U;
34f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum RasterWorkerPoolType {
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RASTER_WORKER_POOL_TYPE_IMAGE,
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  RASTER_WORKER_POOL_TYPE_IMAGE_COPY,
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RASTER_WORKER_POOL_TYPE_DIRECT
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
42a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass TestRasterTaskImpl : public RasterTask {
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  typedef base::Callback<
450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      void(const PicturePileImpl::Analysis& analysis, bool was_canceled)> Reply;
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
47a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  TestRasterTaskImpl(const Resource* resource,
48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                     const Reply& reply,
49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                     ImageDecodeTask::Vector* dependencies)
500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      : RasterTask(resource, dependencies), reply_(reply) {}
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
52a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Overridden from Task:
530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  virtual void RunOnWorkerThread() OVERRIDE {}
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
55a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Overridden from RasterizerTask:
56a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void ScheduleOnOriginThread(RasterizerTaskClient* client) OVERRIDE {
57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    client->AcquireCanvasForRaster(this);
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void CompleteOnOriginThread(RasterizerTaskClient* client) OVERRIDE {
60a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    client->ReleaseCanvasForRaster(this);
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void RunReplyOnOriginThread() OVERRIDE {
630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    reply_.Run(PicturePileImpl::Analysis(), !HasFinishedRunning());
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual ~TestRasterTaskImpl() {}
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const Reply reply_;
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DISALLOW_COPY_AND_ASSIGN(TestRasterTaskImpl);
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass BlockingTestRasterTaskImpl : public TestRasterTaskImpl {
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  BlockingTestRasterTaskImpl(const Resource* resource,
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             const Reply& reply,
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             base::Lock* lock,
80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             ImageDecodeTask::Vector* dependencies)
81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      : TestRasterTaskImpl(resource, reply, dependencies), lock_(lock) {}
82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Overridden from Task:
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  virtual void RunOnWorkerThread() OVERRIDE {
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::AutoLock lock(*lock_);
86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    TestRasterTaskImpl::RunOnWorkerThread();
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Overridden from RasterizerTask:
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void RunReplyOnOriginThread() OVERRIDE {}
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual ~BlockingTestRasterTaskImpl() {}
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::Lock* lock_;
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  DISALLOW_COPY_AND_ASSIGN(BlockingTestRasterTaskImpl);
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class RasterWorkerPoolTest
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : public testing::TestWithParam<RasterWorkerPoolType>,
103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      public RasterizerClient {
104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) public:
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct RasterTaskResult {
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    unsigned id;
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool canceled;
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  typedef std::vector<scoped_refptr<RasterTask> > RasterTaskVector;
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  RasterWorkerPoolTest()
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      : context_provider_(TestContextProvider::Create()),
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        timeout_seconds_(5),
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        timed_out_(false) {
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CHECK(output_surface_->BindToClient(&output_surface_client_));
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    resource_provider_ =
12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)        ResourceProvider::Create(
122010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            false).Pass();
1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    staging_resource_pool_ = ResourcePool::Create(
1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888);
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    switch (GetParam()) {
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER:
129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        raster_worker_pool_ = PixelBufferRasterWorkerPool::Create(
130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::MessageLoopProxy::current().get(),
131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            RasterWorkerPool::GetTaskGraphRunner(),
132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            resource_provider_.get(),
133f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)            kMaxTransferBufferUsageBytes);
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case RASTER_WORKER_POOL_TYPE_IMAGE:
136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        raster_worker_pool_ = ImageRasterWorkerPool::Create(
137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::MessageLoopProxy::current().get(),
138a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            RasterWorkerPool::GetTaskGraphRunner(),
139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            resource_provider_.get());
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      case RASTER_WORKER_POOL_TYPE_IMAGE_COPY:
1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        raster_worker_pool_ = ImageCopyRasterWorkerPool::Create(
1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            base::MessageLoopProxy::current().get(),
1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            RasterWorkerPool::GetTaskGraphRunner(),
1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            resource_provider_.get(),
1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            staging_resource_pool_.get());
1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        break;
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      case RASTER_WORKER_POOL_TYPE_DIRECT:
149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        raster_worker_pool_ = DirectRasterWorkerPool::Create(
150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            base::MessageLoopProxy::current().get(),
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            resource_provider_.get(),
152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            context_provider_.get());
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        break;
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DCHECK(raster_worker_pool_);
157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    raster_worker_pool_->AsRasterizer()->SetClient(this);
158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual ~RasterWorkerPoolTest() {
1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    staging_resource_pool_.reset();
1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    resource_provider_.reset();
1625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Overridden from testing::Test:
165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual void TearDown() OVERRIDE {
166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    raster_worker_pool_->AsRasterizer()->Shutdown();
167a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Overriden from RasterWorkerPoolClient:
171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual bool ShouldForceTasksRequiredForActivationToComplete() const
172a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      OVERRIDE {
1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return false;
1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void DidFinishRunningTasks() OVERRIDE {
176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    raster_worker_pool_->AsRasterizer()->CheckForCompletedTasks();
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::MessageLoop::current()->Quit();
178868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void DidFinishRunningTasksRequiredForActivation() OVERRIDE {}
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void RunMessageLoopUntilAllTasksHaveCompleted() {
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (timeout_seconds_) {
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      timeout_.Reset(
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Bind(&RasterWorkerPoolTest::OnTimeout, base::Unretained(this)));
185868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      base::MessageLoopProxy::current()->PostDelayedTask(
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          FROM_HERE,
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          timeout_.callback(),
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          base::TimeDelta::FromSeconds(timeout_seconds_));
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
190868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
191868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->Run();
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
193868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    timeout_.Cancel();
194868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ASSERT_FALSE(timed_out_) << "Test timed out";
196868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
197868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void ScheduleTasks() {
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    RasterTaskQueue queue;
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for (RasterTaskVector::const_iterator it = tasks_.begin();
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         it != tasks_.end();
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)         ++it)
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      queue.items.push_back(RasterTaskQueue::Item(*it, false));
2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
206a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    raster_worker_pool_->AsRasterizer()->ScheduleTasks(&queue);
2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
209f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  void AppendTask(unsigned id, const gfx::Size& size) {
2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    scoped_ptr<ScopedResource> resource(
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ScopedResource::Create(resource_provider_.get()));
212d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888);
2137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const Resource* const_resource = resource.get();
2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
215a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    ImageDecodeTask::Vector empty;
216a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    tasks_.push_back(new TestRasterTaskImpl(
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        const_resource,
218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::Bind(&RasterWorkerPoolTest::OnTaskCompleted,
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   base::Unretained(this),
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   base::Passed(&resource),
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                   id),
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        &empty));
2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
225f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  void AppendTask(unsigned id) { AppendTask(id, gfx::Size(1, 1)); }
226f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AppendBlockingTask(unsigned id, base::Lock* lock) {
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Size size(1, 1);
2297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    scoped_ptr<ScopedResource> resource(
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ScopedResource::Create(resource_provider_.get()));
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888);
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const Resource* const_resource = resource.get();
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
235a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    ImageDecodeTask::Vector empty;
236a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    tasks_.push_back(new BlockingTestRasterTaskImpl(
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        const_resource,
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&RasterWorkerPoolTest::OnTaskCompleted,
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Unretained(this),
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::Passed(&resource),
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   id),
242a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        lock,
243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        &empty));
244868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const std::vector<RasterTaskResult>& completed_tasks() const {
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return completed_tasks_;
2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void OnTaskCompleted(scoped_ptr<ScopedResource> resource,
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       unsigned id,
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       const PicturePileImpl::Analysis& analysis,
2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                       bool was_canceled) {
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RasterTaskResult result;
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result.id = id;
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    result.canceled = was_canceled;
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    completed_tasks_.push_back(result);
259868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
260868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void OnTimeout() {
262868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    timed_out_ = true;
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    base::MessageLoop::current()->Quit();
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
265868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
2673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_refptr<TestContextProvider> context_provider_;
2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  FakeOutputSurfaceClient output_surface_client_;
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<FakeOutputSurface> output_surface_;
27023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
271868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  scoped_ptr<ResourceProvider> resource_provider_;
2725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scoped_ptr<ResourcePool> staging_resource_pool_;
273a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scoped_ptr<RasterWorkerPool> raster_worker_pool_;
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::CancelableClosure timeout_;
275868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int timeout_seconds_;
276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool timed_out_;
277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RasterTaskVector tasks_;
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::vector<RasterTaskResult> completed_tasks_;
279868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
280868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(RasterWorkerPoolTest, Basic) {
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendTask(0u);
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendTask(1u);
2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScheduleTasks();
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunMessageLoopUntilAllTasksHaveCompleted();
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(2u, completed_tasks().size());
2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(completed_tasks()[0].canceled);
2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(completed_tasks()[1].canceled);
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(RasterWorkerPoolTest, FailedMapResource) {
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  TestWebGraphicsContext3D* context3d = context_provider_->TestContext3d();
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  context3d->set_times_map_image_chromium_succeeds(0);
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  context3d->set_times_map_buffer_chromium_succeeds(0);
2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendTask(0u);
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScheduleTasks();
2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunMessageLoopUntilAllTasksHaveCompleted();
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ASSERT_EQ(1u, completed_tasks().size());
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(completed_tasks()[0].canceled);
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This test checks that replacing a pending raster task with another does
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// not prevent the DidFinishRunningTasks notification from being sent.
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_P(RasterWorkerPoolTest, FalseThrottling) {
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::Lock lock;
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Schedule a task that is prevented from completing with a lock.
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  lock.Acquire();
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendBlockingTask(0u, &lock);
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScheduleTasks();
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Schedule another task to replace the still-pending task. Because the old
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // task is not a throttled task in the new task set, it should not prevent
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // DidFinishRunningTasks from getting signaled.
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  RasterTaskVector tasks;
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  tasks.swap(tasks_);
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AppendTask(1u);
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScheduleTasks();
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Unblock the first task to allow the second task to complete.
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  lock.Release();
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunMessageLoopUntilAllTasksHaveCompleted();
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
330f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)TEST_P(RasterWorkerPoolTest, LargeResources) {
331f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  gfx::Size size(kLargeResourceDimension, kLargeResourceDimension);
332f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)
333f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  {
334f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)    // Verify a resource of this size is larger than the transfer buffer.
335f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)    scoped_ptr<ScopedResource> resource(
336f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)        ScopedResource::Create(resource_provider_.get()));
337f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)    resource->Allocate(size, ResourceProvider::TextureUsageAny, RGBA_8888);
338f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)    EXPECT_GE(resource->bytes(), kMaxTransferBufferUsageBytes);
339f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  }
340f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)
341f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  AppendTask(0u, size);
342f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  AppendTask(1u, size);
343f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  AppendTask(2u, size);
344f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  ScheduleTasks();
345f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)
346f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  // This will time out if a resource that is larger than the throttle limit
347f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  // never gets scheduled.
348f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)  RunMessageLoopUntilAllTasksHaveCompleted();
349f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)}
350f7a18f9da2728b9a347823d741465e09fa665da8Torne (Richard Coles)
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)INSTANTIATE_TEST_CASE_P(RasterWorkerPoolTests,
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        RasterWorkerPoolTest,
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        ::testing::Values(RASTER_WORKER_POOL_TYPE_PIXEL_BUFFER,
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          RASTER_WORKER_POOL_TYPE_IMAGE,
3555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                          RASTER_WORKER_POOL_TYPE_IMAGE_COPY,
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          RASTER_WORKER_POOL_TYPE_DIRECT));
357868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace
359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}  // namespace cc
360