1 // Copyright 2019 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 <memory>
6 
7 #include "cc/animation/animation_host.h"
8 #include "cc/layers/mirror_layer.h"
9 #include "cc/layers/mirror_layer_impl.h"
10 #include "cc/test/fake_impl_task_runner_provider.h"
11 #include "cc/test/fake_layer_tree_host.h"
12 #include "cc/test/fake_layer_tree_host_client.h"
13 #include "cc/test/fake_layer_tree_host_impl.h"
14 #include "cc/test/test_task_graph_runner.h"
15 #include "cc/trees/tree_synchronizer.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 
18 namespace cc {
19 namespace {
20 
21 class MirrorLayerTest : public testing::Test {
22  public:
MirrorLayerTest()23   MirrorLayerTest() : host_impl_(&task_runner_provider_, &task_graph_runner_) {}
24 
25   // Synchronizes |layer_tree_host_| and |host_impl_| and pushes surface ids.
SynchronizeTrees()26   void SynchronizeTrees() {
27     TreeSynchronizer::PushLayerProperties(layer_tree_host_.get(),
28                                           host_impl_.pending_tree());
29   }
30 
31  protected:
SetUp()32   void SetUp() override {
33     animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN);
34     layer_tree_host_ = FakeLayerTreeHost::Create(
35         &fake_client_, &task_graph_runner_, animation_host_.get());
36     layer_tree_host_->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
37                                               viz::LocalSurfaceId());
38     host_impl_.CreatePendingTree();
39   }
40 
TearDown()41   void TearDown() override {
42     layer_tree_host_->SetRootLayer(nullptr);
43     layer_tree_host_ = nullptr;
44   }
45 
46   FakeLayerTreeHostClient fake_client_;
47   FakeImplTaskRunnerProvider task_runner_provider_;
48   TestTaskGraphRunner task_graph_runner_;
49   std::unique_ptr<AnimationHost> animation_host_;
50   std::unique_ptr<FakeLayerTreeHost> layer_tree_host_;
51   FakeLayerTreeHostImpl host_impl_;
52 };
53 
54 // This test verifies that MirrorLayer properties are pushed across to
55 // MirrorLayerImpl.
TEST_F(MirrorLayerTest,PushProperties)56 TEST_F(MirrorLayerTest, PushProperties) {
57   auto root = Layer::Create();
58   layer_tree_host_->SetRootLayer(root);
59 
60   auto mirrored = Layer::Create();
61   root->AddChild(mirrored);
62   auto mirror = MirrorLayer::Create(mirrored);
63   root->AddChild(mirror);
64 
65   EXPECT_EQ(1, mirrored->mirror_count());
66   EXPECT_EQ(mirrored.get(), mirror->mirrored_layer());
67 
68   auto root_impl = LayerImpl::Create(host_impl_.pending_tree(), root->id());
69   auto mirrored_impl =
70       LayerImpl::Create(host_impl_.pending_tree(), mirrored->id());
71   auto mirror_impl =
72       MirrorLayerImpl::Create(host_impl_.pending_tree(), mirror->id());
73 
74   // Verify that impl layers have default property values.
75   EXPECT_EQ(0, mirror_impl->mirrored_layer_id());
76 
77   SynchronizeTrees();
78 
79   // Verify that property values are pushed to impl layers.
80   EXPECT_EQ(mirrored_impl->id(), mirror_impl->mirrored_layer_id());
81 }
82 
83 // This test verifies adding/removing mirror layers updates mirror count
84 // properly and sets appropriate bits on the layer tree host.
TEST_F(MirrorLayerTest,MirrorCount)85 TEST_F(MirrorLayerTest, MirrorCount) {
86   auto mirrored = Layer::Create();
87   mirrored->SetLayerTreeHost(layer_tree_host_.get());
88 
89   layer_tree_host_->property_trees()->needs_rebuild = false;
90   layer_tree_host_->ClearLayersThatShouldPushProperties();
91   EXPECT_EQ(0, mirrored->mirror_count());
92 
93   // Creating the first mirror layer should trigger property trees rebuild.
94   auto mirror1 = MirrorLayer::Create(mirrored);
95   EXPECT_EQ(1, mirrored->mirror_count());
96   EXPECT_EQ(mirrored.get(), mirror1->mirrored_layer());
97   EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild);
98   EXPECT_TRUE(base::Contains(layer_tree_host_->LayersThatShouldPushProperties(),
99                              mirrored.get()));
100 
101   layer_tree_host_->property_trees()->needs_rebuild = false;
102   layer_tree_host_->ClearLayersThatShouldPushProperties();
103 
104   // Creating a second mirror layer should not trigger property trees rebuild.
105   auto mirror2 = MirrorLayer::Create(mirrored);
106   EXPECT_EQ(2, mirrored->mirror_count());
107   EXPECT_EQ(mirrored.get(), mirror2->mirrored_layer());
108   EXPECT_FALSE(layer_tree_host_->property_trees()->needs_rebuild);
109   EXPECT_TRUE(base::Contains(layer_tree_host_->LayersThatShouldPushProperties(),
110                              mirrored.get()));
111 
112   layer_tree_host_->property_trees()->needs_rebuild = false;
113   layer_tree_host_->ClearLayersThatShouldPushProperties();
114 
115   // Destroying one of the mirror layers should not trigger property trees
116   // rebuild.
117   mirror1->RemoveFromParent();
118   mirror1 = nullptr;
119   EXPECT_EQ(1, mirrored->mirror_count());
120   EXPECT_FALSE(layer_tree_host_->property_trees()->needs_rebuild);
121   EXPECT_EQ(1u, layer_tree_host_->LayersThatShouldPushProperties().size());
122 
123   layer_tree_host_->property_trees()->needs_rebuild = false;
124   layer_tree_host_->ClearLayersThatShouldPushProperties();
125 
126   // Destroying the only remaining mirror layer should trigger property trees
127   // rebuild.
128   mirror2->RemoveFromParent();
129   mirror2 = nullptr;
130   EXPECT_EQ(0, mirrored->mirror_count());
131   EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild);
132   EXPECT_TRUE(base::Contains(layer_tree_host_->LayersThatShouldPushProperties(),
133                              mirrored.get()));
134 
135   mirrored->SetLayerTreeHost(nullptr);
136 }
137 
138 }  // namespace
139 }  // namespace cc
140