// Copyright 2014 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 <stdint.h>

#include <set>
#include <vector>

#include "base/location.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "cc/animation/animation_host.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/layers/surface_layer.h"
#include "cc/layers/surface_layer_impl.h"
#include "cc/test/fake_impl_task_runner_provider.h"
#include "cc/test/fake_layer_tree_host.h"
#include "cc/test/fake_layer_tree_host_client.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_output_surface.h"
#include "cc/test/layer_tree_test.h"
#include "cc/test/test_task_graph_runner.h"
#include "cc/trees/layer_tree_host.h"
#include "components/viz/common/quads/compositor_frame.h"
#include "components/viz/common/surfaces/sequence_surface_reference_factory.h"
#include "components/viz/common/surfaces/surface_info.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {
namespace {

using testing::_;
using testing::Eq;
using testing::ElementsAre;
using testing::SizeIs;

static constexpr viz::FrameSinkId kArbitraryFrameSinkId(1, 1);

class SurfaceLayerTest : public testing::Test {
 public:
  SurfaceLayerTest()
      : host_impl_(&task_runner_provider_, &task_graph_runner_) {}

  // Synchronizes |layer_tree_host_| and |host_impl_| and pushes surface ids.
  void SynchronizeTrees() {
    TreeSynchronizer::PushLayerProperties(layer_tree_host_.get(),
                                          host_impl_.pending_tree());
    layer_tree_host_->PushSurfaceIdsTo(host_impl_.pending_tree());
  }

 protected:
  void SetUp() override {
    animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
    layer_tree_host_ = FakeLayerTreeHost::Create(
        &fake_client_, &task_graph_runner_, animation_host_.get());
    layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
    host_impl_.CreatePendingTree();
  }

  void TearDown() override {
    if (layer_tree_host_) {
      layer_tree_host_->SetRootLayer(nullptr);
      layer_tree_host_ = nullptr;
    }
  }

  FakeLayerTreeHostClient fake_client_;
  FakeImplTaskRunnerProvider task_runner_provider_;
  TestTaskGraphRunner task_graph_runner_;
  std::unique_ptr<AnimationHost> animation_host_;
  std::unique_ptr<FakeLayerTreeHost> layer_tree_host_;
  FakeLayerTreeHostImpl host_impl_;
};

class MockSurfaceReferenceFactory
    : public viz::SequenceSurfaceReferenceFactory {
 public:
  MockSurfaceReferenceFactory() = default;

  // SequenceSurfaceReferenceFactory implementation.
  MOCK_CONST_METHOD1(SatisfySequence, void(const viz::SurfaceSequence&));
  MOCK_CONST_METHOD2(RequireSequence,
                     void(const viz::SurfaceId&, const viz::SurfaceSequence&));

 protected:
  ~MockSurfaceReferenceFactory() override = default;

 private:
  DISALLOW_COPY_AND_ASSIGN(MockSurfaceReferenceFactory);
};

// Check that one surface can be referenced by multiple LayerTreeHosts, and
// each will create its own viz::SurfaceSequence that's satisfied on
// destruction.
TEST_F(SurfaceLayerTest, MultipleFramesOneSurface) {
  const base::UnguessableToken kArbitraryToken =
      base::UnguessableToken::Create();
  const viz::SurfaceId surface_id(kArbitraryFrameSinkId,
                                  viz::LocalSurfaceId(1, kArbitraryToken));
  const viz::SurfaceSequence expected_seq1(viz::FrameSinkId(1, 1), 1u);
  const viz::SurfaceSequence expected_seq2(viz::FrameSinkId(2, 2), 1u);
  const viz::SurfaceId expected_id(kArbitraryFrameSinkId,
                                   viz::LocalSurfaceId(1, kArbitraryToken));

  scoped_refptr<MockSurfaceReferenceFactory> ref_factory =
      new testing::StrictMock<MockSurfaceReferenceFactory>();

  // We are going to set up the SurfaceLayers and LayerTreeHosts. Each layer
  // will require a sequence and no sequence should be satisfied for now.
  EXPECT_CALL(*ref_factory, RequireSequence(Eq(expected_id), Eq(expected_seq1)))
      .Times(1);
  EXPECT_CALL(*ref_factory, RequireSequence(Eq(expected_id), Eq(expected_seq2)))
      .Times(1);
  EXPECT_CALL(*ref_factory, SatisfySequence(_)).Times(0);

  auto layer = SurfaceLayer::Create(ref_factory);
  layer->SetPrimarySurfaceId(surface_id, base::nullopt);
  layer->SetFallbackSurfaceId(surface_id);
  layer_tree_host_->GetSurfaceSequenceGenerator()->set_frame_sink_id(
      viz::FrameSinkId(1, 1));
  layer_tree_host_->SetRootLayer(layer);

  auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
  std::unique_ptr<FakeLayerTreeHost> layer_tree_host2 =
      FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_,
                                animation_host2.get());
  auto layer2 = SurfaceLayer::Create(ref_factory);
  layer2->SetPrimarySurfaceId(surface_id, base::nullopt);
  layer2->SetFallbackSurfaceId(surface_id);
  layer_tree_host2->GetSurfaceSequenceGenerator()->set_frame_sink_id(
      viz::FrameSinkId(2, 2));
  layer_tree_host2->SetRootLayer(layer2);

