// 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/debug/lap_timer.h"
#include "cc/resources/picture_layer_tiling.h"
#include "cc/resources/resource_provider.h"
#include "cc/resources/scoped_resource.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/fake_output_surface_client.h"
#include "cc/test/fake_picture_layer_tiling_client.h"
#include "cc/test/test_context_provider.h"
#include "cc/test/test_shared_bitmap_manager.h"

#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"

namespace cc {

namespace {

static const int kTimeLimitMillis = 2000;
static const int kWarmupRuns = 5;
static const int kTimeCheckInterval = 10;

class PictureLayerTilingPerfTest : public testing::Test {
 public:
  PictureLayerTilingPerfTest()
      : timer_(kWarmupRuns,
               base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
               kTimeCheckInterval),
        context_provider_(TestContextProvider::Create()) {
    output_surface_ = FakeOutputSurface::Create3d(context_provider_).Pass();
    CHECK(output_surface_->BindToClient(&output_surface_client_));

    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
    resource_provider_ = ResourceProvider::Create(output_surface_.get(),
                                                  shared_bitmap_manager_.get(),
                                                  NULL,
                                                  NULL,
                                                  0,
                                                  false,
                                                  1).Pass();
  }

  void SetUp() override {
    picture_layer_tiling_client_.SetTileSize(gfx::Size(256, 256));
    picture_layer_tiling_client_.set_max_tiles_for_interest_area(250);
    picture_layer_tiling_client_.set_tree(PENDING_TREE);
    picture_layer_tiling_ = PictureLayerTiling::Create(
        1, gfx::Size(256 * 50, 256 * 50), &picture_layer_tiling_client_);
    picture_layer_tiling_->CreateAllTilesForTesting();
  }

  void TearDown() override { picture_layer_tiling_.reset(NULL); }

  void RunInvalidateTest(const std::string& test_name, const Region& region) {
    timer_.Reset();
    do {
      picture_layer_tiling_->UpdateTilesToCurrentRasterSource(
          picture_layer_tiling_client_.raster_source(), region,
          picture_layer_tiling_->tiling_size());
      timer_.NextLap();
    } while (!timer_.HasTimeLimitExpired());

    perf_test::PrintResult(
        "invalidation", "", test_name, timer_.LapsPerSecond(), "runs/s", true);
  }

  void RunComputeTilePriorityRectsStationaryTest(
      const std::string& test_name,
      const gfx::Transform& transform) {
    gfx::Rect viewport_rect(0, 0, 1024, 768);

    timer_.Reset();
    do {
      picture_layer_tiling_->ComputeTilePriorityRects(
          viewport_rect, 1.f, timer_.NumLaps() + 1, Occlusion());
      timer_.NextLap();
    } while (!timer_.HasTimeLimitExpired());

    perf_test::PrintResult("compute_tile_priority_rects_stationary",
                           "",
                           test_name,
                           timer_.LapsPerSecond(),
                           "runs/s",
                           true);
  }

  void RunComputeTilePriorityRectsScrollingTest(
      const std::string& test_name,
      const gfx::Transform& transform) {
    gfx::Size viewport_size(1024, 768);
    gfx::Rect viewport_rect(viewport_size);
    int xoffsets[] = {10, 0, -10, 0};
    int yoffsets[] = {0, 10, 0, -10};
    int offsetIndex = 0;
    int offsetCount = 0;
    const int maxOffsetCount = 1000;

    timer_.Reset();
    do {
      picture_layer_tiling_->ComputeTilePriorityRects(
          viewport_rect, 1.f, timer_.NumLaps() + 1, Occlusion());

      viewport_rect = gfx::Rect(viewport_rect.x() + xoffsets[offsetIndex],
                                viewport_rect.y() + yoffsets[offsetIndex],
                                viewport_rect.width(),
                                viewport_rect.height());

      if (++offsetCount > maxOffsetCount) {
        offsetCount = 0;
        offsetIndex = (offsetIndex + 1) % 4;
      }
      timer_.NextLap();
    } while (!timer_.HasTimeLimitExpired());

    perf_test::PrintResult("compute_tile_priority_rects_scrolling",
                           "",
                           test_name,
                           timer_.LapsPerSecond(),
                           "runs/s",
                           true);
  }

  void RunRasterIteratorConstructTest(const std::string& test_name,
                                      const gfx::Rect& viewport) {
    gfx::Size bounds(viewport.size());
    picture_layer_tiling_ =
        PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
    picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
    picture_layer_tiling_->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
                                                    Occlusion());

