// 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 "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/time/time.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/test/fake_content_layer_client.h"
#include "cc/test/fake_painted_scrollbar_layer.h"
#include "cc/test/fake_picture_layer.h"
#include "cc/test/layer_test_common.h"
#include "cc/test/layer_tree_test.h"
#include "cc/trees/damage_tracker.h"
#include "cc/trees/layer_tree_impl.h"

namespace cc {
namespace {

// These tests deal with damage tracking.
class LayerTreeHostDamageTest : public LayerTreeTest {};

// LayerTreeHost::SetNeedsRedraw should damage the whole viewport.
class LayerTreeHostDamageTestSetNeedsRedraw
    : public LayerTreeHostDamageTest {
  void SetupTree() override {
    // Viewport is 10x10.
    scoped_refptr<FakePictureLayer> root = FakePictureLayer::Create(&client_);
    root->SetBounds(gfx::Size(10, 10));

    layer_tree_host()->SetRootLayer(root);
    LayerTreeHostDamageTest::SetupTree();
    client_.set_bounds(root->bounds());
  }

  void BeginTest() override {
    draw_count_ = 0;
    PostSetNeedsCommitToMainThread();
  }

  void DidCommitAndDrawFrame() override {
    switch (layer_tree_host()->SourceFrameNumber()) {
      case 1:
        layer_tree_host()->SetNeedsRedrawRect(
            gfx::Rect(layer_tree_host()->device_viewport_size()));
        break;
    }
  }

  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl,
                                   LayerTreeHostImpl::FrameData* frame_data,
                                   DrawResult draw_result) override {
    EXPECT_EQ(DRAW_SUCCESS, draw_result);

    RenderSurfaceImpl* root_surface =
        GetRenderSurface(impl->active_tree()->root_layer_for_testing());
    gfx::Rect root_damage;
    EXPECT_TRUE(
        root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage));

    switch (draw_count_) {
      case 0:
        // The first frame has full damage.
        EXPECT_EQ(gfx::Rect(10, 10), root_damage);
        break;
      case 1:
        // The second frame has full damage.
        EXPECT_EQ(gfx::Rect(10, 10), root_damage);
        EndTest();
        break;
      case 2:
        NOTREACHED();
    }

    ++draw_count_;
    return draw_result;
  }

  void AfterTest() override {}

  int draw_count_;
  FakeContentLayerClient client_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestSetNeedsRedraw);

// LayerTreeHost::SetViewportSizeAndScale should damage the whole viewport.
class LayerTreeHostDamageTestSetViewportSizeAndScale
    : public LayerTreeHostDamageTest {
  void SetupTree() override {
    // Viewport is 10x10.
    scoped_refptr<FakePictureLayer> root = FakePictureLayer::Create(&client_);
    root->SetBounds(gfx::Size(10, 10));

    layer_tree_host()->SetRootLayer(root);
    LayerTreeHostDamageTest::SetupTree();
    client_.set_bounds(root->bounds());
  }

  void BeginTest() override {
    draw_count_ = 0;
    PostSetNeedsCommitToMainThread();
  }

  void DidCommitAndDrawFrame() override {
    switch (layer_tree_host()->SourceFrameNumber()) {
      case 1:
        layer_tree_host()->SetViewportSizeAndScale(
            gfx::Size(15, 15), 1.f, viz::LocalSurfaceIdAllocation());
        break;
    }
  }

  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* impl,
                                   LayerTreeHostImpl::FrameData* frame_data,
                                   DrawResult draw_result) override {
    EXPECT_EQ(DRAW_SUCCESS, draw_result);

    RenderSurfaceImpl* root_surface =
        GetRenderSurface(impl->active_tree()->root_layer_for_testing());
    gfx::Rect root_damage;
    EXPECT_TRUE(
        root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage));

    switch (draw_count_) {
      case 0:
        // The first frame has full damage.
        EXPECT_EQ(gfx::Rect(10, 10), root_damage);
        break;
      case 1:
        // The second frame has full damage.
        EXPECT_EQ(gfx::Rect(15, 15), root_damage);
        EndTest();
        break;
      case 2:
        NOTREACHED();
    }

    ++draw_count_;
    return draw_result;
  }

  void AfterTest() override {}

  int draw_count_;
  FakeContentLayerClient client_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestSetViewportSizeAndScale);

