// 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/output/copy_output_request.h"
#include "cc/output/copy_output_result.h"
#include "cc/test/layer_tree_test.h"
#include "cc/test/test_occlusion_tracker.h"

namespace cc {
namespace {

class TestLayer : public Layer {
 public:
  static scoped_refptr<TestLayer> Create() {
    return make_scoped_refptr(new TestLayer());
  }

  virtual bool Update(ResourceUpdateQueue* update_queue,
                      const OcclusionTracker<Layer>* occlusion) override {
    if (!occlusion)
      return false;

    const TestOcclusionTracker<Layer>* test_occlusion =
        static_cast<const TestOcclusionTracker<Layer>*>(occlusion);
    occlusion_ = UnionSimpleEnclosedRegions(
        test_occlusion->occlusion_from_inside_target(),
        test_occlusion->occlusion_from_outside_target());
    return false;
  }

  const SimpleEnclosedRegion& occlusion() const { return occlusion_; }
  const SimpleEnclosedRegion& expected_occlusion() const {
    return expected_occlusion_;
  }
  void set_expected_occlusion(const gfx::Rect& occlusion) {
    expected_occlusion_ = SimpleEnclosedRegion(occlusion);
  }

 private:
  TestLayer() : Layer() {
    SetIsDrawable(true);
  }
  virtual ~TestLayer() {}

  SimpleEnclosedRegion occlusion_;
  SimpleEnclosedRegion expected_occlusion_;
};

class LayerTreeHostOcclusionTest : public LayerTreeTest {
 public:
  LayerTreeHostOcclusionTest()
      : root_(TestLayer::Create()),
        child_(TestLayer::Create()),
        child2_(TestLayer::Create()),
        grand_child_(TestLayer::Create()),
        mask_(TestLayer::Create()) {
  }

  virtual void BeginTest() override {
    PostSetNeedsCommitToMainThread();
  }

  virtual void DidCommit() override {
    TestLayer* root = static_cast<TestLayer*>(layer_tree_host()->root_layer());
    VerifyOcclusion(root);

    EndTest();
  }

  virtual void AfterTest() override {}

  void VerifyOcclusion(TestLayer* layer) const {
    EXPECT_EQ(layer->expected_occlusion().ToString(),
              layer->occlusion().ToString());

    for (size_t i = 0; i < layer->children().size(); ++i) {
      TestLayer* child = static_cast<TestLayer*>(layer->children()[i].get());
      VerifyOcclusion(child);
    }
  }

  void SetLayerPropertiesForTesting(TestLayer* layer,
                                    TestLayer* parent,
                                    const gfx::Transform& transform,
                                    const gfx::PointF& position,
                                    const gfx::Size& bounds,
                                    bool opaque) const {
    layer->RemoveAllChildren();
    if (parent)
      parent->AddChild(layer);
    layer->SetTransform(transform);
    layer->SetPosition(position);
    layer->SetBounds(bounds);
    layer->SetContentsOpaque(opaque);
  }

 protected:
  virtual void InitializeSettings(LayerTreeSettings* settings) override {
    settings->minimum_occlusion_tracking_size = gfx::Size();
  }

  scoped_refptr<TestLayer> root_;
  scoped_refptr<TestLayer> child_;
  scoped_refptr<TestLayer> child2_;
  scoped_refptr<TestLayer> grand_child_;
  scoped_refptr<TestLayer> mask_;

  gfx::Transform identity_matrix_;
};


class LayerTreeHostOcclusionTestOcclusionSurfaceClipping
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    // The child layer is a surface and the grand_child is opaque, but clipped
    // to the child and root
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), identity_matrix_,
        gfx::PointF(10.f, 10.f), gfx::Size(500, 500), false);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);

    child_->SetMasksToBounds(true);
    child_->SetForceRenderSurface(true);

    child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
    root_->set_expected_occlusion(gfx::Rect(10, 10, 10, 190));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostOcclusionTestOcclusionSurfaceClipping);

class LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    // If the child layer is opaque, then it adds to the occlusion seen by the
    // root_.
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), identity_matrix_,
        gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);

    child_->SetMasksToBounds(true);
    child_->SetForceRenderSurface(true);

    child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
    root_->set_expected_occlusion(gfx::Rect(10, 10, 190, 190));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostOcclusionTestOcclusionSurfaceClippingOpaque);

class LayerTreeHostOcclusionTestOcclusionTwoChildren
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    // Add a second child to the root layer and the regions should merge
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), identity_matrix_,
        gfx::PointF(10.f, 10.f), gfx::Size(500, 500), false);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    SetLayerPropertiesForTesting(
        child2_.get(), root_.get(), identity_matrix_,
        gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);

    child_->SetMasksToBounds(true);
    child_->SetForceRenderSurface(true);

    grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
    child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
    root_->set_expected_occlusion(gfx::Rect(10, 10, 20, 190));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostOcclusionTestOcclusionTwoChildren);

class LayerTreeHostOcclusionTestOcclusionMask
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    // If the child layer has a mask on it, then it shouldn't contribute to
    // occlusion on stuff below it.
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    SetLayerPropertiesForTesting(
        child2_.get(), root_.get(), identity_matrix_,
        gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), identity_matrix_,
        gfx::PointF(20.f, 20.f), gfx::Size(500, 500), true);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(-10.f, -10.f), gfx::Size(500, 500), true);

    child_->SetMasksToBounds(true);
    child_->SetForceRenderSurface(true);
    child_->SetMaskLayer(mask_.get());

    child_->set_expected_occlusion(gfx::Rect(0, 0, 180, 180));
    root_->set_expected_occlusion(gfx::Rect(10, 10, 190, 190));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionMask);

class LayerTreeHostOcclusionTestOcclusionMaskBelowOcclusion
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    // If the child layer with a mask is below child2, then child2 should
    // contribute to occlusion on everything, and child shouldn't contribute
    // to the root_.
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), identity_matrix_,
        gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    SetLayerPropertiesForTesting(
        child2_.get(), root_.get(), identity_matrix_,
        gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);

    child_->SetMasksToBounds(true);
    child_->SetForceRenderSurface(true);
    child_->SetMaskLayer(mask_.get());

    grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
    child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
    root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostOcclusionTestOcclusionMaskBelowOcclusion);

class LayerTreeHostOcclusionTestOcclusionOpacity
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    // If the child layer has a non-opaque opacity, then it shouldn't
    // contribute to occlusion on stuff below it
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    SetLayerPropertiesForTesting(
        child2_.get(), root_.get(), identity_matrix_,
        gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), identity_matrix_,
        gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);

    child_->SetMasksToBounds(true);
    child_->SetForceRenderSurface(true);
    child_->SetOpacity(0.5f);

    child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
    root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionOpacity);

class LayerTreeHostOcclusionTestOcclusionOpacityBelowOcclusion
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    // If the child layer with non-opaque opacity is below child2, then
    // child2 should contribute to occlusion on everything, and child shouldn't
    // contribute to the root_.
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), identity_matrix_,
        gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    SetLayerPropertiesForTesting(
        child2_.get(), root_.get(), identity_matrix_,
        gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);

    child_->SetMasksToBounds(true);
    child_->SetForceRenderSurface(true);
    child_->SetOpacity(0.5f);

    grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
    child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
    root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostOcclusionTestOcclusionOpacityBelowOcclusion);

class LayerTreeHostOcclusionTestOcclusionBlending
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    // If the child layer has a blend mode, then it shouldn't
    // contribute to occlusion on stuff below it
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    SetLayerPropertiesForTesting(
        child2_.get(), root_.get(), identity_matrix_,
        gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), identity_matrix_,
        gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);

    child_->SetMasksToBounds(true);
    child_->SetBlendMode(SkXfermode::kMultiply_Mode);
    child_->SetForceRenderSurface(true);

    child_->set_expected_occlusion(gfx::Rect(0, 0, 10, 190));
    root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionBlending);