    timer_.Reset();
    do {
      PictureLayerTiling::TilingRasterTileIterator it(
          picture_layer_tiling_.get());
      timer_.NextLap();
    } while (!timer_.HasTimeLimitExpired());

    perf_test::PrintResult("tiling_raster_tile_iterator_construct",
                           "",
                           test_name,
                           timer_.LapsPerSecond(),
                           "runs/s",
                           true);
  }

  void RunRasterIteratorConstructAndIterateTest(const std::string& test_name,
                                                int num_tiles,
                                                const gfx::Rect& viewport) {
    gfx::Size bounds(10000, 10000);
    picture_layer_tiling_ =
        PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
    picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
    picture_layer_tiling_->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
                                                    Occlusion());

    timer_.Reset();
    do {
      int count = num_tiles;
      PictureLayerTiling::TilingRasterTileIterator it(
          picture_layer_tiling_.get());
      while (count--) {
        ASSERT_TRUE(it) << "count: " << count;
        ASSERT_TRUE(*it != NULL) << "count: " << count;
        ++it;
      }
      timer_.NextLap();
    } while (!timer_.HasTimeLimitExpired());

    perf_test::PrintResult("tiling_raster_tile_iterator_construct_and_iterate",
                           "",
                           test_name,
                           timer_.LapsPerSecond(),
                           "runs/s",
                           true);
  }

  void RunEvictionIteratorConstructTest(const std::string& test_name,
                                        const gfx::Rect& viewport) {
    gfx::Size bounds(viewport.size());
    picture_layer_tiling_ =
        PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
    picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
    picture_layer_tiling_->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
                                                    Occlusion());

    timer_.Reset();
    TreePriority priorities[] = {SAME_PRIORITY_FOR_BOTH_TREES,
                                 SMOOTHNESS_TAKES_PRIORITY,
                                 NEW_CONTENT_TAKES_PRIORITY};
    int priority_count = 0;
    do {
      PictureLayerTiling::TilingEvictionTileIterator it(
          picture_layer_tiling_.get(),
          priorities[priority_count],
          PictureLayerTiling::NOW);
      priority_count = (priority_count + 1) % arraysize(priorities);
      timer_.NextLap();
    } while (!timer_.HasTimeLimitExpired());

    perf_test::PrintResult("tiling_eviction_tile_iterator_construct",
                           "",
                           test_name,
                           timer_.LapsPerSecond(),
                           "runs/s",
                           true);
  }

  void RunEvictionIteratorConstructAndIterateTest(const std::string& test_name,
                                                  int num_tiles,
                                                  const gfx::Rect& viewport) {
    gfx::Size bounds(10000, 10000);
    picture_layer_tiling_ =
        PictureLayerTiling::Create(1, bounds, &picture_layer_tiling_client_);
    picture_layer_tiling_client_.set_tree(ACTIVE_TREE);
    picture_layer_tiling_->ComputeTilePriorityRects(viewport, 1.0f, 1.0,
                                                    Occlusion());

    TreePriority priorities[] = {SAME_PRIORITY_FOR_BOTH_TREES,
                                 SMOOTHNESS_TAKES_PRIORITY,
                                 NEW_CONTENT_TAKES_PRIORITY};

    // Ensure all tiles have resources.
    std::vector<Tile*> all_tiles = picture_layer_tiling_->AllTilesForTesting();
    for (std::vector<Tile*>::iterator tile_it = all_tiles.begin();
         tile_it != all_tiles.end();
         ++tile_it) {
      Tile* tile = *tile_it;
      ManagedTileState::DrawInfo& draw_info = tile->draw_info();
      draw_info.SetResourceForTesting(
          ScopedResource::Create(resource_provider_.get()).Pass());
    }

    int priority_count = 0;
    timer_.Reset();
    do {
      int count = num_tiles;
      PictureLayerTiling::TilingEvictionTileIterator it(
          picture_layer_tiling_.get(),
          priorities[priority_count],
          PictureLayerTiling::EVENTUALLY);
      while (count--) {
        ASSERT_TRUE(it) << "count: " << count;
        ASSERT_TRUE(*it != NULL) << "count: " << count;
        ++it;
      }
      priority_count = (priority_count + 1) % arraysize(priorities);
      timer_.NextLap();
    } while (!timer_.HasTimeLimitExpired());

    // Remove all resources from tiles to make sure the tile version destructor
    // doesn't complain.
    for (std::vector<Tile*>::iterator tile_it = all_tiles.begin();
         tile_it != all_tiles.end();
         ++tile_it) {
      Tile* tile = *tile_it;
      ManagedTileState::DrawInfo& draw_info = tile->draw_info();
      draw_info.SetResourceForTesting(nullptr);
    }

    perf_test::PrintResult(
        "tiling_eviction_tile_iterator_construct_and_iterate",
        "",
        test_name,
        timer_.LapsPerSecond(),
        "runs/s",
        true);
  }

 private:
  FakePictureLayerTilingClient picture_layer_tiling_client_;
  scoped_ptr<PictureLayerTiling> picture_layer_tiling_;

  LapTimer timer_;

  scoped_refptr<ContextProvider> context_provider_;
  FakeOutputSurfaceClient output_surface_client_;
  scoped_ptr<FakeOutputSurface> output_surface_;
  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
  scoped_ptr<ResourceProvider> resource_provider_;
};

