// 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 <set>
#include <vector>

#include "base/message_loop/message_loop_proxy.h"
#include "cc/layers/solid_color_layer.h"
#include "cc/layers/surface_layer.h"
#include "cc/test/fake_impl_proxy.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_shared_bitmap_manager.h"
#include "cc/trees/layer_tree_host.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cc {
namespace {

class SurfaceLayerTest : public testing::Test {
 public:
  SurfaceLayerTest()
      : fake_client_(
            FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {}

 protected:
  virtual void SetUp() {
    layer_tree_host_ = FakeLayerTreeHost::Create(&fake_client_);
    layer_tree_host_->SetViewportSize(gfx::Size(10, 10));
  }

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

  scoped_ptr<FakeLayerTreeHost> layer_tree_host_;
  FakeLayerTreeHostClient fake_client_;
  TestSharedBitmapManager shared_bitmap_manager_;
};

void SatisfyCallback(SurfaceSequence* out, SurfaceSequence in) {
  *out = in;
}

void RequireCallback(SurfaceId* out_id,
                     std::set<SurfaceSequence>* out,
                     SurfaceId in_id,
                     SurfaceSequence in) {
  *out_id = in_id;
  out->insert(in);
}

// Check that one surface can be referenced by multiple LayerTreeHosts, and
// each will create its own SurfaceSequence that's satisfied on destruction.
TEST_F(SurfaceLayerTest, MultipleFramesOneSurface) {
  SurfaceSequence blank_change;  // Receives sequence if commit doesn't happen.

  SurfaceId required_id;
  std::set<SurfaceSequence> required_seq;
  scoped_refptr<SurfaceLayer> layer(SurfaceLayer::Create(
      base::Bind(&SatisfyCallback, &blank_change),
      base::Bind(&RequireCallback, &required_id, &required_seq)));
  layer->SetSurfaceId(SurfaceId(1), 1.f, gfx::Size(1, 1));
  layer_tree_host_->set_surface_id_namespace(1);
  layer_tree_host_->SetRootLayer(layer);

  scoped_ptr<FakeLayerTreeHost> layer_tree_host2 =
      FakeLayerTreeHost::Create(&fake_client_);
  scoped_refptr<SurfaceLayer> layer2(SurfaceLayer::Create(
      base::Bind(&SatisfyCallback, &blank_change),
      base::Bind(&RequireCallback, &required_id, &required_seq)));
  layer2->SetSurfaceId(SurfaceId(1), 1.f, gfx::Size(1, 1));
  layer_tree_host2->set_surface_id_namespace(2);
  layer_tree_host2->SetRootLayer(layer2);

  // Layers haven't been removed, so no sequence should be satisfied.
  EXPECT_TRUE(blank_change.is_null());

  SurfaceSequence expected1(1u, 1u);
  SurfaceSequence expected2(2u, 1u);

  layer_tree_host2->SetRootLayer(nullptr);
  layer_tree_host2.reset();

  // Layer was removed so sequence from second LayerTreeHost should be
  // satisfied.
  EXPECT_TRUE(blank_change == expected2);

  // Set of sequences that need to be satisfied should include sequences from
  // both trees.
  EXPECT_TRUE(required_id == SurfaceId(1));
  EXPECT_EQ(2u, required_seq.size());
  EXPECT_TRUE(required_seq.count(expected1));
  EXPECT_TRUE(required_seq.count(expected2));

  layer_tree_host_->SetRootLayer(nullptr);
  layer_tree_host_.reset();

  // Layer was removed so sequence from first LayerTreeHost should be
  // satisfied.
  EXPECT_TRUE(blank_change == expected1);

  // No more SurfaceSequences should have been generated that need to have be
  // satisfied.
  EXPECT_EQ(2u, required_seq.size());
}

static void CalcDrawProps(FakeLayerTreeHost* host, float device_scale_factor) {
  RenderSurfaceLayerList render_surface_layer_list;
  LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs(
      host->root_layer(), gfx::Size(500, 500), &render_surface_layer_list);
  inputs.device_scale_factor = device_scale_factor;
  LayerTreeHostCommon::CalculateDrawProperties(&inputs);
}

// Check that setting content scale on the surface works.
TEST_F(SurfaceLayerTest, ScaleSurface) {
  SurfaceSequence blank_change;
  SurfaceId required_id;
  std::set<SurfaceSequence> required_seq;
  scoped_refptr<SurfaceLayer> layer(SurfaceLayer::Create(
      base::Bind(&SatisfyCallback, &blank_change),
      base::Bind(&RequireCallback, &required_id, &required_seq)));
  gfx::Size surface_size(10, 15);
  layer->SetSurfaceId(SurfaceId(1), 2.f, surface_size);
  layer->SetBounds(gfx::Size(25, 45));
  layer_tree_host_->SetRootLayer(layer);

  CalcDrawProps(layer_tree_host_.get(), 5.f);
  EXPECT_EQ(2.f, layer->contents_scale_x());
  EXPECT_EQ(2.f, layer->contents_scale_y());
  EXPECT_EQ(surface_size.ToString(), layer->content_bounds().ToString());

  layer_tree_host_->SetRootLayer(nullptr);
  layer_tree_host_.reset();
}

// Check that 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()->set_surface_id_namespace(1);
    layer_ = SurfaceLayer::Create(
        base::Bind(&SatisfyCallback, &satisfied_sequence_),
        base::Bind(&RequireCallback, &required_id_, &required_set_));
    layer_->SetSurfaceId(SurfaceId(1), 1.f, gfx::Size(1, 1));

