// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/resources/tile_task_worker_pool.h"

#include <limits>
#include <vector>

#include "base/cancelable_callback.h"
#include "cc/resources/bitmap_tile_task_worker_pool.h"
#include "cc/resources/gpu_tile_task_worker_pool.h"
#include "cc/resources/one_copy_tile_task_worker_pool.h"
#include "cc/resources/picture_pile.h"
#include "cc/resources/picture_pile_impl.h"
#include "cc/resources/pixel_buffer_tile_task_worker_pool.h"
#include "cc/resources/raster_buffer.h"
#include "cc/resources/resource_pool.h"
#include "cc/resources/resource_provider.h"
#include "cc/resources/scoped_resource.h"
#include "cc/resources/tile_task_runner.h"
#include "cc/resources/zero_copy_tile_task_worker_pool.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_picture_pile_impl.h"
#include "cc/test/test_gpu_memory_buffer_manager.h"
#include "cc/test/test_shared_bitmap_manager.h"
#include "cc/test/test_web_graphics_context_3d.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {
namespace {

const size_t kMaxTransferBufferUsageBytes = 10000U;
// A resource of this dimension^2 * 4 must be greater than the above transfer
// buffer constant.
const size_t kLargeResourceDimension = 1000U;

enum TileTaskWorkerPoolType {
  TILE_TASK_WORKER_POOL_TYPE_PIXEL_BUFFER,
  TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
  TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
  TILE_TASK_WORKER_POOL_TYPE_GPU,
  TILE_TASK_WORKER_POOL_TYPE_BITMAP
};

class TestRasterTaskImpl : public RasterTask {
 public:
  typedef base::Callback<void(const RasterSource::SolidColorAnalysis& analysis,
                              bool was_canceled)> Reply;

  TestRasterTaskImpl(const Resource* resource,
                     const Reply& reply,
                     ImageDecodeTask::Vector* dependencies)
      : RasterTask(resource, dependencies),
        reply_(reply),
        picture_pile_(FakePicturePileImpl::CreateEmptyPile(gfx::Size(1, 1),
                                                           gfx::Size(1, 1))) {}

  // Overridden from Task:
  void RunOnWorkerThread() override {
    raster_buffer_->Playback(picture_pile_.get(), gfx::Rect(0, 0, 1, 1), 1.0);
  }

  // Overridden from TileTask:
  void ScheduleOnOriginThread(TileTaskClient* client) override {
    raster_buffer_ = client->AcquireBufferForRaster(resource());
  }
  void CompleteOnOriginThread(TileTaskClient* client) override {
    client->ReleaseBufferForRaster(raster_buffer_.Pass());
  }
  void RunReplyOnOriginThread() override {
    reply_.Run(RasterSource::SolidColorAnalysis(), !HasFinishedRunning());
  }

 protected:
  ~TestRasterTaskImpl() override {}

 private:
  const Reply reply_;
  scoped_ptr<RasterBuffer> raster_buffer_;
  scoped_refptr<PicturePileImpl> picture_pile_;

  DISALLOW_COPY_AND_ASSIGN(TestRasterTaskImpl);
};

class BlockingTestRasterTaskImpl : public TestRasterTaskImpl {
 public:
  BlockingTestRasterTaskImpl(const Resource* resource,
                             const Reply& reply,
                             base::Lock* lock,
                             ImageDecodeTask::Vector* dependencies)
      : TestRasterTaskImpl(resource, reply, dependencies), lock_(lock) {}

  // Overridden from Task:
  void RunOnWorkerThread() override {
    base::AutoLock lock(*lock_);
    TestRasterTaskImpl::RunOnWorkerThread();
  }

  // Overridden from TileTask:
  void RunReplyOnOriginThread() override {}

 protected:
  ~BlockingTestRasterTaskImpl() override {}

 private:
  base::Lock* lock_;