class LayerTreeHostDamageTestNoDamageDoesNotSwap
    : public LayerTreeHostDamageTest {
  void BeginTest() override {
    PostSetNeedsCommitToMainThread();
  }

  void SetupTree() override {
    scoped_refptr<FakePictureLayer> root = FakePictureLayer::Create(&client_);
    root->SetBounds(gfx::Size(10, 10));

    // Most of the layer isn't visible.
    content_ = FakePictureLayer::Create(&client_);
    content_->SetBounds(gfx::Size(2000, 100));
    root->AddChild(content_);

    layer_tree_host()->SetRootLayer(root);
    LayerTreeHostDamageTest::SetupTree();
    client_.set_bounds(root->bounds());
  }

  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
                                   LayerTreeHostImpl::FrameData* frame_data,
                                   DrawResult draw_result) override {
    EXPECT_EQ(DRAW_SUCCESS, draw_result);

    int source_frame = host_impl->active_tree()->source_frame_number();
    switch (source_frame) {
      case 0:
        // The first frame has damage, so we should draw and swap.
        EXPECT_FALSE(frame_data->has_no_damage);
        ++expect_swap_;
        break;
      case 1:
        // The second frame has no damage, so we should not draw and swap.
        EXPECT_TRUE(frame_data->has_no_damage);
        break;
      case 2:
        // The third frame has damage again, so we should draw and swap.
        EXPECT_FALSE(frame_data->has_no_damage);
        ++expect_swap_;
        break;
      case 3:
        // The fourth frame has no visible damage, so we should not draw and
        // swap.
        EXPECT_TRUE(frame_data->has_no_damage);
        EndTest();
        break;
    }
    return draw_result;
  }

  void DisplayDidDrawAndSwapOnThread() override {
    ++did_swap_;
    EXPECT_EQ(expect_swap_, did_swap_);
  }

  void DidCommit() override {
    int next_frame = layer_tree_host()->SourceFrameNumber();
    switch (next_frame) {
      case 1:
        layer_tree_host()->SetNeedsCommit();
        break;
      case 2:
        // Cause visible damage.
        content_->SetNeedsDisplayRect(
            gfx::Rect(layer_tree_host()->device_viewport_size()));
        break;
      case 3:
        // Cause non-visible damage.
        content_->SetNeedsDisplayRect(gfx::Rect(1990, 1990, 10, 10));
        layer_tree_host()->SetNeedsCommit();
        break;
    }
  }

  void AfterTest() override {
    EXPECT_EQ(2, expect_swap_);
    EXPECT_EQ(expect_swap_, did_swap_);
  }

  FakeContentLayerClient client_;
  scoped_refptr<FakePictureLayer> content_;
  int expect_swap_ = 0;
  int did_swap_ = 0;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestNoDamageDoesNotSwap);

class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest {
  void BeginTest() override { PostSetNeedsCommitToMainThread(); }

