1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
cc / layers / mirror_layer_unittest.cc [blame]
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include <utility>
#include "cc/animation/animation_host.h"
#include "cc/layers/mirror_layer.h"
#include "cc/layers/mirror_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/test_task_graph_runner.h"
#include "cc/trees/tree_synchronizer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cc {
namespace {
class MirrorLayerTest : public testing::Test {
public:
MirrorLayerTest() : 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_->GetPendingCommitState(),
layer_tree_host_->GetThreadUnsafeCommitState(),
host_impl_.pending_tree());
}
protected:
void SetUp() override {
animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::kMain);
layer_tree_host_ = FakeLayerTreeHost::Create(
&fake_client_, &task_graph_runner_, animation_host_.get());
layer_tree_host_->SetViewportRectAndScale(gfx::Rect(10, 10), 1.f,
viz::LocalSurfaceId());
host_impl_.CreatePendingTree();
}
void TearDown() override {
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_;
};
// This test verifies that MirrorLayer properties are pushed across to
// MirrorLayerImpl.
TEST_F(MirrorLayerTest, PushProperties) {
auto root = Layer::Create();
layer_tree_host_->SetRootLayer(root);
auto mirrored = Layer::Create();
root->AddChild(mirrored);
auto mirror = MirrorLayer::Create(mirrored);
root->AddChild(mirror);
EXPECT_EQ(1, mirrored->mirror_count());
EXPECT_EQ(mirrored.get(), mirror->mirrored_layer());
auto root_impl = LayerImpl::Create(host_impl_.pending_tree(), root->id());
auto mirrored_impl =
LayerImpl::Create(host_impl_.pending_tree(), mirrored->id());
auto mirror_impl =
MirrorLayerImpl::Create(host_impl_.pending_tree(), mirror->id());
// Verify that impl layers have default property values.
EXPECT_EQ(0, mirror_impl->mirrored_layer_id());
SynchronizeTrees();
// Verify that property values are pushed to impl layers.
EXPECT_EQ(mirrored_impl->id(), mirror_impl->mirrored_layer_id());
}
// This test verifies adding/removing mirror layers updates mirror count
// properly and sets appropriate bits on the layer tree host.
TEST_F(MirrorLayerTest, MirrorCount) {
auto mirrored = Layer::Create();
mirrored->SetLayerTreeHost(layer_tree_host_.get());
layer_tree_host_->ClearPendingLayerCommitStates();
auto commit_state = layer_tree_host_->WillCommit(/*completion_event=*/nullptr,
/*has_updates=*/true);
layer_tree_host_->CommitComplete(commit_state->source_frame_number,
{base::TimeTicks(), base::TimeTicks::Now()});
layer_tree_host_->property_trees()->set_needs_rebuild(false);
EXPECT_EQ(0, mirrored->mirror_count());
// Creating the first mirror layer should trigger property trees rebuild.
auto mirror1 = MirrorLayer::Create(mirrored);
EXPECT_EQ(1, mirrored->mirror_count());
EXPECT_EQ(mirrored.get(), mirror1->mirrored_layer());
EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild());
EXPECT_TRUE(
const_cast<const FakeLayerTreeHost*>(layer_tree_host_.get())
->pending_commit_state()
->layers_that_should_push_properties.contains(mirrored.get()));
layer_tree_host_->property_trees()->set_needs_rebuild(false);
// Creating a second mirror layer should not trigger property trees rebuild.
auto mirror2 = MirrorLayer::Create(mirrored);
EXPECT_EQ(2, mirrored->mirror_count());
EXPECT_EQ(mirrored.get(), mirror2->mirrored_layer());
EXPECT_FALSE(layer_tree_host_->property_trees()->needs_rebuild());
EXPECT_TRUE(
const_cast<const FakeLayerTreeHost*>(layer_tree_host_.get())
->pending_commit_state()
->layers_that_should_push_properties.contains(mirrored.get()));
layer_tree_host_->property_trees()->set_needs_rebuild(false);
// Destroying one of the mirror layers should not trigger property trees
// rebuild.
mirror1->RemoveFromParent();
mirror1 = nullptr;
EXPECT_EQ(1, mirrored->mirror_count());
EXPECT_FALSE(layer_tree_host_->property_trees()->needs_rebuild());
EXPECT_EQ(1u, const_cast<const FakeLayerTreeHost*>(layer_tree_host_.get())
->pending_commit_state()
->layers_that_should_push_properties.size());
layer_tree_host_->property_trees()->set_needs_rebuild(false);
// Destroying the only remaining mirror layer should trigger property trees
// rebuild.
mirror2->RemoveFromParent();
mirror2 = nullptr;
EXPECT_EQ(0, mirrored->mirror_count());
EXPECT_TRUE(layer_tree_host_->property_trees()->needs_rebuild());
EXPECT_TRUE(
const_cast<const FakeLayerTreeHost*>(layer_tree_host_.get())
->pending_commit_state()
->layers_that_should_push_properties.contains(mirrored.get()));
layer_tree_host_->property_trees()->set_needs_rebuild(false);
mirrored->SetLayerTreeHost(nullptr);
}
} // namespace
} // namespace cc