Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1023)

Side by Side Diff: cc/surfaces/surface_manager_unittest.cc

Issue 1673783004: Hook up BeginFrameSource to SurfaceFactoryClient via SurfaceManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Register id namespace on Android Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/surfaces/surface_manager.cc ('k') | cc/surfaces/surface_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <stddef.h>
6
7 #include "cc/scheduler/begin_frame_source.h"
8 #include "cc/surfaces/surface_factory_client.h"
9 #include "cc/surfaces/surface_manager.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace cc {
13
14 class FakeSurfaceFactoryClient : public SurfaceFactoryClient {
15 public:
16 explicit FakeSurfaceFactoryClient(int id_namespace)
17 : source_(nullptr), manager_(nullptr), id_namespace_(id_namespace) {}
18 FakeSurfaceFactoryClient(int id_namespace, SurfaceManager* manager)
19 : source_(nullptr), manager_(nullptr), id_namespace_(id_namespace) {
20 DCHECK(manager);
21 Register(manager);
22 }
23
24 ~FakeSurfaceFactoryClient() override {
25 if (manager_) {
26 Unregister();
27 }
28 EXPECT_EQ(source_, nullptr);
29 }
30
31 BeginFrameSource* source() { return source_; }
32 uint32_t id_namespace() { return id_namespace_; }
33
34 void Register(SurfaceManager* manager) {
35 EXPECT_EQ(manager_, nullptr);
36 manager_ = manager;
37 manager_->RegisterSurfaceFactoryClient(id_namespace_, this);
38 }
39
40 void Unregister() {
41 EXPECT_NE(manager_, nullptr);
42 manager_->UnregisterSurfaceFactoryClient(id_namespace_);
43 manager_ = nullptr;
44 }
45
46 // SurfaceFactoryClient implementation.
47 void ReturnResources(const ReturnedResourceArray& resources) override{};
48 void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override {
49 DCHECK(!source_ || !begin_frame_source);
50 source_ = begin_frame_source;
51 };
52
53 private:
54 BeginFrameSource* source_;
55 SurfaceManager* manager_;
56 uint32_t id_namespace_;
57 };
58
59 class EmptyBeginFrameSource : public BeginFrameSource {
60 public:
61 void DidFinishFrame(size_t remaining_frames) override{};
62 void AddObserver(BeginFrameObserver* obs) override{};
63 void RemoveObserver(BeginFrameObserver* obs) override{};
64 void SetClientReady() override {}
65 void AsValueInto(base::trace_event::TracedValue* dict) const override{};
66 };
67
68 class SurfaceManagerTest : public testing::Test {
69 public:
70 // These tests don't care about namespace registration, so just preregister
71 // a set of namespaces that tests can use freely without worrying if they're
72 // valid or not.
73 enum { MAX_NAMESPACE = 10 };
74
75 SurfaceManagerTest() {
76 for (size_t i = 0; i < MAX_NAMESPACE; ++i)
77 manager_.RegisterSurfaceIdNamespace(i);
78 }
79
80 ~SurfaceManagerTest() override {
81 for (size_t i = 0; i < MAX_NAMESPACE; ++i)
82 manager_.InvalidateSurfaceIdNamespace(i);
83 }
84
85 protected:
86 SurfaceManager manager_;
87 };
88
89 TEST_F(SurfaceManagerTest, SingleClients) {
90 FakeSurfaceFactoryClient client(1);
91 FakeSurfaceFactoryClient other_client(2);
92 EmptyBeginFrameSource source;
93
94 EXPECT_EQ(client.source(), nullptr);
95 EXPECT_EQ(other_client.source(), nullptr);
96 client.Register(&manager_);
97 other_client.Register(&manager_);
98 EXPECT_EQ(client.source(), nullptr);
99 EXPECT_EQ(other_client.source(), nullptr);
100
101 // Test setting unsetting BFS
102 manager_.RegisterBeginFrameSource(&source, client.id_namespace());
103 EXPECT_EQ(client.source(), &source);
104 EXPECT_EQ(other_client.source(), nullptr);
105 manager_.UnregisterBeginFrameSource(&source);
106 EXPECT_EQ(client.source(), nullptr);
107 EXPECT_EQ(other_client.source(), nullptr);
108
109 // Set BFS for other namespace
110 manager_.RegisterBeginFrameSource(&source, other_client.id_namespace());
111 EXPECT_EQ(other_client.source(), &source);
112 EXPECT_EQ(client.source(), nullptr);
113 manager_.UnregisterBeginFrameSource(&source);
114 EXPECT_EQ(client.source(), nullptr);
115 EXPECT_EQ(other_client.source(), nullptr);
116
117 // Re-set BFS for original
118 manager_.RegisterBeginFrameSource(&source, client.id_namespace());
119 EXPECT_EQ(client.source(), &source);
120 manager_.UnregisterBeginFrameSource(&source);
121 EXPECT_EQ(client.source(), nullptr);
122 }
123
124 TEST_F(SurfaceManagerTest, MultipleDisplays) {
125 EmptyBeginFrameSource root1_source;
126 EmptyBeginFrameSource root2_source;
127
128 // root1 -> A -> B
129 // root2 -> C
130 FakeSurfaceFactoryClient root1(1, &manager_);
131 FakeSurfaceFactoryClient root2(2, &manager_);
132 FakeSurfaceFactoryClient client_a(3, &manager_);
133 FakeSurfaceFactoryClient client_b(4, &manager_);
134 FakeSurfaceFactoryClient client_c(5, &manager_);
135
136 manager_.RegisterBeginFrameSource(&root1_source, root1.id_namespace());
137 manager_.RegisterBeginFrameSource(&root2_source, root2.id_namespace());
138 EXPECT_EQ(root1.source(), &root1_source);
139 EXPECT_EQ(root2.source(), &root2_source);
140
141 // Set up initial hierarchy.
142 manager_.RegisterSurfaceNamespaceHierarchy(root1.id_namespace(),
143 client_a.id_namespace());
144 EXPECT_EQ(client_a.source(), root1.source());
145 manager_.RegisterSurfaceNamespaceHierarchy(client_a.id_namespace(),
146 client_b.id_namespace());
147 EXPECT_EQ(client_b.source(), root1.source());
148 manager_.RegisterSurfaceNamespaceHierarchy(root2.id_namespace(),
149 client_c.id_namespace());
150 EXPECT_EQ(client_c.source(), root2.source());
151
152 // Attach A into root2's subtree, like a window moving across displays.
153 // root1 -> A -> B
154 // root2 -> C -> A -> B
155 manager_.RegisterSurfaceNamespaceHierarchy(client_c.id_namespace(),
156 client_a.id_namespace());
157 // With the heuristic of just keeping existing BFS in the face of multiple,
158 // no client sources should change.
159 EXPECT_EQ(client_a.source(), root1.source());
160 EXPECT_EQ(client_b.source(), root1.source());
161 EXPECT_EQ(client_c.source(), root2.source());
162
163 // Detach A from root1. A and B should now be updated to root2.
164 manager_.UnregisterSurfaceNamespaceHierarchy(root1.id_namespace(),
165 client_a.id_namespace());
166 EXPECT_EQ(client_a.source(), root2.source());
167 EXPECT_EQ(client_b.source(), root2.source());
168 EXPECT_EQ(client_c.source(), root2.source());
169
170 // Detach root1 from BFS. root1 should now have no source.
171 manager_.UnregisterBeginFrameSource(&root1_source);
172 EXPECT_EQ(root1.source(), nullptr);
173 EXPECT_NE(root2.source(), nullptr);
174
175 // Detatch root2 from BFS.
176 manager_.UnregisterBeginFrameSource(&root2_source);
177 EXPECT_EQ(client_a.source(), nullptr);
178 EXPECT_EQ(client_b.source(), nullptr);
179 EXPECT_EQ(client_c.source(), nullptr);
180 EXPECT_EQ(root2.source(), nullptr);
181
182 // Cleanup hierarchy.
183 manager_.UnregisterSurfaceNamespaceHierarchy(root2.id_namespace(),
184 client_c.id_namespace());
185 manager_.UnregisterSurfaceNamespaceHierarchy(client_c.id_namespace(),
186 client_a.id_namespace());
187 manager_.UnregisterSurfaceNamespaceHierarchy(client_a.id_namespace(),
188 client_b.id_namespace());
189 }
190
191 // In practice, registering and unregistering both parent/child relationships
192 // and SurfaceFactoryClients can happen in any ordering with respect to
193 // each other. These following tests verify that all the data structures
194 // are properly set up and cleaned up under the four permutations of orderings
195 // of this nesting.
196
197 class SurfaceManagerOrderingTest : public SurfaceManagerTest {
198 public:
199 SurfaceManagerOrderingTest()
200 : client_a_(1),
201 client_b_(2),
202 client_c_(3),
203 hierarchy_registered_(false),
204 clients_registered_(false),
205 bfs_registered_(false) {
206 AssertCorrectBFSState();
207 }
208
209 ~SurfaceManagerOrderingTest() override {
210 EXPECT_EQ(hierarchy_registered_, false);
211 EXPECT_EQ(clients_registered_, false);
212 EXPECT_EQ(bfs_registered_, false);
213 AssertCorrectBFSState();
214 }
215
216 void RegisterHierarchy() {
217 DCHECK(!hierarchy_registered_);
218 hierarchy_registered_ = true;
219 manager_.RegisterSurfaceNamespaceHierarchy(client_a_.id_namespace(),
220 client_b_.id_namespace());
221 manager_.RegisterSurfaceNamespaceHierarchy(client_b_.id_namespace(),
222 client_c_.id_namespace());
223 AssertCorrectBFSState();
224 }
225 void UnregisterHierarchy() {
226 DCHECK(hierarchy_registered_);
227 hierarchy_registered_ = false;
228 manager_.UnregisterSurfaceNamespaceHierarchy(client_a_.id_namespace(),
229 client_b_.id_namespace());
230 manager_.UnregisterSurfaceNamespaceHierarchy(client_b_.id_namespace(),
231 client_c_.id_namespace());
232 AssertCorrectBFSState();
233 }
234
235 void RegisterClients() {
236 DCHECK(!clients_registered_);
237 clients_registered_ = true;
238 client_a_.Register(&manager_);
239 client_b_.Register(&manager_);
240 client_c_.Register(&manager_);
241 AssertCorrectBFSState();
242 }
243
244 void UnregisterClients() {
245 DCHECK(clients_registered_);
246 clients_registered_ = false;
247 client_a_.Unregister();
248 client_b_.Unregister();
249 client_c_.Unregister();
250 AssertCorrectBFSState();
251 }
252
253 void RegisterBFS() {
254 DCHECK(!bfs_registered_);
255 bfs_registered_ = true;
256 manager_.RegisterBeginFrameSource(&source_, client_a_.id_namespace());
257 AssertCorrectBFSState();
258 }
259 void UnregisterBFS() {
260 DCHECK(bfs_registered_);
261 bfs_registered_ = false;
262 manager_.UnregisterBeginFrameSource(&source_);
263 AssertCorrectBFSState();
264 }
265
266 void AssertEmptyBFS() {
267 EXPECT_EQ(client_a_.source(), nullptr);
268 EXPECT_EQ(client_b_.source(), nullptr);
269 EXPECT_EQ(client_c_.source(), nullptr);
270 }
271
272 void AssertAllValidBFS() {
273 EXPECT_EQ(client_a_.source(), &source_);
274 EXPECT_EQ(client_b_.source(), &source_);
275 EXPECT_EQ(client_c_.source(), &source_);
276 }
277
278 protected:
279 void AssertCorrectBFSState() {
280 if (!clients_registered_ || !bfs_registered_) {
281 AssertEmptyBFS();
282 return;
283 }
284 if (!hierarchy_registered_) {
285 // A valid but not attached to anything.
286 EXPECT_EQ(client_a_.source(), &source_);
287 EXPECT_EQ(client_b_.source(), nullptr);
288 EXPECT_EQ(client_c_.source(), nullptr);
289 return;
290 }
291
292 AssertAllValidBFS();
293 }
294
295 EmptyBeginFrameSource source_;
296 // A -> B -> C hierarchy, with A always having the BFS.
297 FakeSurfaceFactoryClient client_a_;
298 FakeSurfaceFactoryClient client_b_;
299 FakeSurfaceFactoryClient client_c_;
300
301 bool hierarchy_registered_;
302 bool clients_registered_;
303 bool bfs_registered_;
304 };
305
306 enum RegisterOrder { REGISTER_HIERARCHY_FIRST, REGISTER_CLIENTS_FIRST };
307 enum UnregisterOrder { UNREGISTER_HIERARCHY_FIRST, UNREGISTER_CLIENTS_FIRST };
308 enum BFSOrder { BFS_FIRST, BFS_SECOND, BFS_THIRD };
309
310 static const RegisterOrder kRegisterOrderList[] = {REGISTER_HIERARCHY_FIRST,
311 REGISTER_CLIENTS_FIRST};
312 static const UnregisterOrder kUnregisterOrderList[] = {
313 UNREGISTER_HIERARCHY_FIRST, UNREGISTER_CLIENTS_FIRST};
314 static const BFSOrder kBFSOrderList[] = {BFS_FIRST, BFS_SECOND, BFS_THIRD};
315
316 class SurfaceManagerOrderingParamTest
317 : public SurfaceManagerOrderingTest,
318 public ::testing::WithParamInterface<
319 std::tr1::tuple<RegisterOrder, UnregisterOrder, BFSOrder>> {};
320
321 TEST_P(SurfaceManagerOrderingParamTest, Ordering) {
322 // Test the four permutations of client/hierarchy setting/unsetting and test
323 // each place the BFS can be added and removed. The BFS and the
324 // client/hierarchy are less related, so BFS is tested independently instead
325 // of every permutation of BFS setting and unsetting.
326 // The register/unregister functions themselves test most of the state.
327 RegisterOrder register_order = std::tr1::get<0>(GetParam());
328 UnregisterOrder unregister_order = std::tr1::get<1>(GetParam());
329 BFSOrder bfs_order = std::tr1::get<2>(GetParam());
330
331 // Attach everything up in the specified order.
332 if (bfs_order == BFS_FIRST)
333 RegisterBFS();
334
335 if (register_order == REGISTER_HIERARCHY_FIRST)
336 RegisterHierarchy();
337 else
338 RegisterClients();
339
340 if (bfs_order == BFS_SECOND)
341 RegisterBFS();
342
343 if (register_order == REGISTER_HIERARCHY_FIRST)
344 RegisterClients();
345 else
346 RegisterHierarchy();
347
348 if (bfs_order == BFS_THIRD)
349 RegisterBFS();
350
351 // Everything hooked up, so should be valid.
352 AssertAllValidBFS();
353
354 // Detach everything in the specified order.
355 if (bfs_order == BFS_THIRD)
356 UnregisterBFS();
357
358 if (unregister_order == UNREGISTER_HIERARCHY_FIRST)
359 UnregisterHierarchy();
360 else
361 UnregisterClients();
362
363 if (bfs_order == BFS_SECOND)
364 UnregisterBFS();
365
366 if (unregister_order == UNREGISTER_HIERARCHY_FIRST)
367 UnregisterClients();
368 else
369 UnregisterHierarchy();
370
371 if (bfs_order == BFS_FIRST)
372 UnregisterBFS();
373 }
374
375 INSTANTIATE_TEST_CASE_P(
376 SurfaceManagerOrderingParamTestInstantiation,
377 SurfaceManagerOrderingParamTest,
378 ::testing::Combine(::testing::ValuesIn(kRegisterOrderList),
379 ::testing::ValuesIn(kUnregisterOrderList),
380 ::testing::ValuesIn(kBFSOrderList)));
381
382 } // namespace cc
OLDNEW
« no previous file with comments | « cc/surfaces/surface_manager.cc ('k') | cc/surfaces/surface_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698