OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stddef.h> | 5 #include <stddef.h> |
6 | 6 |
7 #include "cc/scheduler/begin_frame_source.h" | 7 #include "cc/scheduler/begin_frame_source.h" |
8 #include "cc/surfaces/surface_factory_client.h" | 8 #include "cc/surfaces/surface_factory_client.h" |
9 #include "cc/surfaces/surface_manager.h" | 9 #include "cc/surfaces/surface_manager.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
11 | 11 |
12 namespace cc { | 12 namespace cc { |
13 | 13 |
14 class FakeSurfaceFactoryClient : public SurfaceFactoryClient { | 14 class FakeSurfaceFactoryClient : public SurfaceFactoryClient { |
15 public: | 15 public: |
16 explicit FakeSurfaceFactoryClient(int id_namespace) | 16 explicit FakeSurfaceFactoryClient(const FrameSinkId& frame_sink_id) |
17 : source_(nullptr), manager_(nullptr), id_namespace_(id_namespace) {} | 17 : source_(nullptr), manager_(nullptr), frame_sink_id_(frame_sink_id) {} |
18 FakeSurfaceFactoryClient(int id_namespace, SurfaceManager* manager) | 18 |
19 : source_(nullptr), manager_(nullptr), id_namespace_(id_namespace) { | 19 FakeSurfaceFactoryClient(const FrameSinkId& frame_sink_id, |
| 20 SurfaceManager* manager) |
| 21 : source_(nullptr), manager_(nullptr), frame_sink_id_(frame_sink_id) { |
20 DCHECK(manager); | 22 DCHECK(manager); |
21 Register(manager); | 23 Register(manager); |
22 } | 24 } |
23 | 25 |
24 ~FakeSurfaceFactoryClient() override { | 26 ~FakeSurfaceFactoryClient() override { |
25 if (manager_) { | 27 if (manager_) { |
26 Unregister(); | 28 Unregister(); |
27 } | 29 } |
28 EXPECT_EQ(source_, nullptr); | 30 EXPECT_EQ(source_, nullptr); |
29 } | 31 } |
30 | 32 |
31 BeginFrameSource* source() { return source_; } | 33 BeginFrameSource* source() { return source_; } |
32 uint32_t id_namespace() { return id_namespace_; } | 34 const FrameSinkId& frame_sink_id() { return frame_sink_id_; } |
33 | 35 |
34 void Register(SurfaceManager* manager) { | 36 void Register(SurfaceManager* manager) { |
35 EXPECT_EQ(manager_, nullptr); | 37 EXPECT_EQ(manager_, nullptr); |
36 manager_ = manager; | 38 manager_ = manager; |
37 manager_->RegisterSurfaceFactoryClient(id_namespace_, this); | 39 manager_->RegisterSurfaceFactoryClient(frame_sink_id_, this); |
38 } | 40 } |
39 | 41 |
40 void Unregister() { | 42 void Unregister() { |
41 EXPECT_NE(manager_, nullptr); | 43 EXPECT_NE(manager_, nullptr); |
42 manager_->UnregisterSurfaceFactoryClient(id_namespace_); | 44 manager_->UnregisterSurfaceFactoryClient(frame_sink_id_); |
43 manager_ = nullptr; | 45 manager_ = nullptr; |
44 } | 46 } |
45 | 47 |
46 // SurfaceFactoryClient implementation. | 48 // SurfaceFactoryClient implementation. |
47 void ReturnResources(const ReturnedResourceArray& resources) override {} | 49 void ReturnResources(const ReturnedResourceArray& resources) override {} |
48 void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override { | 50 void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override { |
49 DCHECK(!source_ || !begin_frame_source); | 51 DCHECK(!source_ || !begin_frame_source); |
50 source_ = begin_frame_source; | 52 source_ = begin_frame_source; |
51 }; | 53 }; |
52 | 54 |
53 private: | 55 private: |
54 BeginFrameSource* source_; | 56 BeginFrameSource* source_; |
55 SurfaceManager* manager_; | 57 SurfaceManager* manager_; |
56 uint32_t id_namespace_; | 58 FrameSinkId frame_sink_id_; |
57 }; | 59 }; |
58 | 60 |
59 class SurfaceManagerTest : public testing::Test { | 61 class SurfaceManagerTest : public testing::Test { |
60 public: | 62 public: |
61 // These tests don't care about namespace registration, so just preregister | 63 // These tests don't care about namespace registration, so just preregister |
62 // a set of namespaces that tests can use freely without worrying if they're | 64 // a set of namespaces that tests can use freely without worrying if they're |
63 // valid or not. | 65 // valid or not. |
64 enum { MAX_NAMESPACE = 10 }; | 66 enum { MAX_FRAME_SINK = 10 }; |
65 | 67 |
66 SurfaceManagerTest() { | 68 SurfaceManagerTest() { |
67 for (size_t i = 0; i < MAX_NAMESPACE; ++i) | 69 for (size_t i = 0; i < MAX_FRAME_SINK; ++i) |
68 manager_.RegisterSurfaceClientId(i); | 70 manager_.RegisterFrameSinkId(FrameSinkId(i, i)); |
69 } | 71 } |
70 | 72 |
71 ~SurfaceManagerTest() override { | 73 ~SurfaceManagerTest() override { |
72 for (size_t i = 0; i < MAX_NAMESPACE; ++i) | 74 for (size_t i = 0; i < MAX_FRAME_SINK; ++i) |
73 manager_.InvalidateSurfaceClientId(i); | 75 manager_.InvalidateFrameSinkId(FrameSinkId(i, i)); |
74 } | 76 } |
75 | 77 |
76 protected: | 78 protected: |
77 SurfaceManager manager_; | 79 SurfaceManager manager_; |
78 }; | 80 }; |
79 | 81 |
80 TEST_F(SurfaceManagerTest, SingleClients) { | 82 TEST_F(SurfaceManagerTest, SingleClients) { |
81 FakeSurfaceFactoryClient client(1); | 83 FakeSurfaceFactoryClient client(FrameSinkId(1, 1)); |
82 FakeSurfaceFactoryClient other_client(2); | 84 FakeSurfaceFactoryClient other_client(FrameSinkId(2, 2)); |
83 StubBeginFrameSource source; | 85 StubBeginFrameSource source; |
84 | 86 |
85 EXPECT_EQ(client.source(), nullptr); | 87 EXPECT_EQ(client.source(), nullptr); |
86 EXPECT_EQ(other_client.source(), nullptr); | 88 EXPECT_EQ(other_client.source(), nullptr); |
87 client.Register(&manager_); | 89 client.Register(&manager_); |
88 other_client.Register(&manager_); | 90 other_client.Register(&manager_); |
89 EXPECT_EQ(client.source(), nullptr); | 91 EXPECT_EQ(client.source(), nullptr); |
90 EXPECT_EQ(other_client.source(), nullptr); | 92 EXPECT_EQ(other_client.source(), nullptr); |
91 | 93 |
92 // Test setting unsetting BFS | 94 // Test setting unsetting BFS |
93 manager_.RegisterBeginFrameSource(&source, client.id_namespace()); | 95 manager_.RegisterBeginFrameSource(&source, client.frame_sink_id()); |
94 EXPECT_EQ(client.source(), &source); | 96 EXPECT_EQ(client.source(), &source); |
95 EXPECT_EQ(other_client.source(), nullptr); | 97 EXPECT_EQ(other_client.source(), nullptr); |
96 manager_.UnregisterBeginFrameSource(&source); | 98 manager_.UnregisterBeginFrameSource(&source); |
97 EXPECT_EQ(client.source(), nullptr); | 99 EXPECT_EQ(client.source(), nullptr); |
98 EXPECT_EQ(other_client.source(), nullptr); | 100 EXPECT_EQ(other_client.source(), nullptr); |
99 | 101 |
100 // Set BFS for other namespace | 102 // Set BFS for other namespace |
101 manager_.RegisterBeginFrameSource(&source, other_client.id_namespace()); | 103 manager_.RegisterBeginFrameSource(&source, other_client.frame_sink_id()); |
102 EXPECT_EQ(other_client.source(), &source); | 104 EXPECT_EQ(other_client.source(), &source); |
103 EXPECT_EQ(client.source(), nullptr); | 105 EXPECT_EQ(client.source(), nullptr); |
104 manager_.UnregisterBeginFrameSource(&source); | 106 manager_.UnregisterBeginFrameSource(&source); |
105 EXPECT_EQ(client.source(), nullptr); | 107 EXPECT_EQ(client.source(), nullptr); |
106 EXPECT_EQ(other_client.source(), nullptr); | 108 EXPECT_EQ(other_client.source(), nullptr); |
107 | 109 |
108 // Re-set BFS for original | 110 // Re-set BFS for original |
109 manager_.RegisterBeginFrameSource(&source, client.id_namespace()); | 111 manager_.RegisterBeginFrameSource(&source, client.frame_sink_id()); |
110 EXPECT_EQ(client.source(), &source); | 112 EXPECT_EQ(client.source(), &source); |
111 manager_.UnregisterBeginFrameSource(&source); | 113 manager_.UnregisterBeginFrameSource(&source); |
112 EXPECT_EQ(client.source(), nullptr); | 114 EXPECT_EQ(client.source(), nullptr); |
113 } | 115 } |
114 | 116 |
115 TEST_F(SurfaceManagerTest, MultipleDisplays) { | 117 TEST_F(SurfaceManagerTest, MultipleDisplays) { |
116 StubBeginFrameSource root1_source; | 118 StubBeginFrameSource root1_source; |
117 StubBeginFrameSource root2_source; | 119 StubBeginFrameSource root2_source; |
118 | 120 |
119 // root1 -> A -> B | 121 // root1 -> A -> B |
120 // root2 -> C | 122 // root2 -> C |
121 FakeSurfaceFactoryClient root1(1, &manager_); | 123 FakeSurfaceFactoryClient root1(FrameSinkId(1, 1), &manager_); |
122 FakeSurfaceFactoryClient root2(2, &manager_); | 124 FakeSurfaceFactoryClient root2(FrameSinkId(2, 2), &manager_); |
123 FakeSurfaceFactoryClient client_a(3, &manager_); | 125 FakeSurfaceFactoryClient client_a(FrameSinkId(3, 3), &manager_); |
124 FakeSurfaceFactoryClient client_b(4, &manager_); | 126 FakeSurfaceFactoryClient client_b(FrameSinkId(4, 4), &manager_); |
125 FakeSurfaceFactoryClient client_c(5, &manager_); | 127 FakeSurfaceFactoryClient client_c(FrameSinkId(5, 5), &manager_); |
126 | 128 |
127 manager_.RegisterBeginFrameSource(&root1_source, root1.id_namespace()); | 129 manager_.RegisterBeginFrameSource(&root1_source, root1.frame_sink_id()); |
128 manager_.RegisterBeginFrameSource(&root2_source, root2.id_namespace()); | 130 manager_.RegisterBeginFrameSource(&root2_source, root2.frame_sink_id()); |
129 EXPECT_EQ(root1.source(), &root1_source); | 131 EXPECT_EQ(root1.source(), &root1_source); |
130 EXPECT_EQ(root2.source(), &root2_source); | 132 EXPECT_EQ(root2.source(), &root2_source); |
131 | 133 |
132 // Set up initial hierarchy. | 134 // Set up initial hierarchy. |
133 manager_.RegisterSurfaceNamespaceHierarchy(root1.id_namespace(), | 135 manager_.RegisterFrameSinkHierarchy(root1.frame_sink_id(), |
134 client_a.id_namespace()); | 136 client_a.frame_sink_id()); |
135 EXPECT_EQ(client_a.source(), root1.source()); | 137 EXPECT_EQ(client_a.source(), root1.source()); |
136 manager_.RegisterSurfaceNamespaceHierarchy(client_a.id_namespace(), | 138 manager_.RegisterFrameSinkHierarchy(client_a.frame_sink_id(), |
137 client_b.id_namespace()); | 139 client_b.frame_sink_id()); |
138 EXPECT_EQ(client_b.source(), root1.source()); | 140 EXPECT_EQ(client_b.source(), root1.source()); |
139 manager_.RegisterSurfaceNamespaceHierarchy(root2.id_namespace(), | 141 manager_.RegisterFrameSinkHierarchy(root2.frame_sink_id(), |
140 client_c.id_namespace()); | 142 client_c.frame_sink_id()); |
141 EXPECT_EQ(client_c.source(), root2.source()); | 143 EXPECT_EQ(client_c.source(), root2.source()); |
142 | 144 |
143 // Attach A into root2's subtree, like a window moving across displays. | 145 // Attach A into root2's subtree, like a window moving across displays. |
144 // root1 -> A -> B | 146 // root1 -> A -> B |
145 // root2 -> C -> A -> B | 147 // root2 -> C -> A -> B |
146 manager_.RegisterSurfaceNamespaceHierarchy(client_c.id_namespace(), | 148 manager_.RegisterFrameSinkHierarchy(client_c.frame_sink_id(), |
147 client_a.id_namespace()); | 149 client_a.frame_sink_id()); |
148 // With the heuristic of just keeping existing BFS in the face of multiple, | 150 // With the heuristic of just keeping existing BFS in the face of multiple, |
149 // no client sources should change. | 151 // no client sources should change. |
150 EXPECT_EQ(client_a.source(), root1.source()); | 152 EXPECT_EQ(client_a.source(), root1.source()); |
151 EXPECT_EQ(client_b.source(), root1.source()); | 153 EXPECT_EQ(client_b.source(), root1.source()); |
152 EXPECT_EQ(client_c.source(), root2.source()); | 154 EXPECT_EQ(client_c.source(), root2.source()); |
153 | 155 |
154 // Detach A from root1. A and B should now be updated to root2. | 156 // Detach A from root1. A and B should now be updated to root2. |
155 manager_.UnregisterSurfaceNamespaceHierarchy(root1.id_namespace(), | 157 manager_.UnregisterFrameSinkHierarchy(root1.frame_sink_id(), |
156 client_a.id_namespace()); | 158 client_a.frame_sink_id()); |
157 EXPECT_EQ(client_a.source(), root2.source()); | 159 EXPECT_EQ(client_a.source(), root2.source()); |
158 EXPECT_EQ(client_b.source(), root2.source()); | 160 EXPECT_EQ(client_b.source(), root2.source()); |
159 EXPECT_EQ(client_c.source(), root2.source()); | 161 EXPECT_EQ(client_c.source(), root2.source()); |
160 | 162 |
161 // Detach root1 from BFS. root1 should now have no source. | 163 // Detach root1 from BFS. root1 should now have no source. |
162 manager_.UnregisterBeginFrameSource(&root1_source); | 164 manager_.UnregisterBeginFrameSource(&root1_source); |
163 EXPECT_EQ(root1.source(), nullptr); | 165 EXPECT_EQ(root1.source(), nullptr); |
164 EXPECT_NE(root2.source(), nullptr); | 166 EXPECT_NE(root2.source(), nullptr); |
165 | 167 |
166 // Detatch root2 from BFS. | 168 // Detatch root2 from BFS. |
167 manager_.UnregisterBeginFrameSource(&root2_source); | 169 manager_.UnregisterBeginFrameSource(&root2_source); |
168 EXPECT_EQ(client_a.source(), nullptr); | 170 EXPECT_EQ(client_a.source(), nullptr); |
169 EXPECT_EQ(client_b.source(), nullptr); | 171 EXPECT_EQ(client_b.source(), nullptr); |
170 EXPECT_EQ(client_c.source(), nullptr); | 172 EXPECT_EQ(client_c.source(), nullptr); |
171 EXPECT_EQ(root2.source(), nullptr); | 173 EXPECT_EQ(root2.source(), nullptr); |
172 | 174 |
173 // Cleanup hierarchy. | 175 // Cleanup hierarchy. |
174 manager_.UnregisterSurfaceNamespaceHierarchy(root2.id_namespace(), | 176 manager_.UnregisterFrameSinkHierarchy(root2.frame_sink_id(), |
175 client_c.id_namespace()); | 177 client_c.frame_sink_id()); |
176 manager_.UnregisterSurfaceNamespaceHierarchy(client_c.id_namespace(), | 178 manager_.UnregisterFrameSinkHierarchy(client_c.frame_sink_id(), |
177 client_a.id_namespace()); | 179 client_a.frame_sink_id()); |
178 manager_.UnregisterSurfaceNamespaceHierarchy(client_a.id_namespace(), | 180 manager_.UnregisterFrameSinkHierarchy(client_a.frame_sink_id(), |
179 client_b.id_namespace()); | 181 client_b.frame_sink_id()); |
180 } | 182 } |
181 | 183 |
182 // In practice, registering and unregistering both parent/child relationships | 184 // In practice, registering and unregistering both parent/child relationships |
183 // and SurfaceFactoryClients can happen in any ordering with respect to | 185 // and SurfaceFactoryClients can happen in any ordering with respect to |
184 // each other. These following tests verify that all the data structures | 186 // each other. These following tests verify that all the data structures |
185 // are properly set up and cleaned up under the four permutations of orderings | 187 // are properly set up and cleaned up under the four permutations of orderings |
186 // of this nesting. | 188 // of this nesting. |
187 | 189 |
188 class SurfaceManagerOrderingTest : public SurfaceManagerTest { | 190 class SurfaceManagerOrderingTest : public SurfaceManagerTest { |
189 public: | 191 public: |
190 SurfaceManagerOrderingTest() | 192 SurfaceManagerOrderingTest() |
191 : client_a_(1), | 193 : client_a_(FrameSinkId(1, 1)), |
192 client_b_(2), | 194 client_b_(FrameSinkId(2, 2)), |
193 client_c_(3), | 195 client_c_(FrameSinkId(3, 3)), |
194 hierarchy_registered_(false), | 196 hierarchy_registered_(false), |
195 clients_registered_(false), | 197 clients_registered_(false), |
196 bfs_registered_(false) { | 198 bfs_registered_(false) { |
197 AssertCorrectBFSState(); | 199 AssertCorrectBFSState(); |
198 } | 200 } |
199 | 201 |
200 ~SurfaceManagerOrderingTest() override { | 202 ~SurfaceManagerOrderingTest() override { |
201 EXPECT_EQ(hierarchy_registered_, false); | 203 EXPECT_EQ(hierarchy_registered_, false); |
202 EXPECT_EQ(clients_registered_, false); | 204 EXPECT_EQ(clients_registered_, false); |
203 EXPECT_EQ(bfs_registered_, false); | 205 EXPECT_EQ(bfs_registered_, false); |
204 AssertCorrectBFSState(); | 206 AssertCorrectBFSState(); |
205 } | 207 } |
206 | 208 |
207 void RegisterHierarchy() { | 209 void RegisterHierarchy() { |
208 DCHECK(!hierarchy_registered_); | 210 DCHECK(!hierarchy_registered_); |
209 hierarchy_registered_ = true; | 211 hierarchy_registered_ = true; |
210 manager_.RegisterSurfaceNamespaceHierarchy(client_a_.id_namespace(), | 212 manager_.RegisterFrameSinkHierarchy(client_a_.frame_sink_id(), |
211 client_b_.id_namespace()); | 213 client_b_.frame_sink_id()); |
212 manager_.RegisterSurfaceNamespaceHierarchy(client_b_.id_namespace(), | 214 manager_.RegisterFrameSinkHierarchy(client_b_.frame_sink_id(), |
213 client_c_.id_namespace()); | 215 client_c_.frame_sink_id()); |
214 AssertCorrectBFSState(); | 216 AssertCorrectBFSState(); |
215 } | 217 } |
216 void UnregisterHierarchy() { | 218 void UnregisterHierarchy() { |
217 DCHECK(hierarchy_registered_); | 219 DCHECK(hierarchy_registered_); |
218 hierarchy_registered_ = false; | 220 hierarchy_registered_ = false; |
219 manager_.UnregisterSurfaceNamespaceHierarchy(client_a_.id_namespace(), | 221 manager_.UnregisterFrameSinkHierarchy(client_a_.frame_sink_id(), |
220 client_b_.id_namespace()); | 222 client_b_.frame_sink_id()); |
221 manager_.UnregisterSurfaceNamespaceHierarchy(client_b_.id_namespace(), | 223 manager_.UnregisterFrameSinkHierarchy(client_b_.frame_sink_id(), |
222 client_c_.id_namespace()); | 224 client_c_.frame_sink_id()); |
223 AssertCorrectBFSState(); | 225 AssertCorrectBFSState(); |
224 } | 226 } |
225 | 227 |
226 void RegisterClients() { | 228 void RegisterClients() { |
227 DCHECK(!clients_registered_); | 229 DCHECK(!clients_registered_); |
228 clients_registered_ = true; | 230 clients_registered_ = true; |
229 client_a_.Register(&manager_); | 231 client_a_.Register(&manager_); |
230 client_b_.Register(&manager_); | 232 client_b_.Register(&manager_); |
231 client_c_.Register(&manager_); | 233 client_c_.Register(&manager_); |
232 AssertCorrectBFSState(); | 234 AssertCorrectBFSState(); |
233 } | 235 } |
234 | 236 |
235 void UnregisterClients() { | 237 void UnregisterClients() { |
236 DCHECK(clients_registered_); | 238 DCHECK(clients_registered_); |
237 clients_registered_ = false; | 239 clients_registered_ = false; |
238 client_a_.Unregister(); | 240 client_a_.Unregister(); |
239 client_b_.Unregister(); | 241 client_b_.Unregister(); |
240 client_c_.Unregister(); | 242 client_c_.Unregister(); |
241 AssertCorrectBFSState(); | 243 AssertCorrectBFSState(); |
242 } | 244 } |
243 | 245 |
244 void RegisterBFS() { | 246 void RegisterBFS() { |
245 DCHECK(!bfs_registered_); | 247 DCHECK(!bfs_registered_); |
246 bfs_registered_ = true; | 248 bfs_registered_ = true; |
247 manager_.RegisterBeginFrameSource(&source_, client_a_.id_namespace()); | 249 manager_.RegisterBeginFrameSource(&source_, client_a_.frame_sink_id()); |
248 AssertCorrectBFSState(); | 250 AssertCorrectBFSState(); |
249 } | 251 } |
250 void UnregisterBFS() { | 252 void UnregisterBFS() { |
251 DCHECK(bfs_registered_); | 253 DCHECK(bfs_registered_); |
252 bfs_registered_ = false; | 254 bfs_registered_ = false; |
253 manager_.UnregisterBeginFrameSource(&source_); | 255 manager_.UnregisterBeginFrameSource(&source_); |
254 AssertCorrectBFSState(); | 256 AssertCorrectBFSState(); |
255 } | 257 } |
256 | 258 |
257 void AssertEmptyBFS() { | 259 void AssertEmptyBFS() { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 } | 366 } |
365 | 367 |
366 INSTANTIATE_TEST_CASE_P( | 368 INSTANTIATE_TEST_CASE_P( |
367 SurfaceManagerOrderingParamTestInstantiation, | 369 SurfaceManagerOrderingParamTestInstantiation, |
368 SurfaceManagerOrderingParamTest, | 370 SurfaceManagerOrderingParamTest, |
369 ::testing::Combine(::testing::ValuesIn(kRegisterOrderList), | 371 ::testing::Combine(::testing::ValuesIn(kRegisterOrderList), |
370 ::testing::ValuesIn(kUnregisterOrderList), | 372 ::testing::ValuesIn(kUnregisterOrderList), |
371 ::testing::ValuesIn(kBFSOrderList))); | 373 ::testing::ValuesIn(kBFSOrderList))); |
372 | 374 |
373 } // namespace cc | 375 } // namespace cc |
OLD | NEW |