// Copyright 2012 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/layers/tiled_layer_impl.h"

#include "cc/layers/append_quads_data.h"
#include "cc/quads/tile_draw_quad.h"
#include "cc/resources/layer_tiling_data.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/layer_test_common.h"
#include "cc/trees/single_thread_proxy.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {
namespace {

class TiledLayerImplTest : public testing::Test {
 public:
  TiledLayerImplTest() : host_impl_(&proxy_, &shared_bitmap_manager_) {}

  scoped_ptr<TiledLayerImpl> CreateLayerNoTiles(
      const gfx::Size& tile_size,
      const gfx::Size& layer_size,
      LayerTilingData::BorderTexelOption border_texels) {
    scoped_ptr<TiledLayerImpl> layer =
        TiledLayerImpl::Create(host_impl_.active_tree(), 1);
    scoped_ptr<LayerTilingData> tiler =
        LayerTilingData::Create(tile_size, border_texels);
    tiler->SetTilingSize(layer_size);
    layer->SetTilingData(*tiler);
    layer->set_skips_draw(false);
    layer->draw_properties().visible_content_rect =
        gfx::Rect(layer_size);
    layer->draw_properties().opacity = 1;
    layer->SetBounds(layer_size);
    layer->SetContentBounds(layer_size);
    layer->CreateRenderSurface();
    layer->draw_properties().render_target = layer.get();
    return layer.Pass();
  }

  // Create a default tiled layer with textures for all tiles and a default
  // visibility of the entire layer size.
  scoped_ptr<TiledLayerImpl> CreateLayer(
      const gfx::Size& tile_size,
      const gfx::Size& layer_size,
      LayerTilingData::BorderTexelOption border_texels) {
    scoped_ptr<TiledLayerImpl> layer =
        CreateLayerNoTiles(tile_size, layer_size, border_texels);

    ResourceProvider::ResourceId resource_id = 1;
    for (int i = 0; i < layer->TilingForTesting()->num_tiles_x(); ++i) {
      for (int j = 0; j < layer->TilingForTesting()->num_tiles_y(); ++j)
        layer->PushTileProperties(i, j, resource_id++, false);
    }

    return layer.Pass();
  }

  void GetQuads(RenderPass* render_pass,
                const gfx::Size& tile_size,
                const gfx::Size& layer_size,
                LayerTilingData::BorderTexelOption border_texel_option,
                const gfx::Rect& visible_content_rect) {
    scoped_ptr<TiledLayerImpl> layer =
        CreateLayer(tile_size, layer_size, border_texel_option);
    layer->draw_properties().visible_content_rect = visible_content_rect;
    layer->SetBounds(layer_size);

    AppendQuadsData data;
    layer->AppendQuads(render_pass, Occlusion(), &data);
  }

 protected:
  FakeImplProxy proxy_;
  TestSharedBitmapManager shared_bitmap_manager_;
  FakeLayerTreeHostImpl host_impl_;
};

TEST_F(TiledLayerImplTest, EmptyQuadList) {
  gfx::Size tile_size(90, 90);
  int num_tiles_x = 8;
  int num_tiles_y = 4;
  gfx::Size layer_size(tile_size.width() * num_tiles_x,
                       tile_size.height() * num_tiles_y);

  // Verify default layer does creates quads
  {
    scoped_ptr<TiledLayerImpl> layer =
        CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
    scoped_ptr<RenderPass> render_pass = RenderPass::Create();

    AppendQuadsData data;
    EXPECT_TRUE(layer->WillDraw(DRAW_MODE_HARDWARE, nullptr));
    layer->AppendQuads(render_pass.get(), Occlusion(), &data);
    layer->DidDraw(nullptr);
    unsigned num_tiles = num_tiles_x * num_tiles_y;
    EXPECT_EQ(render_pass->quad_list.size(), num_tiles);
  }

  // Layer with empty visible layer rect produces no quads
  {
    scoped_ptr<TiledLayerImpl> layer =
        CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
    layer->draw_properties().visible_content_rect = gfx::Rect();

    scoped_ptr<RenderPass> render_pass = RenderPass::Create();

    EXPECT_FALSE(layer->WillDraw(DRAW_MODE_HARDWARE, nullptr));
  }

  // Layer with non-intersecting visible layer rect produces no quads
  {
    scoped_ptr<TiledLayerImpl> layer =
        CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);

    gfx::Rect outside_bounds(-100, -100, 50, 50);
    layer->draw_properties().visible_content_rect = outside_bounds;

    scoped_ptr<RenderPass> render_pass = RenderPass::Create();

    AppendQuadsData data;
    EXPECT_TRUE(layer->WillDraw(DRAW_MODE_HARDWARE, nullptr));
    layer->AppendQuads(render_pass.get(), Occlusion(), &data);
    layer->DidDraw(nullptr);
    EXPECT_EQ(render_pass->quad_list.size(), 0u);
  }

  // Layer with skips draw produces no quads
  {
    scoped_ptr<TiledLayerImpl> layer =
        CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);
    layer->set_skips_draw(true);