    // Layer hasn't been added to tree so no SurfaceSequence generated yet.
    EXPECT_EQ(0u, required_set_.size());

    layer_tree_host()->SetRootLayer(layer_);

    // Should have SurfaceSequence from first tree.
    SurfaceSequence expected(1u, 1u);
    EXPECT_TRUE(required_id_ == SurfaceId(1));
    EXPECT_EQ(1u, required_set_.size());
    EXPECT_TRUE(required_set_.count(expected));

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

  void DidCommit() override {
    base::MessageLoopProxy::current()->PostTask(
        FROM_HERE, base::Bind(&SurfaceLayerSwapPromise::ChangeTree,
                              base::Unretained(this)));
  }

  void ChangeTree() {
    ++commit_count_;
    switch (commit_count_) {
      case 1:
        // Remove SurfaceLayer from tree to cause SwapPromise to be created.
        blank_layer_ = SolidColorLayer::Create();
        blank_layer_->SetIsDrawable(true);
        blank_layer_->SetBounds(gfx::Size(10, 10));
        layer_tree_host()->SetRootLayer(blank_layer_);
        break;
      case 2:
        break;
      default:
        NOTREACHED();
        break;
    }
  }

  void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
    EXPECT_TRUE(result);
    std::vector<uint32_t>& satisfied =
        output_surface()->last_sent_frame().metadata.satisfies_sequences;
    EXPECT_LE(satisfied.size(), 1u);
    if (satisfied.size() == 1) {
      // Eventually the one SurfaceSequence should be satisfied, but only
      // after the layer was removed from the tree, and only once.
      EXPECT_EQ(1u, satisfied[0]);
      EXPECT_LE(1, commit_count_);
      EXPECT_FALSE(sequence_was_satisfied_);
      sequence_was_satisfied_ = true;
      EndTest();
    }
  }

  void AfterTest() override {
    EXPECT_TRUE(required_id_ == SurfaceId(1));
    EXPECT_EQ(1u, required_set_.size());
    // Sequence should have been satisfied through Swap, not with the
    // callback.
    EXPECT_TRUE(satisfied_sequence_.is_null());
  }

 private:
  int commit_count_;
  bool sequence_was_satisfied_;
  scoped_refptr<SurfaceLayer> layer_;
  scoped_refptr<Layer> blank_layer_;
  SurfaceSequence satisfied_sequence_;

  SurfaceId required_id_;
  std::set<SurfaceSequence> required_set_;
};

// TODO(jbauman): Reenable on single thread once http://crbug.com/421923 is
// fixed.
MULTI_THREAD_TEST_F(SurfaceLayerSwapPromise);

}  // namespace
}  // namespace cc
