// 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/trees/layer_tree_host.h"

#include "cc/layers/layer.h"
#include "cc/layers/picture_layer.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/layer_tree_test.h"
#include "cc/trees/layer_tree_impl.h"

namespace cc {
namespace {

#define EXPECT_OCCLUSION_EQ(expected, actual)              \
  EXPECT_TRUE(expected.IsEqual(actual))                    \
      << " Expected: " << expected.ToString() << std::endl \
      << " Actual: " << actual.ToString();

class LayerTreeHostOcclusionTest : public LayerTreeTest {
 protected:
  void InitializeSettings(LayerTreeSettings* settings) override {
    settings->minimum_occlusion_tracking_size = gfx::Size();
  }
};

// Verify occlusion is set on the layer draw properties.
class LayerTreeHostOcclusionTestDrawPropertiesOnLayer
    : public LayerTreeHostOcclusionTest {
 public:
  void SetupTree() override {
    scoped_refptr<Layer> root = Layer::Create();
    root->SetBounds(gfx::Size(100, 100));
    root->SetIsDrawable(true);

    child_ = Layer::Create();
    child_->SetBounds(gfx::Size(50, 60));
    child_->SetPosition(gfx::PointF(10.f, 5.5f));
    child_->SetContentsOpaque(true);
    child_->SetIsDrawable(true);
    root->AddChild(child_);

    layer_tree()->SetRootLayer(root);
    LayerTreeTest::SetupTree();
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* root = impl->active_tree()->root_layer_for_testing();
    LayerImpl* child = impl->active_tree()->LayerById(child_->id());

    // Verify the draw properties are valid.
    EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member());
    EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member());

    EXPECT_OCCLUSION_EQ(
        Occlusion(child->DrawTransform(), SimpleEnclosedRegion(),
                  SimpleEnclosedRegion()),
        child->draw_properties().occlusion_in_content_space);
    EXPECT_OCCLUSION_EQ(
        Occlusion(root->DrawTransform(), SimpleEnclosedRegion(),
                  SimpleEnclosedRegion(gfx::Rect(10, 6, 50, 59))),
        root->draw_properties().occlusion_in_content_space);
    EndTest();
  }

  void AfterTest() override {}

 private:
  scoped_refptr<Layer> child_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestDrawPropertiesOnLayer);

// Verify occlusion is set on the render surfaces.
class LayerTreeHostOcclusionTestDrawPropertiesOnSurface
    : public LayerTreeHostOcclusionTest {
 public:
  void SetupTree() override {
    scoped_refptr<Layer> root = Layer::Create();
    root->SetBounds(gfx::Size(100, 100));
    root->SetIsDrawable(true);

    child_ = Layer::Create();
    child_->SetBounds(gfx::Size(1, 1));
    child_->SetPosition(gfx::PointF(10.f, 5.5f));
    child_->SetIsDrawable(true);
    child_->SetForceRenderSurfaceForTesting(true);
    root->AddChild(child_);

    scoped_refptr<Layer> child2 = Layer::Create();
    child2->SetBounds(gfx::Size(10, 12));
    child2->SetPosition(gfx::PointF(13.f, 8.5f));
    child2->SetContentsOpaque(true);
    child2->SetIsDrawable(true);
    root->AddChild(child2);

    layer_tree()->SetRootLayer(root);
    LayerTreeTest::SetupTree();
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* root = impl->active_tree()->root_layer_for_testing();
    LayerImpl* child = impl->active_tree()->LayerById(child_->id());
    RenderSurfaceImpl* surface = child->render_surface();

    // Verify the draw properties are valid.
    EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member());
    EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member());
    EXPECT_TRUE(child->has_render_surface());
    EXPECT_EQ(child->render_surface(), child->render_target());

    EXPECT_OCCLUSION_EQ(
        Occlusion(surface->draw_transform(), SimpleEnclosedRegion(),
                  SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))),
        surface->occlusion_in_content_space());
    EndTest();
  }

  void AfterTest() override {}

 private:
  scoped_refptr<Layer> child_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostOcclusionTestDrawPropertiesOnSurface);