TEST_F(PictureLayerTilingPerfTest, Invalidate) {
  Region one_tile(gfx::Rect(256, 256));
  RunInvalidateTest("1x1", one_tile);

  Region half_region(gfx::Rect(25 * 256, 50 * 256));
  RunInvalidateTest("25x50", half_region);

  Region full_region(gfx::Rect(50 * 256, 50 * 256));
  RunInvalidateTest("50x50", full_region);
}

#if defined(OS_ANDROID)
// TODO(vmpstr): Investigate why this is noisy (crbug.com/310220).
TEST_F(PictureLayerTilingPerfTest, DISABLED_ComputeTilePriorityRects) {
#else
TEST_F(PictureLayerTilingPerfTest, ComputeTilePriorityRects) {
#endif  // defined(OS_ANDROID)
  gfx::Transform transform;

  RunComputeTilePriorityRectsStationaryTest("no_transform", transform);
  RunComputeTilePriorityRectsScrollingTest("no_transform", transform);

  transform.Rotate(10);
  RunComputeTilePriorityRectsStationaryTest("rotation", transform);
  RunComputeTilePriorityRectsScrollingTest("rotation", transform);

  transform.ApplyPerspectiveDepth(10);
  RunComputeTilePriorityRectsStationaryTest("perspective", transform);
  RunComputeTilePriorityRectsScrollingTest("perspective", transform);
}

TEST_F(PictureLayerTilingPerfTest, TilingRasterTileIteratorConstruct) {
  RunRasterIteratorConstructTest("0_0_100x100", gfx::Rect(0, 0, 100, 100));
  RunRasterIteratorConstructTest("50_0_100x100", gfx::Rect(50, 0, 100, 100));
  RunRasterIteratorConstructTest("100_0_100x100", gfx::Rect(100, 0, 100, 100));
  RunRasterIteratorConstructTest("150_0_100x100", gfx::Rect(150, 0, 100, 100));
}

TEST_F(PictureLayerTilingPerfTest,
       TilingRasterTileIteratorConstructAndIterate) {
  RunRasterIteratorConstructAndIterateTest(
      "32_100x100", 32, gfx::Rect(0, 0, 100, 100));
  RunRasterIteratorConstructAndIterateTest(
      "32_500x500", 32, gfx::Rect(0, 0, 500, 500));
  RunRasterIteratorConstructAndIterateTest(
      "64_100x100", 64, gfx::Rect(0, 0, 100, 100));
  RunRasterIteratorConstructAndIterateTest(
      "64_500x500", 64, gfx::Rect(0, 0, 500, 500));
}

TEST_F(PictureLayerTilingPerfTest, TilingEvictionTileIteratorConstruct) {
  RunEvictionIteratorConstructTest("0_0_100x100", gfx::Rect(0, 0, 100, 100));
  RunEvictionIteratorConstructTest("50_0_100x100", gfx::Rect(50, 0, 100, 100));
  RunEvictionIteratorConstructTest("100_0_100x100",
                                   gfx::Rect(100, 0, 100, 100));
  RunEvictionIteratorConstructTest("150_0_100x100",
                                   gfx::Rect(150, 0, 100, 100));
}

TEST_F(PictureLayerTilingPerfTest,
       TilingEvictionTileIteratorConstructAndIterate) {
  RunEvictionIteratorConstructAndIterateTest(
      "32_100x100", 32, gfx::Rect(0, 0, 100, 100));
  RunEvictionIteratorConstructAndIterateTest(
      "32_500x500", 32, gfx::Rect(0, 0, 500, 500));
  RunEvictionIteratorConstructAndIterateTest(
      "64_100x100", 64, gfx::Rect(0, 0, 100, 100));
  RunEvictionIteratorConstructAndIterateTest(
      "64_500x500", 64, gfx::Rect(0, 0, 500, 500));
}

}  // namespace

}  // namespace cc
