1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "cc/trees/layer_tree_host.h"
6
7#include "cc/test/fake_content_layer_client.h"
8#include "cc/test/fake_picture_layer.h"
9#include "cc/test/fake_picture_layer_impl.h"
10#include "cc/test/layer_tree_test.h"
11#include "cc/trees/layer_tree_impl.h"
12
13namespace cc {
14namespace {
15
16// These tests deal with picture layers.
17class LayerTreeHostPictureTest : public LayerTreeTest {
18 protected:
19  virtual void InitializeSettings(LayerTreeSettings* settings) OVERRIDE {
20    // PictureLayer can only be used with impl side painting enabled.
21    settings->impl_side_painting = true;
22  }
23};
24
25class LayerTreeHostPictureTestTwinLayer
26    : public LayerTreeHostPictureTest {
27  virtual void SetupTree() OVERRIDE {
28    LayerTreeHostPictureTest::SetupTree();
29
30    scoped_refptr<FakePictureLayer> picture =
31        FakePictureLayer::Create(&client_);
32    layer_tree_host()->root_layer()->AddChild(picture);
33  }
34
35  virtual void BeginTest() OVERRIDE {
36    activates_ = 0;
37    PostSetNeedsCommitToMainThread();
38  }
39
40  virtual void DidCommit() OVERRIDE {
41    switch (layer_tree_host()->source_frame_number()) {
42      case 2:
43        // Drop the picture layer from the tree.
44        layer_tree_host()->root_layer()->children()[0]->RemoveFromParent();
45        break;
46      case 3:
47        // Add a new picture layer.
48        scoped_refptr<FakePictureLayer> picture =
49            FakePictureLayer::Create(&client_);
50        layer_tree_host()->root_layer()->AddChild(picture);
51        break;
52    }
53  }
54
55  virtual void WillActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
56    LayerImpl* pending_root_impl = impl->pending_tree()->root_layer();
57    LayerImpl* active_root_impl = impl->active_tree()->root_layer();
58
59    if (pending_root_impl->children().empty()) {
60      EXPECT_EQ(2, activates_);
61      return;
62    }
63
64    FakePictureLayerImpl* pending_picture_impl =
65        static_cast<FakePictureLayerImpl*>(pending_root_impl->children()[0]);
66
67    if (!active_root_impl) {
68      EXPECT_EQ(0, activates_);
69      EXPECT_EQ(NULL, pending_picture_impl->twin_layer());
70      return;
71    }
72
73    if (active_root_impl->children().empty()) {
74      EXPECT_EQ(3, activates_);
75      EXPECT_EQ(NULL, pending_picture_impl->twin_layer());
76      return;
77    }
78
79    FakePictureLayerImpl* active_picture_impl =
80        static_cast<FakePictureLayerImpl*>(active_root_impl->children()[0]);
81
82    // After the first activation, when we commit again, we'll have a pending
83    // and active layer. Then we recreate a picture layer in the 4th activate
84    // and the next commit will have a pending and active twin again.
85    EXPECT_TRUE(activates_ == 1 || activates_ == 4);
86
87    EXPECT_EQ(pending_picture_impl, active_picture_impl->twin_layer());
88    EXPECT_EQ(active_picture_impl, pending_picture_impl->twin_layer());
89  }
90
91  virtual void DidActivateTreeOnThread(LayerTreeHostImpl* impl) OVERRIDE {
92    LayerImpl* active_root_impl = impl->active_tree()->root_layer();
93
94    if (active_root_impl->children().empty()) {
95      EXPECT_EQ(2, activates_);
96    } else {
97      FakePictureLayerImpl* active_picture_impl =
98          static_cast<FakePictureLayerImpl*>(active_root_impl->children()[0]);
99
100      EXPECT_EQ(NULL, active_picture_impl->twin_layer());
101    }
102
103    ++activates_;
104    if (activates_ <= 4)
105      PostSetNeedsCommitToMainThread();
106    else
107      EndTest();
108  }
109
110  virtual void AfterTest() OVERRIDE {}
111
112  FakeContentLayerClient client_;
113  int activates_;
114};
115
116MULTI_THREAD_TEST_F(LayerTreeHostPictureTestTwinLayer);
117
118}  // namespace
119}  // namespace cc
120