// Verify occlusion is set on mask layers.
class LayerTreeHostOcclusionTestDrawPropertiesOnMask
    : public LayerTreeHostOcclusionTest {
 public:
  void SetupTree() override {
    scoped_refptr<Layer> root = Layer::Create();
    root->SetBounds(gfx::Size(100, 100));
    root->SetIsDrawable(true);

    child_ = Layer::Create();
    child_->SetBounds(gfx::Size(30, 40));
    child_->SetPosition(gfx::PointF(10.f, 5.5f));
    child_->SetIsDrawable(true);
    root->AddChild(child_);

    scoped_refptr<Layer> make_surface_bigger = Layer::Create();
    make_surface_bigger->SetBounds(gfx::Size(100, 100));
    make_surface_bigger->SetPosition(gfx::PointF(-10.f, -15.f));
    make_surface_bigger->SetIsDrawable(true);
    child_->AddChild(make_surface_bigger);

    scoped_refptr<Layer> mask = PictureLayer::Create(&client_);
    mask->SetBounds(gfx::Size(30, 40));
    mask->SetIsDrawable(true);
    child_->SetMaskLayer(mask.get());

    scoped_refptr<Layer> child2 = Layer::Create();
    child2->SetBounds(gfx::Size(10, 12));
    child2->SetPosition(gfx::PointF(13.f, 8.5f));
    child2->SetContentsOpaque(true);
    child2->SetIsDrawable(true);
    root->AddChild(child2);

    layer_tree()->SetRootLayer(root);
    LayerTreeTest::SetupTree();
    client_.set_bounds(root->bounds());
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* root = impl->active_tree()->root_layer_for_testing();
    LayerImpl* child = impl->active_tree()->LayerById(child_->id());
    RenderSurfaceImpl* surface = child->render_surface();
    LayerImpl* mask = surface->MaskLayer();

    // Verify the draw properties are valid.
    EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member());
    EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member());
    EXPECT_TRUE(child->has_render_surface());
    EXPECT_EQ(child->render_surface(), child->render_target());

    gfx::Transform transform = surface->draw_transform();
    transform.PreconcatTransform(child->DrawTransform());

    EXPECT_OCCLUSION_EQ(
        Occlusion(transform, SimpleEnclosedRegion(),
                  SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))),
        mask->draw_properties().occlusion_in_content_space);
    EndTest();
  }

  void AfterTest() override {}

 private:
  FakeContentLayerClient client_;
  scoped_refptr<Layer> child_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestDrawPropertiesOnMask);

// Verify occlusion is correctly set on scaled mask layers.
class LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask
    : public LayerTreeHostOcclusionTest {
 public:
  void SetupTree() override {
    scoped_refptr<Layer> root = Layer::Create();
    root->SetBounds(gfx::Size(100, 100));
    root->SetIsDrawable(true);

    gfx::Transform scale;
    scale.Scale(2, 2);

    child_ = Layer::Create();
    child_->SetBounds(gfx::Size(30, 40));
    child_->SetTransform(scale);
    root->AddChild(child_);

    scoped_refptr<Layer> grand_child = Layer::Create();
    grand_child->SetBounds(gfx::Size(100, 100));
    grand_child->SetPosition(gfx::PointF(-10.f, -15.f));
    grand_child->SetIsDrawable(true);
    child_->AddChild(grand_child);

    scoped_refptr<Layer> mask = PictureLayer::Create(&client_);
    mask->SetBounds(gfx::Size(30, 40));
    mask->SetIsDrawable(true);
    child_->SetMaskLayer(mask.get());

    scoped_refptr<Layer> child2 = Layer::Create();
    child2->SetBounds(gfx::Size(10, 11));
    child2->SetPosition(gfx::PointF(13.f, 15.f));
    child2->SetContentsOpaque(true);
    child2->SetIsDrawable(true);
    root->AddChild(child2);

    layer_tree()->SetRootLayer(root);
    LayerTreeTest::SetupTree();
    client_.set_bounds(root->bounds());
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* child = impl->active_tree()->LayerById(child_->id());
    LayerImpl* mask = child->render_surface()->MaskLayer();

    gfx::Transform scale;
    scale.Scale(2, 2);

    EXPECT_OCCLUSION_EQ(
        Occlusion(scale, SimpleEnclosedRegion(),
                  SimpleEnclosedRegion(gfx::Rect(13, 15, 10, 11))),
        mask->draw_properties().occlusion_in_content_space);
    EndTest();
  }

  void AfterTest() override {}

 private:
  FakeContentLayerClient client_;
  scoped_refptr<Layer> child_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask);