  testing::Mock::VerifyAndClearExpectations(ref_factory.get());

  // Destroy the second LayerTreeHost. The sequence generated by its
  // SurfaceLayer must be satisfied and no new sequences must be required.
  EXPECT_CALL(*ref_factory, SatisfySequence(Eq(expected_seq2))).Times(1);
  layer_tree_host2->SetRootLayer(nullptr);
  layer_tree_host2.reset();
  animation_host2 = nullptr;
  base::RunLoop().RunUntilIdle();
  testing::Mock::VerifyAndClearExpectations(ref_factory.get());

  // Destroy the first LayerTreeHost. The sequence generated by its
  // SurfaceLayer must be satisfied and no new sequences must be required.
  EXPECT_CALL(*ref_factory, SatisfySequence(expected_seq1)).Times(1);
  EXPECT_CALL(*ref_factory, RequireSequence(_, _)).Times(0);
  layer_tree_host_->SetRootLayer(nullptr);
  layer_tree_host_.reset();
  base::RunLoop().RunUntilIdle();
  testing::Mock::VerifyAndClearExpectations(ref_factory.get());
}

// This test verifies that SurfaceLayer properties are pushed across to
// SurfaceLayerImpl.
TEST_F(SurfaceLayerTest, PushProperties) {
  // We use a nice mock here because we are not really interested in calls to
  // MockSurfaceReferenceFactory and we don't want warnings printed.
  scoped_refptr<viz::SurfaceReferenceFactory> ref_factory =
      new testing::NiceMock<MockSurfaceReferenceFactory>();

  scoped_refptr<SurfaceLayer> layer = SurfaceLayer::Create(ref_factory);
  layer_tree_host_->SetRootLayer(layer);
  viz::SurfaceId primary_id(
      kArbitraryFrameSinkId,
      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
  layer->SetPrimarySurfaceId(primary_id, 1u);
  layer->SetPrimarySurfaceId(primary_id, 2u);
  layer->SetFallbackSurfaceId(primary_id);
  layer->SetBackgroundColor(SK_ColorBLUE);
  layer->SetStretchContentToFillBounds(true);

  EXPECT_TRUE(layer_tree_host_->needs_surface_ids_sync());
  EXPECT_EQ(layer_tree_host_->SurfaceLayerIds().size(), 1u);

  // Verify that pending tree has no surface ids already.
  EXPECT_FALSE(host_impl_.pending_tree()->needs_surface_ids_sync());
  EXPECT_EQ(host_impl_.pending_tree()->SurfaceLayerIds().size(), 0u);

  std::unique_ptr<SurfaceLayerImpl> layer_impl =
      SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer->id());
  SynchronizeTrees();

  // Verify that pending tree received the surface id and also has
  // needs_surface_ids_sync set to true as it needs to sync with active tree.
  EXPECT_TRUE(host_impl_.pending_tree()->needs_surface_ids_sync());
  EXPECT_EQ(host_impl_.pending_tree()->SurfaceLayerIds().size(), 1u);

  // Verify we have reset the state on layer tree host.
  EXPECT_FALSE(layer_tree_host_->needs_surface_ids_sync());

  // Verify that the primary and fallback SurfaceIds are pushed through.
  EXPECT_EQ(primary_id, layer_impl->primary_surface_id());
  EXPECT_EQ(primary_id, layer_impl->fallback_surface_id());
  EXPECT_EQ(SK_ColorBLUE, layer_impl->background_color());
  EXPECT_TRUE(layer_impl->stretch_content_to_fill_bounds());
  EXPECT_EQ(2u, layer_impl->deadline_in_frames());

  viz::SurfaceId fallback_id(
      kArbitraryFrameSinkId,
      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
  layer->SetFallbackSurfaceId(fallback_id);
  layer->SetBackgroundColor(SK_ColorGREEN);
  layer->SetStretchContentToFillBounds(false);

  // Verify that fallback surface id is not recorded on the layer tree host as
  // surface synchronization is not enabled.
  EXPECT_TRUE(layer_tree_host_->needs_surface_ids_sync());
  EXPECT_EQ(layer_tree_host_->SurfaceLayerIds().size(), 1u);

  SynchronizeTrees();

  EXPECT_EQ(host_impl_.pending_tree()->SurfaceLayerIds().size(), 1u);

  // Verify that the primary viz::SurfaceId stays the same and the new
  // fallback viz::SurfaceId is pushed through.
  EXPECT_EQ(primary_id, layer_impl->primary_surface_id());
  EXPECT_EQ(fallback_id, layer_impl->fallback_surface_id());
  EXPECT_EQ(SK_ColorGREEN, layer_impl->background_color());
  EXPECT_EQ(base::nullopt, layer_impl->deadline_in_frames());
  EXPECT_FALSE(layer_impl->stretch_content_to_fill_bounds());
}

// This test verifies the list of surface ids is correct when there are cloned
// surface layers. This emulates the flow of maximize and minimize animations on
// Chrome OS.
TEST_F(SurfaceLayerTest, CheckSurfaceReferencesForClonedLayer) {
  // We use a nice mock here because we are not really interested in calls to
  // MockSurfaceReferenceFactory and we don't want warnings printed.
  scoped_refptr<viz::SurfaceReferenceFactory> ref_factory =
      new testing::NiceMock<MockSurfaceReferenceFactory>();

  const viz::SurfaceId old_surface_id(
      kArbitraryFrameSinkId,
      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));

  // This layer will always contain the old surface id and will be deleted when
  // animation is done.
  scoped_refptr<SurfaceLayer> layer1 = SurfaceLayer::Create(ref_factory);
  layer1->SetLayerTreeHost(layer_tree_host_.get());
  layer1->SetPrimarySurfaceId(old_surface_id, base::nullopt);
  layer1->SetFallbackSurfaceId(old_surface_id);

  // This layer will eventually be switched be switched to show the new surface
  // id and will be retained when animation is done.
  scoped_refptr<SurfaceLayer> layer2 = SurfaceLayer::Create(ref_factory);
  layer2->SetLayerTreeHost(layer_tree_host_.get());
  layer2->SetPrimarySurfaceId(old_surface_id, base::nullopt);
  layer2->SetFallbackSurfaceId(old_surface_id);

  std::unique_ptr<SurfaceLayerImpl> layer_impl1 =
      SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer1->id());
  std::unique_ptr<SurfaceLayerImpl> layer_impl2 =
      SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer2->id());

  SynchronizeTrees();

  // Verify that only |old_surface_id| is going to be referenced.
  EXPECT_THAT(layer_tree_host_->SurfaceLayerIds(), ElementsAre(old_surface_id));
  EXPECT_THAT(host_impl_.pending_tree()->SurfaceLayerIds(),
              ElementsAre(old_surface_id));

  const viz::SurfaceId new_surface_id(
      kArbitraryFrameSinkId,
      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));

  // Switch the new layer to use |new_surface_id|.
  layer2->SetPrimarySurfaceId(new_surface_id, base::nullopt);
  layer2->SetFallbackSurfaceId(new_surface_id);

  SynchronizeTrees();

  // Verify that both surface ids are going to be referenced.
  EXPECT_THAT(layer_tree_host_->SurfaceLayerIds(),
              ElementsAre(old_surface_id, new_surface_id));
  EXPECT_THAT(host_impl_.pending_tree()->SurfaceLayerIds(),
              ElementsAre(old_surface_id, new_surface_id));

  // Unparent the old layer like it's being destroyed at the end of animation.
  layer1->SetLayerTreeHost(nullptr);

  SynchronizeTrees();

  // Verify that only |new_surface_id| is going to be referenced.
  EXPECT_THAT(layer_tree_host_->SurfaceLayerIds(), ElementsAre(new_surface_id));
  EXPECT_THAT(host_impl_.pending_tree()->SurfaceLayerIds(),
              ElementsAre(new_surface_id));

  // Cleanup for destruction.
  layer2->SetLayerTreeHost(nullptr);
}