class LayerTreeHostOcclusionTestOcclusionBlendingBelowOcclusion
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    // If the child layer with a blend mode is below child2, then
    // child2 should contribute to occlusion on everything, and child shouldn't
    // contribute to the root_.
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), identity_matrix_,
        gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(-10.f, -10.f), gfx::Size(20, 500), true);
    SetLayerPropertiesForTesting(
        child2_.get(), root_.get(), identity_matrix_,
        gfx::PointF(20.f, 10.f), gfx::Size(10, 500), true);

    child_->SetMasksToBounds(true);
    child_->SetBlendMode(SkXfermode::kMultiply_Mode);

    grand_child_->set_expected_occlusion(gfx::Rect(10, 0, 10, 190));
    child_->set_expected_occlusion(gfx::Rect(0, 0, 20, 190));
    root_->set_expected_occlusion(gfx::Rect(20, 10, 10, 190));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostOcclusionTestOcclusionBlendingBelowOcclusion);

class LayerTreeHostOcclusionTestOcclusionOpacityFilter
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    FilterOperations filters;
    filters.Append(FilterOperation::CreateOpacityFilter(0.5f));

    // If the child layer has a filter that changes alpha values, and is below
    // child2, then child2 should contribute to occlusion on everything,
    // and child shouldn't contribute to the root
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    SetLayerPropertiesForTesting(child_.get(),
                                 root_.get(),
                                 identity_matrix_,
                                 gfx::PointF(0.f, 0.f),
                                 gfx::Size(500, 500),
                                 true);
    SetLayerPropertiesForTesting(grand_child_.get(),
                                 child_.get(),
                                 identity_matrix_,
                                 gfx::PointF(0.f, 0.f),
                                 gfx::Size(500, 500),
                                 true);
    SetLayerPropertiesForTesting(child2_.get(),
                                 root_.get(),
                                 identity_matrix_,
                                 gfx::PointF(10.f, 10.f),
                                 gfx::Size(30, 30),
                                 true);

    child_->SetMasksToBounds(true);
    child_->SetFilters(filters);

    // child2_ occludes grand_child_, showing it does occlude inside child_'s
    // subtree.
    grand_child_->set_expected_occlusion(gfx::Rect(10, 10, 30, 30));
    // grand_child_ occludes child_, showing there is more occlusion in
    // child_'s subtree.
    child_->set_expected_occlusion(gfx::Rect(0, 0, 200, 200));
    // child2_'s occlusion reaches the root, but child_'s subtree does not.
    root_->set_expected_occlusion(gfx::Rect(10, 10, 30, 30));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostOcclusionTestOcclusionOpacityFilter);

class LayerTreeHostOcclusionTestOcclusionBlurFilter
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    gfx::Transform child_transform;
    child_transform.Translate(250.0, 250.0);
    child_transform.Rotate(90.0);
    child_transform.Translate(-250.0, -250.0);

    FilterOperations filters;
    filters.Append(FilterOperation::CreateBlurFilter(10.f));

    // If the child layer has a filter that moves pixels/changes alpha, and is
    // below child2, then child should not inherit occlusion from outside its
    // subtree, and should not contribute to the root
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(0.f, 0.f), gfx::Size(200, 200), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), child_transform,
        gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true);
    SetLayerPropertiesForTesting(
        child2_.get(), root_.get(), identity_matrix_,
        gfx::PointF(10.f, 70.f), gfx::Size(500, 500), true);

    child_->SetMasksToBounds(true);
    child_->SetFilters(filters);

    child_->set_expected_occlusion(gfx::Rect(10, 330, 160, 170));
    root_->set_expected_occlusion(gfx::Rect(10, 70, 190, 130));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(
    LayerTreeHostOcclusionTestOcclusionBlurFilter);