// Verify occlusion is set to empty inside the subtree of a replica. This is
// done because the tile system does not know about replicas, and so would not
// know that something is unoccluded on the replica even though it's occluded on
// the original.
class LayerTreeHostOcclusionTestDrawPropertiesInsideReplica
    : public LayerTreeHostOcclusionTest {
 public:
  void SetupTree() override {
    scoped_refptr<Layer> root = Layer::Create();
    root->SetBounds(gfx::Size(100, 100));
    root->SetIsDrawable(true);

    child_ = Layer::Create();
    child_->SetBounds(gfx::Size(1, 1));
    child_->SetPosition(gfx::PointF(10.f, 5.5f));
    child_->SetIsDrawable(true);
    child_->SetForceRenderSurfaceForTesting(true);
    root->AddChild(child_);

    scoped_refptr<Layer> replica = Layer::Create();
    gfx::Transform translate;
    translate.Translate(20.f, 4.f);
    replica->SetTransform(translate);
    child_->SetReplicaLayer(replica.get());

    scoped_refptr<Layer> mask = PictureLayer::Create(&client_);
    mask->SetBounds(gfx::Size(30, 40));
    mask->SetIsDrawable(true);
    child_->SetMaskLayer(mask.get());

    scoped_refptr<Layer> child2 = Layer::Create();
    child2->SetBounds(gfx::Size(10, 12));
    child2->SetPosition(gfx::PointF(13.f, 8.5f));
    child2->SetContentsOpaque(true);
    child2->SetIsDrawable(true);
    root->AddChild(child2);

    layer_tree()->SetRootLayer(root);
    LayerTreeTest::SetupTree();
    client_.set_bounds(root->bounds());
  }

  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
    LayerImpl* root = impl->active_tree()->root_layer_for_testing();
    LayerImpl* child = impl->active_tree()->LayerById(child_->id());
    RenderSurfaceImpl* surface = child->render_surface();
    LayerImpl* mask = surface->MaskLayer();

    // Verify the draw properties are valid.
    EXPECT_TRUE(root->is_drawn_render_surface_layer_list_member());
    EXPECT_TRUE(child->is_drawn_render_surface_layer_list_member());
    EXPECT_TRUE(child->has_render_surface());
    EXPECT_EQ(child->render_surface(), child->render_target());

    // No occlusion from on child, which is part of the replica.
    EXPECT_OCCLUSION_EQ(Occlusion(),
                        child->draw_properties().occlusion_in_content_space);
    // Occlusion on the surface is okay.
    EXPECT_OCCLUSION_EQ(
        Occlusion(surface->draw_transform(), SimpleEnclosedRegion(),
                  SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))),
        surface->occlusion_in_content_space());
    // No occlusion on the replica'd mask.
    EXPECT_OCCLUSION_EQ(Occlusion(),
                        mask->draw_properties().occlusion_in_content_space);
    EndTest();
  }

  void AfterTest() override {}

 private:
  FakeContentLayerClient client_;
  scoped_refptr<Layer> child_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostOcclusionTestDrawPropertiesInsideReplica);

}  // namespace
}  // namespace cc