    scoped_ptr<RenderPass> render_pass = RenderPass::Create();

    AppendQuadsData data;
    layer->AppendQuads(render_pass.get(), Occlusion(), &data);
    EXPECT_EQ(render_pass->quad_list.size(), 0u);
  }
}

TEST_F(TiledLayerImplTest, Checkerboarding) {
  gfx::Size tile_size(10, 10);
  int num_tiles_x = 2;
  int num_tiles_y = 2;
  gfx::Size layer_size(tile_size.width() * num_tiles_x,
                       tile_size.height() * num_tiles_y);

  scoped_ptr<TiledLayerImpl> layer =
      CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);

  // No checkerboarding
  {
    scoped_ptr<RenderPass> render_pass = RenderPass::Create();

    AppendQuadsData data;
    layer->AppendQuads(render_pass.get(), Occlusion(), &data);
    EXPECT_EQ(render_pass->quad_list.size(), 4u);
    EXPECT_EQ(0u, data.num_missing_tiles);

    for (const auto& quad : render_pass->quad_list)
      EXPECT_EQ(quad.material, DrawQuad::TILED_CONTENT);
  }

  for (int i = 0; i < num_tiles_x; ++i)
    for (int j = 0; j < num_tiles_y; ++j)
      layer->PushTileProperties(i, j, 0, false);

  // All checkerboarding
  {
    scoped_ptr<RenderPass> render_pass = RenderPass::Create();

    AppendQuadsData data;
    layer->AppendQuads(render_pass.get(), Occlusion(), &data);
    EXPECT_LT(0u, data.num_missing_tiles);
    EXPECT_EQ(render_pass->quad_list.size(), 4u);
    for (const auto& quad : render_pass->quad_list)
      EXPECT_NE(quad.material, DrawQuad::TILED_CONTENT);
  }
}

// Test with both border texels and without.
#define WITH_AND_WITHOUT_BORDER_TEST(text_fixture_name)                        \
  TEST_F(TiledLayerImplBorderTest, text_fixture_name##NoBorders) {             \
    text_fixture_name(LayerTilingData::NO_BORDER_TEXELS);                      \
  }                                                                            \
  TEST_F(TiledLayerImplBorderTest, text_fixture_name##HasBorders) {            \
    text_fixture_name(LayerTilingData::HAS_BORDER_TEXELS);                     \
  }

class TiledLayerImplBorderTest : public TiledLayerImplTest {
 public:
  void CoverageVisibleRectOnTileBoundaries(
      LayerTilingData::BorderTexelOption borders) {
    gfx::Size layer_size(1000, 1000);
    scoped_ptr<RenderPass> render_pass = RenderPass::Create();
    GetQuads(render_pass.get(),
             gfx::Size(100, 100),
             layer_size,
             borders,
             gfx::Rect(layer_size));
    LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass->quad_list,
                                                 gfx::Rect(layer_size));
  }

  void CoverageVisibleRectIntersectsTiles(
      LayerTilingData::BorderTexelOption borders) {
    // This rect intersects the middle 3x3 of the 5x5 tiles.
    gfx::Point top_left(65, 73);
    gfx::Point bottom_right(182, 198);
    gfx::Rect visible_content_rect = gfx::BoundingRect(top_left, bottom_right);

    gfx::Size layer_size(250, 250);
    scoped_ptr<RenderPass> render_pass = RenderPass::Create();
    GetQuads(render_pass.get(),
             gfx::Size(50, 50),
             gfx::Size(250, 250),
             LayerTilingData::NO_BORDER_TEXELS,
             visible_content_rect);
    LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass->quad_list,
                                                 visible_content_rect);
  }

  void CoverageVisibleRectIntersectsBounds(
      LayerTilingData::BorderTexelOption borders) {
    gfx::Size layer_size(220, 210);
    gfx::Rect visible_content_rect(layer_size);
    scoped_ptr<RenderPass> render_pass = RenderPass::Create();
    GetQuads(render_pass.get(),
             gfx::Size(100, 100),
             layer_size,
             LayerTilingData::NO_BORDER_TEXELS,
             visible_content_rect);
    LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass->quad_list,
                                                 visible_content_rect);
  }
};
WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectOnTileBoundaries);

WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsTiles);

WITH_AND_WITHOUT_BORDER_TEST(CoverageVisibleRectIntersectsBounds);

TEST_F(TiledLayerImplTest, TextureInfoForLayerNoBorders) {
  gfx::Size tile_size(50, 50);
  gfx::Size layer_size(250, 250);
  scoped_ptr<RenderPass> render_pass = RenderPass::Create();
  GetQuads(render_pass.get(),
           tile_size,
           layer_size,
           LayerTilingData::NO_BORDER_TEXELS,
           gfx::Rect(layer_size));

  for (auto iter = render_pass->quad_list.cbegin();
       iter != render_pass->quad_list.cend();
       ++iter) {
    const TileDrawQuad* quad = TileDrawQuad::MaterialCast(&*iter);

    EXPECT_NE(0u, quad->resource_id) << LayerTestCommon::quad_string
                                     << iter.index();
    EXPECT_EQ(gfx::RectF(gfx::PointF(), tile_size), quad->tex_coord_rect)
        << LayerTestCommon::quad_string << iter.index();
    EXPECT_EQ(tile_size, quad->texture_size) << LayerTestCommon::quad_string
                                             << iter.index();
  }
}