// This test verifies LayerTreeHost::needs_surface_ids_sync() is correct when
// there are cloned surface layers.
TEST_F(SurfaceLayerTest, CheckNeedsSurfaceIdsSyncForClonedLayers) {
  // We use a nice mock here because we are not really interested in calls to
  // MockSurfaceReferenceFactory and we don't want warnings printed.
  scoped_refptr<viz::SurfaceReferenceFactory> ref_factory =
      new testing::NiceMock<MockSurfaceReferenceFactory>();

  const viz::SurfaceId surface_id(
      kArbitraryFrameSinkId,
      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));

  scoped_refptr<SurfaceLayer> layer1 = SurfaceLayer::Create(ref_factory);
  layer1->SetLayerTreeHost(layer_tree_host_.get());
  layer1->SetPrimarySurfaceId(surface_id, base::nullopt);
  layer1->SetFallbackSurfaceId(surface_id);

  // Verify the surface id is in SurfaceLayerIds() and needs_surface_ids_sync()
  // is true.
  EXPECT_TRUE(layer_tree_host_->needs_surface_ids_sync());
  EXPECT_THAT(layer_tree_host_->SurfaceLayerIds(), SizeIs(1));

  std::unique_ptr<SurfaceLayerImpl> layer_impl1 =
      SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer1->id());
  SynchronizeTrees();

  // After syncchronizing trees verify needs_surface_ids_sync() is false.
  EXPECT_FALSE(layer_tree_host_->needs_surface_ids_sync());

  // Create the second layer that is a clone of the first.
  scoped_refptr<SurfaceLayer> layer2 = SurfaceLayer::Create(ref_factory);
  layer2->SetLayerTreeHost(layer_tree_host_.get());
  layer2->SetPrimarySurfaceId(surface_id, base::nullopt);
  layer2->SetFallbackSurfaceId(surface_id);

  // Verify that after creating the second layer with the same surface id that
  // needs_surface_ids_sync() is still false.
  EXPECT_FALSE(layer_tree_host_->needs_surface_ids_sync());
  EXPECT_THAT(layer_tree_host_->SurfaceLayerIds(), SizeIs(1));

  std::unique_ptr<SurfaceLayerImpl> layer_impl2 =
      SurfaceLayerImpl::Create(host_impl_.pending_tree(), layer2->id());
  SynchronizeTrees();

  // Verify needs_surface_ids_sync() is still false after synchronizing trees.
  EXPECT_FALSE(layer_tree_host_->needs_surface_ids_sync());

  // Destroy one of the layers, leaving one layer with the surface id.
  layer1->SetLayerTreeHost(nullptr);

  // Verify needs_surface_ids_sync() is still false.
  EXPECT_FALSE(layer_tree_host_->needs_surface_ids_sync());

  // Destroy the last layer, this should change the set of layer surface ids.
  layer2->SetLayerTreeHost(nullptr);

  // Verify SurfaceLayerIds() is empty and needs_surface_ids_sync() is true.
  EXPECT_TRUE(layer_tree_host_->needs_surface_ids_sync());
  EXPECT_THAT(layer_tree_host_->SurfaceLayerIds(), SizeIs(0));
}