  void SetupTree() override {
    root_ = FakePictureLayer::Create(&client_);
    child_ = FakePictureLayer::Create(&client_);

    root_->SetBounds(gfx::Size(500, 500));
    child_->SetPosition(gfx::PointF(100.f, 100.f));
    child_->SetBounds(gfx::Size(30, 30));

    root_->AddChild(child_);
    layer_tree_host()->SetRootLayer(root_);
    LayerTreeHostDamageTest::SetupTree();
    client_.set_bounds(root_->bounds());
  }

  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
                                   LayerTreeHostImpl::FrameData* frame_data,
                                   DrawResult draw_result) override {
    EXPECT_EQ(DRAW_SUCCESS, draw_result);

    RenderSurfaceImpl* root_surface =
        GetRenderSurface(host_impl->active_tree()->root_layer_for_testing());
    gfx::Rect root_damage;
    EXPECT_TRUE(
        root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage));
    root_damage.Intersect(root_surface->content_rect());

    int source_frame = host_impl->active_tree()->source_frame_number();
    switch (source_frame) {
      case 0:
        // The first frame draws and clears any damage.
        EXPECT_EQ(root_surface->content_rect(), root_damage);
        EXPECT_FALSE(frame_data->has_no_damage);
        break;
      case 1:
        // If we get a frame without damage then we don't draw.
        EXPECT_EQ(gfx::Rect(), root_damage);
        EXPECT_TRUE(frame_data->has_no_damage);

        // Then we set full damage for the next frame.
        host_impl->SetFullViewportDamage();
        break;
      case 2:
        // The whole frame should be damaged as requested.
        EXPECT_EQ(root_surface->content_rect(), root_damage);
        EXPECT_FALSE(frame_data->has_no_damage);

        // Just a part of the next frame should be damaged.
        child_damage_rect_ = gfx::Rect(10, 11, 12, 13);
        break;
      case 3:
        // The update rect in the child should be damaged and the damaged area
        // should match the invalidation.
        EXPECT_EQ(gfx::Rect(100 + 10, 100 + 11, 12, 13), root_damage);
        EXPECT_FALSE(frame_data->has_no_damage);

        // If we damage part of the frame, but also damage the full
        // frame, then the whole frame should be damaged.
        child_damage_rect_ = gfx::Rect(10, 11, 12, 13);
        host_impl->SetFullViewportDamage();
        break;
      case 4:
        // The whole frame is damaged.
        EXPECT_EQ(root_surface->content_rect(), root_damage);
        EXPECT_FALSE(frame_data->has_no_damage);

        EndTest();
        break;
    }
    return draw_result;
  }

  void DidCommitAndDrawFrame() override {
    if (!TestEnded())
      layer_tree_host()->SetNeedsCommit();

    if (!child_damage_rect_.IsEmpty()) {
      child_->SetNeedsDisplayRect(child_damage_rect_);
      child_damage_rect_ = gfx::Rect();
    }
  }

  void AfterTest() override {}

  FakeContentLayerClient client_;
  scoped_refptr<FakePictureLayer> root_;
  scoped_refptr<FakePictureLayer> child_;
  gfx::Rect child_damage_rect_;
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostDamageTestForcedFullDamage);

class LayerTreeHostScrollbarDamageTest : public LayerTreeHostDamageTest {
  void SetupTree() override {
    scoped_refptr<Layer> root_layer = Layer::Create();
    root_layer->SetBounds(gfx::Size(400, 400));
    root_layer->SetMasksToBounds(true);
    layer_tree_host()->SetRootLayer(root_layer);

    content_layer_ = FakePictureLayer::Create(&client_);
    content_layer_->SetElementId(
        LayerIdToElementIdForTesting(content_layer_->id()));
    content_layer_->SetScrollable(root_layer->bounds());
    content_layer_->SetScrollOffset(gfx::ScrollOffset(10, 20));
    content_layer_->SetBounds(gfx::Size(100, 200));
    content_layer_->SetIsDrawable(true);
    root_layer->AddChild(content_layer_);

    scoped_refptr<Layer> scrollbar_layer = FakePaintedScrollbarLayer::Create(
        false, true, content_layer_->element_id());
    scrollbar_layer->SetPosition(gfx::PointF(300.f, 300.f));
    scrollbar_layer->SetBounds(gfx::Size(10, 100));
    root_layer->AddChild(scrollbar_layer);

    gfx::RectF content_rect(content_layer_->position(),
                            gfx::SizeF(content_layer_->bounds()));
    gfx::RectF scrollbar_rect(scrollbar_layer->position(),
                              gfx::SizeF(scrollbar_layer->bounds()));
    EXPECT_FALSE(content_rect.Intersects(scrollbar_rect));

    LayerTreeHostDamageTest::SetupTree();
    client_.set_bounds(root_layer->bounds());
  }

 private:
  FakeContentLayerClient client_;

 protected:
  scoped_refptr<Layer> content_layer_;
};