TEST_F(TiledLayerImplTest, GPUMemoryUsage) {
  gfx::Size tile_size(20, 30);
  int num_tiles_x = 12;
  int num_tiles_y = 32;
  gfx::Size layer_size(tile_size.width() * num_tiles_x,
                       tile_size.height() * num_tiles_y);

  scoped_ptr<TiledLayerImpl> layer = CreateLayerNoTiles(
      tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);

  EXPECT_EQ(layer->GPUMemoryUsageInBytes(), 0u);

  ResourceProvider::ResourceId resource_id = 1;
  layer->PushTileProperties(0, 1, resource_id++, false);
  layer->PushTileProperties(2, 3, resource_id++, false);
  layer->PushTileProperties(2, 0, resource_id++, false);

  EXPECT_EQ(
      layer->GPUMemoryUsageInBytes(),
      static_cast<size_t>(3 * 4 * tile_size.width() * tile_size.height()));

  ResourceProvider::ResourceId empty_resource(0);
  layer->PushTileProperties(0, 1, empty_resource, false);
  layer->PushTileProperties(2, 3, empty_resource, false);
  layer->PushTileProperties(2, 0, empty_resource, false);

  EXPECT_EQ(layer->GPUMemoryUsageInBytes(), 0u);
}

TEST_F(TiledLayerImplTest, EmptyMask) {
  gfx::Size tile_size(20, 20);
  gfx::Size layer_size(0, 0);
  scoped_ptr<TiledLayerImpl> layer =
      CreateLayer(tile_size, layer_size, LayerTilingData::NO_BORDER_TEXELS);

  ResourceProvider::ResourceId mask_resource_id;
  gfx::Size mask_texture_size;
  layer->GetContentsResourceId(&mask_resource_id, &mask_texture_size);
  EXPECT_EQ(0u, mask_resource_id);
  EXPECT_EQ(0, layer->TilingForTesting()->num_tiles_x());
  EXPECT_EQ(0, layer->TilingForTesting()->num_tiles_y());
}

TEST_F(TiledLayerImplTest, Occlusion) {
  gfx::Size tile_size(100, 100);
  gfx::Size layer_bounds(1000, 1000);
  gfx::Size viewport_size(1000, 1000);

  LayerTestCommon::LayerImplTest impl;

  TiledLayerImpl* tiled_layer = impl.AddChildToRoot<TiledLayerImpl>();
  tiled_layer->SetBounds(layer_bounds);
  tiled_layer->SetContentBounds(layer_bounds);
  tiled_layer->SetDrawsContent(true);
  tiled_layer->set_skips_draw(false);

  scoped_ptr<LayerTilingData> tiler =
      LayerTilingData::Create(tile_size, LayerTilingData::NO_BORDER_TEXELS);
  tiler->SetTilingSize(layer_bounds);
  tiled_layer->SetTilingData(*tiler);

  ResourceProvider::ResourceId resource_id = 1;
  for (int i = 0; i < tiled_layer->TilingForTesting()->num_tiles_x(); ++i) {
    for (int j = 0; j < tiled_layer->TilingForTesting()->num_tiles_y(); ++j)
      tiled_layer->PushTileProperties(i, j, resource_id++, false);
  }

  impl.CalcDrawProps(viewport_size);

  {
    SCOPED_TRACE("No occlusion");
    gfx::Rect occluded;
    impl.AppendQuadsWithOcclusion(tiled_layer, occluded);

    LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(),
                                                 gfx::Rect(layer_bounds));
    EXPECT_EQ(100u, impl.quad_list().size());
  }

  {
    SCOPED_TRACE("Full occlusion");
    gfx::Rect occluded(tiled_layer->visible_content_rect());
    impl.AppendQuadsWithOcclusion(tiled_layer, occluded);

    LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect());
    EXPECT_EQ(impl.quad_list().size(), 0u);
  }

  {
    SCOPED_TRACE("Partial occlusion");
    gfx::Rect occluded(150, 0, 200, 1000);
    impl.AppendQuadsWithOcclusion(tiled_layer, occluded);

    size_t partially_occluded_count = 0;
    LayerTestCommon::VerifyQuadsAreOccluded(
        impl.quad_list(), occluded, &partially_occluded_count);
    // The layer outputs one quad, which is partially occluded.
    EXPECT_EQ(100u - 10u, impl.quad_list().size());
    EXPECT_EQ(10u + 10u, partially_occluded_count);
  }
}

}  // namespace
}  // namespace cc