// Check that viz::SurfaceSequence is sent through swap promise.
class SurfaceLayerSwapPromise : public LayerTreeTest {
 public:
  SurfaceLayerSwapPromise()
      : commit_count_(0), sequence_was_satisfied_(false) {}

  void BeginTest() override {
    layer_tree_host()->GetSurfaceSequenceGenerator()->set_frame_sink_id(
        viz::FrameSinkId(1, 1));
    ref_factory_ = new testing::StrictMock<MockSurfaceReferenceFactory>();

    // Create a SurfaceLayer but don't add it to the tree yet. No sequence
    // should be required / satisfied.
    EXPECT_CALL(*ref_factory_, SatisfySequence(_)).Times(0);
    EXPECT_CALL(*ref_factory_, RequireSequence(_, _)).Times(0);
    layer_ = SurfaceLayer::Create(ref_factory_);
    viz::SurfaceId surface_id(kArbitraryFrameSinkId,
                              viz::LocalSurfaceId(1, kArbitraryToken));
    layer_->SetPrimarySurfaceId(surface_id, base::nullopt);
    layer_->SetFallbackSurfaceId(surface_id);
    testing::Mock::VerifyAndClearExpectations(ref_factory_.get());

    // Add the layer to the tree. A sequence must be required.
    viz::SurfaceSequence expected_seq(kArbitraryFrameSinkId, 1u);
    viz::SurfaceId expected_id(kArbitraryFrameSinkId,
                               viz::LocalSurfaceId(1, kArbitraryToken));
    EXPECT_CALL(*ref_factory_, SatisfySequence(_)).Times(0);
    EXPECT_CALL(*ref_factory_,
                RequireSequence(Eq(expected_id), Eq(expected_seq)))
        .Times(1);
    layer_tree_host()->SetRootLayer(layer_);
    testing::Mock::VerifyAndClearExpectations(ref_factory_.get());

    // By the end of the test, the required sequence must be satisfied and no
    // more sequence must be required.
    EXPECT_CALL(*ref_factory_, SatisfySequence(Eq(expected_seq))).Times(1);
    EXPECT_CALL(*ref_factory_, RequireSequence(_, _)).Times(0);

    gfx::Size bounds(100, 100);
    layer_tree_host()->SetViewportSize(bounds);

    blank_layer_ = SolidColorLayer::Create();
    blank_layer_->SetIsDrawable(true);
    blank_layer_->SetBounds(gfx::Size(10, 10));

    PostSetNeedsCommitToMainThread();
  }