class LayerTreeHostDamageTestScrollbarDoesDamage
    : public LayerTreeHostScrollbarDamageTest {
  void BeginTest() override {
    num_draws_ = 0;
    PostSetNeedsCommitToMainThread();
  }

  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
                                   LayerTreeHostImpl::FrameData* frame_data,
                                   DrawResult draw_result) override {
    EXPECT_EQ(DRAW_SUCCESS, draw_result);
    RenderSurfaceImpl* root_surface =
        GetRenderSurface(host_impl->active_tree()->root_layer_for_testing());
    gfx::Rect root_damage;
    EXPECT_TRUE(
        root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage));
    root_damage.Intersect(root_surface->content_rect());
    switch (num_draws_) {
      case 0:
        // The first frame has damage, so we should draw and swap.
        break;
      case 1:
        // The second frame should not damage the scrollbars.
        EXPECT_FALSE(root_damage.Intersects(gfx::Rect(300, 300, 10, 100)));
        break;
      case 2:
        // The third frame should damage the scrollbars.
        EXPECT_TRUE(root_damage.Contains(gfx::Rect(300, 300, 10, 100)));
        break;
      case 3:
        // The fourth frame should damage the scrollbars.
        EXPECT_TRUE(root_damage.Contains(gfx::Rect(300, 300, 10, 100)));
        EndTest();
        break;
    }
    return draw_result;
  }

  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
    ++num_draws_;
    LayerImpl* scroll_layer =
        host_impl->active_tree()->LayerById(content_layer_->id());
    switch (num_draws_) {
      case 1:
        // Test that modifying the position of the content layer (not
        // scrolling) won't damage the scrollbar.
        MainThreadTaskRunner()->PostTask(
            FROM_HERE,
            base::BindOnce(&LayerTreeHostDamageTestScrollbarDoesDamage::
                               ModifyContentLayerPosition,
                           base::Unretained(this)));
        break;
      case 2:
        scroll_layer->ScrollBy(gfx::Vector2dF(10.f, 10.f));
        host_impl->SetNeedsRedraw();
        break;
      case 3:
        // We will resize the content layer, on the main thread.
        MainThreadTaskRunner()->PostTask(
            FROM_HERE,
            base::BindOnce(
                &LayerTreeHostDamageTestScrollbarDoesDamage::ResizeScrollLayer,
                base::Unretained(this)));
        break;
    }
  }

  void ModifyContentLayerPosition() {
    EXPECT_EQ(1, num_draws_);
    content_layer_->SetPosition(gfx::PointF(10.f, 10.f));
  }

  void ResizeScrollLayer() {
    EXPECT_EQ(3, num_draws_);
    Layer* root = layer_tree_host()->root_layer();
    content_layer_->SetBounds(
        gfx::Size(root->bounds().width() + 60, root->bounds().height() + 100));
  }

  void AfterTest() override { EXPECT_EQ(4, num_draws_); }

  int num_draws_;
};

MULTI_THREAD_TEST_F(LayerTreeHostDamageTestScrollbarDoesDamage);

class LayerTreeHostDamageTestScrollbarCommitDoesNoDamage
    : public LayerTreeHostScrollbarDamageTest {
  void BeginTest() override {
    num_draws_ = 0;
    PostSetNeedsCommitToMainThread();
  }

  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
                                   LayerTreeHostImpl::FrameData* frame_data,
                                   DrawResult draw_result) override {
    EXPECT_EQ(DRAW_SUCCESS, draw_result);
    RenderSurfaceImpl* root_surface =
        GetRenderSurface(host_impl->active_tree()->root_layer_for_testing());
    gfx::Rect root_damage;
    EXPECT_TRUE(
        root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage));
    root_damage.Intersect(root_surface->content_rect());
    int frame = host_impl->active_tree()->source_frame_number();
    switch (num_draws_) {
      case 0:
        // The first frame has damage, so we should draw and swap.
        EXPECT_EQ(0, frame);
        break;
      case 1:
        // The second frame has scrolled, so the scrollbar should be damaged.
        EXPECT_EQ(0, frame);
        EXPECT_TRUE(root_damage.Contains(gfx::Rect(300, 300, 10, 100)));
        break;
      case 2:
        // The third frame (after the commit) has no changes, so it shouldn't.
        EXPECT_EQ(1, frame);
        EXPECT_FALSE(root_damage.Intersects(gfx::Rect(300, 300, 10, 100)));
        break;
      default:
        NOTREACHED();
        break;
    }
    return draw_result;
  }

  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
    ++num_draws_;
    LayerImpl* scroll_layer =
        host_impl->active_tree()->LayerById(content_layer_->id());
    switch (num_draws_) {
      case 1:
        // Scroll on the thread.  This should damage the scrollbar for the
        // next draw on the thread.
        scroll_layer->ScrollBy(gfx::Vector2dF(10.f, 10.f));
        host_impl->SetNeedsRedraw();
        break;
      case 2:
        // Forcibly send the scroll to the main thread.
        PostSetNeedsCommitToMainThread();
        break;
      case 3:
        // First swap after second commit.
        EndTest();
        break;
      default:
        NOTREACHED();
        break;
    }
  }

  void AfterTest() override { EXPECT_EQ(3, num_draws_); }

  int num_draws_;
};

MULTI_THREAD_TEST_F(LayerTreeHostDamageTestScrollbarCommitDoesNoDamage);

}  // namespace
}  // namespace cc
