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

Side by Side Diff: components/viz/hittest/hittest_aggregator_unittest.cc

Issue 2908783002: WIP Hittest Component.
Patch Set: surface observer and test setup Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
rjkroege 2017/06/02 22:45:45 removed the commented out code?
gklassen 2017/06/05 21:32:14 Done.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 /*
6 #include "base/containers/flat_set.h"
7 #include "cc/surfaces/compositor_frame_sink_support.h"
8 #include "cc/surfaces/surface_manager.h"
9 #include "cc/test/begin_frame_args_test.h"
10 #include "cc/test/compositor_frame_helpers.h"
11 #include "cc/test/fake_external_begin_frame_source.h"
12 #include "cc/test/fake_surface_observer.h"
13 #include "cc/test/mock_compositor_frame_sink_support_client.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 */
16
17 #include "cc/surfaces/frame_sink_id.h"
18 #include "cc/surfaces/local_surface_id.h"
19 #include "cc/surfaces/surface_id.h"
20 #include "hittest_aggregator.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
23 namespace viz {
24 namespace test {
25
26 namespace {
27
28 /*
29 constexpr bool kIsRoot = true;
30 constexpr bool kIsChildRoot = false;
31 constexpr bool kHandlesFrameSinkIdInvalidation = true;
32 constexpr bool kNeedsSyncPoints = true;
33 constexpr FrameSinkId kDisplayFrameSink(2, 0);
34 constexpr FrameSinkId kParentFrameSink(3, 0);
35 constexpr FrameSinkId kChildFrameSink1(65563, 0);
36 constexpr FrameSinkId kChildFrameSink2(65564, 0);
37 constexpr FrameSinkId kArbitraryFrameSink(1337, 7331);
38
39 std::vector<SurfaceId> empty_surface_ids() {
40 return std::vector<SurfaceId>();
41 }
42 */
43 constexpr cc::FrameSinkId kDisplayFrameSink(2, 0);
44 // constexpr gfx::Transform identityTransform();
45
46 cc::SurfaceId MakeSurfaceId(const cc::FrameSinkId& frame_sink_id,
47 uint32_t local_id) {
48 return cc::SurfaceId(
49 frame_sink_id,
50 cc::LocalSurfaceId(local_id, base::UnguessableToken::Deserialize(0, 1u)));
51 }
52
53 } // namespace
54
55 using namespace hittest::mojom;
56
57 class HittestAggregatorTest : public testing::Test {
58 public:
59 HittestAggregatorTest() {}
60 ~HittestAggregatorTest() override {}
61
62 void SetUp() override {}
63
64 void TearDown() override {}
65
66 HittestAggregator aggregator_;
67
68 int count() {
69 HittestAggregator::Element* end = aggregator_.current_regions_;
70 while (end->child_count_ != LAST_REGION) {
71 end++;
72 }
73 return end - aggregator_.current_regions_;
74 }
75
76 HittestRegion RegionAtIndex(int i) {
77 return aggregator_.current_regions_[i].region_;
78 }
79 };
80
81 TEST_F(HittestAggregatorTest, HittestAggregation) {
82 EXPECT_TRUE(true);
83 }
84
85 TEST(HittestAggregatorTestNoFixture, HittestDataValidation) {
86 EXPECT_TRUE(false);
87 }
88
89 // tests brainstorm
90 // A. Validation
91 // - SurfaceId is valid and exists
rjkroege 2017/06/02 22:45:45 let cc worry about it. You can assume in your obse
gklassen 2017/06/05 21:32:14 Acknowledged.
92 // - Rect is within the display
93 // - flags is one of available values?
94 // B. Aggregation
95 // - happy paths:
96 // - missing surface parent
97 // - cyclic surfaces ( possible? )
rjkroege 2017/06/02 22:45:46 probably can't/won't happen
gklassen 2017/06/05 21:32:14 Acknowledged.
98 // C. SurfaceFinding
99 // -
100
101 TEST_F(HittestAggregatorTest, SimplestHappyPath) {
rjkroege 2017/06/02 22:45:46 A happy path is like a happy meal for the input ta
102 // one hittest_data with no sub-regions gets all events
rjkroege 2017/06/02 22:45:45 Ascii art would be simply spiffy here.
gklassen 2017/06/05 21:32:14 Acknowledged.
103
104 EXPECT_TRUE(count() == 0);
105
106 cc::SurfaceId display_surface_id = MakeSurfaceId(kDisplayFrameSink, 1);
107
108 auto hittest_data = HittestData::New();
rjkroege 2017/06/02 22:45:46 New is an unfortunate choice of method name. Given
gklassen 2017/06/05 21:32:14 perhaps, but it's the name given by the auto-gen c
109 hittest_data->surface_id_ = display_surface_id;
110 hittest_data->flags_ = hittest::mojom::HittestRegionFlags::HITTEST_NONE;
111 hittest_data->rect_.SetRect(0, 0, 1024, 768);
112
113 aggregator_.SubmitHittestData(std::move(hittest_data));
114
115 EXPECT_TRUE(count() == 0);
116
117 aggregator_.Aggregate(display_surface_id);
118
119 // there should now be only one region
120 EXPECT_TRUE(count() == 1);
121
122 HittestRegion region = RegionAtIndex(0);
123 EXPECT_TRUE(region.rect_ == gfx::Rect(0, 0, 1027, 768));
124 EXPECT_TRUE(region.flags_ == HittestRegionFlags::HITTEST_NONE);
125 }
126
127 TEST_F(HittestAggregatorTest, HittestDataValidation) {
128 auto hittest_data = hittest::mojom::HittestData::New();
129 hittest_data->surface_id_ = MakeSurfaceId(kDisplayFrameSink, 1);
130 hittest_data->flags_ = hittest::mojom::HittestRegionFlags::HITTEST_NONE;
131 hittest_data->rect_.SetRect(0, 0, 10, 10);
132
133 auto hittest_region = hittest::mojom::HittestRegion::New();
134 hittest_region->surface_id_ = MakeSurfaceId(kDisplayFrameSink, 2);
135 hittest_region->flags_ = hittest::mojom::HittestRegionFlags::HITTEST_ASK;
136 hittest_region->rect_.SetRect(0, 0, 10, 10);
137
138 // todo: confirm that transform inits to Identity
139 // DCHECK( hittest_region.transform_ )
140
141 hittest_data->regions_.push_back(std::move(hittest_region));
142
143 aggregator_.SubmitHittestData(std::move(hittest_data));
144 }
145
146 /*
rjkroege 2017/06/02 22:45:46 this looks copied from elsewhere. not reviewing ye
gklassen 2017/06/05 21:32:14 Acknowledged.
147
148 class SurfaceSynchronizationTest : public testing::Test {
149 public:
150 SurfaceSynchronizationTest()
151 : surface_manager_(SurfaceManager::LifetimeType::REFERENCES),
152 surface_observer_(false) {}
153 ~SurfaceSynchronizationTest() override {}
154
155 CompositorFrameSinkSupport& display_support() { return *supports_[0]; }
156 Surface* display_surface() {
157 return display_support().current_surface_for_testing();
158 }
159
160 CompositorFrameSinkSupport& parent_support() { return *supports_[1]; }
161 Surface* parent_surface() {
162 return parent_support().current_surface_for_testing();
163 }
164 const ReferencedSurfaceTracker& parent_reference_tracker() {
165 return parent_support().ReferenceTrackerForTesting();
166 }
167
168 CompositorFrameSinkSupport& child_support1() { return *supports_[2]; }
169 Surface* child_surface1() {
170 return child_support1().current_surface_for_testing();
171 }
172
173 CompositorFrameSinkSupport& child_support2() { return *supports_[3]; }
174 Surface* child_surface2() {
175 return child_support2().current_surface_for_testing();
176 }
177
178 CompositorFrameSinkSupport& support(int index) { return *supports_[index]; }
179 Surface* surface(int index) {
180 return support(index).current_surface_for_testing();
181 }
182
183 SurfaceManager& surface_manager() { return surface_manager_; }
184
185 // Returns all the references where |surface_id| is the parent.
186 const base::flat_set<SurfaceId>& GetChildReferences(
187 const SurfaceId& surface_id) {
188 return surface_manager().parent_to_child_refs_[surface_id];
189 }
190
191 // Returns true if there is a temporary reference for |surface_id|.
192 bool HasTemporaryReference(const SurfaceId& surface_id) {
193 return surface_manager().HasTemporaryReference(surface_id);
194 }
195
196 SurfaceDependencyTracker& dependency_tracker() {
197 return *surface_manager_.dependency_tracker();
198 }
199
200 FakeExternalBeginFrameSource* begin_frame_source() {
201 return begin_frame_source_.get();
202 }
203
204 FakeSurfaceObserver& surface_observer() { return surface_observer_; }
205
206 // testing::Test:
207 void SetUp() override {
208 testing::Test::SetUp();
209
210 begin_frame_source_ =
211 base::MakeUnique<FakeExternalBeginFrameSource>(0.f, false);
212 dependency_tracker_ = base::MakeUnique<SurfaceDependencyTracker>(
213 &surface_manager_, begin_frame_source_.get());
214 surface_manager_.SetDependencyTracker(dependency_tracker_.get());
215 surface_manager_.AddObserver(&surface_observer_);
216 supports_.push_back(CompositorFrameSinkSupport::Create(
217 &support_client_, &surface_manager_, kDisplayFrameSink, kIsRoot,
218 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints));
219 supports_.push_back(CompositorFrameSinkSupport::Create(
220 &support_client_, &surface_manager_, kParentFrameSink, kIsChildRoot,
221 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints));
222 supports_.push_back(CompositorFrameSinkSupport::Create(
223 &support_client_, &surface_manager_, kChildFrameSink1, kIsChildRoot,
224 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints));
225 supports_.push_back(CompositorFrameSinkSupport::Create(
226 &support_client_, &surface_manager_, kChildFrameSink2, kIsChildRoot,
227 kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints));
228
229 // Normally, the BeginFrameSource would be registered by the Display. We
230 // register it here so that BeginFrames are received by the display support,
231 // for use in the PassesOnBeginFrameAcks test. Other supports do not receive
232 // BeginFrames, since the frame sink hierarchy is not set up in this test.
233 surface_manager_.RegisterBeginFrameSource(begin_frame_source_.get(),
234 kDisplayFrameSink);
235 }
236
237 void TearDown() override {
238 surface_manager_.RemoveObserver(&surface_observer_);
239 surface_manager_.SetDependencyTracker(nullptr);
240 surface_manager_.UnregisterBeginFrameSource(begin_frame_source_.get());
241
242 dependency_tracker_.reset();
243
244 // SurfaceDependencyTracker depends on this BeginFrameSource and so it must
245 // be destroyed AFTER the dependency tracker is destroyed.
246 begin_frame_source_.reset();
247
248 supports_.clear();
249
250 surface_observer_.Reset();
251 }
252
253 protected:
254 testing::NiceMock<MockCompositorFrameSinkSupportClient> support_client_;
255
256 private:
257 SurfaceManager surface_manager_;
258 FakeSurfaceObserver surface_observer_;
259 std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source_;
260 std::unique_ptr<SurfaceDependencyTracker> dependency_tracker_;
261 std::vector<std::unique_ptr<CompositorFrameSinkSupport>> supports_;
262
263 DISALLOW_COPY_AND_ASSIGN(SurfaceSynchronizationTest);
264 };
265
266 // The display root surface should have a surface reference from the top-level
267 // root added/removed when a CompositorFrame is submitted with a new SurfaceId.
268 TEST_F(SurfaceSynchronizationTest, RootSurfaceReceivesReferences) {
269 const SurfaceId display_id_first = MakeSurfaceId(kDisplayFrameSink, 1);
270 const SurfaceId display_id_second = MakeSurfaceId(kDisplayFrameSink, 2);
271
272 // Submit a CompositorFrame for the first display root surface.
273 display_support().SubmitCompositorFrame(display_id_first.local_surface_id(),
274 MakeCompositorFrame());
275
276 // A surface reference from the top-level root is added and there shouldn't be
277 // a temporary reference.
278 EXPECT_FALSE(HasTemporaryReference(display_id_first));
279 EXPECT_THAT(GetChildReferences(surface_manager().GetRootSurfaceId()),
280 UnorderedElementsAre(display_id_first));
281
282 // Submit a CompositorFrame for the second display root surface.
283 display_support().SubmitCompositorFrame(display_id_second.local_surface_id(),
284 MakeCompositorFrame());
285
286 // A surface reference from the top-level root to |display_id_second| should
287 // be added and the reference to |display_root_first| removed.
288 EXPECT_FALSE(HasTemporaryReference(display_id_second));
289 EXPECT_THAT(GetChildReferences(surface_manager().GetRootSurfaceId()),
290 UnorderedElementsAre(display_id_second));
291
292 // Surface |display_id_first| is unreachable and should get deleted.
293 EXPECT_EQ(nullptr, surface_manager().GetSurfaceForId(display_id_first));
294 }
295
296 // The parent Surface is blocked on |child_id1| and |child_id2|.
297 TEST_F(SurfaceSynchronizationTest, BlockedOnTwo) {
298 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
299 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
300 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
301
302 parent_support().SubmitCompositorFrame(
303 parent_id.local_surface_id(),
304 MakeCompositorFrame({child_id1, child_id2}, empty_surface_ids(),
305 TransferableResourceArray()));
306
307 // parent_support is blocked on |child_id1| and |child_id2|.
308 EXPECT_TRUE(dependency_tracker().has_deadline());
309 EXPECT_FALSE(parent_surface()->HasActiveFrame());
310 EXPECT_TRUE(parent_surface()->HasPendingFrame());
311 EXPECT_THAT(parent_surface()->blocking_surfaces(),
312 UnorderedElementsAre(child_id1, child_id2));
313
314 // Submit a CompositorFrame without any dependencies to |child_id1|.
315 // parent_support should now only be blocked on |child_id2|.
316 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
317 MakeCompositorFrame());
318
319 EXPECT_TRUE(dependency_tracker().has_deadline());
320 EXPECT_FALSE(parent_surface()->HasActiveFrame());
321 EXPECT_TRUE(parent_surface()->HasPendingFrame());
322 EXPECT_THAT(parent_surface()->blocking_surfaces(),
323 UnorderedElementsAre(child_id2));
324
325 // Submit a CompositorFrame without any dependencies to |child_id2|.
326 // parent_support should be activated.
327 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
328 MakeCompositorFrame());
329
330 EXPECT_FALSE(dependency_tracker().has_deadline());
331 EXPECT_TRUE(parent_surface()->HasActiveFrame());
332 EXPECT_FALSE(parent_surface()->HasPendingFrame());
333 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
334 }
335
336 // The parent Surface is blocked on |child_id2| which is blocked on |child_id3|.
337 TEST_F(SurfaceSynchronizationTest, BlockedChain) {
338 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
339 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
340 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
341
342 parent_support().SubmitCompositorFrame(
343 parent_id.local_surface_id(),
344 MakeCompositorFrame({child_id1}, empty_surface_ids(),
345 TransferableResourceArray()));
346
347 // parent_support is blocked on |child_id1|.
348 EXPECT_TRUE(dependency_tracker().has_deadline());
349 EXPECT_FALSE(parent_surface()->HasActiveFrame());
350 EXPECT_TRUE(parent_surface()->HasPendingFrame());
351 EXPECT_THAT(parent_surface()->blocking_surfaces(),
352 UnorderedElementsAre(child_id1));
353 // The parent should not report damage until it activates.
354 EXPECT_FALSE(surface_observer().IsSurfaceDamaged(parent_id));
355
356 child_support1().SubmitCompositorFrame(
357 child_id1.local_surface_id(),
358 MakeCompositorFrame({child_id2}, empty_surface_ids(),
359 TransferableResourceArray()));
360
361 // child_support1 should now be blocked on |child_id2|.
362 EXPECT_TRUE(dependency_tracker().has_deadline());
363 EXPECT_FALSE(child_surface1()->HasActiveFrame());
364 EXPECT_TRUE(child_surface1()->HasPendingFrame());
365 EXPECT_THAT(child_surface1()->blocking_surfaces(),
366 UnorderedElementsAre(child_id2));
367 // The parent and child should not report damage until they activate.
368 EXPECT_FALSE(surface_observer().IsSurfaceDamaged(parent_id));
369 EXPECT_FALSE(surface_observer().IsSurfaceDamaged(child_id1));
370
371 // The parent should still be blocked on |child_id1| because it's pending.
372 EXPECT_THAT(parent_surface()->blocking_surfaces(),
373 UnorderedElementsAre(child_id1));
374
375 // Submit a CompositorFrame without any dependencies to |child_id2|.
376 // parent_support should be activated.
377 child_support2().SubmitCompositorFrame(
378 child_id2.local_surface_id(),
379 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(),
380 TransferableResourceArray()));
381
382 EXPECT_FALSE(dependency_tracker().has_deadline());
383
384 // child_surface1 should now be active.
385 EXPECT_TRUE(child_surface1()->HasActiveFrame());
386 EXPECT_FALSE(child_surface1()->HasPendingFrame());
387 EXPECT_THAT(child_surface1()->blocking_surfaces(), IsEmpty());
388
389 // parent_surface should now be active.
390 EXPECT_TRUE(parent_surface()->HasActiveFrame());
391 EXPECT_FALSE(parent_surface()->HasPendingFrame());
392 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
393
394 // All three surfaces |parent_id|, |child_id1|, and |child_id2| should
395 // now report damage. This would trigger a new display frame.
396 EXPECT_TRUE(surface_observer().IsSurfaceDamaged(parent_id));
397 EXPECT_TRUE(surface_observer().IsSurfaceDamaged(child_id1));
398 EXPECT_TRUE(surface_observer().IsSurfaceDamaged(child_id2));
399 }
400
401 // parent_surface and child_surface1 are blocked on |child_id2|.
402 TEST_F(SurfaceSynchronizationTest, TwoBlockedOnOne) {
403 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
404 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
405 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
406
407 parent_support().SubmitCompositorFrame(
408 parent_id.local_surface_id(),
409 MakeCompositorFrame({child_id2}, empty_surface_ids(),
410 TransferableResourceArray()));
411
412 // parent_support is blocked on |child_id2|.
413 EXPECT_TRUE(dependency_tracker().has_deadline());
414 EXPECT_FALSE(parent_surface()->HasActiveFrame());
415 EXPECT_TRUE(parent_surface()->HasPendingFrame());
416 EXPECT_THAT(parent_surface()->blocking_surfaces(),
417 UnorderedElementsAre(child_id2));
418
419 // child_support1 should now be blocked on |child_id2|.
420 child_support1().SubmitCompositorFrame(
421 child_id1.local_surface_id(),
422 MakeCompositorFrame({child_id2}, empty_surface_ids(),
423 TransferableResourceArray()));
424
425 EXPECT_TRUE(dependency_tracker().has_deadline());
426 EXPECT_FALSE(child_surface1()->HasActiveFrame());
427 EXPECT_TRUE(child_surface1()->HasPendingFrame());
428 EXPECT_THAT(child_surface1()->blocking_surfaces(),
429 UnorderedElementsAre(child_id2));
430
431 // The parent should still be blocked on |child_id2|.
432 EXPECT_THAT(parent_surface()->blocking_surfaces(),
433 UnorderedElementsAre(child_id2));
434
435 // Submit a CompositorFrame without any dependencies to |child_id2|.
436 // parent_support should be activated.
437 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
438 MakeCompositorFrame());
439
440 EXPECT_FALSE(dependency_tracker().has_deadline());
441
442 // child_surface1 should now be active.
443 EXPECT_TRUE(child_surface1()->HasActiveFrame());
444 EXPECT_FALSE(child_surface1()->HasPendingFrame());
445 EXPECT_THAT(child_surface1()->blocking_surfaces(), IsEmpty());
446
447 // parent_surface should now be active.
448 EXPECT_TRUE(parent_surface()->HasActiveFrame());
449 EXPECT_FALSE(parent_surface()->HasPendingFrame());
450 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
451 }
452
453 // parent_surface is blocked on |child_id1|, and child_surface2 is blocked on
454 // |child_id2| until the deadline hits.
455 TEST_F(SurfaceSynchronizationTest, DeadlineHits) {
456 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
457 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
458 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
459
460 parent_support().SubmitCompositorFrame(
461 parent_id.local_surface_id(),
462 MakeCompositorFrame({child_id1}, empty_surface_ids(),
463 TransferableResourceArray()));
464
465 // parent_support is blocked on |child_id1|.
466 EXPECT_TRUE(dependency_tracker().has_deadline());
467 EXPECT_FALSE(parent_surface()->HasActiveFrame());
468 EXPECT_TRUE(parent_surface()->HasPendingFrame());
469 EXPECT_THAT(parent_surface()->blocking_surfaces(),
470 UnorderedElementsAre(child_id1));
471
472 child_support1().SubmitCompositorFrame(
473 child_id1.local_surface_id(),
474 MakeCompositorFrame({child_id2}, empty_surface_ids(),
475 TransferableResourceArray()));
476
477 // child_support1 should now be blocked on |child_id2|.
478 EXPECT_TRUE(dependency_tracker().has_deadline());
479 EXPECT_FALSE(child_surface1()->HasActiveFrame());
480 EXPECT_TRUE(child_surface1()->HasPendingFrame());
481 EXPECT_THAT(child_surface1()->blocking_surfaces(),
482 UnorderedElementsAre(child_id2));
483
484 // The parent should still be blocked on |child_id1| because it's pending.
485 EXPECT_THAT(parent_surface()->blocking_surfaces(),
486 UnorderedElementsAre(child_id1));
487
488 BeginFrameArgs args =
489 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
490
491 for (int i = 0; i < 3; ++i) {
492 begin_frame_source()->TestOnBeginFrame(args);
493 // There is still a looming deadline! Eeek!
494 EXPECT_TRUE(dependency_tracker().has_deadline());
495
496 // parent_support is still blocked on |child_id1|.
497 EXPECT_FALSE(parent_surface()->HasActiveFrame());
498 EXPECT_TRUE(parent_surface()->HasPendingFrame());
499 EXPECT_THAT(parent_surface()->blocking_surfaces(),
500 UnorderedElementsAre(child_id1));
501
502 // child_support1 is still blocked on |child_id2|.
503 EXPECT_FALSE(child_surface1()->HasActiveFrame());
504 EXPECT_TRUE(child_surface1()->HasPendingFrame());
505 EXPECT_THAT(child_surface1()->blocking_surfaces(),
506 UnorderedElementsAre(child_id2));
507 }
508
509 begin_frame_source()->TestOnBeginFrame(args);
510
511 // The deadline has passed.
512 EXPECT_FALSE(dependency_tracker().has_deadline());
513
514 // parent_surface has been activated.
515 EXPECT_TRUE(parent_surface()->HasActiveFrame());
516 EXPECT_FALSE(parent_surface()->HasPendingFrame());
517 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
518
519 // child_surface1 has been activated.
520 EXPECT_TRUE(child_surface1()->HasActiveFrame());
521 EXPECT_FALSE(child_surface1()->HasPendingFrame());
522 EXPECT_THAT(child_surface1()->blocking_surfaces(), IsEmpty());
523 }
524
525 // Verifies that the deadline does not reset if we submit CompositorFrames
526 // to new Surfaces with unresolved dependencies.
527 TEST_F(SurfaceSynchronizationTest, FramesSubmittedAfterDeadlineSet) {
528 const SurfaceId arbitrary_id = MakeSurfaceId(kArbitraryFrameSink, 1);
529 BeginFrameArgs args =
530 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
531 for (int i = 0; i < 3; ++i) {
532 LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create());
533 support(i).SubmitCompositorFrame(
534 local_surface_id,
535 MakeCompositorFrame({arbitrary_id}, empty_surface_ids(),
536 TransferableResourceArray()));
537 // The deadline has been set.
538 EXPECT_TRUE(dependency_tracker().has_deadline());
539
540 // support(i) should be blocked on arbitrary_id.
541 EXPECT_FALSE(surface(i)->HasActiveFrame());
542 EXPECT_TRUE(surface(i)->HasPendingFrame());
543 EXPECT_THAT(surface(i)->blocking_surfaces(),
544 UnorderedElementsAre(arbitrary_id));
545
546 // Issue a BeginFrame to get closer to the deadline.
547 begin_frame_source()->TestOnBeginFrame(args);
548 }
549
550 // The deadline hits and all the Surfaces should activate.
551 begin_frame_source()->TestOnBeginFrame(args);
552 for (int i = 0; i < 3; ++i) {
553 EXPECT_TRUE(surface(i)->HasActiveFrame());
554 EXPECT_FALSE(surface(i)->HasPendingFrame());
555 EXPECT_THAT(surface(i)->blocking_surfaces(), IsEmpty());
556 }
557 }
558
559 // This test verifies at the Surface activates once a CompositorFrame is
560 // submitted that has no unresolved dependencies.
561 TEST_F(SurfaceSynchronizationTest, NewFrameOverridesOldDependencies) {
562 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
563 const SurfaceId arbitrary_id = MakeSurfaceId(kArbitraryFrameSink, 1);
564
565 // Submit a CompositorFrame that depends on |arbitrary_id|.
566 parent_support().SubmitCompositorFrame(
567 parent_id.local_surface_id(),
568 MakeCompositorFrame({arbitrary_id}, empty_surface_ids(),
569 TransferableResourceArray()));
570
571 // Verify that the CompositorFrame is blocked on |arbitrary_id|.
572 EXPECT_FALSE(parent_surface()->HasActiveFrame());
573 EXPECT_TRUE(parent_surface()->HasPendingFrame());
574 EXPECT_THAT(parent_surface()->blocking_surfaces(),
575 UnorderedElementsAre(arbitrary_id));
576
577 // Submit a CompositorFrame that has no dependencies.
578 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
579 MakeCompositorFrame());
580
581 // Verify that the CompositorFrame has been activated.
582 EXPECT_TRUE(parent_surface()->HasActiveFrame());
583 EXPECT_FALSE(parent_surface()->HasPendingFrame());
584 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
585 }
586
587 // This test verifies that a pending CompositorFrame does not affect surface
588 // references. A new surface from a child will continue to exist as a temporary
589 // reference until the parent's frame activates.
590 TEST_F(SurfaceSynchronizationTest, OnlyActiveFramesAffectSurfaceReferences) {
591 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
592 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
593 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
594
595 // child_support1 submits a CompositorFrame without any dependencies.
596 // DidReceiveCompositorFrameAck should call on immediate activation.
597 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(1);
598 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
599 MakeCompositorFrame());
600 testing::Mock::VerifyAndClearExpectations(&support_client_);
601
602 // Verify that the child surface is not blocked.
603 EXPECT_TRUE(child_surface1()->HasActiveFrame());
604 EXPECT_FALSE(child_surface1()->HasPendingFrame());
605 EXPECT_THAT(child_surface1()->blocking_surfaces(), IsEmpty());
606
607 // Verify that there's a temporary reference for |child_id1|.
608 EXPECT_TRUE(HasTemporaryReference(child_id1));
609
610 // parent_support submits a CompositorFrame that depends on |child_id1|
611 // (which is already active) and |child_id2|. Thus, the parent should not
612 // activate immediately. DidReceiveCompositorFrameAck should not be called
613 // immediately because the parent CompositorFrame is also blocked on
614 // |child_id2|.
615 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(0);
616 parent_support().SubmitCompositorFrame(
617 parent_id.local_surface_id(),
618 MakeCompositorFrame({child_id2}, {child_id1},
619 TransferableResourceArray()));
620 EXPECT_FALSE(parent_surface()->HasActiveFrame());
621 EXPECT_TRUE(parent_surface()->HasPendingFrame());
622 EXPECT_THAT(parent_surface()->blocking_surfaces(),
623 UnorderedElementsAre(child_id2));
624 EXPECT_THAT(GetChildReferences(parent_id), IsEmpty());
625 testing::Mock::VerifyAndClearExpectations(&support_client_);
626
627 // Verify that there's a temporary reference for |child_id1| that still
628 // exists.
629 EXPECT_TRUE(HasTemporaryReference(child_id1));
630
631 // child_support2 submits a CompositorFrame without any dependencies.
632 // Both the child and the parent should immediately ACK CompositorFrames
633 // on activation.
634 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(2);
635 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
636 MakeCompositorFrame());
637 testing::Mock::VerifyAndClearExpectations(&support_client_);
638
639 // Verify that the child surface is not blocked.
640 EXPECT_TRUE(child_surface1()->HasActiveFrame());
641 EXPECT_FALSE(child_surface1()->HasPendingFrame());
642 EXPECT_THAT(child_surface1()->blocking_surfaces(), IsEmpty());
643
644 // Verify that the parent surface's CompositorFrame has activated and that the
645 // temporary reference has been replaced by a permanent one.
646 EXPECT_TRUE(parent_surface()->HasActiveFrame());
647 EXPECT_FALSE(parent_surface()->HasPendingFrame());
648 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
649 EXPECT_FALSE(HasTemporaryReference(child_id1));
650 EXPECT_THAT(GetChildReferences(parent_id), UnorderedElementsAre(child_id1));
651 }
652
653 // This test verifies that we do not double count returned resources when a
654 // CompositorFrame starts out as pending, then becomes active, and then is
655 // replaced with another active CompositorFrame.
656 TEST_F(SurfaceSynchronizationTest, ResourcesOnlyReturnedOnce) {
657 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
658 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
659
660 // The parent submits a CompositorFrame that depends on |child_id| before the
661 // child submits a CompositorFrame. The CompositorFrame also has resources in
662 // its resource list.
663 TransferableResource resource;
664 resource.id = 1337;
665 resource.format = ALPHA_8;
666 resource.filter = 1234;
667 resource.size = gfx::Size(1234, 5678);
668 TransferableResourceArray resource_list = {resource};
669 parent_support().SubmitCompositorFrame(
670 parent_id.local_surface_id(),
671 MakeCompositorFrame({child_id}, empty_surface_ids(), resource_list));
672
673 // Verify that the CompositorFrame is blocked on |child_id|.
674 EXPECT_FALSE(parent_surface()->HasActiveFrame());
675 EXPECT_TRUE(parent_surface()->HasPendingFrame());
676 EXPECT_THAT(parent_surface()->blocking_surfaces(),
677 UnorderedElementsAre(child_id));
678
679 child_support1().SubmitCompositorFrame(
680 child_id.local_surface_id(),
681 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(),
682 TransferableResourceArray()));
683
684 // Verify that the child CompositorFrame activates immediately.
685 EXPECT_TRUE(child_surface1()->HasActiveFrame());
686 EXPECT_FALSE(child_surface1()->HasPendingFrame());
687 EXPECT_THAT(child_surface1()->blocking_surfaces(), IsEmpty());
688
689 // Verify that the parent has activated.
690 EXPECT_TRUE(parent_surface()->HasActiveFrame());
691 EXPECT_FALSE(parent_surface()->HasPendingFrame());
692 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
693
694 ReturnedResourceArray returned_resources = {resource.ToReturnedResource()};
695 EXPECT_CALL(support_client_,
696 DidReceiveCompositorFrameAck(returned_resources));
697
698 // The parent submits a CompositorFrame without any dependencies. That frame
699 // should activate immediately, replacing the earlier frame. The resource from
700 // the earlier frame should be returned to the client.
701 parent_support().SubmitCompositorFrame(
702 parent_id.local_surface_id(),
703 MakeCompositorFrame({empty_surface_ids()}, {empty_surface_ids()},
704 TransferableResourceArray()));
705 EXPECT_TRUE(parent_surface()->HasActiveFrame());
706 EXPECT_FALSE(parent_surface()->HasPendingFrame());
707 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
708 }
709
710 // The parent Surface is blocked on |child_id2| which is blocked on |child_id3|.
711 // child_support1 evicts its blocked Surface. The parent surface should
712 // activate.
713 TEST_F(SurfaceSynchronizationTest, EvictSurfaceWithPendingFrame) {
714 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
715 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
716 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
717
718 // Submit a CompositorFrame that depends on |child_id1|.
719 parent_support().SubmitCompositorFrame(
720 parent_id1.local_surface_id(),
721 MakeCompositorFrame({child_id1}, empty_surface_ids(),
722 TransferableResourceArray()));
723
724 // Verify that the CompositorFrame is blocked on |child_id1|.
725 EXPECT_FALSE(parent_surface()->HasActiveFrame());
726 EXPECT_TRUE(parent_surface()->HasPendingFrame());
727 EXPECT_THAT(parent_surface()->blocking_surfaces(),
728 UnorderedElementsAre(child_id1));
729
730 // Submit a CompositorFrame that depends on |child_id2|.
731 child_support1().SubmitCompositorFrame(
732 child_id1.local_surface_id(),
733 MakeCompositorFrame({child_id2}, empty_surface_ids(),
734 TransferableResourceArray()));
735
736 // Verify that the CompositorFrame is blocked on |child_id2|.
737 EXPECT_FALSE(child_surface1()->HasActiveFrame());
738 EXPECT_TRUE(child_surface1()->HasPendingFrame());
739 EXPECT_THAT(child_surface1()->blocking_surfaces(),
740 UnorderedElementsAre(child_id2));
741
742 // Evict child_support1's current Surface.
743 // TODO(fsamuel): EvictCurrentSurface => EvictCurrentSurface.
744 child_support1().EvictCurrentSurface();
745
746 // The parent Surface should immediately activate.
747 EXPECT_TRUE(parent_surface()->HasActiveFrame());
748 EXPECT_FALSE(parent_surface()->HasPendingFrame());
749 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
750 EXPECT_FALSE(dependency_tracker().has_deadline());
751 }
752
753 // This test verifies that if a surface has both a pending and active
754 // CompositorFrame and the pending CompositorFrame activates, replacing the
755 // existing active CompositorFrame, then the surface reference hierarchy will be
756 // updated allowing garbage collection of surfaces that are no longer
757 // referenced.
758 TEST_F(SurfaceSynchronizationTest, DropStaleReferencesAfterActivation) {
759 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
760 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
761 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink2, 1);
762
763 // The parent submits a CompositorFrame that depends on |child_id1| before the
764 // child submits a CompositorFrame.
765 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(0);
766 parent_support().SubmitCompositorFrame(
767 parent_id.local_surface_id(),
768 MakeCompositorFrame({child_id1}, empty_surface_ids(),
769 TransferableResourceArray()));
770
771 // Verify that the CompositorFrame is blocked on |child_id|.
772 EXPECT_FALSE(parent_surface()->HasActiveFrame());
773 EXPECT_TRUE(parent_surface()->HasPendingFrame());
774 EXPECT_THAT(parent_surface()->blocking_surfaces(),
775 UnorderedElementsAre(child_id1));
776 testing::Mock::VerifyAndClearExpectations(&support_client_);
777
778 // Verify that no references are added while the CompositorFrame is pending.
779 EXPECT_THAT(GetChildReferences(parent_id), IsEmpty());
780
781 // DidReceiveCompositorFrameAck should get called twice: once for the child
782 // and once for the now active parent CompositorFrame.
783 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(2);
784 child_support1().SubmitCompositorFrame(child_id1.local_surface_id(),
785 MakeCompositorFrame());
786 testing::Mock::VerifyAndClearExpectations(&support_client_);
787
788 // Verify that the child CompositorFrame activates immediately.
789 EXPECT_TRUE(child_surface1()->HasActiveFrame());
790 EXPECT_FALSE(child_surface1()->HasPendingFrame());
791 EXPECT_THAT(child_surface1()->blocking_surfaces(), IsEmpty());
792
793 // Verify that the parent Surface has activated.
794 EXPECT_TRUE(parent_surface()->HasActiveFrame());
795 EXPECT_FALSE(parent_surface()->HasPendingFrame());
796 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
797
798 // Submit a new parent CompositorFrame to add a reference.
799 parent_support().SubmitCompositorFrame(
800 parent_id.local_surface_id(),
801 MakeCompositorFrame(empty_surface_ids(), {child_id1},
802 TransferableResourceArray()));
803
804 // Verify that the parent Surface has activated.
805 EXPECT_TRUE(parent_surface()->HasActiveFrame());
806 EXPECT_FALSE(parent_surface()->HasPendingFrame());
807 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
808
809 // Verify that there is no temporary reference for the child and that
810 // the reference from the parent to the child still exists.
811 EXPECT_FALSE(HasTemporaryReference(child_id1));
812 EXPECT_THAT(GetChildReferences(parent_id), UnorderedElementsAre(child_id1));
813
814 // The parent submits another CompositorFrame that depends on |child_id2|.
815 // Submitting a pending CompositorFrame will not trigger a CompositorFrameAck.
816 EXPECT_CALL(support_client_, DidReceiveCompositorFrameAck(_)).Times(0);
817 parent_support().SubmitCompositorFrame(
818 parent_id.local_surface_id(),
819 MakeCompositorFrame({child_id2}, empty_surface_ids(),
820 TransferableResourceArray()));
821 testing::Mock::VerifyAndClearExpectations(&support_client_);
822
823 // The parent surface should now have both a pending and activate
824 // CompositorFrame. Verify that the set of child references from
825 // |parent_id| are only from the active CompositorFrame.
826 EXPECT_TRUE(parent_surface()->HasActiveFrame());
827 EXPECT_TRUE(parent_surface()->HasPendingFrame());
828 EXPECT_THAT(parent_surface()->blocking_surfaces(),
829 UnorderedElementsAre(child_id2));
830 EXPECT_THAT(GetChildReferences(parent_id), UnorderedElementsAre(child_id1));
831
832 child_support2().SubmitCompositorFrame(child_id2.local_surface_id(),
833 MakeCompositorFrame());
834
835 // Verify that the parent Surface has activated and no longer has a pending
836 // CompositorFrame. Also verify that |child_id1| is no longer a child
837 // reference of |parent_id|.
838 EXPECT_TRUE(parent_surface()->HasActiveFrame());
839 EXPECT_FALSE(parent_surface()->HasPendingFrame());
840 EXPECT_THAT(parent_surface()->blocking_surfaces(), IsEmpty());
841 // The parent will not immediately refer to the child until it submits a new
842 // CompositorFrame with the reference.
843 EXPECT_THAT(GetChildReferences(parent_id), IsEmpty());
844 }
845
846 // Checks whether the latency info are moved to the new surface from the old
847 // one when LocalSurfaceId changes. No frame has unresolved dependencies.
848 TEST_F(SurfaceSynchronizationTest,
849 LatencyInfoCarriedOverOnResize_NoUnresolvedDependencies) {
850 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
851 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
852 const ui::LatencyComponentType latency_type1 =
853 ui::BROWSER_SNAPSHOT_FRAME_NUMBER_COMPONENT;
854 const int64_t latency_id1 = 234;
855 const int64_t latency_sequence_number1 = 5645432;
856 const ui::LatencyComponentType latency_type2 = ui::TAB_SHOW_COMPONENT;
857 const int64_t latency_id2 = 31434351;
858 const int64_t latency_sequence_number2 = 663788;
859
860 // Submit a frame with latency info
861 ui::LatencyInfo info;
862 info.AddLatencyNumber(latency_type1, latency_id1, latency_sequence_number1);
863
864 CompositorFrame frame = MakeCompositorFrame();
865 frame.metadata.latency_info.push_back(info);
866
867 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
868 std::move(frame));
869
870 // Verify that the old surface has an active frame and no pending frame.
871 Surface* old_surface = surface_manager().GetSurfaceForId(parent_id1);
872 ASSERT_NE(nullptr, old_surface);
873 EXPECT_TRUE(old_surface->HasActiveFrame());
874 EXPECT_FALSE(old_surface->HasPendingFrame());
875
876 // Submit another frame with some other latency info and a different
877 // LocalSurfaceId.
878 ui::LatencyInfo info2;
879 info2.AddLatencyNumber(latency_type2, latency_id2, latency_sequence_number2);
880
881 CompositorFrame frame2 = MakeCompositorFrame();
882 frame2.metadata.latency_info.push_back(info2);
883
884 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
885 std::move(frame2));
886
887 // Verify that the new surface has an active frame and no pending frames.
888 Surface* surface = surface_manager().GetSurfaceForId(parent_id2);
889 ASSERT_NE(nullptr, surface);
890 EXPECT_TRUE(surface->HasActiveFrame());
891 EXPECT_FALSE(surface->HasPendingFrame());
892
893 // Verify that the new surface has both latency info elements.
894 std::vector<ui::LatencyInfo> info_list;
895 surface->TakeLatencyInfo(&info_list);
896 EXPECT_EQ(2u, info_list.size());
897
898 ui::LatencyInfo aggregated_latency_info = info_list[0];
899 aggregated_latency_info.AddNewLatencyFrom(info_list[1]);
900
901 // Two components are the original ones, and the third one is
902 // DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, logged on compositor frame
903 // submit.
904 EXPECT_EQ(3u, aggregated_latency_info.latency_components().size());
905
906 ui::LatencyInfo::LatencyComponent comp1;
907 EXPECT_TRUE(
908 aggregated_latency_info.FindLatency(latency_type1, latency_id1, &comp1));
909 EXPECT_EQ(latency_sequence_number1, comp1.sequence_number);
910 EXPECT_TRUE(
911 aggregated_latency_info.FindLatency(latency_type2, latency_id2, nullptr));
912 EXPECT_TRUE(aggregated_latency_info.FindLatency(
913 ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, nullptr));
914 }
915
916 // Checks whether the latency info are moved to the new surface from the old
917 // one when LocalSurfaceId changes. Old surface has unresolved dependencies.
918 TEST_F(SurfaceSynchronizationTest,
919 LatencyInfoCarriedOverOnResize_OldSurfaceHasPendingAndActiveFrame) {
920 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
921 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
922 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
923
924 const ui::LatencyComponentType latency_type1 =
925 ui::BROWSER_SNAPSHOT_FRAME_NUMBER_COMPONENT;
926 const int64_t latency_id1 = 234;
927 const int64_t latency_sequence_number1 = 5645432;
928 const ui::LatencyComponentType latency_type2 = ui::TAB_SHOW_COMPONENT;
929 const int64_t latency_id2 = 31434351;
930 const int64_t latency_sequence_number2 = 663788;
931
932 // Submit a frame with no unresolved dependecy.
933 ui::LatencyInfo info;
934 info.AddLatencyNumber(latency_type1, latency_id1, latency_sequence_number1);
935
936 CompositorFrame frame = MakeCompositorFrame();
937 frame.metadata.latency_info.push_back(info);
938
939 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
940 std::move(frame));
941
942 // Submit a frame with unresolved dependencies.
943 ui::LatencyInfo info2;
944 info2.AddLatencyNumber(latency_type2, latency_id2, latency_sequence_number2);
945
946 CompositorFrame frame2 = MakeCompositorFrame({child_id}, empty_surface_ids(),
947 TransferableResourceArray());
948 frame2.metadata.latency_info.push_back(info2);
949
950 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
951 std::move(frame2));
952
953 // Verify that the old surface has both an active and a pending frame.
954 Surface* old_surface = surface_manager().GetSurfaceForId(parent_id1);
955 ASSERT_NE(nullptr, old_surface);
956 EXPECT_TRUE(old_surface->HasActiveFrame());
957 EXPECT_TRUE(old_surface->HasPendingFrame());
958
959 // Submit a frame with a new local surface id.
960 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
961 MakeCompositorFrame());
962
963 // Verify that the new surface has an active frame only.
964 Surface* surface = surface_manager().GetSurfaceForId(parent_id2);
965 ASSERT_NE(nullptr, surface);
966 EXPECT_TRUE(surface->HasActiveFrame());
967 EXPECT_FALSE(surface->HasPendingFrame());
968
969 // Verify that the new surface has latency info from both active and pending
970 // frame of the old surface.
971 std::vector<ui::LatencyInfo> info_list;
972 surface->TakeLatencyInfo(&info_list);
973 EXPECT_EQ(2u, info_list.size());
974
975 ui::LatencyInfo aggregated_latency_info = info_list[0];
976 aggregated_latency_info.AddNewLatencyFrom(info_list[1]);
977
978 // Two components are the original ones, and the third one is
979 // DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, logged on compositor frame
980 // submit.
981 EXPECT_EQ(3u, aggregated_latency_info.latency_components().size());
982
983 ui::LatencyInfo::LatencyComponent comp1;
984 EXPECT_TRUE(
985 aggregated_latency_info.FindLatency(latency_type1, latency_id1, &comp1));
986 EXPECT_EQ(latency_sequence_number1, comp1.sequence_number);
987 EXPECT_TRUE(
988 aggregated_latency_info.FindLatency(latency_type2, latency_id2, nullptr));
989 EXPECT_TRUE(aggregated_latency_info.FindLatency(
990 ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, nullptr));
991 }
992
993 // Checks whether the latency info are moved to the new surface from the old
994 // one when LocalSurfaceId changes. The new surface has unresolved dependencies.
995 TEST_F(SurfaceSynchronizationTest,
996 LatencyInfoCarriedOverOnResize_NewSurfaceHasPendingFrame) {
997 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
998 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
999 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
1000
1001 const ui::LatencyComponentType latency_type1 =
1002 ui::BROWSER_SNAPSHOT_FRAME_NUMBER_COMPONENT;
1003 const int64_t latency_id1 = 234;
1004 const int64_t latency_sequence_number1 = 5645432;
1005 const ui::LatencyComponentType latency_type2 = ui::TAB_SHOW_COMPONENT;
1006 const int64_t latency_id2 = 31434351;
1007 const int64_t latency_sequence_number2 = 663788;
1008
1009 // Submit a frame with no unresolved dependencies.
1010 ui::LatencyInfo info;
1011 info.AddLatencyNumber(latency_type1, latency_id1, latency_sequence_number1);
1012
1013 CompositorFrame frame = MakeCompositorFrame();
1014 frame.metadata.latency_info.push_back(info);
1015
1016 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
1017 std::move(frame));
1018
1019 // Verify that the old surface has an active frame only.
1020 Surface* old_surface = surface_manager().GetSurfaceForId(parent_id1);
1021 ASSERT_NE(nullptr, old_surface);
1022 EXPECT_TRUE(old_surface->HasActiveFrame());
1023 EXPECT_FALSE(old_surface->HasPendingFrame());
1024
1025 // Submit a frame with a new local surface id and with unresolved
1026 // dependencies.
1027 ui::LatencyInfo info2;
1028 info2.AddLatencyNumber(latency_type2, latency_id2, latency_sequence_number2);
1029
1030 CompositorFrame frame2 = MakeCompositorFrame({child_id}, empty_surface_ids(),
1031 TransferableResourceArray());
1032 frame2.metadata.latency_info.push_back(info2);
1033
1034 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
1035 std::move(frame2));
1036
1037 // Verify that the new surface has a pending frame and no active frame.
1038 Surface* surface = surface_manager().GetSurfaceForId(parent_id2);
1039 ASSERT_NE(nullptr, surface);
1040 EXPECT_TRUE(surface->HasPendingFrame());
1041 EXPECT_FALSE(surface->HasActiveFrame());
1042
1043 // Resolve the dependencies. The frame in parent's surface must become active.
1044 child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
1045 MakeCompositorFrame());
1046 EXPECT_FALSE(surface->HasPendingFrame());
1047 EXPECT_TRUE(surface->HasActiveFrame());
1048
1049 // Both latency info elements must exist in the now-activated frame of the
1050 // new surface.
1051 std::vector<ui::LatencyInfo> info_list;
1052 surface->TakeLatencyInfo(&info_list);
1053 EXPECT_EQ(2u, info_list.size());
1054
1055 ui::LatencyInfo aggregated_latency_info = info_list[0];
1056 aggregated_latency_info.AddNewLatencyFrom(info_list[1]);
1057
1058 // Two components are the original ones, and the third one is
1059 // DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, logged on compositor frame
1060 // submit.
1061 EXPECT_EQ(3u, aggregated_latency_info.latency_components().size());
1062
1063 ui::LatencyInfo::LatencyComponent comp1;
1064 EXPECT_TRUE(
1065 aggregated_latency_info.FindLatency(latency_type1, latency_id1, &comp1));
1066 EXPECT_EQ(latency_sequence_number1, comp1.sequence_number);
1067 EXPECT_TRUE(
1068 aggregated_latency_info.FindLatency(latency_type2, latency_id2, nullptr));
1069 EXPECT_TRUE(aggregated_latency_info.FindLatency(
1070 ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT, nullptr));
1071 }
1072
1073 // Checks that resources and ack are sent together if possible.
1074 TEST_F(SurfaceSynchronizationTest, ReturnResourcesWithAck) {
1075 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
1076 TransferableResource resource;
1077 resource.id = 1234;
1078 parent_support().SubmitCompositorFrame(
1079 parent_id.local_surface_id(),
1080 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(),
1081 {resource}));
1082 ReturnedResourceArray returned_resources;
1083 TransferableResource::ReturnResources({resource}, &returned_resources);
1084 EXPECT_CALL(support_client_, ReclaimResources(_)).Times(0);
1085 EXPECT_CALL(support_client_,
1086 DidReceiveCompositorFrameAck(Eq(returned_resources)));
1087 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
1088 MakeCompositorFrame());
1089 }
1090
1091 // Verifies that if a surface is marked destroyed and a new frame arrives for
1092 // it, it will be recovered.
1093 TEST_F(SurfaceSynchronizationTest, SurfaceResurrection) {
1094 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
1095 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 3);
1096
1097 // Create the child surface by submitting a frame to it.
1098 EXPECT_EQ(nullptr, surface_manager().GetSurfaceForId(child_id));
1099 child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
1100 MakeCompositorFrame());
1101
1102 // Verify that the child surface is created.
1103 Surface* surface = surface_manager().GetSurfaceForId(child_id);
1104 EXPECT_NE(nullptr, surface);
1105
1106 // Add a reference from the parent to the child.
1107 parent_support().SubmitCompositorFrame(
1108 parent_id.local_surface_id(),
1109 MakeCompositorFrame({child_id}, {child_id}, TransferableResourceArray()));
1110
1111 // Attempt to destroy the child surface. The surface must still exist since
1112 // the parent needs it but it will be marked as destroyed.
1113 child_support1().EvictCurrentSurface();
1114 surface = surface_manager().GetSurfaceForId(child_id);
1115 EXPECT_NE(nullptr, surface);
1116 EXPECT_TRUE(surface->destroyed());
1117
1118 // Child submits another frame to the same local surface id that is marked
1119 // destroyed.
1120 child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
1121 MakeCompositorFrame());
1122
1123 // Verify that the surface that was marked destroyed is recovered and is being
1124 // used again.
1125 Surface* surface2 = surface_manager().GetSurfaceForId(child_id);
1126 EXPECT_EQ(surface, surface2);
1127 EXPECT_FALSE(surface2->destroyed());
1128 }
1129
1130 // Verifies that if a LocalSurfaceId belonged to a surface that doesn't exist
1131 // anymore, it can still be reused for new surfaces.
1132 TEST_F(SurfaceSynchronizationTest, LocalSurfaceIdIsReusable) {
1133 const SurfaceId parent_id = MakeSurfaceId(kParentFrameSink, 1);
1134 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 3);
1135
1136 // Submit the first frame. Creates the surface.
1137 child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
1138 MakeCompositorFrame());
1139 EXPECT_NE(nullptr, surface_manager().GetSurfaceForId(child_id));
1140
1141 // Add a reference from parent.
1142 parent_support().SubmitCompositorFrame(
1143 parent_id.local_surface_id(),
1144 MakeCompositorFrame({child_id}, {child_id}, TransferableResourceArray()));
1145
1146 // Remove the reference from parant. This allows us to destroy the surface.
1147 parent_support().SubmitCompositorFrame(parent_id.local_surface_id(),
1148 MakeCompositorFrame());
1149
1150 // Destroy the surface.
1151 child_support1().EvictCurrentSurface();
1152 EXPECT_EQ(nullptr, surface_manager().GetSurfaceForId(child_id));
1153
1154 // Submit another frame with the same local surface id. This should work fine
1155 // and a new surface must be created.
1156 child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
1157 MakeCompositorFrame());
1158 EXPECT_NE(nullptr, surface_manager().GetSurfaceForId(child_id));
1159 }
1160
1161 // This test verifies that a crash does not occur if garbage collection is
1162 // triggered during surface dependency resolution. This test triggers garbage
1163 // collection during surface resolution, by causing an activation to remove
1164 // a surface subtree from the root. Both the old subtree and the new
1165 // activated subtree refer to the same dependency. The old subtree was activated
1166 // by deadline, and the new subtree was activated by a dependency finally
1167 // resolving.
1168 TEST_F(SurfaceSynchronizationTest, DependencyTrackingGarbageCollection) {
1169 const SurfaceId display_id = MakeSurfaceId(kDisplayFrameSink, 1);
1170 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1171 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
1172 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
1173
1174 parent_support().SubmitCompositorFrame(
1175 parent_id1.local_surface_id(),
1176 MakeCompositorFrame({child_id}, empty_surface_ids(),
1177 TransferableResourceArray()));
1178 display_support().SubmitCompositorFrame(
1179 display_id.local_surface_id(),
1180 MakeCompositorFrame({parent_id1}, empty_surface_ids(),
1181 TransferableResourceArray()));
1182
1183 EXPECT_TRUE(dependency_tracker().has_deadline());
1184
1185 BeginFrameArgs args =
1186 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
1187
1188 // Advance BeginFrames to trigger a deadline.
1189 for (int i = 0; i < 3; ++i) {
1190 begin_frame_source()->TestOnBeginFrame(args);
1191 EXPECT_TRUE(dependency_tracker().has_deadline());
1192 }
1193 begin_frame_source()->TestOnBeginFrame(args);
1194 EXPECT_FALSE(dependency_tracker().has_deadline());
1195
1196 EXPECT_TRUE(display_surface()->HasActiveFrame());
1197 EXPECT_FALSE(display_surface()->HasPendingFrame());
1198 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1199 EXPECT_FALSE(parent_surface()->HasPendingFrame());
1200
1201 parent_support().SubmitCompositorFrame(
1202 parent_id2.local_surface_id(),
1203 MakeCompositorFrame({child_id}, empty_surface_ids(),
1204 TransferableResourceArray()));
1205 display_support().SubmitCompositorFrame(
1206 display_id.local_surface_id(),
1207 MakeCompositorFrame({parent_id2}, empty_surface_ids(),
1208 TransferableResourceArray()));
1209
1210 // The display surface now has two CompositorFrames. One that is pending,
1211 // indirectly blocked on child_id and one that is active, also indirectly
1212 // referring to child_id, but activated due to the deadline above.
1213 EXPECT_TRUE(display_surface()->HasActiveFrame());
1214 EXPECT_TRUE(display_surface()->HasPendingFrame());
1215
1216 // Submitting a CompositorFrame will trigger garbage collection of the
1217 // |parent_id1| subtree. This should not crash.
1218 child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
1219 MakeCompositorFrame());
1220 }
1221
1222 // This test verifies that a crash does not occur if garbage collection is
1223 // triggered when a deadline forces frame activation. This test triggers garbage
1224 // collection during deadline activation by causing the activation of a display
1225 // frame to replace a previously activated display frame that was referring to
1226 // a now-unreachable surface subtree. That subtree gets garbage collected during
1227 // deadline activation. SurfaceDependencyTracker is also tracking a surface
1228 // from that subtree due to an unresolved dependency. This test verifies that
1229 // this dependency resolution does not crash.
1230 TEST_F(SurfaceSynchronizationTest, GarbageCollectionOnDeadline) {
1231 const SurfaceId display_id = MakeSurfaceId(kDisplayFrameSink, 1);
1232 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1233 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
1234 const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
1235
1236 // |parent_id1| is blocked on |child_id|.
1237 parent_support().SubmitCompositorFrame(
1238 parent_id1.local_surface_id(),
1239 MakeCompositorFrame({child_id}, empty_surface_ids(),
1240 TransferableResourceArray()));
1241
1242 display_support().SubmitCompositorFrame(
1243 display_id.local_surface_id(),
1244 MakeCompositorFrame({parent_id1}, {parent_id1},
1245 TransferableResourceArray()));
1246
1247 EXPECT_TRUE(dependency_tracker().has_deadline());
1248 EXPECT_TRUE(display_surface()->HasPendingFrame());
1249 EXPECT_FALSE(display_surface()->HasActiveFrame());
1250
1251 // Advance BeginFrames to trigger a deadline. This activates the
1252 // CompositorFrame submitted above.
1253 BeginFrameArgs args =
1254 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
1255 for (int i = 0; i < 3; ++i) {
1256 begin_frame_source()->TestOnBeginFrame(args);
1257 EXPECT_TRUE(dependency_tracker().has_deadline());
1258 }
1259 begin_frame_source()->TestOnBeginFrame(args);
1260 EXPECT_FALSE(dependency_tracker().has_deadline());
1261 EXPECT_FALSE(display_surface()->HasPendingFrame());
1262 EXPECT_TRUE(display_surface()->HasActiveFrame());
1263
1264 // By submitting a display CompositorFrame, and replacing the parent's
1265 // CompositorFrame with another surface ID, parent_id1 becomes unreachable and
1266 // a candidate for garbage collection.
1267 display_support().SubmitCompositorFrame(
1268 display_id.local_surface_id(),
1269 MakeCompositorFrame({parent_id2}, empty_surface_ids(),
1270 TransferableResourceArray()));
1271
1272 // Now |parent_id1| is only kept alive by the active |display_id| frame.
1273 parent_support().SubmitCompositorFrame(
1274 parent_id2.local_surface_id(),
1275 MakeCompositorFrame({child_id}, empty_surface_ids(),
1276 TransferableResourceArray()));
1277
1278 // SurfaceDependencyTracker should now be tracking |display_id|, |parent_id1|
1279 // and |parent_id2|. By activating the pending |display_id| frame by deadline,
1280 // |parent_id1| becomes unreachable and is garbage collected while
1281 // SurfaceDependencyTracker is in the process of activating surfaces. This
1282 // should not cause a crash or use-after-free.
1283 for (int i = 0; i < 3; ++i) {
1284 begin_frame_source()->TestOnBeginFrame(args);
1285 EXPECT_TRUE(dependency_tracker().has_deadline());
1286 }
1287 begin_frame_source()->TestOnBeginFrame(args);
1288 EXPECT_FALSE(dependency_tracker().has_deadline());
1289 }
1290
1291 // This test verifies that a CompositorFrame will only blocked on embedded
1292 // surfaces but not on other retained surface IDs in the CompositorFrame.
1293 TEST_F(SurfaceSynchronizationTest, OnlyBlockOnEmbeddedSurfaces) {
1294 const SurfaceId display_id = MakeSurfaceId(kDisplayFrameSink, 1);
1295 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1296 const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
1297
1298 // Submitting a CompositorFrame with |parent_id2| so that the display
1299 // CompositorFrame can hold a reference to it.
1300 parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
1301 MakeCompositorFrame());
1302
1303 display_support().SubmitCompositorFrame(
1304 display_id.local_surface_id(),
1305 MakeCompositorFrame({parent_id1}, {parent_id2},
1306 TransferableResourceArray()));
1307
1308 EXPECT_TRUE(display_surface()->HasPendingFrame());
1309 EXPECT_FALSE(display_surface()->HasActiveFrame());
1310 EXPECT_TRUE(dependency_tracker().has_deadline());
1311
1312 // Verify that the display CompositorFrame will only block on |parent_id1| but
1313 // not |parent_id2|.
1314 EXPECT_THAT(display_surface()->blocking_surfaces(),
1315 UnorderedElementsAre(parent_id1));
1316 // Verify that the display surface holds no references while its
1317 // CompositorFrame is pending.
1318 EXPECT_THAT(GetChildReferences(display_id), IsEmpty());
1319
1320 // Submitting a CompositorFrame with |parent_id1| should unblock the display
1321 // CompositorFrame.
1322 parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
1323 MakeCompositorFrame());
1324
1325 EXPECT_FALSE(dependency_tracker().has_deadline());
1326 EXPECT_FALSE(display_surface()->HasPendingFrame());
1327 EXPECT_TRUE(display_surface()->HasActiveFrame());
1328 EXPECT_THAT(display_surface()->blocking_surfaces(), IsEmpty());
1329 }
1330
1331 // This test verifies that a late arriving CompositorFrame activates immediately
1332 // and does not trigger a new deadline.
1333 TEST_F(SurfaceSynchronizationTest, LateArrivingDependency) {
1334 const SurfaceId display_id = MakeSurfaceId(kDisplayFrameSink, 1);
1335 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1336 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
1337
1338 display_support().SubmitCompositorFrame(
1339 display_id.local_surface_id(),
1340 MakeCompositorFrame({parent_id1}, empty_surface_ids(),
1341 TransferableResourceArray()));
1342
1343 EXPECT_TRUE(display_surface()->HasPendingFrame());
1344 EXPECT_FALSE(display_surface()->HasActiveFrame());
1345 EXPECT_TRUE(dependency_tracker().has_deadline());
1346
1347 // Advance BeginFrames to trigger a deadline. This activates the
1348 // CompositorFrame submitted above.
1349 BeginFrameArgs args =
1350 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
1351 for (int i = 0; i < 3; ++i) {
1352 begin_frame_source()->TestOnBeginFrame(args);
1353 EXPECT_TRUE(dependency_tracker().has_deadline());
1354 }
1355 begin_frame_source()->TestOnBeginFrame(args);
1356 EXPECT_FALSE(dependency_tracker().has_deadline());
1357 EXPECT_FALSE(display_surface()->HasPendingFrame());
1358 EXPECT_TRUE(display_surface()->HasActiveFrame());
1359
1360 // A late arriving CompositorFrame should activate immediately without
1361 // scheduling a deadline and without waiting for dependencies to resolve.
1362 parent_support().SubmitCompositorFrame(
1363 parent_id1.local_surface_id(),
1364 MakeCompositorFrame({child_id1}, empty_surface_ids(),
1365 TransferableResourceArray()));
1366 EXPECT_FALSE(dependency_tracker().has_deadline());
1367 EXPECT_FALSE(parent_surface()->HasPendingFrame());
1368 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1369 }
1370
1371 // This test verifies that CompositorFrames submitted to a surface referenced
1372 // by a parent CompositorFrame as a fallback will be rejected and ACK'ed
1373 // immediately.
1374 TEST_F(SurfaceSynchronizationTest, FallbackSurfacesClosed) {
1375 const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
1376 // This is the fallback child surface that the parent holds a reference to.
1377 const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1);
1378 // This is the primary child surface that the parent wants to block on.
1379 const SurfaceId child_id2 = MakeSurfaceId(kChildFrameSink1, 2);
1380
1381 // child_support1 submits a CompositorFrame without any dependencies.
1382 // DidReceiveCompositorFrameAck should call on immediate activation.
1383 // However, resources will not be returned because this frame is a candidate
1384 // for display.
1385 TransferableResource resource;
1386 resource.id = 1337;
1387 resource.format = ALPHA_8;
1388 resource.filter = 1234;
1389 resource.size = gfx::Size(1234, 5678);
1390 ReturnedResourceArray returned_resources;
1391 TransferableResource::ReturnResources({resource}, &returned_resources);
1392
1393 EXPECT_CALL(support_client_,
1394 DidReceiveCompositorFrameAck(Eq(ReturnedResourceArray())));
1395 child_support1().SubmitCompositorFrame(
1396 child_id1.local_surface_id(),
1397 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(),
1398 {resource}));
1399 testing::Mock::VerifyAndClearExpectations(&support_client_);
1400
1401 // The parent is blocked on |child_id2| and references |child_id1|. The
1402 // surface corresponding to |child_id1| will not accept new CompositorFrames
1403 // while the parent CompositorFrame is blocked.
1404 parent_support().SubmitCompositorFrame(
1405 parent_id1.local_surface_id(),
1406 MakeCompositorFrame({child_id2}, {child_id1},
1407 TransferableResourceArray()));
1408 EXPECT_TRUE(dependency_tracker().has_deadline());
1409 EXPECT_TRUE(parent_surface()->HasPendingFrame());
1410 EXPECT_FALSE(parent_surface()->HasActiveFrame());
1411
1412 // Resources will be returned immediately because |child_id1|'s surface is
1413 // closed.
1414 TransferableResource resource2;
1415 resource2.id = 1246;
1416 resource2.format = ALPHA_8;
1417 resource2.filter = 1357;
1418 resource2.size = gfx::Size(8765, 4321);
1419 ReturnedResourceArray returned_resources2;
1420 TransferableResource::ReturnResources({resource2}, &returned_resources2);
1421 EXPECT_CALL(support_client_,
1422 DidReceiveCompositorFrameAck(Eq(returned_resources2)));
1423 child_support1().SubmitCompositorFrame(
1424 child_id1.local_surface_id(),
1425 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(),
1426 {resource2}));
1427 testing::Mock::VerifyAndClearExpectations(&support_client_);
1428
1429 // Advance BeginFrames to trigger a deadline. This activates the
1430 // CompositorFrame submitted to the parent.
1431 BeginFrameArgs args =
1432 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
1433 for (int i = 0; i < 3; ++i) {
1434 begin_frame_source()->TestOnBeginFrame(args);
1435 EXPECT_TRUE(dependency_tracker().has_deadline());
1436 }
1437 begin_frame_source()->TestOnBeginFrame(args);
1438 EXPECT_FALSE(dependency_tracker().has_deadline());
1439 EXPECT_FALSE(parent_surface()->HasPendingFrame());
1440 EXPECT_TRUE(parent_surface()->HasActiveFrame());
1441
1442 // Resources will be returned immediately because |child_id1|'s surface is
1443 // closed forever.
1444 EXPECT_CALL(support_client_,
1445 DidReceiveCompositorFrameAck(Eq(returned_resources2)));
1446 child_support1().SubmitCompositorFrame(
1447 child_id1.local_surface_id(),
1448 MakeCompositorFrame(empty_surface_ids(), empty_surface_ids(),
1449 {resource2}));
1450 testing::Mock::VerifyAndClearExpectations(&support_client_);
1451 }
1452 */
1453
1454 } // namespace test
1455 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698