  virtual void ChangeTree() = 0;

  void DidCommitAndDrawFrame() override {
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(&SurfaceLayerSwapPromise::ChangeTree,
                                  base::Unretained(this)));
  }

  void AfterTest() override {}

 protected:
  int commit_count_;
  bool sequence_was_satisfied_;
  scoped_refptr<SurfaceLayer> layer_;
  scoped_refptr<Layer> blank_layer_;
  scoped_refptr<MockSurfaceReferenceFactory> ref_factory_;

  const base::UnguessableToken kArbitraryToken =
      base::UnguessableToken::Create();
};

// Check that viz::SurfaceSequence is sent through swap promise.
class SurfaceLayerSwapPromiseWithDraw : public SurfaceLayerSwapPromise {
 public:
  void ChangeTree() override {
    ++commit_count_;
    switch (commit_count_) {
      case 1:
        // Remove SurfaceLayer from tree to cause SwapPromise to be created.
        layer_tree_host()->SetRootLayer(blank_layer_);
        break;
      case 2:
        EndTest();
        break;
      default:
        NOTREACHED();
        break;
    }
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(SurfaceLayerSwapPromiseWithDraw);

// Check that viz::SurfaceSequence is sent through swap promise and resolved
// when swap fails.
class SurfaceLayerSwapPromiseWithoutDraw : public SurfaceLayerSwapPromise {
 public:
  SurfaceLayerSwapPromiseWithoutDraw() : SurfaceLayerSwapPromise() {}

  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
                                   LayerTreeHostImpl::FrameData* frame,
                                   DrawResult draw_result) override {
    return DRAW_ABORTED_MISSING_HIGH_RES_CONTENT;
  }

  void ChangeTree() override {
    ++commit_count_;
    switch (commit_count_) {
      case 1:
        // Remove SurfaceLayer from tree to cause SwapPromise to be created.
        layer_tree_host()->SetRootLayer(blank_layer_);
        break;
      case 2:
        layer_tree_host()->SetNeedsCommit();
        break;
      default:
        EndTest();
        break;
    }
  }
};

MULTI_THREAD_TEST_F(SurfaceLayerSwapPromiseWithoutDraw);

}  // namespace
}  // namespace cc