  DISALLOW_COPY_AND_ASSIGN(BlockingTestRasterTaskImpl);
};

class TileTaskWorkerPoolTest
    : public testing::TestWithParam<TileTaskWorkerPoolType>,
      public TileTaskRunnerClient {
 public:
  struct RasterTaskResult {
    unsigned id;
    bool canceled;
  };

  typedef std::vector<scoped_refptr<RasterTask>> RasterTaskVector;

  enum NamedTaskSet { ALL, REQUIRED_FOR_ACTIVATION, REQUIRED_FOR_DRAW };

  TileTaskWorkerPoolTest()
      : context_provider_(TestContextProvider::Create()),
        timeout_seconds_(5),
        timed_out_(false) {}

  // Overridden from testing::Test:
  void SetUp() override {
    switch (GetParam()) {
      case TILE_TASK_WORKER_POOL_TYPE_PIXEL_BUFFER:
        Create3dOutputSurfaceAndResourceProvider();
        tile_task_worker_pool_ = PixelBufferTileTaskWorkerPool::Create(
            base::MessageLoopProxy::current().get(),
            TileTaskWorkerPool::GetTaskGraphRunner(), context_provider_.get(),
            resource_provider_.get(), kMaxTransferBufferUsageBytes);
        break;
      case TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY:
        Create3dOutputSurfaceAndResourceProvider();
        tile_task_worker_pool_ = ZeroCopyTileTaskWorkerPool::Create(
            base::MessageLoopProxy::current().get(),
            TileTaskWorkerPool::GetTaskGraphRunner(), resource_provider_.get());
        break;
      case TILE_TASK_WORKER_POOL_TYPE_ONE_COPY:
        Create3dOutputSurfaceAndResourceProvider();
        staging_resource_pool_ = ResourcePool::Create(resource_provider_.get(),
                                                      GL_TEXTURE_2D, RGBA_8888);
        tile_task_worker_pool_ = OneCopyTileTaskWorkerPool::Create(
            base::MessageLoopProxy::current().get(),
            TileTaskWorkerPool::GetTaskGraphRunner(), context_provider_.get(),
            resource_provider_.get(), staging_resource_pool_.get());
        break;
      case TILE_TASK_WORKER_POOL_TYPE_GPU:
        Create3dOutputSurfaceAndResourceProvider();
        tile_task_worker_pool_ = GpuTileTaskWorkerPool::Create(
            base::MessageLoopProxy::current().get(), context_provider_.get(),
            resource_provider_.get(), false);
        break;
      case TILE_TASK_WORKER_POOL_TYPE_BITMAP:
        CreateSoftwareOutputSurfaceAndResourceProvider();
        tile_task_worker_pool_ = BitmapTileTaskWorkerPool::Create(
            base::MessageLoopProxy::current().get(),
            TileTaskWorkerPool::GetTaskGraphRunner(), resource_provider_.get());
        break;
    }

    DCHECK(tile_task_worker_pool_);
    tile_task_worker_pool_->AsTileTaskRunner()->SetClient(this);
  }

  void TearDown() override {
    tile_task_worker_pool_->AsTileTaskRunner()->Shutdown();
    tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
  }

  // Overriden from TileTaskWorkerPoolClient:
  void DidFinishRunningTileTasks(TaskSet task_set) override {
    if (task_set == ALL) {
      tile_task_worker_pool_->AsTileTaskRunner()->CheckForCompletedTasks();
      base::MessageLoop::current()->Quit();
    }
  }
  TaskSetCollection TasksThatShouldBeForcedToComplete() const override {
    return TaskSetCollection();
  }

  void RunMessageLoopUntilAllTasksHaveCompleted() {
    if (timeout_seconds_) {
      timeout_.Reset(base::Bind(&TileTaskWorkerPoolTest::OnTimeout,
                                base::Unretained(this)));
      base::MessageLoopProxy::current()->PostDelayedTask(
          FROM_HERE, timeout_.callback(),
          base::TimeDelta::FromSeconds(timeout_seconds_));
    }

    base::MessageLoop::current()->Run();

    timeout_.Cancel();

    ASSERT_FALSE(timed_out_) << "Test timed out";
  }

  void ScheduleTasks() {
    TileTaskQueue queue;

    for (RasterTaskVector::const_iterator it = tasks_.begin();
         it != tasks_.end(); ++it) {
      TaskSetCollection task_sets;
      task_sets[ALL] = true;
      queue.items.push_back(TileTaskQueue::Item(it->get(), task_sets));
    }

    tile_task_worker_pool_->AsTileTaskRunner()->ScheduleTasks(&queue);
  }

  void AppendTask(unsigned id, const gfx::Size& size) {
    scoped_ptr<ScopedResource> resource(
        ScopedResource::Create(resource_provider_.get()));
    resource->Allocate(size, ResourceProvider::TextureHintImmutable, RGBA_8888);
    const Resource* const_resource = resource.get();

    ImageDecodeTask::Vector empty;
    tasks_.push_back(new TestRasterTaskImpl(
        const_resource,
        base::Bind(&TileTaskWorkerPoolTest::OnTaskCompleted,
                   base::Unretained(this), base::Passed(&resource), id),
        &empty));
  }

  void AppendTask(unsigned id) { AppendTask(id, gfx::Size(1, 1)); }

  void AppendBlockingTask(unsigned id, base::Lock* lock) {
    const gfx::Size size(1, 1);

    scoped_ptr<ScopedResource> resource(
        ScopedResource::Create(resource_provider_.get()));
    resource->Allocate(size, ResourceProvider::TextureHintImmutable, RGBA_8888);
    const Resource* const_resource = resource.get();

    ImageDecodeTask::Vector empty;
    tasks_.push_back(new BlockingTestRasterTaskImpl(
        const_resource,
        base::Bind(&TileTaskWorkerPoolTest::OnTaskCompleted,
                   base::Unretained(this), base::Passed(&resource), id),
        lock, &empty));
  }

  const std::vector<RasterTaskResult>& completed_tasks() const {
    return completed_tasks_;
  }

 private:
  void Create3dOutputSurfaceAndResourceProvider() {
    output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
    CHECK(output_surface_->BindToClient(&output_surface_client_));
    TestWebGraphicsContext3D* context3d = context_provider_->TestContext3d();
    context3d->set_support_sync_query(true);
    resource_provider_ = ResourceProvider::Create(output_surface_.get(), NULL,
                                                  &gpu_memory_buffer_manager_,
                                                  NULL, 0, false, 1).Pass();
  }

  void CreateSoftwareOutputSurfaceAndResourceProvider() {
    output_surface_ = FakeOutputSurface::CreateSoftware(
        make_scoped_ptr(new SoftwareOutputDevice));
    CHECK(output_surface_->BindToClient(&output_surface_client_));
    resource_provider_ =
        ResourceProvider::Create(output_surface_.get(), &shared_bitmap_manager_,
                                 NULL, NULL, 0, false, 1).Pass();
  }

  void OnTaskCompleted(scoped_ptr<ScopedResource> resource,
                       unsigned id,
                       const RasterSource::SolidColorAnalysis& analysis,
                       bool was_canceled) {
    RasterTaskResult result;
    result.id = id;
    result.canceled = was_canceled;
    completed_tasks_.push_back(result);
  }

  void OnTimeout() {
    timed_out_ = true;
    base::MessageLoop::current()->Quit();
  }

 protected:
  scoped_refptr<TestContextProvider> context_provider_;
  FakeOutputSurfaceClient output_surface_client_;
  scoped_ptr<FakeOutputSurface> output_surface_;
  scoped_ptr<ResourceProvider> resource_provider_;
  scoped_ptr<ResourcePool> staging_resource_pool_;
  scoped_ptr<TileTaskWorkerPool> tile_task_worker_pool_;
  TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
  TestSharedBitmapManager shared_bitmap_manager_;
  base::CancelableClosure timeout_;
  int timeout_seconds_;
  bool timed_out_;
  RasterTaskVector tasks_;
  std::vector<RasterTaskResult> completed_tasks_;
};

TEST_P(TileTaskWorkerPoolTest, Basic) {
  AppendTask(0u);
  AppendTask(1u);
  ScheduleTasks();

  RunMessageLoopUntilAllTasksHaveCompleted();

  ASSERT_EQ(2u, completed_tasks().size());
  EXPECT_FALSE(completed_tasks()[0].canceled);
  EXPECT_FALSE(completed_tasks()[1].canceled);
}

TEST_P(TileTaskWorkerPoolTest, FailedMapResource) {
  if (GetParam() == TILE_TASK_WORKER_POOL_TYPE_BITMAP)
    return;

  TestWebGraphicsContext3D* context3d = context_provider_->TestContext3d();
  context3d->set_times_map_buffer_chromium_succeeds(0);
  AppendTask(0u);
  ScheduleTasks();

  RunMessageLoopUntilAllTasksHaveCompleted();

  ASSERT_EQ(1u, completed_tasks().size());
  EXPECT_FALSE(completed_tasks()[0].canceled);
}

// This test checks that replacing a pending raster task with another does
// not prevent the DidFinishRunningTileTasks notification from being sent.
TEST_P(TileTaskWorkerPoolTest, FalseThrottling) {
  base::Lock lock;

  // Schedule a task that is prevented from completing with a lock.
  lock.Acquire();
  AppendBlockingTask(0u, &lock);
  ScheduleTasks();

  // Schedule another task to replace the still-pending task. Because the old
  // task is not a throttled task in the new task set, it should not prevent
  // DidFinishRunningTileTasks from getting signaled.
  RasterTaskVector tasks;
  tasks.swap(tasks_);
  AppendTask(1u);
  ScheduleTasks();

  // Unblock the first task to allow the second task to complete.
  lock.Release();

  RunMessageLoopUntilAllTasksHaveCompleted();
}

TEST_P(TileTaskWorkerPoolTest, LargeResources) {
  gfx::Size size(kLargeResourceDimension, kLargeResourceDimension);

  {
    // Verify a resource of this size is larger than the transfer buffer.
    scoped_ptr<ScopedResource> resource(
        ScopedResource::Create(resource_provider_.get()));
    resource->Allocate(size, ResourceProvider::TextureHintImmutable, RGBA_8888);
    EXPECT_GE(resource->bytes(), kMaxTransferBufferUsageBytes);
  }

  AppendTask(0u, size);
  AppendTask(1u, size);
  AppendTask(2u, size);
  ScheduleTasks();

  // This will time out if a resource that is larger than the throttle limit
  // never gets scheduled.
  RunMessageLoopUntilAllTasksHaveCompleted();
}

INSTANTIATE_TEST_CASE_P(
    TileTaskWorkerPoolTests,
    TileTaskWorkerPoolTest,
    ::testing::Values(TILE_TASK_WORKER_POOL_TYPE_PIXEL_BUFFER,
                      TILE_TASK_WORKER_POOL_TYPE_ZERO_COPY,
                      TILE_TASK_WORKER_POOL_TYPE_ONE_COPY,
                      TILE_TASK_WORKER_POOL_TYPE_GPU,
                      TILE_TASK_WORKER_POOL_TYPE_BITMAP));

}  // namespace
}  // namespace cc