class LayerTreeHostOcclusionTestOcclusionCopyRequest
    : public LayerTreeHostOcclusionTest {
 public:
  static void CopyOutputCallback(scoped_ptr<CopyOutputResult> result) {}

  virtual void SetupTree() override {
    // If the child layer has copy request, and is below child2,
    // then child should not inherit occlusion from outside its subtree.
    // The child layer will still receive occlusion from inside, and
    // the root layer will recive occlusion from child.
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(), gfx::Size(100, 100), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), identity_matrix_,
        gfx::PointF(), gfx::Size(75, 75), true);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(), gfx::Size(75, 50), true);
    SetLayerPropertiesForTesting(
        child2_.get(), root_.get(), identity_matrix_,
        gfx::PointF(0.f, 25.f), gfx::Size(75, 75), true);

    child_->RequestCopyOfOutput(CopyOutputRequest::CreateBitmapRequest(
        base::Bind(&CopyOutputCallback)));
    EXPECT_TRUE(child_->HasCopyRequest());

    child_->set_expected_occlusion(gfx::Rect(0, 0, 75, 50));
    root_->set_expected_occlusion(gfx::Rect(0, 0, 75, 100));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionCopyRequest);

class LayerTreeHostOcclusionTestOcclusionReplica
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    // If the child layer has copy request, and is below child2,
    // then child should not inherit occlusion from outside its subtree.
    // The child layer will still receive occlusion from inside, and
    // the root layer will recive occlusion from child.
    SetLayerPropertiesForTesting(
        root_.get(), NULL, identity_matrix_,
        gfx::PointF(), gfx::Size(100, 100), true);
    SetLayerPropertiesForTesting(
        child_.get(), root_.get(), identity_matrix_,
        gfx::PointF(), gfx::Size(75, 75), true);
    SetLayerPropertiesForTesting(
        grand_child_.get(), child_.get(), identity_matrix_,
        gfx::PointF(), gfx::Size(75, 50), true);
    SetLayerPropertiesForTesting(
        child2_.get(), root_.get(), identity_matrix_,
        gfx::PointF(0.f, 25.f), gfx::Size(75, 75), true);

    scoped_refptr<Layer> replica_layer(Layer::Create());
    child_->SetReplicaLayer(replica_layer.get());
    EXPECT_TRUE(child_->has_replica());

    child_->set_expected_occlusion(gfx::Rect(0, 0, 75, 50));
    root_->set_expected_occlusion(gfx::Rect(0, 0, 75, 100));

    layer_tree_host()->SetRootLayer(root_);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestOcclusionReplica);

class LayerTreeHostOcclusionTestManySurfaces
    : public LayerTreeHostOcclusionTest {
 public:
  virtual void SetupTree() override {
    // We create enough RenderSurfaces that it will trigger Vector reallocation
    // while computing occlusion.
    std::vector<scoped_refptr<TestLayer> > layers;
    int num_surfaces = 200;
    int root_width = 400;
    int root_height = 400;

    for (int i = 0; i < num_surfaces; ++i) {
      layers.push_back(TestLayer::Create());
      if (i == 0) {
        SetLayerPropertiesForTesting(
            layers.back().get(), NULL, identity_matrix_,
            gfx::PointF(0.f, 0.f),
            gfx::Size(root_width, root_height), true);
      } else {
        SetLayerPropertiesForTesting(
            layers.back().get(), layers[layers.size() - 2].get(),
            identity_matrix_,
            gfx::PointF(1.f, 1.f),
            gfx::Size(root_width-i, root_height-i), true);
        layers.back()->SetForceRenderSurface(true);
      }
    }

    for (int i = 1; i < num_surfaces; ++i) {
      scoped_refptr<TestLayer> child = TestLayer::Create();
      SetLayerPropertiesForTesting(
          child.get(), layers[i].get(), identity_matrix_,
          gfx::PointF(0.f, 0.f), gfx::Size(root_width, root_height), false);
    }

    for (int i = 0; i < num_surfaces-1; ++i) {
      gfx::Rect expected_occlusion(1, 1, root_width-i-1, root_height-i-1);
      layers[i]->set_expected_occlusion(expected_occlusion);
    }

    layer_tree_host()->SetRootLayer(layers[0]);
    LayerTreeTest::SetupTree();
  }
};

SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestManySurfaces);

}  // namespace
}  // namespace cc
