1 // Copyright 2017 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 "base/containers/flat_set.h"
6 #include "base/test/simple_test_tick_clock.h"
7 #include "components/viz/common/surfaces/surface_id.h"
8 #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
9 #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
10 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
11 #include "components/viz/service/surfaces/surface.h"
12 #include "components/viz/service/surfaces/surface_allocation_group.h"
13 #include "components/viz/test/begin_frame_args_test.h"
14 #include "components/viz/test/compositor_frame_helpers.h"
15 #include "components/viz/test/fake_external_begin_frame_source.h"
16 #include "components/viz/test/fake_surface_observer.h"
17 #include "components/viz/test/mock_compositor_frame_sink_client.h"
18 #include "components/viz/test/surface_id_allocator_set.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using testing::_;
23 using testing::Eq;
24 using testing::IsEmpty;
25 using testing::UnorderedElementsAre;
26
27 namespace viz {
28 namespace {
29
30 constexpr bool kIsRoot = true;
31 constexpr bool kIsChildRoot = false;
32 constexpr FrameSinkId kDisplayFrameSink(2, 0);
33 constexpr FrameSinkId kParentFrameSink(3, 0);
34 constexpr FrameSinkId kChildFrameSink1(65563, 0);
35 constexpr FrameSinkId kChildFrameSink2(65564, 0);
36 constexpr FrameSinkId kArbitraryFrameSink(1337, 7331);
37
empty_surface_ids()38 std::vector<SurfaceId> empty_surface_ids() {
39 return std::vector<SurfaceId>();
40 }
empty_surface_ranges()41 std::vector<SurfaceRange> empty_surface_ranges() {
42 return std::vector<SurfaceRange>();
43 }
44
MakeCompositorFrame(std::vector<SurfaceId> activation_dependencies,std::vector<SurfaceRange> referenced_surfaces,std::vector<TransferableResource> resource_list,const FrameDeadline & deadline=FrameDeadline ())45 CompositorFrame MakeCompositorFrame(
46 std::vector<SurfaceId> activation_dependencies,
47 std::vector<SurfaceRange> referenced_surfaces,
48 std::vector<TransferableResource> resource_list,
49 const FrameDeadline& deadline = FrameDeadline()) {
50 return CompositorFrameBuilder()
51 .AddDefaultRenderPass()
52 .SetActivationDependencies(std::move(activation_dependencies))
53 .SetReferencedSurfaces(std::move(referenced_surfaces))
54 .SetTransferableResources(std::move(resource_list))
55 .SetDeadline(deadline)
56 .Build();
57 }
58
59 } // namespace
60
61 class SurfaceSynchronizationTest : public testing::Test {
62 public:
SurfaceSynchronizationTest()63 SurfaceSynchronizationTest()
64 : frame_sink_manager_(&shared_bitmap_manager_),
65 surface_observer_(false) {}
~SurfaceSynchronizationTest()66 ~SurfaceSynchronizationTest() override {}
67
display_support()68 CompositorFrameSinkSupport& display_support() {
69 return *supports_[kDisplayFrameSink];
70 }
display_surface()71 Surface* display_surface() {
72 return display_support().GetLastCreatedSurfaceForTesting();
73 }
74
parent_support()75 CompositorFrameSinkSupport& parent_support() {
76 return *supports_[kParentFrameSink];
77 }
parent_surface()78 Surface* parent_surface() {
79 return parent_support().GetLastCreatedSurfaceForTesting();
80 }
81
child_support1()82 CompositorFrameSinkSupport& child_support1() {
83 return *supports_[kChildFrameSink1];
84 }
child_surface1()85 Surface* child_surface1() {
86 return child_support1().GetLastCreatedSurfaceForTesting();
87 }
88
child_support2()89 CompositorFrameSinkSupport& child_support2() {
90 return *supports_[kChildFrameSink2];
91 }
child_surface2()92 Surface* child_surface2() {
93 return child_support2().GetLastCreatedSurfaceForTesting();
94 }
95
CreateFrameSink(const FrameSinkId & frame_sink_id,bool is_root)96 void CreateFrameSink(const FrameSinkId& frame_sink_id, bool is_root) {
97 supports_[frame_sink_id] = std::make_unique<CompositorFrameSinkSupport>(
98 &support_client_, &frame_sink_manager_, frame_sink_id, is_root);
99 }
100
DestroyFrameSink(const FrameSinkId & frame_sink_id)101 void DestroyFrameSink(const FrameSinkId& frame_sink_id) {
102 auto it = supports_.find(frame_sink_id);
103 if (it == supports_.end())
104 return;
105 supports_.erase(it);
106 }
107
ExpireAllTemporaryReferencesAndGarbageCollect()108 void ExpireAllTemporaryReferencesAndGarbageCollect() {
109 frame_sink_manager_.surface_manager()->ExpireOldTemporaryReferences();
110 frame_sink_manager_.surface_manager()->ExpireOldTemporaryReferences();
111 frame_sink_manager_.surface_manager()->GarbageCollectSurfaces();
112 }
113
114 // Returns all the references where |surface_id| is the parent.
GetReferencesFrom(const SurfaceId & surface_id)115 const base::flat_set<SurfaceId>& GetReferencesFrom(
116 const SurfaceId& surface_id) {
117 return frame_sink_manager()
118 .surface_manager()
119 ->GetSurfacesReferencedByParent(surface_id);
120 }
121
frame_sink_manager()122 FrameSinkManagerImpl& frame_sink_manager() { return frame_sink_manager_; }
surface_manager()123 SurfaceManager* surface_manager() {
124 return frame_sink_manager_.surface_manager();
125 }
126
127 // Returns all the references where |surface_id| is the parent.
GetChildReferences(const SurfaceId & surface_id)128 const base::flat_set<SurfaceId>& GetChildReferences(
129 const SurfaceId& surface_id) {
130 return frame_sink_manager()
131 .surface_manager()
132 ->GetSurfacesReferencedByParent(surface_id);
133 }
134
135 // Returns true if there is a temporary reference for |surface_id|.
HasTemporaryReference(const SurfaceId & surface_id)136 bool HasTemporaryReference(const SurfaceId& surface_id) {
137 return frame_sink_manager().surface_manager()->HasTemporaryReference(
138 surface_id);
139 }
140
GetLatestInFlightSurface(const SurfaceRange & surface_range)141 Surface* GetLatestInFlightSurface(const SurfaceRange& surface_range) {
142 return frame_sink_manager().surface_manager()->GetLatestInFlightSurface(
143 surface_range);
144 }
145
begin_frame_source()146 FakeExternalBeginFrameSource* begin_frame_source() {
147 return begin_frame_source_.get();
148 }
149
Now()150 base::TimeTicks Now() { return now_src_->NowTicks(); }
151
MakeDefaultDeadline()152 FrameDeadline MakeDefaultDeadline() {
153 return FrameDeadline(Now(), 4u, BeginFrameArgs::DefaultInterval(), false);
154 }
155
MakeDeadline(uint32_t deadline_in_frames)156 FrameDeadline MakeDeadline(uint32_t deadline_in_frames) {
157 return FrameDeadline(Now(), deadline_in_frames,
158 BeginFrameArgs::DefaultInterval(), false);
159 }
160
SendNextBeginFrame()161 void SendNextBeginFrame() {
162 // Creep the time forward so that any BeginFrameArgs is not equal to the
163 // last one otherwise we violate the BeginFrameSource contract.
164 now_src_->Advance(BeginFrameArgs::DefaultInterval());
165 BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
166 BEGINFRAME_FROM_HERE, now_src_.get());
167 begin_frame_source_->TestOnBeginFrame(args);
168 }
169
SendLateBeginFrame()170 void SendLateBeginFrame() {
171 // Creep the time forward so that any BeginFrameArgs is not equal to the
172 // last one otherwise we violate the BeginFrameSource contract.
173 now_src_->Advance(4u * BeginFrameArgs::DefaultInterval());
174 BeginFrameArgs args = begin_frame_source_->CreateBeginFrameArgs(
175 BEGINFRAME_FROM_HERE, now_src_.get());
176 begin_frame_source_->TestOnBeginFrame(args);
177 }
178
surface_observer()179 FakeSurfaceObserver& surface_observer() { return surface_observer_; }
180
181 // testing::Test:
SetUp()182 void SetUp() override {
183 testing::Test::SetUp();
184
185 begin_frame_source_ =
186 std::make_unique<FakeExternalBeginFrameSource>(0.f, false);
187 now_src_ = std::make_unique<base::SimpleTestTickClock>();
188 frame_sink_manager_.surface_manager()->SetTickClockForTesting(
189 now_src_.get());
190 frame_sink_manager_.surface_manager()->AddObserver(&surface_observer_);
191 supports_[kDisplayFrameSink] = std::make_unique<CompositorFrameSinkSupport>(
192 &support_client_, &frame_sink_manager_, kDisplayFrameSink, kIsRoot);
193
194 supports_[kParentFrameSink] = std::make_unique<CompositorFrameSinkSupport>(
195 &support_client_, &frame_sink_manager_, kParentFrameSink, kIsChildRoot);
196
197 supports_[kChildFrameSink1] = std::make_unique<CompositorFrameSinkSupport>(
198 &support_client_, &frame_sink_manager_, kChildFrameSink1, kIsChildRoot);
199
200 supports_[kChildFrameSink2] = std::make_unique<CompositorFrameSinkSupport>(
201 &support_client_, &frame_sink_manager_, kChildFrameSink2, kIsChildRoot);
202
203 // Normally, the BeginFrameSource would be registered by the Display. We
204 // register it here so that BeginFrames are received by the display support,
205 // for use in the PassesOnBeginFrameAcks test. Other supports do not receive
206 // BeginFrames, since the frame sink hierarchy is not set up in this test.
207 frame_sink_manager_.RegisterBeginFrameSource(begin_frame_source_.get(),
208 kDisplayFrameSink);
209 frame_sink_manager_.RegisterFrameSinkHierarchy(kDisplayFrameSink,
210 kParentFrameSink);
211 frame_sink_manager_.RegisterFrameSinkHierarchy(kDisplayFrameSink,
212 kChildFrameSink1);
213 frame_sink_manager_.RegisterFrameSinkHierarchy(kDisplayFrameSink,
214 kChildFrameSink2);
215 }
216
TearDown()217 void TearDown() override {
218 frame_sink_manager_.surface_manager()->RemoveObserver(&surface_observer_);
219 frame_sink_manager_.UnregisterBeginFrameSource(begin_frame_source_.get());
220
221 begin_frame_source_->SetClient(nullptr);
222 begin_frame_source_.reset();
223
224 supports_.clear();
225
226 surface_observer_.Reset();
227 }
228
IsMarkedForDestruction(const SurfaceId & surface_id)229 bool IsMarkedForDestruction(const SurfaceId& surface_id) {
230 return frame_sink_manager_.surface_manager()->IsMarkedForDestruction(
231 surface_id);
232 }
233
GetSurfaceForId(const SurfaceId & surface_id)234 Surface* GetSurfaceForId(const SurfaceId& surface_id) {
235 return frame_sink_manager_.surface_manager()->GetSurfaceForId(surface_id);
236 }
237
MakeSurfaceId(const FrameSinkId & frame_sink_id,uint32_t parent_sequence_number,uint32_t child_sequence_number=1u)238 SurfaceId MakeSurfaceId(const FrameSinkId& frame_sink_id,
239 uint32_t parent_sequence_number,
240 uint32_t child_sequence_number = 1u) {
241 return allocator_set_.MakeSurfaceId(frame_sink_id, parent_sequence_number,
242 child_sequence_number);
243 }
244
allocation_groups_need_garbage_collection()245 bool allocation_groups_need_garbage_collection() {
246 return surface_manager()->allocation_groups_need_garbage_collection_;
247 }
248
249 protected:
250 testing::NiceMock<MockCompositorFrameSinkClient> support_client_;
251
252 private:
253 std::unique_ptr<base::SimpleTestTickClock> now_src_;
254 ServerSharedBitmapManager shared_bitmap_manager_;
255 FrameSinkManagerImpl frame_sink_manager_;
256 FakeSurfaceObserver surface_observer_;
257 std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source_;
258 std::unordered_map<FrameSinkId,
259 std::unique_ptr<CompositorFrameSinkSupport>,
260 FrameSinkIdHash>
261 supports_;
262 SurfaceIdAllocatorSet allocator_set_;
263
264 DISALLOW_COPY_AND_ASSIGN(SurfaceSynchronizationTest);
265 };
266
267 // The display root surface should have a surface reference from the top-level
268 // root added/removed when a CompositorFrame is submitted with a new
269 // SurfaceId.
TEST_F(SurfaceSynchronizationTest,RootSurfaceReceivesReferences)270 TEST_F(SurfaceSynchronizationTest, RootSurfaceReceivesReferences) {
271 const SurfaceId display_id_first = MakeSurfaceId(kDisplayFrameSink, 1);
272 const SurfaceId display_id_second = MakeSurfaceId(kDisplayFrameSink, 2);
273
274 // Submit a CompositorFrame for the first display root surface.
275 display_support().SubmitCompositorFrame(display_id_first.local_surface_id(),
276 MakeDefaultCompositorFrame());
277
278 // A surface reference from the top-level root is added and there shouldn't be
279 // a temporary reference.
280 EXPECT_FALSE(HasTemporaryReference(display_id_first));
281 EXPECT_THAT(GetChildReferences(
282 frame_sink_manager().surface_manager()->GetRootSurfaceId()),
283 UnorderedElementsAre(display_id_first));
284
285 // Submit a CompositorFrame for the second display root surface.
286 display_support().SubmitCompositorFrame(display_id_second.local_surface_id(),
287 MakeDefaultCompositorFrame());
288
289 // A surface reference from the top-level root to |display_id_second| should
290 // be added and the reference to |display_root_first| removed.
291 EXPECT_FALSE(HasTemporaryReference(display_id_second));
292 EXPECT_THAT(GetChildReferences(
293 frame_sink_manager().surface_manager()->GetRootSurfaceId()),
294 UnorderedElementsAre(display_id_second));
295
296 frame_sink_manager().surface_manager()->GarbageCollectSurfaces();
297
298 // Surface |display_id_first| is unreachable and should get deleted.
299 EXPECT_EQ(nullptr, GetSurfaceForId(display_id_first));
300 }
301
302 // The parent Surface is blocked on |child_id1| and |child_id2|.
TEST_F(SurfaceSynchronizationTest,BlockedOnTwo)303 TEST_F(SurfaceSynchronizationTest, BlockedOnTwo) {
304 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
305 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
306 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
307
308 parent_support().SubmitCompositorFrame(
309 parent_id.local_surface_id(),
310 MakeCompositorFrame({child_id1, child_id2}, empty_surface_ranges(),
311 std::vector<TransferableResource>()));
312
313 // parent_support is blocked on |child_id1| and |child_id2|.
314 EXPECT_TRUE(parent_surface()->has_deadline());
315 EXPECT_FALSE(parent_surface()->HasActiveFrame());
316 EXPECT_TRUE(parent_surface()->HasPendingFrame());
317 EXPECT_THAT(parent_surface()->activation_dependencies(),
318 UnorderedElementsAre(child_id1, child_id2));
319
320 // Submit a CompositorFrame without any dependencies to |child_id1|.
321 // parent_support should now only be blocked on |child_id2|.
322 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
323 MakeDefaultCompositorFrame());
324
325 EXPECT_TRUE(parent_surface()->has_deadline());
326 EXPECT_FALSE(parent_surface()->HasActiveFrame());
327 EXPECT_TRUE(parent_surface()->HasPendingFrame());
328 EXPECT_THAT(parent_surface()->activation_dependencies(),
329 UnorderedElementsAre(child_id2));
330
331 // Submit a CompositorFrame without any dependencies to |child_id2|.
332 // parent_support should be activated.
333 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
334 MakeDefaultCompositorFrame());
335
336 EXPECT_FALSE(child_surface2()->has_deadline());
337 EXPECT_TRUE(parent_surface()->HasActiveFrame());
338 EXPECT_FALSE(parent_surface()->HasPendingFrame());
339 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
340 }
341
342 // The parent Surface is blocked on |child_id2| which is blocked on
343 // |child_id3|.
TEST_F(SurfaceSynchronizationTest,BlockedChain)344 TEST_F(SurfaceSynchronizationTest, BlockedChain) {
345 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
346 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
347 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
348
349 parent_support().SubmitCompositorFrame(
350 parent_id.local_surface_id(),
351 MakeCompositorFrame({child_id1}, empty_surface_ranges(),
352 std::vector<TransferableResource>()));
353
354 // parent_support is blocked on |child_id1|.
355 EXPECT_TRUE(parent_surface()->has_deadline());
356 EXPECT_FALSE(parent_surface()->HasActiveFrame());
357 EXPECT_TRUE(parent_surface()->HasPendingFrame());
358 EXPECT_THAT(parent_surface()->activation_dependencies(),
359 UnorderedElementsAre(child_id1));
360 // The parent should not report damage until it activates.
361 EXPECT_FALSE(surface_observer().IsSurfaceDamaged(parent_id));
362
363 child_support1().SubmitCompositorFrame(
364 child_id1.local_surface_id(),
365 MakeCompositorFrame({child_id2}, empty_surface_ranges(),
366 std::vector<TransferableResource>()));
367
368 // child_support1 should now be blocked on |child_id2|.
369 EXPECT_TRUE(child_surface1()->has_deadline());
370 EXPECT_FALSE(child_surface1()->HasActiveFrame());
371 EXPECT_TRUE(child_surface1()->HasPendingFrame());
372 EXPECT_THAT(child_surface1()->activation_dependencies(),
373 UnorderedElementsAre(child_id2));
374 // The parent and child should not report damage until they activate.
375 EXPECT_FALSE(surface_observer().IsSurfaceDamaged(parent_id));
376 EXPECT_FALSE(surface_observer().IsSurfaceDamaged(child_id1));
377
378 // The parent should still be blocked on |child_id1| because it's pending.
379 EXPECT_THAT(parent_surface()->activation_dependencies(),
380 UnorderedElementsAre(child_id1));
381
382 // Submit a CompositorFrame without any dependencies to |child_id2|.
383 // parent_support should be activated.
384 child_support2().SubmitCompositorFrame(
385 child_id2.local_surface_id(),
386 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
387 std::vector<TransferableResource>()));
388
389 EXPECT_FALSE(child_surface2()->has_deadline());
390
391 // child_surface1 should now be active.
392 EXPECT_TRUE(child_surface1()->HasActiveFrame());
393 EXPECT_FALSE(child_surface1()->HasPendingFrame());
394 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
395
396 // parent_surface should now be active.
397 EXPECT_TRUE(parent_surface()->HasActiveFrame());
398 EXPECT_FALSE(parent_surface()->HasPendingFrame());
399 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
400
401 // All three surfaces |parent_id|, |child_id1|, and |child_id2| should
402 // now report damage. This would trigger a new display frame.
403 EXPECT_TRUE(surface_observer().IsSurfaceDamaged(parent_id));
404 EXPECT_TRUE(surface_observer().IsSurfaceDamaged(child_id1));
405 EXPECT_TRUE(surface_observer().IsSurfaceDamaged(child_id2));
406 }
407
408 // parent_surface and child_surface1 are blocked on |child_id2|.
TEST_F(SurfaceSynchronizationTest,TwoBlockedOnOne)409 TEST_F(SurfaceSynchronizationTest, TwoBlockedOnOne) {
410 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
411 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
412 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
413
414 parent_support().SubmitCompositorFrame(
415 parent_id.local_surface_id(),
416 MakeCompositorFrame({child_id2}, {SurfaceRange(base::nullopt, child_id2)},
417 std::vector<TransferableResource>()));
418
419 // parent_support is blocked on |child_id2|.
420 EXPECT_TRUE(parent_surface()->has_deadline());
421 EXPECT_FALSE(parent_surface()->HasActiveFrame());
422 EXPECT_TRUE(parent_surface()->HasPendingFrame());
423 EXPECT_THAT(parent_surface()->activation_dependencies(),
424 UnorderedElementsAre(child_id2));
425
426 // child_support1 should now be blocked on |child_id2|.
427 child_support1().SubmitCompositorFrame(
428 child_id1.local_surface_id(),
429 MakeCompositorFrame({child_id2}, {SurfaceRange(base::nullopt, child_id2)},
430 std::vector<TransferableResource>()));
431
432 EXPECT_TRUE(child_surface1()->has_deadline());
433 EXPECT_FALSE(child_surface1()->HasActiveFrame());
434 EXPECT_TRUE(child_surface1()->HasPendingFrame());
435 EXPECT_THAT(child_surface1()->activation_dependencies(),
436 UnorderedElementsAre(child_id2));
437
438 // The parent should still be blocked on |child_id2|.
439 EXPECT_THAT(parent_surface()->activation_dependencies(),
440 UnorderedElementsAre(child_id2));
441
442 // Submit a CompositorFrame without any dependencies to |child_id2|.
443 // parent_support should be activated.
444 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
445 MakeDefaultCompositorFrame());
446
447 EXPECT_FALSE(child_surface2()->has_deadline());
448
449 // child_surface1 should now be active.
450 EXPECT_TRUE(child_surface1()->HasActiveFrame());
451 EXPECT_FALSE(child_surface1()->HasPendingFrame());
452 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
453
454 // parent_surface should now be active.
455 EXPECT_TRUE(parent_surface()->HasActiveFrame());
456 EXPECT_FALSE(parent_surface()->HasPendingFrame());
457 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
458 }
459
460 // parent_surface is blocked on |child_id1|, and child_surface2 is blocked on
461 // |child_id2| until the deadline hits.
TEST_F(SurfaceSynchronizationTest,DeadlineHits)462 TEST_F(SurfaceSynchronizationTest, DeadlineHits) {
463 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
464 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
465 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
466
467 parent_support().SubmitCompositorFrame(
468 parent_id.local_surface_id(),
469 MakeCompositorFrame({child_id1}, empty_surface_ranges(),
470 std::vector<TransferableResource>(),
471 MakeDefaultDeadline()));
472
473 // parent_support is blocked on |child_id1|.
474 EXPECT_TRUE(parent_surface()->has_deadline());
475 EXPECT_FALSE(parent_surface()->HasActiveFrame());
476 EXPECT_TRUE(parent_surface()->HasPendingFrame());
477 EXPECT_THAT(parent_surface()->activation_dependencies(),
478 UnorderedElementsAre(child_id1));
479
480 child_support1().SubmitCompositorFrame(
481 child_id1.local_surface_id(),
482 MakeCompositorFrame({child_id2}, empty_surface_ranges(),
483 std::vector<TransferableResource>(),
484 MakeDefaultDeadline()));
485
486 // child_support1 should now be blocked on |child_id2|.
487 EXPECT_TRUE(child_surface1()->has_deadline());
488 EXPECT_FALSE(child_surface1()->HasActiveFrame());
489 EXPECT_TRUE(child_surface1()->HasPendingFrame());
490 EXPECT_THAT(child_surface1()->activation_dependencies(),
491 UnorderedElementsAre(child_id2));
492
493 // The parent should still be blocked on |child_id1| because it's pending.
494 EXPECT_THAT(parent_surface()->activation_dependencies(),
495 UnorderedElementsAre(child_id1));
496
497 for (int i = 0; i < 3; ++i) {
498 SendNextBeginFrame();
499 // There is still a looming deadline! Eeek!
500 EXPECT_TRUE(parent_surface()->has_deadline());
501
502 // parent_support is still blocked on |child_id1|.
503 EXPECT_FALSE(parent_surface()->HasActiveFrame());
504 EXPECT_TRUE(parent_surface()->HasPendingFrame());
505 EXPECT_THAT(parent_surface()->activation_dependencies(),
506 UnorderedElementsAre(child_id1));
507
508 // child_support1 is still blocked on |child_id2|.
509 EXPECT_FALSE(child_surface1()->HasActiveFrame());
510 EXPECT_TRUE(child_surface1()->HasPendingFrame());
511 EXPECT_THAT(child_surface1()->activation_dependencies(),
512 UnorderedElementsAre(child_id2));
513 }
514
515 SendNextBeginFrame();
516
517 // The deadline has passed.
518 EXPECT_FALSE(parent_surface()->has_deadline());
519
520 // parent_surface has been activated.
521 EXPECT_TRUE(parent_surface()->HasActiveFrame());
522 EXPECT_FALSE(parent_surface()->HasPendingFrame());
523 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
524
525 // child_surface1 has been activated.
526 EXPECT_TRUE(child_surface1()->HasActiveFrame());
527 EXPECT_FALSE(child_surface1()->HasPendingFrame());
528 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
529 }
530
531 // This test verifies that unlimited deadline mode works and that surfaces will
532 // not activate until dependencies are resolved.
TEST_F(SurfaceSynchronizationTest,UnlimitedDeadline)533 TEST_F(SurfaceSynchronizationTest, UnlimitedDeadline) {
534 // Turn on unlimited deadline mode.
535 frame_sink_manager()
536 .surface_manager()
537 ->SetActivationDeadlineInFramesForTesting(base::nullopt);
538
539 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
540 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
541
542 // The deadline specified by the parent is ignored in unlimited deadline
543 // mode.
544 parent_support().SubmitCompositorFrame(
545 parent_id.local_surface_id(),
546 MakeCompositorFrame({child_id1}, empty_surface_ranges(),
547 std::vector<TransferableResource>(),
548 MakeDefaultDeadline()));
549
550 // parent_support is blocked on |child_id1|.
551 EXPECT_FALSE(parent_surface()->HasActiveFrame());
552 EXPECT_TRUE(parent_surface()->HasPendingFrame());
553 EXPECT_THAT(parent_surface()->activation_dependencies(),
554 UnorderedElementsAre(child_id1));
555
556 for (int i = 0; i < 4; ++i) {
557 SendNextBeginFrame();
558 // parent_support is still blocked on |child_id1|.
559 EXPECT_FALSE(parent_surface()->HasActiveFrame());
560 EXPECT_TRUE(parent_surface()->HasPendingFrame());
561 EXPECT_THAT(parent_surface()->activation_dependencies(),
562 UnorderedElementsAre(child_id1));
563 }
564
565 // parent_support is STILL blocked on |child_id1|.
566 EXPECT_FALSE(parent_surface()->HasActiveFrame());
567 EXPECT_TRUE(parent_surface()->HasPendingFrame());
568 EXPECT_THAT(parent_surface()->activation_dependencies(),
569 UnorderedElementsAre(child_id1));
570
571 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
572 MakeDefaultCompositorFrame());
573
574 // parent_surface has been activated.
575 EXPECT_TRUE(parent_surface()->HasActiveFrame());
576 EXPECT_FALSE(parent_surface()->HasPendingFrame());
577 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
578 }
579
580 // parent_surface is blocked on |child_id1| until a late BeginFrame arrives and
581 // triggers a deadline.
TEST_F(SurfaceSynchronizationTest,LateBeginFrameTriggersDeadline)582 TEST_F(SurfaceSynchronizationTest, LateBeginFrameTriggersDeadline) {
583 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
584 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
585
586 parent_support().SubmitCompositorFrame(
587 parent_id.local_surface_id(),
588 MakeCompositorFrame({child_id1}, empty_surface_ranges(),
589 std::vector<TransferableResource>()));
590
591 // parent_support is blocked on |child_id1|.
592 EXPECT_TRUE(parent_surface()->has_deadline());
593 EXPECT_FALSE(parent_surface()->HasActiveFrame());
594 EXPECT_TRUE(parent_surface()->HasPendingFrame());
595 EXPECT_THAT(parent_surface()->activation_dependencies(),
596 UnorderedElementsAre(child_id1));
597
598 SendLateBeginFrame();
599
600 // The deadline has passed.
601 EXPECT_FALSE(parent_surface()->has_deadline());
602
603 // parent_surface has been activated.
604 EXPECT_TRUE(parent_surface()->HasActiveFrame());
605 EXPECT_FALSE(parent_surface()->HasPendingFrame());
606 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
607 }
608
609 // This test verifies at the Surface activates once a CompositorFrame is
610 // submitted that has no unresolved dependencies.
TEST_F(SurfaceSynchronizationTest,NewFrameOverridesOldDependencies)611 TEST_F(SurfaceSynchronizationTest, NewFrameOverridesOldDependencies) {
612 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
613 const SurfaceId arbitrary_id = MakeSurfaceId(kArbitraryFrameSink, 1);
614
615 // Submit a CompositorFrame that depends on |arbitrary_id|.
616 parent_support().SubmitCompositorFrame(
617 parent_id.local_surface_id(),
618 MakeCompositorFrame({arbitrary_id}, empty_surface_ranges(),
619 std::vector<TransferableResource>()));
620
621 // Verify that the CompositorFrame is blocked on |arbitrary_id|.
622 EXPECT_FALSE(parent_surface()->HasActiveFrame());
623 EXPECT_TRUE(parent_surface()->HasPendingFrame());
624 EXPECT_THAT(parent_surface()->activation_dependencies(),
625 UnorderedElementsAre(arbitrary_id));
626
627 // Submit a CompositorFrame that has no dependencies.
628 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
629 MakeDefaultCompositorFrame());
630
631 // Verify that the CompositorFrame has been activated.
632 EXPECT_TRUE(parent_surface()->HasActiveFrame());
633 EXPECT_FALSE(parent_surface()->HasPendingFrame());
634 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
635 }
636
637 // This test verifies that a pending CompositorFrame does not affect surface
638 // references. A new surface from a child will continue to exist as a temporary
639 // reference until the parent's frame activates.
TEST_F(SurfaceSynchronizationTest,OnlyActiveFramesAffectSurfaceReferences)640 TEST_F(SurfaceSynchronizationTest, OnlyActiveFramesAffectSurfaceReferences) {
641 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
642 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
643 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
644
645 // child_support1 submits a CompositorFrame without any dependencies.
646 // DidReceiveCompositorFrameAck should call on immediate activation.
647 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(1);
648 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
649 MakeDefaultCompositorFrame());
650 testing::Mock::VerifyAndClearExpectations(&support_client_);
651
652 // Verify that the child surface is not blocked.
653 EXPECT_TRUE(child_surface1()->HasActiveFrame());
654 EXPECT_FALSE(child_surface1()->HasPendingFrame());
655 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
656
657 // Verify that there's a temporary reference for |child_id1|.
658 EXPECT_TRUE(HasTemporaryReference(child_id1));
659
660 // parent_support submits a CompositorFrame that depends on |child_id1|
661 // (which is already active) and |child_id2|. Thus, the parent should not
662 // activate immediately. DidReceiveCompositorFrameAck should not be called
663 // immediately because the parent CompositorFrame is also blocked on
664 // |child_id2|.
665 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(0);
666 parent_support().SubmitCompositorFrame(
667 parent_id.local_surface_id(),
668 MakeCompositorFrame({child_id2}, {SurfaceRange(child_id1)},
669 std::vector<TransferableResource>()));
670 EXPECT_FALSE(parent_surface()->HasActiveFrame());
671 EXPECT_TRUE(parent_surface()->HasPendingFrame());
672 EXPECT_THAT(parent_surface()->activation_dependencies(),
673 UnorderedElementsAre(child_id2));
674 EXPECT_THAT(GetChildReferences(parent_id), IsEmpty());
675 testing::Mock::VerifyAndClearExpectations(&support_client_);
676
677 // Verify that there's a temporary reference for |child_id1| that still
678 // exists.
679 EXPECT_TRUE(HasTemporaryReference(child_id1));
680
681 // child_support2 submits a CompositorFrame without any dependencies.
682 // Both the child and the parent should immediately ACK CompositorFrames
683 // on activation.
684 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(2);
685 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
686 MakeDefaultCompositorFrame());
687 testing::Mock::VerifyAndClearExpectations(&support_client_);
688
689 // Verify that the child surface is not blocked.
690 EXPECT_TRUE(child_surface1()->HasActiveFrame());
691 EXPECT_FALSE(child_surface1()->HasPendingFrame());
692 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
693
694 // Verify that the parent surface's CompositorFrame has activated and that
695 // the temporary reference has been replaced by a permanent one.
696 EXPECT_TRUE(parent_surface()->HasActiveFrame());
697 EXPECT_FALSE(parent_surface()->HasPendingFrame());
698 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
699 EXPECT_FALSE(HasTemporaryReference(child_id1));
700 EXPECT_THAT(GetChildReferences(parent_id), UnorderedElementsAre(child_id1));
701 }
702
703 // This test verifies that we do not double count returned resources when a
704 // CompositorFrame starts out as pending, then becomes active, and then is
705 // replaced with another active CompositorFrame.
TEST_F(SurfaceSynchronizationTest,ResourcesOnlyReturnedOnce)706 TEST_F(SurfaceSynchronizationTest, ResourcesOnlyReturnedOnce) {
707 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
708 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
709
710 // The parent submits a CompositorFrame that depends on |child_id| before
711 // the child submits a CompositorFrame. The CompositorFrame also has
712 // resources in its resource list.
713 TransferableResource resource;
714 resource.id = 1337;
715 resource.format = ALPHA_8;
716 resource.filter = 1234;
717 resource.size = gfx::Size(1234, 5678);
718 std::vector<TransferableResource> resource_list = {resource};
719 parent_support().SubmitCompositorFrame(
720 parent_id.local_surface_id(),
721 MakeCompositorFrame({child_id}, empty_surface_ranges(), resource_list));
722
723 // Verify that the CompositorFrame is blocked on |child_id|.
724 EXPECT_FALSE(parent_surface()->HasActiveFrame());
725 EXPECT_TRUE(parent_surface()->HasPendingFrame());
726 EXPECT_THAT(parent_surface()->activation_dependencies(),
727 UnorderedElementsAre(child_id));
728
729 child_support1().SubmitCompositorFrame(
730 child_id.local_surface_id(),
731 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
732 std::vector<TransferableResource>()));
733
734 // Verify that the child CompositorFrame activates immediately.
735 EXPECT_TRUE(child_surface1()->HasActiveFrame());
736 EXPECT_FALSE(child_surface1()->HasPendingFrame());
737 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
738
739 // Verify that the parent has activated.
740 EXPECT_TRUE(parent_surface()->HasActiveFrame());
741 EXPECT_FALSE(parent_surface()->HasPendingFrame());
742 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
743
744 std::vector<ReturnedResource> returned_resources = {
745 resource.ToReturnedResource()};
746 EXPECT_CALL(support_client_,
747 DidReceiveCompositorFrameAck(returned_resources));
748
749 // The parent submits a CompositorFrame without any dependencies. That
750 // frame should activate immediately, replacing the earlier frame. The
751 // resource from the earlier frame should be returned to the client.
752 parent_support().SubmitCompositorFrame(
753 parent_id.local_surface_id(),
754 MakeCompositorFrame({empty_surface_ids()}, {empty_surface_ranges()},
755 std::vector<TransferableResource>()));
756 EXPECT_TRUE(parent_surface()->HasActiveFrame());
757 EXPECT_FALSE(parent_surface()->HasPendingFrame());
758 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
759 }
760
761 // This test verifies that if a surface has both a pending and active
762 // CompositorFrame and the pending CompositorFrame activates, replacing
763 // the existing active CompositorFrame, then the surface reference hierarchy
764 // will be updated allowing garbage collection of surfaces that are no longer
765 // referenced.
TEST_F(SurfaceSynchronizationTest,DropStaleReferencesAfterActivation)766 TEST_F(SurfaceSynchronizationTest, DropStaleReferencesAfterActivation) {
767 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
768 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
769 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
770
771 // The parent submits a CompositorFrame that depends on |child_id1| before
772 // the child submits a CompositorFrame.
773 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(0);
774 parent_support().SubmitCompositorFrame(
775 parent_id.local_surface_id(),
776 MakeCompositorFrame({child_id1}, empty_surface_ranges(),
777 std::vector<TransferableResource>()));
778
779 // Verify that the CompositorFrame is blocked on |child_id|.
780 EXPECT_FALSE(parent_surface()->HasActiveFrame());
781 EXPECT_TRUE(parent_surface()->HasPendingFrame());
782 EXPECT_THAT(parent_surface()->activation_dependencies(),
783 UnorderedElementsAre(child_id1));
784 testing::Mock::VerifyAndClearExpectations(&support_client_);
785
786 // Verify that no references are added while the CompositorFrame is
787 // pending.
788 EXPECT_THAT(GetChildReferences(parent_id), IsEmpty());
789
790 // DidReceiveCompositorFrameAck should get called twice: once for the child
791 // and once for the now active parent CompositorFrame.
792 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(2);
793 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
794 MakeDefaultCompositorFrame());
795 testing::Mock::VerifyAndClearExpectations(&support_client_);
796
797 // Verify that the child CompositorFrame activates immediately.
798 EXPECT_TRUE(child_surface1()->HasActiveFrame());
799 EXPECT_FALSE(child_surface1()->HasPendingFrame());
800 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
801
802 // Verify that the parent Surface has activated.
803 EXPECT_TRUE(parent_surface()->HasActiveFrame());
804 EXPECT_FALSE(parent_surface()->HasPendingFrame());
805 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
806
807 // Submit a new parent CompositorFrame to add a reference.
808 parent_support().SubmitCompositorFrame(
809 parent_id.local_surface_id(),
810 MakeCompositorFrame(empty_surface_ids(), {SurfaceRange(child_id1)},
811 std::vector<TransferableResource>()));
812
813 // Verify that the parent Surface has activated.
814 EXPECT_TRUE(parent_surface()->HasActiveFrame());
815 EXPECT_FALSE(parent_surface()->HasPendingFrame());
816 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
817
818 // Verify that there is no temporary reference for the child and that
819 // the reference from the parent to the child still exists.
820 EXPECT_FALSE(HasTemporaryReference(child_id1));
821 EXPECT_THAT(GetChildReferences(parent_id), UnorderedElementsAre(child_id1));
822
823 // The parent submits another CompositorFrame that depends on |child_id2|.
824 // Submitting a pending CompositorFrame will not trigger a
825 // CompositorFrameAck.
826 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(0);
827 parent_support().SubmitCompositorFrame(
828 parent_id.local_surface_id(),
829 MakeCompositorFrame({child_id2}, empty_surface_ranges(),
830 std::vector<TransferableResource>()));
831 testing::Mock::VerifyAndClearExpectations(&support_client_);
832
833 // The parent surface should now have both a pending and activate
834 // CompositorFrame. Verify that the set of child references from
835 // |parent_id| are only from the active CompositorFrame.
836 EXPECT_TRUE(parent_surface()->HasActiveFrame());
837 EXPECT_TRUE(parent_surface()->HasPendingFrame());
838 EXPECT_THAT(parent_surface()->activation_dependencies(),
839 UnorderedElementsAre(child_id2));
840 EXPECT_THAT(GetChildReferences(parent_id), UnorderedElementsAre(child_id1));
841
842 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
843 MakeDefaultCompositorFrame());
844
845 // Verify that the parent Surface has activated and no longer has a
846 // pending CompositorFrame. Also verify that |child_id1| is no longer a
847 // child reference of |parent_id|.
848 EXPECT_TRUE(parent_surface()->HasActiveFrame());
849 EXPECT_FALSE(parent_surface()->HasPendingFrame());
850 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
851 // The parent will not immediately refer to the child until it submits a new
852 // CompositorFrame with the reference.
853 EXPECT_THAT(GetChildReferences(parent_id), IsEmpty());
854 }
855
856 // Verifies that LatencyInfo does not get too large after multiple frame
857 // submissions.
TEST_F(SurfaceSynchronizationTest,LimitLatencyInfo)858 TEST_F(SurfaceSynchronizationTest, LimitLatencyInfo) {
859 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
860 const ui::LatencyComponentType latency_type1 =
861 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT;
862 const ui::LatencyComponentType latency_type2 =
863 ui::LATENCY_COMPONENT_TYPE_LAST;
864
865 // Submit a frame with latency info
866 ui::LatencyInfo info;
867 info.AddLatencyNumber(latency_type1);
868
869 CompositorFrameBuilder builder;
870 builder.AddDefaultRenderPass();
871 for (int i = 0; i < 60; ++i)
872 builder.AddLatencyInfo(info);
873 CompositorFrame frame = builder.Build();
874
875 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
876 std::move(frame));
877
878 // Verify that the surface has an active frame and no pending frame.
879 Surface* surface = GetSurfaceForId(parent_id);
880 ASSERT_NE(nullptr, surface);
881 EXPECT_TRUE(surface->HasActiveFrame());
882 EXPECT_FALSE(surface->HasPendingFrame());
883
884 // Submit another frame with some other latency info.
885 ui::LatencyInfo info2;
886 info2.AddLatencyNumber(latency_type2);
887
888 builder.AddDefaultRenderPass();
889 for (int i = 0; i < 60; ++i)
890 builder.AddLatencyInfo(info);
891 CompositorFrame frame2 = builder.Build();
892
893 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
894 std::move(frame2));
895
896 // Verify that the surface has an active frame and no pending frames.
897 EXPECT_TRUE(surface->HasActiveFrame());
898 EXPECT_FALSE(surface->HasPendingFrame());
899
900 // Verify that the surface has no latency info objects because it grew
901 // too large.
902 std::vector<ui::LatencyInfo> info_list;
903 surface->TakeActiveLatencyInfo(&info_list);
904 EXPECT_EQ(0u, info_list.size());
905 }
906
907 // Checks whether SurfaceAllocationGroup properly aggregates LatencyInfo of
908 // multiple surfaces. In this variation of the test, there are no pending
909 // frames.
TEST_F(SurfaceSynchronizationTest,LatencyInfoAggregation_NoUnresolvedDependencies)910 TEST_F(SurfaceSynchronizationTest,
911 LatencyInfoAggregation_NoUnresolvedDependencies) {
912 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
913 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
914 const ui::LatencyComponentType latency_type1 =
915 ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT;
916 const ui::LatencyComponentType latency_type2 =
917 ui::LATENCY_COMPONENT_TYPE_LAST;
918
919 // Submit a frame with latency info
920 ui::LatencyInfo info;
921 info.AddLatencyNumber(latency_type1);
922
923 CompositorFrame frame = CompositorFrameBuilder()
924 .AddDefaultRenderPass()
925 .AddLatencyInfo(info)
926 .Build();
927
928 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
929 std::move(frame));
930
931 // Verify that the old surface has an active frame and no pending frame.
932 Surface* old_surface = GetSurfaceForId(parent_id1);
933 ASSERT_NE(nullptr, old_surface);
934 EXPECT_TRUE(old_surface->HasActiveFrame());
935 EXPECT_FALSE(old_surface->HasPendingFrame());
936
937 // Submit another frame with some other latency info and a different
938 // LocalSurfaceId.
939 ui::LatencyInfo info2;
940 info2.AddLatencyNumber(latency_type2);
941
942 CompositorFrame frame2 = CompositorFrameBuilder()
943 .AddDefaultRenderPass()
944 .AddLatencyInfo(info2)
945 .Build();
946
947 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
948 std::move(frame2));
949
950 // Verify that the new surface has an active frame and no pending frames.
951 Surface* surface = GetSurfaceForId(parent_id2);
952 ASSERT_NE(nullptr, surface);
953 EXPECT_TRUE(surface->HasActiveFrame());
954 EXPECT_FALSE(surface->HasPendingFrame());
955
956 // Verify that the new surface has both latency info elements.
957 std::vector<ui::LatencyInfo> info_list;
958 surface->allocation_group()->TakeAggregatedLatencyInfoUpTo(surface,
959 &info_list);
960 EXPECT_EQ(2u, info_list.size());
961
962 ui::LatencyInfo aggregated_latency_info = info_list[0];
963 aggregated_latency_info.AddNewLatencyFrom(info_list[1]);
964
965 // Two components are the original ones, and the third one is
966 // DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, logged on compositor frame
967 // submit.
968 EXPECT_EQ(3u, aggregated_latency_info.latency_components().size());
969
970 EXPECT_TRUE(aggregated_latency_info.FindLatency(latency_type1, nullptr));
971 EXPECT_TRUE(aggregated_latency_info.FindLatency(latency_type2, nullptr));
972 EXPECT_TRUE(aggregated_latency_info.FindLatency(
973 ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, nullptr));
974 }
975
976 // Checks whether SurfaceAllocationGroup properly aggregates LatencyInfo of
977 // multiple surfaces. In this variation of the test, the older surface has both
978 // pending and active frames and we verify that the LatencyInfo of both pending
979 // and active frame are present in the aggregated LatencyInfo.
TEST_F(SurfaceSynchronizationTest,LatencyInfoAggregation_OldSurfaceHasPendingAndActiveFrame)980 TEST_F(SurfaceSynchronizationTest,
981 LatencyInfoAggregation_OldSurfaceHasPendingAndActiveFrame) {
982 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
983 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
984 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
985
986 const ui::LatencyComponentType latency_type1 =
987 ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT;
988 const ui::LatencyComponentType latency_type2 =
989 ui::LATENCY_COMPONENT_TYPE_LAST;
990
991 // Submit a frame with no unresolved dependency.
992 ui::LatencyInfo info;
993 info.AddLatencyNumber(latency_type1);
994
995 CompositorFrame frame = MakeDefaultCompositorFrame();
996 frame.metadata.latency_info.push_back(info);
997
998 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
999 std::move(frame));
1000
1001 // Submit a frame with unresolved dependencies.
1002 ui::LatencyInfo info2;
1003 info2.AddLatencyNumber(latency_type2);
1004
1005 CompositorFrame frame2 = MakeCompositorFrame(
1006 {child_id}, empty_surface_ranges(), std::vector<TransferableResource>());
1007 frame2.metadata.latency_info.push_back(info2);
1008
1009 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
1010 std::move(frame2));
1011
1012 // Verify that the old surface has both an active and a pending frame.
1013 Surface* old_surface = GetSurfaceForId(parent_id1);
1014 ASSERT_NE(nullptr, old_surface);
1015 EXPECT_TRUE(old_surface->HasActiveFrame());
1016 EXPECT_TRUE(old_surface->HasPendingFrame());
1017
1018 // Submit a frame with a new local surface id.
1019 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
1020 MakeDefaultCompositorFrame());
1021
1022 // Verify that the new surface has an active frame only.
1023 Surface* surface = GetSurfaceForId(parent_id2);
1024 ASSERT_NE(nullptr, surface);
1025 EXPECT_TRUE(surface->HasActiveFrame());
1026 EXPECT_FALSE(surface->HasPendingFrame());
1027
1028 // Verify that the aggregated LatencyInfo has LatencyInfo from both active and
1029 // pending frame of the old surface.
1030 std::vector<ui::LatencyInfo> info_list;
1031 surface->allocation_group()->TakeAggregatedLatencyInfoUpTo(surface,
1032 &info_list);
1033 EXPECT_EQ(2u, info_list.size());
1034
1035 ui::LatencyInfo aggregated_latency_info = info_list[0];
1036 aggregated_latency_info.AddNewLatencyFrom(info_list[1]);
1037
1038 // Two components are the original ones, and the third one is
1039 // DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, logged on compositor frame
1040 // submit.
1041 EXPECT_EQ(3u, aggregated_latency_info.latency_components().size());
1042
1043 EXPECT_TRUE(aggregated_latency_info.FindLatency(latency_type1, nullptr));
1044 EXPECT_TRUE(aggregated_latency_info.FindLatency(latency_type2, nullptr));
1045 EXPECT_TRUE(aggregated_latency_info.FindLatency(
1046 ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, nullptr));
1047 }
1048
1049 // Checks whether SurfaceAllocationGroup properly aggregates LatencyInfo of
1050 // multiple surfaces. In this variation of the test, the newer surface has a
1051 // pending frame that becomes active after the dependency is resolved and we
1052 // make sure the LatencyInfo of the activated frame is included in the
1053 // aggregated LatencyInfo.
TEST_F(SurfaceSynchronizationTest,LatencyInfoAggregation_NewSurfaceHasPendingFrame)1054 TEST_F(SurfaceSynchronizationTest,
1055 LatencyInfoAggregation_NewSurfaceHasPendingFrame) {
1056 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1057 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
1058 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
1059
1060 const ui::LatencyComponentType latency_type1 =
1061 ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT;
1062 const ui::LatencyComponentType latency_type2 =
1063 ui::LATENCY_COMPONENT_TYPE_LAST;
1064
1065 // Submit a frame with no unresolved dependencies.
1066 ui::LatencyInfo info;
1067 info.AddLatencyNumber(latency_type1);
1068
1069 CompositorFrame frame = MakeDefaultCompositorFrame();
1070 frame.metadata.latency_info.push_back(info);
1071
1072 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
1073 std::move(frame));
1074
1075 // Verify that the old surface has an active frame only.
1076 Surface* old_surface = GetSurfaceForId(parent_id1);
1077 ASSERT_NE(nullptr, old_surface);
1078 EXPECT_TRUE(old_surface->HasActiveFrame());
1079 EXPECT_FALSE(old_surface->HasPendingFrame());
1080
1081 // Submit a frame with a new local surface id and with unresolved
1082 // dependencies.
1083 ui::LatencyInfo info2;
1084 info2.AddLatencyNumber(latency_type2);
1085
1086 CompositorFrame frame2 = MakeCompositorFrame(
1087 {child_id}, empty_surface_ranges(), std::vector<TransferableResource>());
1088 frame2.metadata.latency_info.push_back(info2);
1089
1090 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
1091 std::move(frame2));
1092
1093 // Verify that the new surface has a pending frame and no active frame.
1094 Surface* surface = GetSurfaceForId(parent_id2);
1095 ASSERT_NE(nullptr, surface);
1096 EXPECT_TRUE(surface->HasPendingFrame());
1097 EXPECT_FALSE(surface->HasActiveFrame());
1098
1099 // Resolve the dependencies. The frame in parent's surface must become active.
1100 child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
1101 MakeDefaultCompositorFrame());
1102 EXPECT_FALSE(surface->HasPendingFrame());
1103 EXPECT_TRUE(surface->HasActiveFrame());
1104
1105 // Both latency info elements must exist in the aggregated LatencyInfo.
1106 std::vector<ui::LatencyInfo> info_list;
1107 surface->allocation_group()->TakeAggregatedLatencyInfoUpTo(surface,
1108 &info_list);
1109 EXPECT_EQ(2u, info_list.size());
1110
1111 ui::LatencyInfo aggregated_latency_info = info_list[0];
1112 aggregated_latency_info.AddNewLatencyFrom(info_list[1]);
1113
1114 // Two components are the original ones, and the third one is
1115 // DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, logged on compositor frame
1116 // submit.
1117 EXPECT_EQ(3u, aggregated_latency_info.latency_components().size());
1118
1119 EXPECT_TRUE(aggregated_latency_info.FindLatency(latency_type1, nullptr));
1120 EXPECT_TRUE(aggregated_latency_info.FindLatency(latency_type2, nullptr));
1121 EXPECT_TRUE(aggregated_latency_info.FindLatency(
1122 ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, nullptr));
1123 }
1124
1125 // Checks whether SurfaceAllocationGroup properly aggregates LatencyInfo of
1126 // multiple surfaces. In this variation of the test, multiple older surfaces
1127 // with pending frames exist during aggregation of an activated frame on a newer
1128 // surface.
TEST_F(SurfaceSynchronizationTest,LatencyInfoAggregation_MultipleOldSurfacesWithPendingFrames)1129 TEST_F(SurfaceSynchronizationTest,
1130 LatencyInfoAggregation_MultipleOldSurfacesWithPendingFrames) {
1131 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1132 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
1133 const SurfaceId parent_id3 = MakeSurfaceId(kParentFrameSink, 3);
1134 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
1135 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
1136
1137 const ui::LatencyComponentType latency_type1 =
1138 ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT;
1139 const ui::LatencyComponentType latency_type2 =
1140 ui::LATENCY_COMPONENT_TYPE_LAST;
1141
1142 // Submit a frame with unresolved dependencies to parent_id1.
1143 ui::LatencyInfo info1;
1144 info1.AddLatencyNumber(latency_type1);
1145
1146 CompositorFrame frame1 = MakeCompositorFrame(
1147 {child_id1}, empty_surface_ranges(), std::vector<TransferableResource>());
1148 frame1.metadata.latency_info.push_back(info1);
1149
1150 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
1151 std::move(frame1));
1152
1153 // Submit a frame with unresolved dependencies to parent_id2.
1154 ui::LatencyInfo info2;
1155 info2.AddLatencyNumber(latency_type2);
1156
1157 CompositorFrame frame2 = MakeCompositorFrame(
1158 {child_id2}, empty_surface_ranges(), std::vector<TransferableResource>());
1159 frame2.metadata.latency_info.push_back(info2);
1160
1161 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
1162 std::move(frame2));
1163
1164 // Verify that the both old surfaces have pending frames.
1165 Surface* old_surface1 = GetSurfaceForId(parent_id1);
1166 Surface* old_surface2 = GetSurfaceForId(parent_id2);
1167 ASSERT_NE(nullptr, old_surface1);
1168 ASSERT_NE(nullptr, old_surface2);
1169 EXPECT_FALSE(old_surface1->HasActiveFrame());
1170 EXPECT_FALSE(old_surface2->HasActiveFrame());
1171 EXPECT_TRUE(old_surface1->HasPendingFrame());
1172 EXPECT_TRUE(old_surface2->HasPendingFrame());
1173
1174 // Submit a frame with no dependencies to the new surface parent_id3.
1175 parent_support().SubmitCompositorFrame(parent_id3.local_surface_id(),
1176 MakeDefaultCompositorFrame());
1177
1178 // Verify that the new surface has an active frame only.
1179 Surface* surface = GetSurfaceForId(parent_id3);
1180 ASSERT_NE(nullptr, surface);
1181 EXPECT_TRUE(surface->HasActiveFrame());
1182 EXPECT_FALSE(surface->HasPendingFrame());
1183
1184 // Verify that the aggregated LatencyInfo has LatencyInfo from both old
1185 // surfaces.
1186 std::vector<ui::LatencyInfo> info_list;
1187 surface->allocation_group()->TakeAggregatedLatencyInfoUpTo(surface,
1188 &info_list);
1189 EXPECT_EQ(2u, info_list.size());
1190
1191 ui::LatencyInfo aggregated_latency_info = info_list[0];
1192 aggregated_latency_info.AddNewLatencyFrom(info_list[1]);
1193
1194 // Two components are the original ones, and the third one is
1195 // DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, logged on compositor frame
1196 // submit.
1197 EXPECT_EQ(3u, aggregated_latency_info.latency_components().size());
1198
1199 EXPECT_TRUE(aggregated_latency_info.FindLatency(latency_type1, nullptr));
1200 EXPECT_TRUE(aggregated_latency_info.FindLatency(latency_type2, nullptr));
1201 EXPECT_TRUE(aggregated_latency_info.FindLatency(
1202 ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, nullptr));
1203 }
1204
1205 // This test verifies that when a new surface is created, the LatencyInfo of the
1206 // previous surface does not get carried over into the new surface.
TEST_F(SurfaceSynchronizationTest,LatencyInfoNotCarriedOver)1207 TEST_F(SurfaceSynchronizationTest, LatencyInfoNotCarriedOver) {
1208 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1209 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
1210 const ui::LatencyComponentType latency_type1 =
1211 ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT;
1212 const ui::LatencyComponentType latency_type2 =
1213 ui::LATENCY_COMPONENT_TYPE_LAST;
1214
1215 // Submit a frame with latency info
1216 ui::LatencyInfo info;
1217 info.AddLatencyNumber(latency_type1);
1218
1219 CompositorFrame frame = CompositorFrameBuilder()
1220 .AddDefaultRenderPass()
1221 .AddLatencyInfo(info)
1222 .Build();
1223
1224 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
1225 std::move(frame));
1226
1227 // Verify that the old surface has an active frame and no pending frame.
1228 Surface* old_surface = GetSurfaceForId(parent_id1);
1229 ASSERT_NE(nullptr, old_surface);
1230 EXPECT_TRUE(old_surface->HasActiveFrame());
1231 EXPECT_FALSE(old_surface->HasPendingFrame());
1232
1233 // Submit another frame with some other latency info and a different
1234 // LocalSurfaceId.
1235 ui::LatencyInfo info2;
1236 info2.AddLatencyNumber(latency_type2);
1237
1238 CompositorFrame frame2 = CompositorFrameBuilder()
1239 .AddDefaultRenderPass()
1240 .AddLatencyInfo(info2)
1241 .Build();
1242
1243 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
1244 std::move(frame2));
1245
1246 // Verify that the new surface has an active frame and no pending frames.
1247 Surface* surface = GetSurfaceForId(parent_id2);
1248 ASSERT_NE(nullptr, surface);
1249 EXPECT_TRUE(surface->HasActiveFrame());
1250 EXPECT_FALSE(surface->HasPendingFrame());
1251
1252 // Verify that the old surface still has its LatencyInfo.
1253 std::vector<ui::LatencyInfo> info_list;
1254 old_surface->TakeActiveLatencyInfo(&info_list);
1255 EXPECT_EQ(1u, info_list.size());
1256 EXPECT_TRUE(info_list[0].FindLatency(latency_type1, nullptr));
1257 EXPECT_FALSE(info_list[0].FindLatency(latency_type2, nullptr));
1258 EXPECT_TRUE(info_list[0].FindLatency(
1259 ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, nullptr));
1260
1261 // Take the aggregated LatencyInfo. Since the LatencyInfo of the old surface
1262 // is previously taken, it should not show up here.
1263 info_list.clear();
1264 surface->allocation_group()->TakeAggregatedLatencyInfoUpTo(surface,
1265 &info_list);
1266 EXPECT_EQ(1u, info_list.size());
1267 EXPECT_EQ(2u, info_list[0].latency_components().size());
1268 EXPECT_FALSE(info_list[0].FindLatency(latency_type1, nullptr));
1269 EXPECT_TRUE(info_list[0].FindLatency(latency_type2, nullptr));
1270 EXPECT_TRUE(info_list[0].FindLatency(
1271 ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, nullptr));
1272 }
1273
1274 // Checks that resources and ack are sent together if possible.
TEST_F(SurfaceSynchronizationTest,ReturnResourcesWithAck)1275 TEST_F(SurfaceSynchronizationTest, ReturnResourcesWithAck) {
1276 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
1277 TransferableResource resource;
1278 resource.id = 1234;
1279 parent_support().SubmitCompositorFrame(
1280 parent_id.local_surface_id(),
1281 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
1282 {resource}));
1283 std::vector<ReturnedResource> returned_resources =
1284 TransferableResource::ReturnResources({resource});
1285 EXPECT_CALL(support_client_, ReclaimResources(_)).Times(0);
1286 EXPECT_CALL(support_client_,
1287 DidReceiveCompositorFrameAck(Eq(returned_resources)));
1288 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
1289 MakeDefaultCompositorFrame());
1290 }
1291
1292 // Verifies that arrival of a new CompositorFrame doesn't change the fact that a
1293 // surface is marked for destruction.
TEST_F(SurfaceSynchronizationTest,SubmitToDestroyedSurface)1294 TEST_F(SurfaceSynchronizationTest, SubmitToDestroyedSurface) {
1295 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
1296 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 3);
1297
1298 // Create the child surface by submitting a frame to it.
1299 EXPECT_EQ(nullptr, GetSurfaceForId(child_id));
1300 TransferableResource resource;
1301 resource.id = 1234;
1302 child_support1().SubmitCompositorFrame(
1303 child_id.local_surface_id(),
1304 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
1305 {resource}));
1306 // Verify that the child surface is created.
1307 Surface* surface = GetSurfaceForId(child_id);
1308 EXPECT_NE(nullptr, surface);
1309
1310 // Add a reference from the parent to the child.
1311 parent_support().SubmitCompositorFrame(
1312 parent_id.local_surface_id(),
1313 MakeCompositorFrame({child_id}, {SurfaceRange(child_id)},
1314 std::vector<TransferableResource>()));
1315
1316 // Attempt to destroy the child surface. The surface must still exist since
1317 // the parent needs it but it will be marked as destroyed.
1318 child_support1().EvictSurface(child_id.local_surface_id());
1319 surface = GetSurfaceForId(child_id);
1320 EXPECT_NE(nullptr, surface);
1321 EXPECT_TRUE(IsMarkedForDestruction(child_id));
1322
1323 // Child submits another frame to the same local surface id that is marked
1324 // destroyed. The frame is immediately rejected.
1325 {
1326 EXPECT_CALL(support_client_, ReclaimResources(_)).Times(0);
1327 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_));
1328 surface_observer().Reset();
1329 child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
1330 MakeDefaultCompositorFrame());
1331 testing::Mock::VerifyAndClearExpectations(&support_client_);
1332 }
1333
1334 // The parent stops referencing the child surface. This allows the child
1335 // surface to be garbage collected.
1336 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
1337 MakeDefaultCompositorFrame());
1338
1339 {
1340 std::vector<ReturnedResource> returned_resources =
1341 TransferableResource::ReturnResources({resource});
1342 EXPECT_CALL(support_client_, ReclaimResources(Eq(returned_resources)));
1343 frame_sink_manager().surface_manager()->GarbageCollectSurfaces();
1344 testing::Mock::VerifyAndClearExpectations(&support_client_);
1345 }
1346
1347 // We shouldn't observe an OnFirstSurfaceActivation because we reject the
1348 // CompositorFrame to the evicted surface.
1349 EXPECT_EQ(SurfaceId(), surface_observer().last_created_surface_id());
1350 }
1351
1352 // Verifies that if a LocalSurfaceId belonged to a surface that doesn't
1353 // exist anymore, it can not be recreated.
TEST_F(SurfaceSynchronizationTest,LocalSurfaceIdIsNotReusable)1354 TEST_F(SurfaceSynchronizationTest, LocalSurfaceIdIsNotReusable) {
1355 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
1356 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 3);
1357
1358 // Submit the first frame. Creates the surface.
1359 child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
1360 MakeDefaultCompositorFrame());
1361 EXPECT_NE(nullptr, GetSurfaceForId(child_id));
1362
1363 // Add a reference from parent.
1364 parent_support().SubmitCompositorFrame(
1365 parent_id.local_surface_id(),
1366 MakeCompositorFrame({child_id}, {SurfaceRange(child_id)},
1367 std::vector<TransferableResource>()));
1368
1369 // Remove the reference from parant. This allows us to destroy the surface.
1370 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
1371 MakeDefaultCompositorFrame());
1372
1373 // Destroy the surface.
1374 child_support1().EvictSurface(child_id.local_surface_id());
1375 frame_sink_manager().surface_manager()->GarbageCollectSurfaces();
1376
1377 EXPECT_EQ(nullptr, GetSurfaceForId(child_id));
1378
1379 // Submit another frame with the same local surface id. The surface should not
1380 // be recreated.
1381 child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
1382 MakeDefaultCompositorFrame());
1383 EXPECT_EQ(nullptr, GetSurfaceForId(child_id));
1384 }
1385
1386 // This test verifies that a crash does not occur if garbage collection is
1387 // triggered during surface dependency resolution. This test triggers garbage
1388 // collection during surface resolution, by causing an activation to remove
1389 // a surface subtree from the root. Both the old subtree and the new
1390 // activated subtree refer to the same dependency. The old subtree was activated
1391 // by deadline, and the new subtree was activated by a dependency finally
1392 // resolving.
TEST_F(SurfaceSynchronizationTest,DependencyTrackingGarbageCollection)1393 TEST_F(SurfaceSynchronizationTest, DependencyTrackingGarbageCollection) {
1394 const SurfaceId display_id = MakeSurfaceId(kDisplayFrameSink, 1);
1395 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1396 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
1397 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
1398
1399 parent_support().SubmitCompositorFrame(
1400 parent_id1.local_surface_id(),
1401 MakeCompositorFrame({child_id}, empty_surface_ranges(),
1402 std::vector<TransferableResource>(),
1403 MakeDefaultDeadline()));
1404 display_support().SubmitCompositorFrame(
1405 display_id.local_surface_id(),
1406 MakeCompositorFrame({parent_id1}, empty_surface_ranges(),
1407 std::vector<TransferableResource>(),
1408 MakeDefaultDeadline()));
1409
1410 EXPECT_TRUE(parent_surface()->has_deadline());
1411
1412 // Advance BeginFrames to trigger a deadline.
1413 for (int i = 0; i < 3; ++i) {
1414 SendNextBeginFrame();
1415 EXPECT_TRUE(display_surface()->has_deadline());
1416 EXPECT_TRUE(parent_surface()->has_deadline());
1417 }
1418 SendNextBeginFrame();
1419
1420 EXPECT_TRUE(display_surface()->HasActiveFrame());
1421 EXPECT_FALSE(display_surface()->HasPendingFrame());
1422 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1423 EXPECT_FALSE(parent_surface()->HasPendingFrame());
1424
1425 parent_support().SubmitCompositorFrame(
1426 parent_id2.local_surface_id(),
1427 MakeCompositorFrame({child_id}, empty_surface_ranges(),
1428 std::vector<TransferableResource>(),
1429 MakeDefaultDeadline()));
1430 display_support().SubmitCompositorFrame(
1431 display_id.local_surface_id(),
1432 MakeCompositorFrame({parent_id2}, empty_surface_ranges(),
1433 std::vector<TransferableResource>(),
1434 MakeDefaultDeadline()));
1435
1436 // The display surface now has two CompositorFrames. One that is pending,
1437 // indirectly blocked on child_id and one that is active, also indirectly
1438 // referring to child_id, but activated due to the deadline above.
1439 EXPECT_TRUE(display_surface()->HasActiveFrame());
1440 EXPECT_TRUE(display_surface()->HasPendingFrame());
1441
1442 // Submitting a CompositorFrame will trigger garbage collection of the
1443 // |parent_id1| subtree. This should not crash.
1444 child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
1445 MakeDefaultCompositorFrame());
1446 }
1447
1448 // This test verifies that a crash does not occur if garbage collection is
1449 // triggered when a deadline forces frame activation. This test triggers garbage
1450 // collection during deadline activation by causing the activation of a display
1451 // frame to replace a previously activated display frame that was referring to
1452 // a now-unreachable surface subtree. That subtree gets garbage collected during
1453 // deadline activation. SurfaceDependencyTracker is also tracking a surface
1454 // from that subtree due to an unresolved dependency. This test verifies that
1455 // this dependency resolution does not crash.
TEST_F(SurfaceSynchronizationTest,GarbageCollectionOnDeadline)1456 TEST_F(SurfaceSynchronizationTest, GarbageCollectionOnDeadline) {
1457 const SurfaceId display_id = MakeSurfaceId(kDisplayFrameSink, 1);
1458 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1459 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
1460 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
1461
1462 // |parent_id1| is blocked on |child_id|.
1463 parent_support().SubmitCompositorFrame(
1464 parent_id1.local_surface_id(),
1465 MakeCompositorFrame({child_id}, empty_surface_ranges(),
1466 std::vector<TransferableResource>(),
1467 MakeDefaultDeadline()));
1468
1469 display_support().SubmitCompositorFrame(
1470 display_id.local_surface_id(),
1471 MakeCompositorFrame({parent_id1}, {SurfaceRange(parent_id1)},
1472 std::vector<TransferableResource>(),
1473 MakeDefaultDeadline()));
1474
1475 EXPECT_TRUE(display_surface()->has_deadline());
1476 EXPECT_TRUE(parent_surface()->has_deadline());
1477 EXPECT_TRUE(display_surface()->HasPendingFrame());
1478 EXPECT_FALSE(display_surface()->HasActiveFrame());
1479
1480 // Advance BeginFrames to trigger a deadline. This activates the
1481 // CompositorFrame submitted above.
1482 for (int i = 0; i < 3; ++i) {
1483 SendNextBeginFrame();
1484 EXPECT_TRUE(display_surface()->has_deadline());
1485 EXPECT_TRUE(parent_surface()->has_deadline());
1486 }
1487 SendNextBeginFrame();
1488 EXPECT_FALSE(display_surface()->has_deadline());
1489 EXPECT_FALSE(parent_surface()->has_deadline());
1490 EXPECT_FALSE(display_surface()->HasPendingFrame());
1491 EXPECT_TRUE(display_surface()->HasActiveFrame());
1492
1493 // By submitting a display CompositorFrame, and replacing the parent's
1494 // CompositorFrame with another surface ID, parent_id1 becomes unreachable
1495 // and a candidate for garbage collection.
1496 display_support().SubmitCompositorFrame(
1497 display_id.local_surface_id(),
1498 MakeCompositorFrame({parent_id2}, empty_surface_ranges(),
1499 std::vector<TransferableResource>(),
1500 MakeDefaultDeadline()));
1501 EXPECT_TRUE(display_surface()->has_deadline());
1502
1503 // Now |parent_id1| is only kept alive by the active |display_id| frame.
1504 parent_support().SubmitCompositorFrame(
1505 parent_id2.local_surface_id(),
1506 MakeCompositorFrame({child_id}, empty_surface_ranges(),
1507 std::vector<TransferableResource>(),
1508 MakeDefaultDeadline()));
1509 EXPECT_TRUE(display_surface()->has_deadline());
1510 EXPECT_TRUE(parent_surface()->has_deadline());
1511
1512 // SurfaceDependencyTracker should now be tracking |display_id|, |parent_id1|
1513 // and |parent_id2|. By activating the pending |display_id| frame by deadline,
1514 // |parent_id1| becomes unreachable and is garbage collected while
1515 // SurfaceDependencyTracker is in the process of activating surfaces. This
1516 // should not cause a crash or use-after-free.
1517 for (int i = 0; i < 3; ++i) {
1518 SendNextBeginFrame();
1519 EXPECT_TRUE(display_surface()->has_deadline());
1520 }
1521 SendNextBeginFrame();
1522 EXPECT_FALSE(display_surface()->has_deadline());
1523 }
1524
1525 // This test verifies that a CompositorFrame will only blocked on embedded
1526 // surfaces but not on other retained surface IDs in the CompositorFrame.
TEST_F(SurfaceSynchronizationTest,OnlyBlockOnEmbeddedSurfaces)1527 TEST_F(SurfaceSynchronizationTest, OnlyBlockOnEmbeddedSurfaces) {
1528 const SurfaceId display_id = MakeSurfaceId(kDisplayFrameSink, 1);
1529 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1530 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
1531
1532 // Submitting a CompositorFrame with |parent_id2| so that the display
1533 // CompositorFrame can hold a reference to it.
1534 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
1535 MakeDefaultCompositorFrame());
1536
1537 display_support().SubmitCompositorFrame(
1538 display_id.local_surface_id(),
1539 MakeCompositorFrame({parent_id2}, {SurfaceRange(parent_id1)},
1540 std::vector<TransferableResource>()));
1541
1542 EXPECT_TRUE(display_surface()->HasPendingFrame());
1543 EXPECT_FALSE(display_surface()->HasActiveFrame());
1544 EXPECT_TRUE(display_surface()->has_deadline());
1545
1546 // Verify that the display CompositorFrame will only block on |parent_id2|
1547 // but not |parent_id1|.
1548 EXPECT_THAT(display_surface()->activation_dependencies(),
1549 UnorderedElementsAre(parent_id2));
1550 // Verify that the display surface holds no references while its
1551 // CompositorFrame is pending.
1552 EXPECT_THAT(GetChildReferences(display_id), IsEmpty());
1553
1554 // Submitting a CompositorFrame with |parent_id2| should unblock the
1555 // display CompositorFrame.
1556 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
1557 MakeDefaultCompositorFrame());
1558
1559 EXPECT_FALSE(display_surface()->has_deadline());
1560 EXPECT_FALSE(display_surface()->HasPendingFrame());
1561 EXPECT_TRUE(display_surface()->HasActiveFrame());
1562 EXPECT_THAT(display_surface()->activation_dependencies(), IsEmpty());
1563 }
1564
1565 // This test verifies that a late arriving CompositorFrame activates
1566 // immediately and does not trigger a new deadline.
TEST_F(SurfaceSynchronizationTest,LateArrivingDependency)1567 TEST_F(SurfaceSynchronizationTest, LateArrivingDependency) {
1568 const SurfaceId display_id = MakeSurfaceId(kDisplayFrameSink, 1);
1569 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1570 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
1571
1572 display_support().SubmitCompositorFrame(
1573 display_id.local_surface_id(),
1574 MakeCompositorFrame(
1575 {parent_id1}, {SurfaceRange(base::nullopt, parent_id1)},
1576 std::vector<TransferableResource>(), MakeDefaultDeadline()));
1577
1578 EXPECT_TRUE(display_surface()->HasPendingFrame());
1579 EXPECT_FALSE(display_surface()->HasActiveFrame());
1580 EXPECT_TRUE(display_surface()->has_deadline());
1581
1582 // Advance BeginFrames to trigger a deadline. This activates the
1583 // CompositorFrame submitted above.
1584 for (int i = 0; i < 3; ++i) {
1585 SendNextBeginFrame();
1586 EXPECT_TRUE(display_surface()->has_deadline());
1587 }
1588 SendNextBeginFrame();
1589 EXPECT_FALSE(display_surface()->has_deadline());
1590 EXPECT_FALSE(display_surface()->HasPendingFrame());
1591 EXPECT_TRUE(display_surface()->HasActiveFrame());
1592
1593 // A late arriving CompositorFrame should activate immediately without
1594 // scheduling a deadline and without waiting for dependencies to resolve.
1595 parent_support().SubmitCompositorFrame(
1596 parent_id1.local_surface_id(),
1597 MakeCompositorFrame({child_id1}, {SurfaceRange(base::nullopt, child_id1)},
1598 std::vector<TransferableResource>(),
1599 MakeDefaultDeadline()));
1600 EXPECT_FALSE(parent_surface()->has_deadline());
1601 EXPECT_FALSE(parent_surface()->HasPendingFrame());
1602 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1603 }
1604
1605 // This test verifies that a late arriving CompositorFrame activates
1606 // immediately along with its subtree and does not trigger a new deadline.
TEST_F(SurfaceSynchronizationTest,MultiLevelLateArrivingDependency)1607 TEST_F(SurfaceSynchronizationTest, MultiLevelLateArrivingDependency) {
1608 const SurfaceId display_id = MakeSurfaceId(kDisplayFrameSink, 1);
1609 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
1610 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
1611 const SurfaceId arbitrary_id = MakeSurfaceId(kArbitraryFrameSink, 1);
1612
1613 display_support().SubmitCompositorFrame(
1614 display_id.local_surface_id(),
1615 MakeCompositorFrame({parent_id}, {SurfaceRange(base::nullopt, parent_id)},
1616 std::vector<TransferableResource>(),
1617 MakeDefaultDeadline()));
1618 EXPECT_TRUE(display_surface()->HasPendingFrame());
1619 EXPECT_FALSE(display_surface()->HasActiveFrame());
1620 EXPECT_TRUE(display_surface()->has_deadline());
1621
1622 // Issue some BeginFrames to trigger the deadline and activate the display's
1623 // surface. |parent_id| is now late. Advance BeginFrames to trigger a
1624 // deadline.
1625 for (int i = 0; i < 4; ++i) {
1626 EXPECT_TRUE(display_surface()->has_deadline());
1627 SendNextBeginFrame();
1628 }
1629 EXPECT_FALSE(display_surface()->HasPendingFrame());
1630 EXPECT_TRUE(display_surface()->HasActiveFrame());
1631 EXPECT_FALSE(display_surface()->has_deadline());
1632
1633 // The child surface is not currently causally linked to the display's
1634 // surface and so it gets a separate deadline.
1635 child_support1().SubmitCompositorFrame(
1636 child_id.local_surface_id(),
1637 MakeCompositorFrame(
1638 {arbitrary_id}, {SurfaceRange(base::nullopt, arbitrary_id)},
1639 std::vector<TransferableResource>(), MakeDefaultDeadline()));
1640 EXPECT_TRUE(child_surface1()->HasPendingFrame());
1641 EXPECT_FALSE(child_surface1()->HasActiveFrame());
1642 EXPECT_TRUE(child_surface1()->has_deadline());
1643
1644 // Submitting a CompositorFrame to the parent surface creates a dependency
1645 // chain from the display to the parent to the child, allowing them all to
1646 // assume the same deadline. Both the parent and the child are determined to
1647 // be late and activate immediately.
1648 parent_support().SubmitCompositorFrame(
1649 parent_id.local_surface_id(),
1650 MakeCompositorFrame({child_id}, {SurfaceRange(base::nullopt, child_id)},
1651 std::vector<TransferableResource>(),
1652 MakeDefaultDeadline()));
1653 EXPECT_FALSE(parent_surface()->HasPendingFrame());
1654 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1655 EXPECT_FALSE(parent_surface()->has_deadline());
1656
1657 EXPECT_FALSE(child_surface1()->HasPendingFrame());
1658 EXPECT_TRUE(child_surface1()->HasActiveFrame());
1659 EXPECT_FALSE(child_surface1()->has_deadline());
1660 }
1661
1662 // This test verifies that CompositorFrames submitted to a surface referenced
1663 // by a parent CompositorFrame as a fallback will be ACK'ed immediately.
TEST_F(SurfaceSynchronizationTest,FallbackSurfacesClosed)1664 TEST_F(SurfaceSynchronizationTest, FallbackSurfacesClosed) {
1665 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1666 // This is the fallback child surface that the parent holds a reference to.
1667 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
1668 // This is the primary child surface that the parent wants to block on.
1669 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
1670 const SurfaceId arbitrary_id = MakeSurfaceId(kChildFrameSink2, 3);
1671
1672 SendNextBeginFrame();
1673
1674 // child_support1 submits a CompositorFrame with unresolved dependencies.
1675 // DidReceiveCompositorFrameAck should not be called because the frame hasn't
1676 // activated yet.
1677 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(0);
1678 child_support1().SubmitCompositorFrame(
1679 child_id1.local_surface_id(),
1680 MakeCompositorFrame({arbitrary_id},
1681 {SurfaceRange(base::nullopt, arbitrary_id)}, {},
1682 MakeDefaultDeadline()));
1683 EXPECT_TRUE(child_surface1()->has_deadline());
1684 EXPECT_TRUE(child_surface1()->HasPendingFrame());
1685 EXPECT_FALSE(child_surface1()->HasActiveFrame());
1686 testing::Mock::VerifyAndClearExpectations(&support_client_);
1687
1688 // The parent is blocked on |child_id2| and references |child_id1|.
1689 // |child_id1| should immediately activate and the ack must be sent.
1690 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_));
1691 parent_support().SubmitCompositorFrame(
1692 parent_id1.local_surface_id(),
1693 MakeCompositorFrame({child_id2}, {SurfaceRange(child_id1, child_id2)},
1694 std::vector<TransferableResource>(),
1695 MakeDefaultDeadline()));
1696 EXPECT_TRUE(parent_surface()->has_deadline());
1697 EXPECT_TRUE(parent_surface()->HasPendingFrame());
1698 EXPECT_FALSE(parent_surface()->HasActiveFrame());
1699 EXPECT_FALSE(child_surface1()->HasPendingFrame());
1700 EXPECT_TRUE(child_surface1()->HasActiveFrame());
1701 testing::Mock::VerifyAndClearExpectations(&support_client_);
1702
1703 // Any further CompositorFrames sent to |child_id1| will also activate
1704 // immediately so that the child can submit another frame and catch up with
1705 // the parent.
1706 SendNextBeginFrame();
1707 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_));
1708 child_support1().SubmitCompositorFrame(
1709 child_id1.local_surface_id(),
1710 MakeCompositorFrame({arbitrary_id},
1711 {SurfaceRange(base::nullopt, arbitrary_id)}, {},
1712 MakeDefaultDeadline()));
1713 EXPECT_FALSE(child_surface1()->HasPendingFrame());
1714 EXPECT_TRUE(child_surface1()->HasActiveFrame());
1715 testing::Mock::VerifyAndClearExpectations(&support_client_);
1716 }
1717
1718 // This test verifies that two surface subtrees have independent deadlines.
TEST_F(SurfaceSynchronizationTest,IndependentDeadlines)1719 TEST_F(SurfaceSynchronizationTest, IndependentDeadlines) {
1720 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1721 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
1722 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
1723 const SurfaceId arbitrary_id = MakeSurfaceId(kArbitraryFrameSink, 1);
1724
1725 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
1726 MakeDefaultCompositorFrame());
1727 EXPECT_FALSE(child_surface1()->HasPendingFrame());
1728 EXPECT_TRUE(child_surface1()->HasActiveFrame());
1729
1730 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
1731 MakeDefaultCompositorFrame());
1732 EXPECT_FALSE(child_surface2()->HasPendingFrame());
1733 EXPECT_TRUE(child_surface2()->HasActiveFrame());
1734
1735 parent_support().SubmitCompositorFrame(
1736 parent_id1.local_surface_id(),
1737 MakeCompositorFrame({child_id1, child_id2}, empty_surface_ranges(),
1738 std::vector<TransferableResource>(),
1739 MakeDefaultDeadline()));
1740
1741 EXPECT_FALSE(parent_surface()->HasPendingFrame());
1742 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1743 EXPECT_FALSE(parent_surface()->has_deadline());
1744
1745 // Submit another CompositorFrame to |child_id1| that blocks on
1746 // |arbitrary_id|.
1747 child_support1().SubmitCompositorFrame(
1748 child_id1.local_surface_id(),
1749 MakeCompositorFrame(
1750 {arbitrary_id}, empty_surface_ranges(),
1751 std::vector<TransferableResource>(),
1752 FrameDeadline(Now(), 3, BeginFrameArgs::DefaultInterval(), false)));
1753 EXPECT_TRUE(child_surface1()->HasPendingFrame());
1754 EXPECT_TRUE(child_surface1()->HasActiveFrame());
1755 EXPECT_TRUE(child_surface1()->has_deadline());
1756
1757 // Advance to the next BeginFrame. |child_id1|'s pending Frame should activate
1758 // after 2 frames.
1759 SendNextBeginFrame();
1760
1761 // Submit another CompositorFrame to |child_id2| that blocks on
1762 // |arbitrary_id|.
1763 child_support2().SubmitCompositorFrame(
1764 child_id2.local_surface_id(),
1765 MakeCompositorFrame({arbitrary_id}, empty_surface_ranges(),
1766 std::vector<TransferableResource>(),
1767 MakeDefaultDeadline()));
1768 EXPECT_TRUE(child_surface2()->HasPendingFrame());
1769 EXPECT_TRUE(child_surface2()->HasActiveFrame());
1770 EXPECT_TRUE(child_surface2()->has_deadline());
1771
1772 // If we issue another two BeginFrames both children should remain blocked.
1773 SendNextBeginFrame();
1774 EXPECT_TRUE(child_surface1()->has_deadline());
1775 EXPECT_TRUE(child_surface2()->has_deadline());
1776
1777 // Issuing another BeginFrame should activate the frame in |child_id1| but not
1778 // |child_id2|. This verifies that |child_id1| and |child_id2| have different
1779 // deadlines.
1780 SendNextBeginFrame();
1781
1782 EXPECT_TRUE(child_surface2()->has_deadline());
1783
1784 EXPECT_FALSE(child_surface1()->has_deadline());
1785 EXPECT_FALSE(child_surface1()->HasPendingFrame());
1786 EXPECT_TRUE(child_surface1()->HasActiveFrame());
1787
1788 SendNextBeginFrame();
1789
1790 EXPECT_TRUE(child_surface2()->has_deadline());
1791 EXPECT_TRUE(child_surface2()->HasPendingFrame());
1792 EXPECT_TRUE(child_surface2()->HasActiveFrame());
1793
1794 // Issuing another BeginFrame should activate the frame in |child_id2|.
1795 SendNextBeginFrame();
1796
1797 EXPECT_FALSE(child_surface2()->has_deadline());
1798 EXPECT_FALSE(child_surface2()->HasPendingFrame());
1799 EXPECT_TRUE(child_surface2()->HasActiveFrame());
1800 }
1801
1802 // This test verifies that a child inherits its deadline from its dependent
1803 // parent (embedder) if the deadline is shorter than child's deadline.
TEST_F(SurfaceSynchronizationTest,InheritShorterDeadline)1804 TEST_F(SurfaceSynchronizationTest, InheritShorterDeadline) {
1805 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1806 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
1807 const SurfaceId arbitrary_id = MakeSurfaceId(kArbitraryFrameSink, 1);
1808
1809 // Using the default lower bound deadline results in the deadline of 2 frames
1810 // effectively being ignored because the default lower bound is 4 frames.
1811 parent_support().SubmitCompositorFrame(
1812 parent_id1.local_surface_id(),
1813 MakeCompositorFrame(
1814 {child_id1}, {SurfaceRange(base::nullopt, child_id1)},
1815 std::vector<TransferableResource>(),
1816 FrameDeadline(Now(), 2, BeginFrameArgs::DefaultInterval(), true)));
1817
1818 EXPECT_TRUE(parent_surface()->HasPendingFrame());
1819 EXPECT_FALSE(parent_surface()->HasActiveFrame());
1820 EXPECT_TRUE(parent_surface()->has_deadline());
1821
1822 // Advance to the next BeginFrame. The parent surface will activate in 3
1823 // frames.
1824 SendNextBeginFrame();
1825
1826 child_support1().SubmitCompositorFrame(
1827 child_id1.local_surface_id(),
1828 MakeCompositorFrame({arbitrary_id}, empty_surface_ranges(),
1829 std::vector<TransferableResource>(),
1830 MakeDefaultDeadline()));
1831 EXPECT_TRUE(child_surface1()->HasPendingFrame());
1832 EXPECT_FALSE(child_surface1()->HasActiveFrame());
1833 EXPECT_TRUE(child_surface1()->has_deadline());
1834
1835 // If we issue another three BeginFrames then both the parent and the child
1836 // should activate, verifying that the child's deadline is inherited from the
1837 // parent.
1838 for (int i = 0; i < 3; ++i) {
1839 EXPECT_TRUE(parent_surface()->has_deadline());
1840 EXPECT_TRUE(child_surface1()->has_deadline());
1841 SendNextBeginFrame();
1842 }
1843
1844 // Verify that both the parent and child have activated.
1845 EXPECT_FALSE(parent_surface()->HasPendingFrame());
1846 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1847 EXPECT_FALSE(parent_surface()->has_deadline());
1848
1849 EXPECT_FALSE(child_surface1()->HasPendingFrame());
1850 EXPECT_TRUE(child_surface1()->HasActiveFrame());
1851 EXPECT_FALSE(child_surface1()->has_deadline());
1852 }
1853
1854 // This test verifies that in case of A embedding B embedding C, if the deadline
1855 // of A is longer than the deadline of B, B's deadline is not extended.
TEST_F(SurfaceSynchronizationTest,ChildDeadlineNotExtendedByInheritance)1856 TEST_F(SurfaceSynchronizationTest, ChildDeadlineNotExtendedByInheritance) {
1857 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
1858 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
1859 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
1860
1861 // Parent blocks on Child1 with a deadline of 10.
1862 parent_support().SubmitCompositorFrame(
1863 parent_id.local_surface_id(),
1864 MakeCompositorFrame({child_id1}, empty_surface_ranges(),
1865 std::vector<TransferableResource>(),
1866 MakeDeadline(10)));
1867
1868 // Child1 blocks on Child2 with a deadline of 2.
1869 child_support1().SubmitCompositorFrame(
1870 child_id1.local_surface_id(),
1871 MakeCompositorFrame({child_id2}, {SurfaceRange(base::nullopt, child_id2)},
1872 std::vector<TransferableResource>(),
1873 MakeDeadline(2)));
1874
1875 // Both Parent and Child1 should be blocked because Child2 doesn't exist.
1876 EXPECT_FALSE(parent_surface()->HasActiveFrame());
1877 EXPECT_TRUE(parent_surface()->HasPendingFrame());
1878 EXPECT_FALSE(child_surface1()->HasActiveFrame());
1879 EXPECT_TRUE(child_surface1()->HasPendingFrame());
1880
1881 // Send one BeginFrame. Both Parent and Child1 should be still blocked because
1882 // Child2 still doesn't exist and Child1's deadline is 2.
1883 SendNextBeginFrame();
1884 EXPECT_FALSE(parent_surface()->HasActiveFrame());
1885 EXPECT_TRUE(parent_surface()->HasPendingFrame());
1886 EXPECT_FALSE(child_surface1()->HasActiveFrame());
1887 EXPECT_TRUE(child_surface1()->HasPendingFrame());
1888
1889 // Send one more BeginFrame. Child1 should activate by deadline, and parent
1890 // will consequenctly activates. This wouldn't happen if Child1's deadline was
1891 // extended to match Parent's deadline.
1892 SendNextBeginFrame();
1893 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1894 EXPECT_FALSE(parent_surface()->HasPendingFrame());
1895 EXPECT_TRUE(child_surface1()->HasActiveFrame());
1896 EXPECT_FALSE(child_surface1()->HasPendingFrame());
1897 }
1898
1899 // This test verifies that all surfaces within a dependency chain will
1900 // ultimately inherit the parent's shorter deadline even if the grandchild is
1901 // available before the child.
TEST_F(SurfaceSynchronizationTest,MultiLevelDeadlineInheritance)1902 TEST_F(SurfaceSynchronizationTest, MultiLevelDeadlineInheritance) {
1903 const SurfaceId display_id = MakeSurfaceId(kDisplayFrameSink, 1);
1904 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
1905 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
1906 const SurfaceId arbitrary_id = MakeSurfaceId(kArbitraryFrameSink, 1);
1907
1908 display_support().SubmitCompositorFrame(
1909 display_id.local_surface_id(),
1910 MakeCompositorFrame({parent_id}, {SurfaceRange(base::nullopt, parent_id)},
1911 std::vector<TransferableResource>(),
1912 MakeDefaultDeadline()));
1913 EXPECT_TRUE(display_surface()->HasPendingFrame());
1914 EXPECT_FALSE(display_surface()->HasActiveFrame());
1915 EXPECT_TRUE(display_surface()->has_deadline());
1916
1917 // Issue a BeginFrame to move closer to the display's deadline.
1918 SendNextBeginFrame();
1919
1920 // The child surface is not currently causally linked to the display's
1921 // surface and so it gets a separate deadline.
1922 child_support1().SubmitCompositorFrame(
1923 child_id.local_surface_id(),
1924 MakeCompositorFrame(
1925 {arbitrary_id}, {SurfaceRange(base::nullopt, arbitrary_id)},
1926 std::vector<TransferableResource>(), MakeDefaultDeadline()));
1927 EXPECT_TRUE(child_surface1()->HasPendingFrame());
1928 EXPECT_FALSE(child_surface1()->HasActiveFrame());
1929 EXPECT_TRUE(child_surface1()->has_deadline());
1930
1931 // Submitting a CompositorFrame to the parent frame creates a dependency
1932 // chain from the display to the parent to the child, allowing them all to
1933 // assume the same deadline.
1934 parent_support().SubmitCompositorFrame(
1935 parent_id.local_surface_id(),
1936 MakeCompositorFrame({child_id}, {SurfaceRange(base::nullopt, child_id)},
1937 std::vector<TransferableResource>(),
1938 MakeDefaultDeadline()));
1939 EXPECT_TRUE(parent_surface()->HasPendingFrame());
1940 EXPECT_FALSE(parent_surface()->HasActiveFrame());
1941 EXPECT_TRUE(parent_surface()->has_deadline());
1942
1943 // Advancing the time by three BeginFrames should activate all the surfaces.
1944 for (int i = 0; i < 3; ++i) {
1945 EXPECT_TRUE(display_surface()->has_deadline());
1946 EXPECT_TRUE(parent_surface()->has_deadline());
1947 EXPECT_TRUE(child_surface1()->has_deadline());
1948 SendNextBeginFrame();
1949 }
1950
1951 // Verify that all the CompositorFrames have activated.
1952 EXPECT_FALSE(display_surface()->HasPendingFrame());
1953 EXPECT_TRUE(display_surface()->HasActiveFrame());
1954 EXPECT_FALSE(display_surface()->has_deadline());
1955
1956 EXPECT_FALSE(parent_surface()->HasPendingFrame());
1957 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1958 EXPECT_FALSE(parent_surface()->has_deadline());
1959
1960 EXPECT_FALSE(child_surface1()->HasPendingFrame());
1961 EXPECT_TRUE(child_surface1()->HasActiveFrame());
1962 EXPECT_FALSE(child_surface1()->has_deadline());
1963 }
1964
1965 // This test verifies that no crash occurs if a CompositorFrame activates AFTER
1966 // its FrameSink has been destroyed.
TEST_F(SurfaceSynchronizationTest,FrameActivationAfterFrameSinkDestruction)1967 TEST_F(SurfaceSynchronizationTest, FrameActivationAfterFrameSinkDestruction) {
1968 const SurfaceId display_id = MakeSurfaceId(kDisplayFrameSink, 1);
1969 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
1970 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
1971
1972 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
1973 MakeDefaultCompositorFrame());
1974
1975 EXPECT_FALSE(parent_surface()->has_deadline());
1976 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1977 EXPECT_FALSE(parent_surface()->HasPendingFrame());
1978
1979 // Submit a CompositorFrame that refers to to |parent_id|.
1980 display_support().SubmitCompositorFrame(
1981 display_id.local_surface_id(),
1982 MakeCompositorFrame(empty_surface_ids(), {SurfaceRange(parent_id)},
1983 std::vector<TransferableResource>()));
1984
1985 EXPECT_FALSE(display_surface()->has_deadline());
1986 EXPECT_FALSE(display_surface()->HasPendingFrame());
1987 EXPECT_TRUE(display_surface()->HasActiveFrame());
1988 EXPECT_THAT(GetChildReferences(display_id), UnorderedElementsAre(parent_id));
1989
1990 // Submit a new CompositorFrame to the parent CompositorFrameSink. It should
1991 // now have a pending and active CompositorFrame.
1992 parent_support().SubmitCompositorFrame(
1993 parent_id.local_surface_id(),
1994 MakeCompositorFrame({child_id}, empty_surface_ranges(),
1995 std::vector<TransferableResource>()));
1996
1997 EXPECT_TRUE(parent_surface()->has_deadline());
1998 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1999 EXPECT_TRUE(parent_surface()->HasPendingFrame());
2000 surface_observer().Reset();
2001
2002 // Destroy the parent CompositorFrameSink. The parent_surface will be kept
2003 // alive by the display.
2004 DestroyFrameSink(kParentFrameSink);
2005
2006 // The parent surface stays alive through the display.
2007 Surface* parent_surface = GetSurfaceForId(parent_id);
2008 EXPECT_NE(nullptr, parent_surface);
2009
2010 // Submitting a new CompositorFrame to the display should free the parent.
2011 display_support().SubmitCompositorFrame(display_id.local_surface_id(),
2012 MakeDefaultCompositorFrame());
2013
2014 frame_sink_manager().surface_manager()->GarbageCollectSurfaces();
2015
2016 parent_surface = GetSurfaceForId(parent_id);
2017 EXPECT_EQ(nullptr, parent_surface);
2018 }
2019
TEST_F(SurfaceSynchronizationTest,PreviousFrameSurfaceId)2020 TEST_F(SurfaceSynchronizationTest, PreviousFrameSurfaceId) {
2021 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
2022 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
2023 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
2024
2025 // Submit a frame with no dependencies to |parent_id1|.
2026 parent_support().SubmitCompositorFrame(
2027 parent_id1.local_surface_id(),
2028 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
2029 std::vector<TransferableResource>()));
2030
2031 // Submit a frame with unresolved dependencies to |parent_id2|. The frame
2032 // should become pending and previous_frame_surface_id() should return
2033 // |parent_id1|.
2034 parent_support().SubmitCompositorFrame(
2035 parent_id2.local_surface_id(),
2036 MakeCompositorFrame({child_id}, empty_surface_ranges(),
2037 std::vector<TransferableResource>()));
2038 Surface* parent_surface2 =
2039 frame_sink_manager().surface_manager()->GetSurfaceForId(parent_id2);
2040 EXPECT_FALSE(parent_surface2->HasActiveFrame());
2041 EXPECT_TRUE(parent_surface2->HasPendingFrame());
2042
2043 // Activate the pending frame in |parent_id2|. previous_frame_surface_id()
2044 // should still return |parent_id1|.
2045 parent_surface2->ActivatePendingFrameForDeadline();
2046 EXPECT_TRUE(parent_surface2->HasActiveFrame());
2047 EXPECT_FALSE(parent_surface2->HasPendingFrame());
2048 EXPECT_EQ(parent_id1, parent_surface2->previous_frame_surface_id());
2049 }
2050
TEST_F(SurfaceSynchronizationTest,FrameIndexWithPendingFrames)2051 TEST_F(SurfaceSynchronizationTest, FrameIndexWithPendingFrames) {
2052 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2053 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2054 constexpr int n_iterations = 7;
2055
2056 // Submit a frame with no dependencies that will activate immediately. Record
2057 // the initial frame index.
2058 parent_support().SubmitCompositorFrame(
2059 parent_id.local_surface_id(),
2060 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
2061 std::vector<TransferableResource>()));
2062 Surface* parent_surface =
2063 frame_sink_manager().surface_manager()->GetSurfaceForId(parent_id);
2064 uint64_t initial_frame_index = parent_surface->GetActiveFrameIndex();
2065
2066 // Submit frames with unresolved dependencies. GetActiveFrameIndex should
2067 // return the same value as before.
2068 for (int i = 0; i < n_iterations; i++) {
2069 parent_support().SubmitCompositorFrame(
2070 parent_id.local_surface_id(),
2071 MakeCompositorFrame({child_id1}, empty_surface_ranges(),
2072 std::vector<TransferableResource>()));
2073 EXPECT_EQ(initial_frame_index, parent_surface->GetActiveFrameIndex());
2074 }
2075
2076 // Activate the pending frame. GetActiveFrameIndex should return the frame
2077 // index of the newly activated frame.
2078 parent_surface->ActivatePendingFrameForDeadline();
2079 EXPECT_EQ(initial_frame_index + n_iterations,
2080 parent_surface->GetActiveFrameIndex());
2081 }
2082
2083 // This test verifies that a new surface with a pending CompositorFrame gets
2084 // a temporary reference immediately, as opposed to when the surface activates.
TEST_F(SurfaceSynchronizationTest,PendingSurfaceKeptAlive)2085 TEST_F(SurfaceSynchronizationTest, PendingSurfaceKeptAlive) {
2086 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2087 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2088
2089 // |parent_id| depends on |child_id1|. It shouldn't activate.
2090 parent_support().SubmitCompositorFrame(
2091 parent_id.local_surface_id(),
2092 MakeCompositorFrame({child_id1}, empty_surface_ranges(),
2093 std::vector<TransferableResource>()));
2094 EXPECT_FALSE(parent_surface()->HasActiveFrame());
2095 EXPECT_TRUE(parent_surface()->HasPendingFrame());
2096 EXPECT_TRUE(HasTemporaryReference(parent_id));
2097 }
2098
2099 // Tests getting the correct active frame index.
TEST_F(SurfaceSynchronizationTest,ActiveFrameIndex)2100 TEST_F(SurfaceSynchronizationTest, ActiveFrameIndex) {
2101 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2102 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2103 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
2104
2105 parent_support().SubmitCompositorFrame(
2106 parent_id.local_surface_id(),
2107 MakeCompositorFrame({child_id1, child_id2}, empty_surface_ranges(),
2108 std::vector<TransferableResource>()));
2109
2110 // parent_support is blocked on |child_id1| and |child_id2|.
2111 EXPECT_FALSE(parent_surface()->HasActiveFrame());
2112 EXPECT_EQ(0u, parent_surface()->GetActiveFrameIndex());
2113
2114 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2115 MakeDefaultCompositorFrame());
2116 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
2117 MakeDefaultCompositorFrame());
2118 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2119 uint64_t expected_index = CompositorFrameSinkSupport::kFrameIndexStart;
2120 EXPECT_EQ(expected_index, parent_surface()->GetActiveFrameIndex());
2121 }
2122
2123 // This test verifies that SurfaceManager::GetLatestInFlightSurface returns
2124 // the latest child surface not yet set as a fallback by the parent.
2125 // Alternatively, it returns the fallback surface specified, if no tempoary
2126 // references to child surfaces are available. This mechanism is used by surface
2127 // synchronization to present the freshest surfaces available at aggregation
2128 // time.
TEST_F(SurfaceSynchronizationTest,LatestInFlightSurface)2129 TEST_F(SurfaceSynchronizationTest, LatestInFlightSurface) {
2130 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2131 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2132 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
2133 const SurfaceId child_id3 = MakeSurfaceId(kChildFrameSink1, 2, 2);
2134 const SurfaceId child_id4 = MakeSurfaceId(kChildFrameSink1, 2, 3);
2135
2136 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2137 MakeDefaultCompositorFrame());
2138
2139 parent_support().SubmitCompositorFrame(
2140 parent_id.local_surface_id(),
2141 MakeCompositorFrame({child_id1}, empty_surface_ranges(),
2142 std::vector<TransferableResource>()));
2143
2144 // Verify that the child CompositorFrame activates immediately.
2145 EXPECT_TRUE(child_surface1()->HasActiveFrame());
2146 EXPECT_FALSE(child_surface1()->HasPendingFrame());
2147 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
2148
2149 // Verify that the parent Surface has activated.
2150 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2151 EXPECT_FALSE(parent_surface()->HasPendingFrame());
2152 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
2153
2154 // Verify that there is a temporary reference for the child and there is
2155 // no reference from the parent to the child yet.
2156 EXPECT_TRUE(HasTemporaryReference(child_id1));
2157 EXPECT_THAT(GetChildReferences(parent_id), IsEmpty());
2158 EXPECT_EQ(GetSurfaceForId(child_id1),
2159 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id2)));
2160
2161 parent_support().SubmitCompositorFrame(
2162 parent_id.local_surface_id(),
2163 MakeCompositorFrame(empty_surface_ids(), {SurfaceRange(child_id1)},
2164 std::vector<TransferableResource>()));
2165
2166 // Verify that the parent Surface has activated.
2167 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2168 EXPECT_FALSE(parent_surface()->HasPendingFrame());
2169 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
2170
2171 // Verify that there is no temporary reference for the child and there is
2172 // a reference from the parent to the child.
2173 EXPECT_FALSE(HasTemporaryReference(child_id1));
2174 EXPECT_THAT(GetChildReferences(parent_id), UnorderedElementsAre(child_id1));
2175 EXPECT_EQ(GetSurfaceForId(child_id1),
2176 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id2)));
2177
2178 // Submit a child CompositorFrame to a new SurfaceId and verify that
2179 // GetLatestInFlightSurface returns the right surface.
2180 child_support1().SubmitCompositorFrame(child_id2.local_surface_id(),
2181 MakeDefaultCompositorFrame());
2182
2183 // Verify that there is a temporary reference for child_id2 and there is
2184 // a reference from the parent to child_id1.
2185 EXPECT_TRUE(HasTemporaryReference(child_id2));
2186 EXPECT_THAT(GetChildReferences(parent_id), UnorderedElementsAre(child_id1));
2187
2188 EXPECT_EQ(GetSurfaceForId(child_id2),
2189 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id3)));
2190
2191 // If the primary surface is old, then we shouldn't return an in-flight
2192 // surface that is newer than the primary.
2193 EXPECT_EQ(GetSurfaceForId(child_id1),
2194 GetLatestInFlightSurface(SurfaceRange(child_id1)));
2195
2196 // Submit a child CompositorFrame to a new SurfaceId and verify that
2197 // GetLatestInFlightSurface returns the right surface.
2198 child_support1().SubmitCompositorFrame(child_id3.local_surface_id(),
2199 MakeDefaultCompositorFrame());
2200
2201 // Verify that there is a temporary reference for child_id3.
2202 EXPECT_TRUE(HasTemporaryReference(child_id3));
2203
2204 EXPECT_EQ(GetSurfaceForId(child_id3),
2205 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id4)));
2206
2207 parent_support().SubmitCompositorFrame(
2208 parent_id.local_surface_id(),
2209 MakeCompositorFrame({child_id3}, {SurfaceRange(base::nullopt, child_id3)},
2210 std::vector<TransferableResource>()));
2211
2212 EXPECT_THAT(GetChildReferences(parent_id), UnorderedElementsAre(child_id3));
2213
2214 // If the primary surface is active, we return it.
2215 EXPECT_EQ(GetSurfaceForId(child_id3),
2216 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id3)));
2217 }
2218
2219 // This test verifies that GetLatestInFlightSurface will return nullptr when the
2220 // start of the range is newer than its end, even if a surface matching the end
2221 // exists.
TEST_F(SurfaceSynchronizationTest,LatestInFlightSurfaceWithInvalidSurfaceRange)2222 TEST_F(SurfaceSynchronizationTest,
2223 LatestInFlightSurfaceWithInvalidSurfaceRange) {
2224 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2225 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2226 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
2227
2228 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2229 MakeDefaultCompositorFrame());
2230
2231 parent_support().SubmitCompositorFrame(
2232 parent_id.local_surface_id(),
2233 MakeCompositorFrame({child_id1}, empty_surface_ranges(),
2234 std::vector<TransferableResource>()));
2235
2236 // Verify that the parent and child CompositorFrames are active.
2237 EXPECT_TRUE(child_surface1()->HasActiveFrame());
2238 EXPECT_FALSE(child_surface1()->HasPendingFrame());
2239 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
2240
2241 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2242 EXPECT_FALSE(parent_surface()->HasPendingFrame());
2243 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
2244
2245 const SurfaceId bogus_child_id = MakeSurfaceId(kChildFrameSink1, 10);
2246
2247 // The end exists but don't return it because the start is newer than the end.
2248 EXPECT_EQ(nullptr,
2249 GetLatestInFlightSurface(SurfaceRange(bogus_child_id, child_id1)));
2250
2251 // In this case, the end doesn't exist either. Still return nullptr.
2252 EXPECT_EQ(nullptr,
2253 GetLatestInFlightSurface(SurfaceRange(bogus_child_id, child_id2)));
2254 }
2255
2256 // This test verifies that GetLatestInFlightSurface will return the primary or
2257 // nullptr if fallback is not specified.
2258 // TODO(akaba): this would change after https://crbug.com/861769
TEST_F(SurfaceSynchronizationTest,LatestInFlightSurfaceWithoutFallback)2259 TEST_F(SurfaceSynchronizationTest, LatestInFlightSurfaceWithoutFallback) {
2260 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2261 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2262 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
2263
2264 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2265 MakeDefaultCompositorFrame());
2266 // Verify that |child_id1| is active.
2267 EXPECT_TRUE(child_surface1()->HasActiveFrame());
2268 EXPECT_FALSE(child_surface1()->HasPendingFrame());
2269 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
2270
2271 parent_support().SubmitCompositorFrame(
2272 parent_id.local_surface_id(),
2273 MakeCompositorFrame({child_id2}, {SurfaceRange(child_id1, child_id2)},
2274 std::vector<TransferableResource>()));
2275
2276 // Verify that the |parent_id| is not active yet.
2277 EXPECT_FALSE(parent_surface()->HasActiveFrame());
2278 EXPECT_TRUE(parent_surface()->HasPendingFrame());
2279 EXPECT_THAT(parent_surface()->activation_dependencies(),
2280 UnorderedElementsAre(child_id2));
2281
2282 // Verify that |child_id1| is the latest active surface.
2283 EXPECT_EQ(GetSurfaceForId(child_id1),
2284 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id2)));
2285
2286 // Fallback is not specified and |child_id1| is the latest.
2287 EXPECT_EQ(GetSurfaceForId(child_id1),
2288 GetLatestInFlightSurface(SurfaceRange(base::nullopt, child_id2)));
2289
2290 // Activate |child_id2|
2291 child_support1().SubmitCompositorFrame(child_id2.local_surface_id(),
2292 MakeDefaultCompositorFrame());
2293 // Verify that child2 is active.
2294 EXPECT_TRUE(child_surface1()->HasActiveFrame());
2295 EXPECT_FALSE(child_surface1()->HasPendingFrame());
2296 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
2297
2298 // Verify that |child_id2| is the latest active surface.
2299 EXPECT_EQ(GetSurfaceForId(child_id2),
2300 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id2)));
2301
2302 // Fallback is not specified but primary exists so we return it.
2303 EXPECT_EQ(GetSurfaceForId(child_id2),
2304 GetLatestInFlightSurface(SurfaceRange(base::nullopt, child_id2)));
2305 }
2306
2307 // This test verifies that GetLatestInFlightSurface will not return null if the
2308 // fallback is garbage collected, but instead returns the latest surface older
2309 // than primary if that exists.
TEST_F(SurfaceSynchronizationTest,LatestInFlightSurfaceWithGarbageFallback)2310 TEST_F(SurfaceSynchronizationTest, LatestInFlightSurfaceWithGarbageFallback) {
2311 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2312 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2313 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
2314 const SurfaceId child_id3 = MakeSurfaceId(kChildFrameSink1, 3);
2315 const SurfaceId child_id4 = MakeSurfaceId(kChildFrameSink1, 4);
2316
2317 // Activate |child_id1|.
2318 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2319 MakeDefaultCompositorFrame());
2320
2321 // Verify that |child_id1| CompositorFrames is active.
2322 EXPECT_TRUE(child_surface1()->HasActiveFrame());
2323 EXPECT_FALSE(child_surface1()->HasPendingFrame());
2324 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
2325 EXPECT_TRUE(HasTemporaryReference(child_id1));
2326
2327 parent_support().SubmitCompositorFrame(
2328 parent_id.local_surface_id(),
2329 MakeCompositorFrame(empty_surface_ids(), {SurfaceRange(child_id1)},
2330 std::vector<TransferableResource>()));
2331
2332 // Verify that parent is referencing |child_id1|.
2333 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2334 EXPECT_FALSE(parent_surface()->HasPendingFrame());
2335 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
2336 EXPECT_THAT(parent_surface()->active_referenced_surfaces(),
2337 UnorderedElementsAre(child_id1));
2338 EXPECT_FALSE(HasTemporaryReference(child_id1));
2339
2340 // Activate |child_id2|.
2341 child_support1().SubmitCompositorFrame(child_id2.local_surface_id(),
2342 MakeDefaultCompositorFrame());
2343
2344 // Verify that |child_id2| CompositorFrames is active and it has a temporary
2345 // reference.
2346 EXPECT_TRUE(child_surface1()->HasActiveFrame());
2347 EXPECT_FALSE(child_surface1()->HasPendingFrame());
2348 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
2349 EXPECT_TRUE(HasTemporaryReference(child_id2));
2350
2351 // Activate |child_id3|.
2352 child_support1().SubmitCompositorFrame(child_id3.local_surface_id(),
2353 MakeDefaultCompositorFrame());
2354
2355 // Verify that |child_id3| CompositorFrames is active.
2356 EXPECT_TRUE(child_surface1()->HasActiveFrame());
2357 EXPECT_FALSE(child_surface1()->HasPendingFrame());
2358 EXPECT_THAT(child_surface1()->activation_dependencies(), IsEmpty());
2359 EXPECT_TRUE(HasTemporaryReference(child_id3));
2360
2361 parent_support().SubmitCompositorFrame(
2362 parent_id.local_surface_id(),
2363 MakeCompositorFrame(empty_surface_ids(), {SurfaceRange(child_id2)},
2364 std::vector<TransferableResource>()));
2365
2366 // Verify that parent is referencing |child_id2| which lost its temporary
2367 // reference, but |child_id3| still has a temporary reference.
2368 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2369 EXPECT_FALSE(parent_surface()->HasPendingFrame());
2370 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
2371 EXPECT_THAT(parent_surface()->active_referenced_surfaces(),
2372 UnorderedElementsAre(child_id2));
2373 EXPECT_FALSE(HasTemporaryReference(child_id2));
2374 EXPECT_TRUE(HasTemporaryReference(child_id3));
2375
2376 // Garbage collect |child_id1|.
2377 frame_sink_manager().surface_manager()->GarbageCollectSurfaces();
2378
2379 // Make sure |child_id1| is garbage collected.
2380 EXPECT_EQ(frame_sink_manager().surface_manager()->GetSurfaceForId(child_id1),
2381 nullptr);
2382
2383 EXPECT_EQ(GetSurfaceForId(child_id3),
2384 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id4)));
2385 }
2386
2387 // This test verifies that in the case of different frame sinks
2388 // GetLatestInFlightSurface will return the latest surface in the primary's
2389 // FrameSinkId or the latest in the fallback's FrameSinkId if no surface exists
2390 // in the primary's.
TEST_F(SurfaceSynchronizationTest,LatestInFlightSurfaceDifferentFrameSinkIds)2391 TEST_F(SurfaceSynchronizationTest, LatestInFlightSurfaceDifferentFrameSinkIds) {
2392 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2393 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2394 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
2395 const SurfaceId child_id3 = MakeSurfaceId(kChildFrameSink2, 1);
2396 const SurfaceId child_id4 = MakeSurfaceId(kChildFrameSink2, 2);
2397
2398 // Activate |child_id1|.
2399 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2400 MakeDefaultCompositorFrame());
2401
2402 // Activate |child_id2|.
2403 child_support1().SubmitCompositorFrame(child_id2.local_surface_id(),
2404 MakeDefaultCompositorFrame());
2405
2406 parent_support().SubmitCompositorFrame(
2407 parent_id.local_surface_id(),
2408 MakeCompositorFrame({child_id4}, {SurfaceRange(child_id1, child_id4)},
2409 std::vector<TransferableResource>()));
2410
2411 // Primary's frame sink id empty and |child_id2| is the latest in fallback's
2412 // frame sink.
2413 EXPECT_EQ(GetSurfaceForId(child_id2),
2414 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id4)));
2415
2416 // Activate |child_id3| which is in different frame sink.
2417 child_support2().SubmitCompositorFrame(child_id3.local_surface_id(),
2418 MakeDefaultCompositorFrame());
2419
2420 // |child_id3| is the latest in primary's frame sink.
2421 EXPECT_EQ(GetSurfaceForId(child_id3),
2422 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id4)));
2423 }
2424
2425 // This test verifies that GetLatestInFlightSurface will return the
2426 // primary surface ID if it is in the temporary reference queue.
TEST_F(SurfaceSynchronizationTest,LatestInFlightSurfaceReturnPrimary)2427 TEST_F(SurfaceSynchronizationTest, LatestInFlightSurfaceReturnPrimary) {
2428 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2429 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2430 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
2431 const SurfaceId child_id3 = MakeSurfaceId(kChildFrameSink1, 3);
2432
2433 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2434 MakeDefaultCompositorFrame());
2435
2436 // Create a reference from |parent_id| to |child_id|.
2437 parent_support().SubmitCompositorFrame(
2438 parent_id.local_surface_id(),
2439 MakeCompositorFrame(empty_surface_ids(), {SurfaceRange(child_id1)},
2440 std::vector<TransferableResource>()));
2441
2442 child_support1().SubmitCompositorFrame(child_id2.local_surface_id(),
2443 MakeDefaultCompositorFrame());
2444
2445 EXPECT_EQ(GetSurfaceForId(child_id2),
2446 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id3)));
2447
2448 child_support1().SubmitCompositorFrame(child_id3.local_surface_id(),
2449 MakeDefaultCompositorFrame());
2450
2451 // GetLatestInFlightSurface will return the primary surface ID if it's
2452 // available.
2453 EXPECT_EQ(GetSurfaceForId(child_id3),
2454 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id3)));
2455 }
2456
2457 // This test verifies that GetLatestInFlightSurface can use persistent
2458 // references to compute the latest surface.
TEST_F(SurfaceSynchronizationTest,LatestInFlightSurfaceUsesPersistentReferences)2459 TEST_F(SurfaceSynchronizationTest,
2460 LatestInFlightSurfaceUsesPersistentReferences) {
2461 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2462 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2463 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
2464 const SurfaceId child_id3 = MakeSurfaceId(kChildFrameSink1, 3);
2465
2466 // Activate |child_id1|.
2467 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2468 MakeDefaultCompositorFrame());
2469
2470 // |child_id1| now should have a temporary reference.
2471 EXPECT_TRUE(HasTemporaryReference(child_id1));
2472 EXPECT_TRUE(surface_manager()
2473 ->GetSurfacesThatReferenceChildForTesting(child_id1)
2474 .empty());
2475
2476 // Activate |child_id2|.
2477 child_support1().SubmitCompositorFrame(child_id2.local_surface_id(),
2478 MakeDefaultCompositorFrame());
2479
2480 // |child_id2| now should have a temporary reference.
2481 EXPECT_TRUE(HasTemporaryReference(child_id2));
2482 EXPECT_TRUE(surface_manager()
2483 ->GetSurfacesThatReferenceChildForTesting(child_id2)
2484 .empty());
2485
2486 // Create a reference from |parent_id| to |child_id2|.
2487 parent_support().SubmitCompositorFrame(
2488 parent_id.local_surface_id(),
2489 MakeCompositorFrame(empty_surface_ids(), {SurfaceRange(child_id2)},
2490 std::vector<TransferableResource>()));
2491
2492 // |child_id1| have no references and can be garbage collected.
2493 EXPECT_FALSE(HasTemporaryReference(child_id1));
2494 EXPECT_TRUE(surface_manager()
2495 ->GetSurfacesThatReferenceChildForTesting(child_id1)
2496 .empty());
2497
2498 // |child_id2| has a persistent references now.
2499 EXPECT_FALSE(HasTemporaryReference(child_id2));
2500 EXPECT_FALSE(surface_manager()
2501 ->GetSurfacesThatReferenceChildForTesting(child_id2)
2502 .empty());
2503
2504 // Verify that GetLatestInFlightSurface returns |child_id2|.
2505 EXPECT_EQ(GetSurfaceForId(child_id2),
2506 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id3)));
2507 }
2508
2509 // This test verifies that GetLatestInFlightSurface will skip a surface if
2510 // its nonce is different.
TEST_F(SurfaceSynchronizationTest,LatestInFlightSurfaceSkipDifferentNonce)2511 TEST_F(SurfaceSynchronizationTest, LatestInFlightSurfaceSkipDifferentNonce) {
2512 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2513 const base::UnguessableToken nonce1(
2514 base::UnguessableToken::Deserialize(0, 1));
2515 const base::UnguessableToken nonce2(
2516 base::UnguessableToken::Deserialize(1, 1));
2517 const base::UnguessableToken nonce3(
2518 base::UnguessableToken::Deserialize(2, 1));
2519 const SurfaceId child_id1 =
2520 SurfaceId(kChildFrameSink1, LocalSurfaceId(1, nonce1));
2521 const SurfaceId child_id2 =
2522 SurfaceId(kChildFrameSink1, LocalSurfaceId(2, nonce1));
2523 const SurfaceId child_id3 =
2524 SurfaceId(kChildFrameSink1, LocalSurfaceId(3, nonce2));
2525 const SurfaceId child_id4 =
2526 SurfaceId(kChildFrameSink1, LocalSurfaceId(4, nonce2));
2527 const SurfaceId child_id5 =
2528 SurfaceId(kChildFrameSink1, LocalSurfaceId(5, nonce3));
2529
2530 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2531 MakeDefaultCompositorFrame());
2532
2533 // Create a reference from |parent_id| to |child_id|.
2534 parent_support().SubmitCompositorFrame(
2535 parent_id.local_surface_id(),
2536 MakeCompositorFrame(empty_surface_ids(), {SurfaceRange(child_id1)},
2537 std::vector<TransferableResource>()));
2538
2539 child_support1().SubmitCompositorFrame(child_id2.local_surface_id(),
2540 MakeDefaultCompositorFrame());
2541
2542 EXPECT_EQ(GetSurfaceForId(child_id2),
2543 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id4)));
2544
2545 child_support1().SubmitCompositorFrame(child_id3.local_surface_id(),
2546 MakeDefaultCompositorFrame());
2547
2548 // GetLatestInFlightSurface will return child_id3 because the nonce
2549 // matches that of child_id4.
2550 EXPECT_EQ(GetSurfaceForId(child_id3),
2551 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id4)));
2552
2553 // GetLatestInFlightSurface will return child_id2 because the nonce
2554 // doesn't match |child_id1| or |child_id5|.
2555 EXPECT_EQ(GetSurfaceForId(child_id2),
2556 GetLatestInFlightSurface(SurfaceRange(child_id1, child_id5)));
2557 }
2558
2559 // This test verifies that if a child submits a LocalSurfaceId newer that the
2560 // parent's dependency, then the parent will drop its dependency and activate
2561 // if possible. In this version of the test, parent sequence number of the
2562 // activated surface is larger than that in the dependency, while the child
2563 // sequence number is smaller.
TEST_F(SurfaceSynchronizationTest,DropDependenciesThatWillNeverArrive1)2564 TEST_F(SurfaceSynchronizationTest, DropDependenciesThatWillNeverArrive1) {
2565 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2566 const SurfaceId child_id11 = MakeSurfaceId(kChildFrameSink1, 1, 2);
2567 const SurfaceId child_id12 = MakeSurfaceId(kChildFrameSink1, 2, 1);
2568 const SurfaceId child_id21 = MakeSurfaceId(kChildFrameSink2, 1);
2569
2570 // |parent_id| depends on { child_id11, child_id21 }. It shouldn't activate.
2571 parent_support().SubmitCompositorFrame(
2572 parent_id.local_surface_id(),
2573 MakeCompositorFrame({child_id11, child_id21}, empty_surface_ranges(),
2574 std::vector<TransferableResource>()));
2575 EXPECT_FALSE(parent_surface()->HasActiveFrame());
2576 EXPECT_TRUE(parent_surface()->HasPendingFrame());
2577
2578 // The first child submits a new CompositorFrame to |child_id12|. |parent_id|
2579 // no longer depends on |child_id11| because it cannot expect it to arrive.
2580 // However, the parent is still blocked on |child_id21|.
2581 child_support1().SubmitCompositorFrame(
2582 child_id12.local_surface_id(),
2583 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
2584 std::vector<TransferableResource>()));
2585 EXPECT_FALSE(parent_surface()->HasActiveFrame());
2586 EXPECT_TRUE(parent_surface()->HasPendingFrame());
2587 EXPECT_THAT(parent_surface()->activation_dependencies(),
2588 UnorderedElementsAre(child_id21));
2589
2590 // Finally, the second child submits a frame to the remaining dependency and
2591 // the parent activates.
2592 child_support2().SubmitCompositorFrame(
2593 child_id21.local_surface_id(),
2594 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
2595 std::vector<TransferableResource>()));
2596 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2597 EXPECT_FALSE(parent_surface()->HasPendingFrame());
2598 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
2599 }
2600
2601 // This test verifies that if a child submits a LocalSurfaceId newer that the
2602 // parent's dependency, then the parent will drop its dependency and activate
2603 // if possible. In this version of the test, parent sequence number of the
2604 // activated surface is smaller than that in the dependency, while the child
2605 // sequence number is larger.
TEST_F(SurfaceSynchronizationTest,DropDependenciesThatWillNeverArrive2)2606 TEST_F(SurfaceSynchronizationTest, DropDependenciesThatWillNeverArrive2) {
2607 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2608 const SurfaceId child_id11 = MakeSurfaceId(kChildFrameSink1, 2, 1);
2609 const SurfaceId child_id12 = MakeSurfaceId(kChildFrameSink1, 1, 2);
2610 const SurfaceId child_id21 = MakeSurfaceId(kChildFrameSink2, 1);
2611
2612 // |parent_id| depends on { child_id11, child_id21 }. It shouldn't activate.
2613 parent_support().SubmitCompositorFrame(
2614 parent_id.local_surface_id(),
2615 MakeCompositorFrame({child_id11, child_id21}, empty_surface_ranges(),
2616 std::vector<TransferableResource>()));
2617 EXPECT_FALSE(parent_surface()->HasActiveFrame());
2618 EXPECT_TRUE(parent_surface()->HasPendingFrame());
2619
2620 // The first child submits a new CompositorFrame to |child_id12|. |parent_id|
2621 // no longer depends on |child_id11| because it cannot expect it to arrive.
2622 // However, the parent is still blocked on |child_id21|.
2623 child_support1().SubmitCompositorFrame(
2624 child_id12.local_surface_id(),
2625 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
2626 std::vector<TransferableResource>()));
2627 EXPECT_FALSE(parent_surface()->HasActiveFrame());
2628 EXPECT_TRUE(parent_surface()->HasPendingFrame());
2629 EXPECT_THAT(parent_surface()->activation_dependencies(),
2630 UnorderedElementsAre(child_id21));
2631
2632 // Finally, the second child submits a frame to the remaining dependency and
2633 // the parent activates.
2634 child_support2().SubmitCompositorFrame(
2635 child_id21.local_surface_id(),
2636 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
2637 std::vector<TransferableResource>()));
2638 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2639 EXPECT_FALSE(parent_surface()->HasPendingFrame());
2640 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
2641 }
2642
2643 // This test verifies that a surface will continue to observe a child surface
2644 // until its dependency arrives.
TEST_F(SurfaceSynchronizationTest,ObserveDependenciesUntilArrival)2645 TEST_F(SurfaceSynchronizationTest, ObserveDependenciesUntilArrival) {
2646 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2647 const SurfaceId child_id21 = MakeSurfaceId(kChildFrameSink1, 2, 1);
2648 const SurfaceId child_id22 = MakeSurfaceId(kChildFrameSink1, 2, 2);
2649
2650 // |parent_id| depends on |child_id22|. It shouldn't activate.
2651 parent_support().SubmitCompositorFrame(
2652 parent_id.local_surface_id(),
2653 MakeCompositorFrame({child_id22}, empty_surface_ranges(),
2654 std::vector<TransferableResource>()));
2655 EXPECT_FALSE(parent_surface()->HasActiveFrame());
2656 EXPECT_TRUE(parent_surface()->HasPendingFrame());
2657
2658 // The child submits to |child_id21|. The parent should not activate.
2659 child_support1().SubmitCompositorFrame(
2660 child_id21.local_surface_id(),
2661 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
2662 std::vector<TransferableResource>()));
2663 EXPECT_FALSE(parent_surface()->HasActiveFrame());
2664 EXPECT_TRUE(parent_surface()->HasPendingFrame());
2665 EXPECT_THAT(parent_surface()->activation_dependencies(),
2666 UnorderedElementsAre(child_id22));
2667
2668 // The child submits to |child_id22|. The parent should activate.
2669 child_support1().SubmitCompositorFrame(
2670 child_id22.local_surface_id(),
2671 MakeCompositorFrame(empty_surface_ids(), empty_surface_ranges(),
2672 std::vector<TransferableResource>()));
2673 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2674 EXPECT_FALSE(parent_surface()->HasPendingFrame());
2675 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
2676 }
2677
2678 // This test verifies that we don't mark the previous active surface for
2679 // destruction until the new surface activates.
TEST_F(SurfaceSynchronizationTest,MarkPreviousSurfaceForDestructionAfterActivation)2680 TEST_F(SurfaceSynchronizationTest,
2681 MarkPreviousSurfaceForDestructionAfterActivation) {
2682 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
2683 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
2684 const SurfaceId arbitrary_id = MakeSurfaceId(kArbitraryFrameSink, 1);
2685
2686 // Submit a CompositorFrame that has no dependencies.
2687 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
2688 MakeDefaultCompositorFrame());
2689
2690 // Verify that the CompositorFrame has been activated.
2691 Surface* parent_surface1 = GetSurfaceForId(parent_id1);
2692 EXPECT_TRUE(parent_surface1->HasActiveFrame());
2693 EXPECT_FALSE(parent_surface1->HasPendingFrame());
2694 EXPECT_THAT(parent_surface1->activation_dependencies(), IsEmpty());
2695 EXPECT_FALSE(IsMarkedForDestruction(parent_id1));
2696
2697 parent_support().SubmitCompositorFrame(
2698 parent_id2.local_surface_id(),
2699 MakeCompositorFrame({arbitrary_id}, empty_surface_ranges(),
2700 std::vector<TransferableResource>(),
2701 MakeDefaultDeadline()));
2702
2703 // Verify that the CompositorFrame to the new surface has not been activated.
2704 Surface* parent_surface2 = GetSurfaceForId(parent_id2);
2705 EXPECT_FALSE(parent_surface2->HasActiveFrame());
2706 EXPECT_TRUE(parent_surface2->HasPendingFrame());
2707 EXPECT_THAT(parent_surface2->activation_dependencies(),
2708 UnorderedElementsAre(arbitrary_id));
2709 EXPECT_FALSE(IsMarkedForDestruction(parent_id1));
2710 EXPECT_FALSE(IsMarkedForDestruction(parent_id2));
2711
2712 // Advance BeginFrames to trigger a deadline.
2713 for (int i = 0; i < 3; ++i) {
2714 SendNextBeginFrame();
2715 EXPECT_TRUE(parent_surface2->has_deadline());
2716 }
2717 SendNextBeginFrame();
2718 EXPECT_FALSE(parent_surface2->has_deadline());
2719
2720 // Verify that the CompositorFrame has been activated.
2721 EXPECT_TRUE(parent_surface2->HasActiveFrame());
2722 EXPECT_FALSE(parent_surface2->HasPendingFrame());
2723 EXPECT_THAT(parent_surface2->activation_dependencies(), IsEmpty());
2724
2725 // Verify that the old surface is now marked for destruction.
2726 EXPECT_TRUE(IsMarkedForDestruction(parent_id1));
2727 EXPECT_FALSE(IsMarkedForDestruction(parent_id2));
2728 }
2729
2730 // This test verifies that CompositorFrameSinkSupport does not refer to
2731 // a valid but non-existant |last_activated_surface_id_|.
TEST_F(SurfaceSynchronizationTest,SetPreviousFrameSurfaceDoesntCrash)2732 TEST_F(SurfaceSynchronizationTest, SetPreviousFrameSurfaceDoesntCrash) {
2733 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2734 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
2735 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2736
2737 // The parent CompositorFrame is not blocked on anything and so it should
2738 // immediately activate.
2739 EXPECT_FALSE(parent_support().last_activated_surface_id().is_valid());
2740 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
2741 MakeDefaultCompositorFrame());
2742
2743 // Verify that the parent CompositorFrame has activated.
2744 EXPECT_FALSE(parent_surface()->has_deadline());
2745 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2746 EXPECT_FALSE(parent_surface()->HasPendingFrame());
2747 EXPECT_THAT(parent_surface()->activation_dependencies(), IsEmpty());
2748 EXPECT_TRUE(parent_support().last_activated_surface_id().is_valid());
2749
2750 // Submit another CompositorFrame to |parent_id|, but this time block it
2751 // on |child_id1|.
2752 parent_support().SubmitCompositorFrame(
2753 parent_id.local_surface_id(),
2754 MakeCompositorFrame({child_id1}, empty_surface_ranges(),
2755 std::vector<TransferableResource>(),
2756 MakeDefaultDeadline()));
2757
2758 // Verify that the surface has both a pending and activate CompositorFrame.
2759 EXPECT_TRUE(parent_surface()->has_deadline());
2760 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2761 EXPECT_TRUE(parent_surface()->HasPendingFrame());
2762 EXPECT_THAT(parent_surface()->activation_dependencies(),
2763 UnorderedElementsAre(child_id1));
2764
2765 // Evict the activated surface in the parent_support.
2766 EXPECT_TRUE(parent_support().last_activated_surface_id().is_valid());
2767 parent_support().EvictSurface(
2768 parent_support().last_activated_surface_id().local_surface_id());
2769 EXPECT_FALSE(parent_support().last_activated_surface_id().is_valid());
2770
2771 // The CompositorFrame in the evicted |parent_id| activates here because it
2772 // was blocked on |child_id1|.
2773 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2774 MakeDefaultCompositorFrame());
2775
2776 // parent_support will be informed of the activation of a CompositorFrame
2777 // associated with |parent_id|, but we clear |last_active_surface_id_| because
2778 // it was evicted before.
2779 EXPECT_FALSE(parent_support().last_activated_surface_id().is_valid());
2780
2781 // Perform a garbage collection. |parent_id| should no longer exist.
2782 EXPECT_NE(nullptr, GetSurfaceForId(parent_id));
2783 ExpireAllTemporaryReferencesAndGarbageCollect();
2784 EXPECT_EQ(nullptr, GetSurfaceForId(parent_id));
2785
2786 // This should not crash as the previous surface was cleared in
2787 // CompositorFrameSinkSupport.
2788 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
2789 MakeDefaultCompositorFrame());
2790 }
2791
2792 // This test verifies that when a surface activates that has the same
2793 // FrameSinkId of the primary but its embed token doesn't match, we don't
2794 // update the references of the parent.
TEST_F(SurfaceSynchronizationTest,SurfaceReferenceTracking_PrimaryEmbedTokenDoesntMatch)2795 TEST_F(SurfaceSynchronizationTest,
2796 SurfaceReferenceTracking_PrimaryEmbedTokenDoesntMatch) {
2797 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2798 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2799 const SurfaceId child_id2(
2800 kChildFrameSink2, LocalSurfaceId(2, base::UnguessableToken::Create()));
2801 const SurfaceId child_id3 = MakeSurfaceId(kChildFrameSink2, 5);
2802
2803 // The parent embeds (child_id1, child_id3).
2804 parent_support().SubmitCompositorFrame(
2805 parent_id.local_surface_id(),
2806 MakeCompositorFrame(
2807 empty_surface_ids(), {SurfaceRange(child_id1, child_id3)},
2808 std::vector<TransferableResource>(), MakeDefaultDeadline()));
2809
2810 // Verify that no references exist.
2811 EXPECT_THAT(GetReferencesFrom(parent_id), empty_surface_ids());
2812
2813 // Activate |child_id2|.
2814 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
2815 MakeDefaultCompositorFrame());
2816
2817 // Since |child_id2| has a different embed token than both primary and
2818 // fallback, it should not be used as a reference even if it has the same
2819 // FrameSinkId as the primary.
2820 EXPECT_THAT(GetReferencesFrom(parent_id), empty_surface_ids());
2821
2822 // Activate |child_id3|.
2823 child_support2().SubmitCompositorFrame(child_id3.local_surface_id(),
2824 MakeDefaultCompositorFrame());
2825
2826 // Verify that a reference is acquired.
2827 EXPECT_THAT(GetReferencesFrom(parent_id), UnorderedElementsAre(child_id3));
2828 }
2829
2830 // This test verifies that a parent referencing a SurfaceRange get updated
2831 // whenever a child surface activates inside this range. This should also update
2832 // the SurfaceReferences tree.
TEST_F(SurfaceSynchronizationTest,SurfaceReferenceTracking_NewerSurfaceUpdatesReferences)2833 TEST_F(SurfaceSynchronizationTest,
2834 SurfaceReferenceTracking_NewerSurfaceUpdatesReferences) {
2835 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2836 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2837 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
2838 const SurfaceId child_id3 = MakeSurfaceId(kChildFrameSink1, 3);
2839 const SurfaceId child_id4 = MakeSurfaceId(kChildFrameSink2, 1);
2840
2841 parent_support().SubmitCompositorFrame(
2842 parent_id.local_surface_id(),
2843 MakeCompositorFrame(
2844 empty_surface_ids(), {SurfaceRange(child_id1, child_id4)},
2845 std::vector<TransferableResource>(), MakeDefaultDeadline()));
2846
2847 // Verify that no references exist.
2848 EXPECT_THAT(GetReferencesFrom(parent_id), empty_surface_ids());
2849
2850 // Activate |child_id1|.
2851 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2852 MakeDefaultCompositorFrame());
2853
2854 // Verify that a reference is acquired.
2855 EXPECT_THAT(GetReferencesFrom(parent_id), UnorderedElementsAre(child_id1));
2856
2857 // Activate |child_id2|.
2858 child_support1().SubmitCompositorFrame(child_id2.local_surface_id(),
2859 MakeDefaultCompositorFrame());
2860
2861 // Verify that the reference is updated.
2862 EXPECT_THAT(GetReferencesFrom(parent_id), UnorderedElementsAre(child_id2));
2863
2864 // Activate |child_id4| in a different frame sink.
2865 child_support2().SubmitCompositorFrame(child_id4.local_surface_id(),
2866 MakeDefaultCompositorFrame());
2867
2868 // Verify that the reference is updated.
2869 EXPECT_THAT(GetReferencesFrom(parent_id), UnorderedElementsAre(child_id4));
2870
2871 // Activate |child_id3|.
2872 child_support1().SubmitCompositorFrame(child_id3.local_surface_id(),
2873 MakeDefaultCompositorFrame());
2874
2875 // Verify that the reference will not get updated since |child_id3| is in the
2876 // fallback's FrameSinkId.
2877 EXPECT_THAT(GetReferencesFrom(parent_id), UnorderedElementsAre(child_id4));
2878 }
2879
2880 // This test verifies that once a frame sink become invalidated, it should
2881 // immediately unblock all pending frames depending on that sink.
TEST_F(SurfaceSynchronizationTest,InvalidatedFrameSinkShouldNotBlockActivation)2882 TEST_F(SurfaceSynchronizationTest,
2883 InvalidatedFrameSinkShouldNotBlockActivation) {
2884 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
2885 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
2886
2887 // The parent submitted a frame that refers to a future child surface.
2888 EXPECT_FALSE(parent_support().last_activated_surface_id().is_valid());
2889 parent_support().SubmitCompositorFrame(
2890 parent_id.local_surface_id(), MakeCompositorFrame({child_id1}, {}, {}));
2891
2892 // The frame is pending because the child frame hasn't be submitted yet.
2893 EXPECT_FALSE(parent_surface()->HasActiveFrame());
2894 EXPECT_TRUE(parent_surface()->HasPendingFrame());
2895 EXPECT_FALSE(parent_support().last_activated_surface_id().is_valid());
2896
2897 // Killing the child sink should unblock the frame because it is known
2898 // the dependency can never fulfill.
2899 frame_sink_manager().InvalidateFrameSinkId(kChildFrameSink1);
2900 EXPECT_TRUE(parent_surface()->HasActiveFrame());
2901 EXPECT_FALSE(parent_surface()->HasPendingFrame());
2902 EXPECT_EQ(parent_id, parent_support().last_activated_surface_id());
2903 }
2904
TEST_F(SurfaceSynchronizationTest,EvictSurface)2905 TEST_F(SurfaceSynchronizationTest, EvictSurface) {
2906 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1, 1);
2907 // Child-initiated synchronization event:
2908 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 1, 2);
2909 // Parent-initiated synchronizaton event:
2910 const SurfaceId child_id3 = MakeSurfaceId(kChildFrameSink1, 2, 2);
2911
2912 // Submit a CompositorFrame to |child_id1|.
2913 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2914 MakeDefaultCompositorFrame());
2915
2916 // Evict |child_id1|. It should get marked for destruction immediately.
2917 child_support1().EvictSurface(child_id1.local_surface_id());
2918 EXPECT_TRUE(IsMarkedForDestruction(child_id1));
2919
2920 // Submit a CompositorFrame to |child_id2|. This CompositorFrame should be
2921 // immediately rejected because |child_id2| has the same parent sequence
2922 // number as |child_id1|.
2923 child_support1().SubmitCompositorFrame(child_id2.local_surface_id(),
2924 MakeDefaultCompositorFrame());
2925 EXPECT_EQ(nullptr, GetSurfaceForId(child_id2));
2926
2927 // Submit a CompositorFrame to |child_id3|. It should not be accepted and not
2928 // marked for destruction.
2929 child_support1().SubmitCompositorFrame(child_id3.local_surface_id(),
2930 MakeDefaultCompositorFrame());
2931 ASSERT_NE(nullptr, GetSurfaceForId(child_id3));
2932 EXPECT_FALSE(IsMarkedForDestruction(child_id3));
2933 }
2934
2935 // Tests that in cases where a pending-deletion surface (surface A) is
2936 // activated during anothother surface (surface B)'s deletion, we don't attempt
2937 // to delete surface A twice.
TEST_F(SurfaceSynchronizationTest,SurfaceActivationDuringDeletion)2938 TEST_F(SurfaceSynchronizationTest, SurfaceActivationDuringDeletion) {
2939 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1, 1);
2940 // Child-initiated synchronization event:
2941 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 1, 2);
2942 const SurfaceId arbitrary_id = MakeSurfaceId(kArbitraryFrameSink, 1);
2943
2944 // Submit a CompositorFrame to |child_id1|.
2945 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
2946 MakeDefaultCompositorFrame());
2947
2948 // Child 1 should not yet be active.
2949 Surface* child_surface1 = GetSurfaceForId(child_id1);
2950 ASSERT_NE(nullptr, child_surface1);
2951 EXPECT_FALSE(child_surface1->HasPendingFrame());
2952 EXPECT_TRUE(child_surface1->HasActiveFrame());
2953
2954 // Submit a CompositorFrame to |child_id2|.
2955 child_support1().SubmitCompositorFrame(
2956 child_id2.local_surface_id(),
2957 MakeCompositorFrame({arbitrary_id}, empty_surface_ranges(),
2958 std::vector<TransferableResource>()));
2959
2960 // Child 2 should not yet be active.
2961 Surface* child_surface2 = GetSurfaceForId(child_id2);
2962 ASSERT_NE(nullptr, child_surface2);
2963 EXPECT_TRUE(child_surface2->HasPendingFrame());
2964 EXPECT_FALSE(child_surface2->HasActiveFrame());
2965
2966 // Evict |child_id2|. both surfaces should be marked for deletion.
2967 child_support1().EvictSurface(child_id1.local_surface_id());
2968 EXPECT_TRUE(IsMarkedForDestruction(child_id1));
2969 EXPECT_TRUE(IsMarkedForDestruction(child_id2));
2970
2971 // Garbage collect to delete the above surfaces. This will activate
2972 // |child_id2|, which will cause it to attempt re-deletion.
2973 ExpireAllTemporaryReferencesAndGarbageCollect();
2974
2975 // Neither should still be marked for deletion.
2976 EXPECT_FALSE(IsMarkedForDestruction(child_id1));
2977 EXPECT_FALSE(IsMarkedForDestruction(child_id2));
2978 }
2979
2980 // This test verifies that if a surface is created with new embed token, a new
2981 // allocation group is created, and once that surface is destroyed, the
2982 // allocation group is destroyed as well.
TEST_F(SurfaceSynchronizationTest,AllocationGroupCreationInitiatedBySubmitter)2983 TEST_F(SurfaceSynchronizationTest,
2984 AllocationGroupCreationInitiatedBySubmitter) {
2985 const SurfaceId surface_id = MakeSurfaceId(kChildFrameSink1, 1, 1);
2986
2987 // The allocation group should not exist yet.
2988 EXPECT_FALSE(surface_manager()->GetAllocationGroupForSurfaceId(surface_id));
2989
2990 // Submit a CompositorFrame to |child_id1|.
2991 child_support1().SubmitCompositorFrame(surface_id.local_surface_id(),
2992 MakeDefaultCompositorFrame());
2993
2994 // The allocation group should now exist.
2995 EXPECT_TRUE(surface_manager()->GetAllocationGroupForSurfaceId(surface_id));
2996
2997 // Mark the surface for destruction. The allocation group should continue to
2998 // exist because the surface won't be actually destroyed until garbage
2999 // collection time.
3000 child_support1().EvictSurface(surface_id.local_surface_id());
3001 EXPECT_TRUE(surface_manager()->GetSurfaceForId(surface_id));
3002 EXPECT_TRUE(surface_manager()->GetAllocationGroupForSurfaceId(surface_id));
3003
3004 // Now garbage-collect. Both allocation group and the surface itself will be
3005 // destroyed.
3006 surface_manager()->GarbageCollectSurfaces();
3007 EXPECT_FALSE(surface_manager()->GetSurfaceForId(surface_id));
3008 EXPECT_FALSE(surface_manager()->GetAllocationGroupForSurfaceId(surface_id));
3009 }
3010
3011 // This test verifies that if a surface references another surface that has an
3012 // embed token that was never seen before, an allocation group will be created
3013 // for the embedded surface.
TEST_F(SurfaceSynchronizationTest,AllocationGroupCreationInitiatedByEmbedder)3014 TEST_F(SurfaceSynchronizationTest, AllocationGroupCreationInitiatedByEmbedder) {
3015 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1, 1);
3016 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1, 1);
3017
3018 // The allocation group should not exist yet.
3019 EXPECT_FALSE(surface_manager()->GetAllocationGroupForSurfaceId(child_id));
3020
3021 // Now submit a CompositorFrame that references |child_id|. An allocation
3022 // group will be created for it.
3023 CompositorFrame frame =
3024 MakeCompositorFrame({}, {SurfaceRange(base::nullopt, child_id)}, {});
3025 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
3026 std::move(frame));
3027 EXPECT_TRUE(surface_manager()->GetAllocationGroupForSurfaceId(child_id));
3028
3029 // Now the parent unembeds the child surface. The allocation group for child
3030 // surface should be marked for destruction. However, it won't get actually
3031 // destroyed until garbage collection time.
3032 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
3033 MakeDefaultCompositorFrame());
3034 ASSERT_TRUE(surface_manager()->GetAllocationGroupForSurfaceId(child_id));
3035 EXPECT_TRUE(surface_manager()
3036 ->GetAllocationGroupForSurfaceId(child_id)
3037 ->IsReadyToDestroy());
3038 EXPECT_TRUE(allocation_groups_need_garbage_collection());
3039
3040 // Now start garbage-collection. Note that no surface has been deleted
3041 // recently, but the allocation group is ready to destroy and must be
3042 // garbage-collected.
3043 surface_manager()->GarbageCollectSurfaces();
3044 EXPECT_FALSE(surface_manager()->GetAllocationGroupForSurfaceId(child_id));
3045 EXPECT_FALSE(allocation_groups_need_garbage_collection());
3046 }
3047
3048 // This test verifies that if the parent embeds a SurfaceRange that has
3049 // different embed tokens at start and end, then initially both allocation
3050 // groups are created, but once the primary becomes available, the allocation
3051 // group for the fallback gets destroyed.
TEST_F(SurfaceSynchronizationTest,FallbackAllocationGroupDestroyedAfterPrimaryAvailable)3052 TEST_F(SurfaceSynchronizationTest,
3053 FallbackAllocationGroupDestroyedAfterPrimaryAvailable) {
3054 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1, 1);
3055 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1, 1);
3056 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1, 1);
3057
3058 // The allocation group should not exist yet.
3059 EXPECT_FALSE(surface_manager()->GetAllocationGroupForSurfaceId(child_id1));
3060 EXPECT_FALSE(surface_manager()->GetAllocationGroupForSurfaceId(child_id2));
3061
3062 // Now submit a CompositorFrame that references |child_id2| as primary and
3063 // |child_id1| as the fallback. An allocation group will be created for both
3064 // of them.
3065 CompositorFrame frame =
3066 MakeCompositorFrame({}, {SurfaceRange(child_id1, child_id2)}, {});
3067 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
3068 std::move(frame));
3069 EXPECT_TRUE(surface_manager()->GetAllocationGroupForSurfaceId(child_id1));
3070 EXPECT_TRUE(surface_manager()->GetAllocationGroupForSurfaceId(child_id2));
3071
3072 // Make |child_id2| available. The allocation group for |child_id1| should be
3073 // marked for destruction.
3074 EXPECT_FALSE(allocation_groups_need_garbage_collection());
3075 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
3076 MakeDefaultCompositorFrame());
3077 ASSERT_TRUE(surface_manager()->GetAllocationGroupForSurfaceId(child_id1));
3078 EXPECT_TRUE(surface_manager()
3079 ->GetAllocationGroupForSurfaceId(child_id1)
3080 ->IsReadyToDestroy());
3081 ASSERT_TRUE(surface_manager()->GetAllocationGroupForSurfaceId(child_id2));
3082 EXPECT_FALSE(surface_manager()
3083 ->GetAllocationGroupForSurfaceId(child_id2)
3084 ->IsReadyToDestroy());
3085 EXPECT_TRUE(allocation_groups_need_garbage_collection());
3086
3087 // Initiate garbage-collection. The allocation group for |child_id1| should be
3088 // destroyed but the one for |child_id2| should stay alive.
3089 surface_manager()->GarbageCollectSurfaces();
3090 EXPECT_FALSE(surface_manager()->GetAllocationGroupForSurfaceId(child_id1));
3091 EXPECT_TRUE(surface_manager()->GetAllocationGroupForSurfaceId(child_id2));
3092 EXPECT_FALSE(allocation_groups_need_garbage_collection());
3093 }
3094
3095 // This test verifies that if the parent embeds a SurfaceRange that has
3096 // different embed tokens for primary and fallback and a surface already exists
3097 // in the primary's allocation group, we don't create an allocation group for
3098 // the fallback at all.
TEST_F(SurfaceSynchronizationTest,FallbackAllocationGroupNotCreatedIfPrimaryAvailable)3099 TEST_F(SurfaceSynchronizationTest,
3100 FallbackAllocationGroupNotCreatedIfPrimaryAvailable) {
3101 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1, 1);
3102 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1, 1);
3103 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1, 1);
3104
3105 // The allocation group should not exist yet.
3106 EXPECT_FALSE(surface_manager()->GetAllocationGroupForSurfaceId(child_id1));
3107 EXPECT_FALSE(surface_manager()->GetAllocationGroupForSurfaceId(child_id2));
3108
3109 // Make |child_id2| available. An allocation group should be created for it.
3110 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
3111 MakeDefaultCompositorFrame());
3112 EXPECT_FALSE(surface_manager()->GetAllocationGroupForSurfaceId(child_id1));
3113 EXPECT_TRUE(surface_manager()->GetAllocationGroupForSurfaceId(child_id2));
3114
3115 // Now submit a CompositorFrame that references |child_id2| as primary and
3116 // |child_id1| as the fallback. An allocation group should not be created for
3117 // the fallback because if the primary is available, we don't need the
3118 // fallback.
3119 CompositorFrame frame =
3120 MakeCompositorFrame({}, {SurfaceRange(child_id1, child_id2)}, {});
3121 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
3122 std::move(frame));
3123 EXPECT_FALSE(surface_manager()->GetAllocationGroupForSurfaceId(child_id1));
3124 EXPECT_TRUE(surface_manager()->GetAllocationGroupForSurfaceId(child_id2));
3125 }
3126
3127 // Verifies that the value of last active surface is correct after embed token
3128 // changes. https://crbug.com/967012
TEST_F(SurfaceSynchronizationTest,CheckLastActiveSurfaceAfterEmbedTokenChange)3129 TEST_F(SurfaceSynchronizationTest,
3130 CheckLastActiveSurfaceAfterEmbedTokenChange) {
3131 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 2);
3132 const SurfaceId parent_id2(
3133 kParentFrameSink, LocalSurfaceId(1, base::UnguessableToken::Create()));
3134 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
3135 MakeDefaultCompositorFrame());
3136 Surface* parent_surface1 = GetSurfaceForId(parent_id1);
3137 EXPECT_TRUE(parent_surface1->HasActiveFrame());
3138 EXPECT_FALSE(parent_surface1->HasPendingFrame());
3139 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
3140 MakeDefaultCompositorFrame());
3141 Surface* parent_surface2 = GetSurfaceForId(parent_id2);
3142 EXPECT_TRUE(parent_surface2->HasActiveFrame());
3143 EXPECT_FALSE(parent_surface2->HasPendingFrame());
3144
3145 // Even though |parent_id1| has a larger sequence number, the value of
3146 // |last_activated_surface_id| should be |parent_id2|.
3147 EXPECT_EQ(parent_id2, parent_support().last_activated_surface_id());
3148 }
3149
3150 // Regression test for https://crbug.com/1000868. Verify that the output of
3151 // GetLatestInFlightSurface is correct when there is a conflict between the last
3152 // surface in the group and the queried SurfaceRange.
TEST_F(SurfaceSynchronizationTest,LatestInFlightSurfaceConflict)3153 TEST_F(SurfaceSynchronizationTest, LatestInFlightSurfaceConflict) {
3154 const SurfaceId id1 = MakeSurfaceId(kParentFrameSink, 1, 1);
3155 const SurfaceId id2 = MakeSurfaceId(kParentFrameSink, 2, 2);
3156 const SurfaceId id3 = MakeSurfaceId(kParentFrameSink, 1, 3);
3157
3158 parent_support().SubmitCompositorFrame(id1.local_surface_id(),
3159 MakeDefaultCompositorFrame());
3160 parent_support().SubmitCompositorFrame(id2.local_surface_id(),
3161 MakeDefaultCompositorFrame());
3162 EXPECT_EQ(GetSurfaceForId(id1),
3163 GetLatestInFlightSurface(SurfaceRange(base::nullopt, id3)));
3164 }
3165
3166 // Check that if two different SurfaceIds with the same embed token are
3167 // embedded, viz doesn't crash. https://crbug.com/1001143
TEST_F(SurfaceSynchronizationTest,DuplicateAllocationGroupInActivationDependencies)3168 TEST_F(SurfaceSynchronizationTest,
3169 DuplicateAllocationGroupInActivationDependencies) {
3170 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
3171 const SurfaceId child1_id1 = MakeSurfaceId(kChildFrameSink1, 1);
3172 const SurfaceId child1_id2 = MakeSurfaceId(kChildFrameSink1, 2);
3173 const SurfaceId child2_id1 = MakeSurfaceId(kChildFrameSink2, 1);
3174
3175 // Submit a CompositorFrame to |child1_id1| embedding |child2_id1|.
3176 CompositorFrame child1_frame =
3177 CompositorFrameBuilder()
3178 .AddDefaultRenderPass()
3179 .SetActivationDependencies({child2_id1})
3180 .SetReferencedSurfaces({SurfaceRange(base::nullopt, child2_id1)})
3181 .Build();
3182 child_support1().SubmitCompositorFrame(child1_id1.local_surface_id(),
3183 std::move(child1_frame));
3184
3185 // Submit a CompositorFrame to |parent_id| embedding both |child1_id1| and
3186 // |child1_id2|.
3187 CompositorFrame parent_frame =
3188 CompositorFrameBuilder()
3189 .AddDefaultRenderPass()
3190 .SetActivationDependencies({child1_id1, child1_id2})
3191 .SetReferencedSurfaces({SurfaceRange(base::nullopt, child1_id1),
3192 SurfaceRange(base::nullopt, child1_id2)})
3193 .Build();
3194 // This shouldn't crash.
3195 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
3196 std::move(parent_frame));
3197
3198 // When multiple dependencies have the same embed token, only the first one
3199 // should be taken into account.
3200 EXPECT_EQ(1u, parent_surface()->activation_dependencies().size());
3201 EXPECT_EQ(child1_id1, *parent_surface()->activation_dependencies().begin());
3202 }
3203
3204 } // namespace viz
3205