1 // Copyright 2011 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 "components/viz/common/frame_sinks/begin_frame_source.h"
6 
7 #include <stdint.h>
8 
9 #include <memory>
10 
11 #include "base/test/test_mock_time_task_runner.h"
12 #include "components/viz/test/begin_frame_args_test.h"
13 #include "components/viz/test/begin_frame_source_test.h"
14 #include "components/viz/test/fake_delay_based_time_source.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 
18 using testing::NiceMock;
19 using testing::_;
20 
21 namespace viz {
22 namespace {
23 
24 // Returns a fake TimeTicks based on the given microsecond offset.
TicksFromMicroseconds(int64_t micros)25 base::TimeTicks TicksFromMicroseconds(int64_t micros) {
26   return base::TimeTicks() + base::TimeDelta::FromMicroseconds(micros);
27 }
28 
29 // BeginFrameSource testing ----------------------------------------------------
TEST(BeginFrameSourceTest,SourceIdsAreUnique)30 TEST(BeginFrameSourceTest, SourceIdsAreUnique) {
31   StubBeginFrameSource source1;
32   StubBeginFrameSource source2;
33   StubBeginFrameSource source3;
34   EXPECT_NE(source1.source_id(), source2.source_id());
35   EXPECT_NE(source1.source_id(), source3.source_id());
36   EXPECT_NE(source2.source_id(), source3.source_id());
37 }
38 
39 class TestTaskRunner : public base::TestMockTimeTaskRunner {
40  public:
TestTaskRunner()41   TestTaskRunner()
42       : base::TestMockTimeTaskRunner(
43             base::TestMockTimeTaskRunner::Type::kStandalone) {
44     AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(1000));
45   }
46 
FastForwardTo(base::TimeTicks end_time)47   void FastForwardTo(base::TimeTicks end_time) {
48     base::TimeDelta offset = end_time - NowTicks();
49     DCHECK_GE(offset, base::TimeDelta());
50     FastForwardBy(offset);
51   }
52 
53  private:
54   ~TestTaskRunner() override = default;  // Ref-counted.
55   DISALLOW_COPY_AND_ASSIGN(TestTaskRunner);
56 };
57 
58 // BackToBackBeginFrameSource testing
59 // ------------------------------------------
60 class BackToBackBeginFrameSourceTest : public ::testing::Test {
61  protected:
62   static const int64_t kDeadline;
63   static const int64_t kInterval;
64 
SetUp()65   void SetUp() override {
66     task_runner_ = base::MakeRefCounted<TestTaskRunner>();
67     std::unique_ptr<FakeDelayBasedTimeSource> time_source =
68         std::make_unique<FakeDelayBasedTimeSource>(
69             task_runner_->GetMockTickClock(), task_runner_.get());
70 
71     delay_based_time_source_ = time_source.get();
72     source_.reset(new BackToBackBeginFrameSource(std::move(time_source)));
73     obs_ = std::make_unique<::testing::NiceMock<MockBeginFrameObserver>>();
74   }
75 
TearDown()76   void TearDown() override { obs_.reset(); }
77 
78   scoped_refptr<TestTaskRunner> task_runner_;
79   std::unique_ptr<BackToBackBeginFrameSource> source_;
80   std::unique_ptr<MockBeginFrameObserver> obs_;
81   FakeDelayBasedTimeSource* delay_based_time_source_;  // Owned by |source_|.
82 };
83 
84 const int64_t BackToBackBeginFrameSourceTest::kDeadline =
85     BeginFrameArgs::DefaultInterval().InMicroseconds();
86 
87 const int64_t BackToBackBeginFrameSourceTest::kInterval =
88     BeginFrameArgs::DefaultInterval().InMicroseconds();
89 
TEST_F(BackToBackBeginFrameSourceTest,AddObserverSendsBeginFrame)90 TEST_F(BackToBackBeginFrameSourceTest, AddObserverSendsBeginFrame) {
91   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
92   source_->AddObserver(obs_.get());
93   EXPECT_TRUE(task_runner_->HasPendingTask());
94   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 1, 1000,
95                           1000 + kDeadline, kInterval);
96   task_runner_->RunUntilIdle();
97 
98   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 1100,
99                           1100 + kDeadline, kInterval);
100   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
101   source_->DidFinishFrame(obs_.get());
102   task_runner_->RunUntilIdle();
103 }
104 
TEST_F(BackToBackBeginFrameSourceTest,RemoveObserverThenDidFinishFrameProducesNoFrame)105 TEST_F(BackToBackBeginFrameSourceTest,
106        RemoveObserverThenDidFinishFrameProducesNoFrame) {
107   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
108   source_->AddObserver(obs_.get());
109   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 1, 1000,
110                           1000 + kDeadline, kInterval);
111   task_runner_->RunUntilIdle();
112 
113   source_->RemoveObserver(obs_.get());
114   source_->DidFinishFrame(obs_.get());
115 
116   // Verify no BeginFrame is sent to |obs_|. There is a pending task in the
117   // task_runner_ as a BeginFrame was posted, but it gets aborted since |obs_|
118   // is removed.
119   task_runner_->RunUntilIdle();
120   EXPECT_FALSE(task_runner_->HasPendingTask());
121 }
122 
TEST_F(BackToBackBeginFrameSourceTest,DidFinishFrameThenRemoveObserverProducesNoFrame)123 TEST_F(BackToBackBeginFrameSourceTest,
124        DidFinishFrameThenRemoveObserverProducesNoFrame) {
125   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
126   source_->AddObserver(obs_.get());
127   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 1, 1000,
128                           1000 + kDeadline, kInterval);
129   task_runner_->RunUntilIdle();
130 
131   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
132   source_->DidFinishFrame(obs_.get());
133   source_->RemoveObserver(obs_.get());
134 
135   // Task gets cancelled so it doesn't count as a pending task.
136   EXPECT_FALSE(task_runner_->HasPendingTask());
137 }
138 
TEST_F(BackToBackBeginFrameSourceTest,TogglingObserverThenDidFinishFrameProducesCorrectFrame)139 TEST_F(BackToBackBeginFrameSourceTest,
140        TogglingObserverThenDidFinishFrameProducesCorrectFrame) {
141   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
142   source_->AddObserver(obs_.get());
143   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 1, 1000,
144                           1000 + kDeadline, kInterval);
145   task_runner_->RunUntilIdle();
146 
147   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
148   source_->RemoveObserver(obs_.get());
149 
150   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(10));
151   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
152   source_->AddObserver(obs_.get());
153 
154   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(10));
155   source_->DidFinishFrame(obs_.get());
156 
157   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(10));
158   // The begin frame is posted at the time when the observer was added,
159   // so it ignores changes to "now" afterward.
160   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 1110,
161                           1110 + kDeadline, kInterval);
162   EXPECT_TRUE(task_runner_->HasPendingTask());
163   task_runner_->RunUntilIdle();
164 }
165 
TEST_F(BackToBackBeginFrameSourceTest,DidFinishFrameThenTogglingObserverProducesCorrectFrame)166 TEST_F(BackToBackBeginFrameSourceTest,
167        DidFinishFrameThenTogglingObserverProducesCorrectFrame) {
168   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
169   source_->AddObserver(obs_.get());
170   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 1, 1000,
171                           1000 + kDeadline, kInterval);
172   task_runner_->RunUntilIdle();
173 
174   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
175   source_->DidFinishFrame(obs_.get());
176 
177   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(10));
178   source_->RemoveObserver(obs_.get());
179 
180   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(10));
181   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
182   source_->AddObserver(obs_.get());
183 
184   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(10));
185   // Ticks at the time at which the observer was added, ignoring the
186   // last change to "now".
187   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 1120,
188                           1120 + kDeadline, kInterval);
189   EXPECT_TRUE(task_runner_->HasPendingTask());
190   task_runner_->RunUntilIdle();
191 }
192 
TEST_F(BackToBackBeginFrameSourceTest,DidFinishFrameNoObserver)193 TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameNoObserver) {
194   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
195   source_->AddObserver(obs_.get());
196   source_->RemoveObserver(obs_.get());
197   source_->DidFinishFrame(obs_.get());
198   task_runner_->RunUntilIdle();
199   EXPECT_FALSE(task_runner_->HasPendingTask());
200 }
201 
TEST_F(BackToBackBeginFrameSourceTest,DidFinishFrameMultipleCallsIdempotent)202 TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameMultipleCallsIdempotent) {
203   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
204   source_->AddObserver(obs_.get());
205   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 1, 1000,
206                           1000 + kDeadline, kInterval);
207   task_runner_->RunUntilIdle();
208 
209   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
210   source_->DidFinishFrame(obs_.get());
211   source_->DidFinishFrame(obs_.get());
212   source_->DidFinishFrame(obs_.get());
213   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 1100,
214                           1100 + kDeadline, kInterval);
215   task_runner_->RunUntilIdle();
216 
217   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
218   source_->DidFinishFrame(obs_.get());
219   source_->DidFinishFrame(obs_.get());
220   source_->DidFinishFrame(obs_.get());
221   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 3, 1200,
222                           1200 + kDeadline, kInterval);
223   task_runner_->RunUntilIdle();
224 }
225 
TEST_F(BackToBackBeginFrameSourceTest,DelayInPostedTaskProducesCorrectFrame)226 TEST_F(BackToBackBeginFrameSourceTest, DelayInPostedTaskProducesCorrectFrame) {
227   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
228   source_->AddObserver(obs_.get());
229   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 1, 1000,
230                           1000 + kDeadline, kInterval);
231   task_runner_->RunUntilIdle();
232 
233   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
234   source_->DidFinishFrame(obs_.get());
235   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(50));
236   // Ticks at the time the last frame finished, so ignores the last change to
237   // "now".
238   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 1100,
239                           1100 + kDeadline, kInterval);
240 
241   EXPECT_TRUE(task_runner_->HasPendingTask());
242   task_runner_->RunUntilIdle();
243 }
244 
TEST_F(BackToBackBeginFrameSourceTest,MultipleObserversSynchronized)245 TEST_F(BackToBackBeginFrameSourceTest, MultipleObserversSynchronized) {
246   NiceMock<MockBeginFrameObserver> obs1, obs2;
247 
248   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false);
249   source_->AddObserver(&obs1);
250   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false);
251   source_->AddObserver(&obs2);
252 
253   EXPECT_BEGIN_FRAME_USED(obs1, source_->source_id(), 1, 1000, 1000 + kDeadline,
254                           kInterval);
255   EXPECT_BEGIN_FRAME_USED(obs2, source_->source_id(), 1, 1000, 1000 + kDeadline,
256                           kInterval);
257   task_runner_->RunUntilIdle();
258 
259   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
260   source_->DidFinishFrame(&obs1);
261   source_->DidFinishFrame(&obs2);
262   EXPECT_BEGIN_FRAME_USED(obs1, source_->source_id(), 2, 1100, 1100 + kDeadline,
263                           kInterval);
264   EXPECT_BEGIN_FRAME_USED(obs2, source_->source_id(), 2, 1100, 1100 + kDeadline,
265                           kInterval);
266   task_runner_->RunUntilIdle();
267 
268   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
269   source_->DidFinishFrame(&obs1);
270   source_->DidFinishFrame(&obs2);
271   EXPECT_TRUE(task_runner_->HasPendingTask());
272   source_->RemoveObserver(&obs1);
273   source_->RemoveObserver(&obs2);
274   task_runner_->RunUntilIdle();
275 }
276 
TEST_F(BackToBackBeginFrameSourceTest,MultipleObserversInterleaved)277 TEST_F(BackToBackBeginFrameSourceTest, MultipleObserversInterleaved) {
278   NiceMock<MockBeginFrameObserver> obs1, obs2;
279 
280   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false);
281   source_->AddObserver(&obs1);
282   EXPECT_BEGIN_FRAME_USED(obs1, source_->source_id(), 1, 1000, 1000 + kDeadline,
283                           kInterval);
284   task_runner_->RunUntilIdle();
285 
286   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
287   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false);
288   source_->AddObserver(&obs2);
289   EXPECT_BEGIN_FRAME_USED(obs2, source_->source_id(), 2, 1100, 1100 + kDeadline,
290                           kInterval);
291   task_runner_->RunUntilIdle();
292 
293   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
294   source_->DidFinishFrame(&obs1);
295   EXPECT_BEGIN_FRAME_USED(obs1, source_->source_id(), 3, 1200, 1200 + kDeadline,
296                           kInterval);
297   task_runner_->RunUntilIdle();
298 
299   source_->DidFinishFrame(&obs1);
300   source_->RemoveObserver(&obs1);
301   // Removing all finished observers should disable the time source.
302   EXPECT_FALSE(delay_based_time_source_->Active());
303   // Finishing the frame for |obs1| posts a begin frame task, which will be
304   // aborted since |obs1| is removed. Clear that from the task runner.
305   task_runner_->RunUntilIdle();
306 
307   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
308   source_->DidFinishFrame(&obs2);
309   EXPECT_BEGIN_FRAME_USED(obs2, source_->source_id(), 4, 1300, 1300 + kDeadline,
310                           kInterval);
311   task_runner_->RunUntilIdle();
312 
313   source_->DidFinishFrame(&obs2);
314   source_->RemoveObserver(&obs2);
315 }
316 
TEST_F(BackToBackBeginFrameSourceTest,MultipleObserversAtOnce)317 TEST_F(BackToBackBeginFrameSourceTest, MultipleObserversAtOnce) {
318   NiceMock<MockBeginFrameObserver> obs1, obs2;
319 
320   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false);
321   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false);
322   source_->AddObserver(&obs1);
323   source_->AddObserver(&obs2);
324   EXPECT_BEGIN_FRAME_USED(obs1, source_->source_id(), 1, 1000, 1000 + kDeadline,
325                           kInterval);
326   EXPECT_BEGIN_FRAME_USED(obs2, source_->source_id(), 1, 1000, 1000 + kDeadline,
327                           kInterval);
328   task_runner_->RunUntilIdle();
329 
330   // |obs1| finishes first.
331   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
332   source_->DidFinishFrame(&obs1);
333 
334   // |obs2| finishes also, before getting to the newly posted begin frame.
335   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(100));
336   source_->DidFinishFrame(&obs2);
337 
338   // Because the begin frame source already ticked when |obs1| finished,
339   // we see it as the frame time for both observers.
340   EXPECT_BEGIN_FRAME_USED(obs1, source_->source_id(), 2, 1100, 1100 + kDeadline,
341                           kInterval);
342   EXPECT_BEGIN_FRAME_USED(obs2, source_->source_id(), 2, 1100, 1100 + kDeadline,
343                           kInterval);
344   task_runner_->RunUntilIdle();
345 
346   source_->DidFinishFrame(&obs1);
347   source_->RemoveObserver(&obs1);
348   source_->DidFinishFrame(&obs2);
349   source_->RemoveObserver(&obs2);
350 }
351 
352 // DelayBasedBeginFrameSource testing
353 // ------------------------------------------
354 class DelayBasedBeginFrameSourceTest : public ::testing::Test {
355  public:
SetUp()356   void SetUp() override {
357     task_runner_ = base::MakeRefCounted<TestTaskRunner>();
358     std::unique_ptr<FakeDelayBasedTimeSource> time_source =
359         std::make_unique<FakeDelayBasedTimeSource>(
360             task_runner_->GetMockTickClock(), task_runner_.get());
361 
362     time_source->SetTimebaseAndInterval(
363         base::TimeTicks(), base::TimeDelta::FromMicroseconds(10000));
364     source_ = std::make_unique<DelayBasedBeginFrameSource>(
365         std::move(time_source), BeginFrameSource::kNotRestartableId);
366     obs_.reset(new MockBeginFrameObserver);
367   }
368 
TearDown()369   void TearDown() override { obs_.reset(); }
370 
371   scoped_refptr<TestTaskRunner> task_runner_;
372   std::unique_ptr<DelayBasedBeginFrameSource> source_;
373   std::unique_ptr<MockBeginFrameObserver> obs_;
374 };
375 
TEST_F(DelayBasedBeginFrameSourceTest,AddObserverCallsOnBeginFrameWithMissedTick)376 TEST_F(DelayBasedBeginFrameSourceTest,
377        AddObserverCallsOnBeginFrameWithMissedTick) {
378   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(9010));
379   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
380   EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, source_->source_id(), 1, 10000, 20000,
381                                  10000);
382   source_->AddObserver(obs_.get());  // Should cause the last tick to be sent
383   // No tasks should need to be run for this to occur.
384 }
385 
TEST_F(DelayBasedBeginFrameSourceTest,AddObserverCallsCausesOnBeginFrame)386 TEST_F(DelayBasedBeginFrameSourceTest, AddObserverCallsCausesOnBeginFrame) {
387   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
388   EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, source_->source_id(), 1, 0, 10000,
389                                  10000);
390   source_->AddObserver(obs_.get());
391   EXPECT_EQ(TicksFromMicroseconds(10000),
392             task_runner_->NowTicks() + task_runner_->NextPendingTaskDelay());
393 
394   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 10000, 20000, 10000);
395   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(9010));
396   task_runner_->RunUntilIdle();
397 }
398 
TEST_F(DelayBasedBeginFrameSourceTest,BasicOperation)399 TEST_F(DelayBasedBeginFrameSourceTest, BasicOperation) {
400   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
401   EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, source_->source_id(), 1, 0, 10000,
402                                  10000);
403   source_->AddObserver(obs_.get());
404   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 10000, 20000, 10000);
405   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 3, 20000, 30000, 10000);
406   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 4, 30000, 40000, 10000);
407   task_runner_->FastForwardTo(TicksFromMicroseconds(30001));
408 
409   source_->RemoveObserver(obs_.get());
410   // No new frames....
411   task_runner_->FastForwardTo(TicksFromMicroseconds(60000));
412 }
413 
TEST_F(DelayBasedBeginFrameSourceTest,VSyncChanges)414 TEST_F(DelayBasedBeginFrameSourceTest, VSyncChanges) {
415   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
416   EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, source_->source_id(), 1, 0, 10000,
417                                  10000);
418   source_->AddObserver(obs_.get());
419 
420   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 10000, 20000, 10000);
421   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 3, 20000, 30000, 10000);
422   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 4, 30000, 40000, 10000);
423   task_runner_->FastForwardTo(TicksFromMicroseconds(30001));
424 
425   // Update the vsync information
426   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(27500),
427                                    base::TimeDelta::FromMicroseconds(10001));
428 
429   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 5, 40000, 47502, 10001);
430   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 6, 47502, 57503, 10001);
431   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 7, 57503, 67504, 10001);
432   task_runner_->FastForwardTo(TicksFromMicroseconds(60000));
433 }
434 
TEST_F(DelayBasedBeginFrameSourceTest,VSyncChangeTimebaseBeforeLastTick)435 TEST_F(DelayBasedBeginFrameSourceTest, VSyncChangeTimebaseBeforeLastTick) {
436   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
437   EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, source_->source_id(), 1, 0, 10000,
438                                  10000);
439   source_->AddObserver(obs_.get());
440 
441   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 10000, 20000, 10000);
442   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 3, 20000, 30000, 10000);
443   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 4, 30000, 40000, 10000);
444   task_runner_->FastForwardTo(TicksFromMicroseconds(30000));
445 
446   // Update the vsync information such that timebase is before last tick time,
447   // and next tick happens within less than the new interval of the following
448   // tick (i.e. next_tick -> 40000, following_tick -> 41000)
449   // Begin frame won't be used at 41000 because this is a double-tick.
450   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(26000),
451                                    base::TimeDelta::FromMicroseconds(5000));
452   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 5, 40000, 41000, 5000);
453   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 7, 46000, 51000, 5000);
454   task_runner_->FastForwardTo(TicksFromMicroseconds(46000));
455 
456   // Update the vsync information such that timebase is before last tick time,
457   // and next tick happens exactly one interval before the following tick
458   // tick (i.e. next_tick -> 51000, following_tick -> 60000)
459   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(42000),
460                                    base::TimeDelta::FromMicroseconds(9000));
461   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 8, 51000, 60000, 9000);
462   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 9, 60000, 69000, 9000);
463   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 10, 69000, 78000, 9000);
464   task_runner_->FastForwardTo(TicksFromMicroseconds(70000));
465 }
466 
TEST_F(DelayBasedBeginFrameSourceTest,VSyncChangeTimebaseAfterNextTick)467 TEST_F(DelayBasedBeginFrameSourceTest, VSyncChangeTimebaseAfterNextTick) {
468   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
469   EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, source_->source_id(), 1, 0, 10000,
470                                  10000);
471   source_->AddObserver(obs_.get());
472 
473   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 10000, 20000, 10000);
474   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 3, 20000, 30000, 10000);
475   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 4, 30000, 40000, 10000);
476   task_runner_->FastForwardTo(TicksFromMicroseconds(30000));
477 
478   // Update the vsync information such that timebase is after next tick time,
479   // and next tick happens within less than one interval of the new timebase
480   // Begin frame won't be used at 41000 because this is a double-tick.
481   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(41000),
482                                    base::TimeDelta::FromMicroseconds(5000));
483   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 5, 40000, 41000, 5000);
484   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 7, 46000, 51000, 5000);
485   task_runner_->FastForwardTo(TicksFromMicroseconds(46000));
486 
487   // Update the vsync information such that timebase is after next tick time,
488   // and next tick happens exactly one interval before the new timebase
489   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(60000),
490                                    base::TimeDelta::FromMicroseconds(9000));
491   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 8, 51000, 60000, 9000);
492   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 9, 60000, 69000, 9000);
493   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 10, 69000, 78000, 9000);
494   task_runner_->FastForwardTo(TicksFromMicroseconds(70000));
495 
496   // Update the vsync information such that timebase is after next tick time,
497   // and next tick happens more than one interval before the new timebase
498   // Begin frame won't be used at 80000 because this is a double-tick.
499   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(100000),
500                                    base::TimeDelta::FromMicroseconds(5000));
501   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 11, 78000, 80000, 5000);
502   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 13, 85000, 90000, 5000);
503   task_runner_->FastForwardTo(TicksFromMicroseconds(85000));
504 }
505 
TEST_F(DelayBasedBeginFrameSourceTest,VSyncChangeTimebaseBetweenTicks)506 TEST_F(DelayBasedBeginFrameSourceTest, VSyncChangeTimebaseBetweenTicks) {
507   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
508   EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, source_->source_id(), 1, 0, 10000,
509                                  10000);
510   source_->AddObserver(obs_.get());
511 
512   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 10000, 20000, 10000);
513   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 3, 20000, 30000, 10000);
514   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 4, 30000, 40000, 10000);
515   task_runner_->FastForwardTo(TicksFromMicroseconds(30000));
516 
517   // Update the vsync information such that timebase is between next tick time,
518   // and last tick time.
519   // Begin frame won't be used at 41000 because this is a double-tick.
520   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(35000),
521                                    base::TimeDelta::FromMicroseconds(6000));
522   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 5, 40000, 41000, 6000);
523   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 7, 47000, 53000, 6000);
524   task_runner_->FastForwardTo(TicksFromMicroseconds(47000));
525 
526   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(49000),
527                                    base::TimeDelta::FromMicroseconds(10000));
528   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 8, 53000, 59000, 10000);
529   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 9, 59000, 69000, 10000);
530   EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 10, 69000, 79000, 10000);
531   task_runner_->FastForwardTo(TicksFromMicroseconds(70000));
532 }
533 
TEST_F(DelayBasedBeginFrameSourceTest,MultipleObservers)534 TEST_F(DelayBasedBeginFrameSourceTest, MultipleObservers) {
535   NiceMock<MockBeginFrameObserver> obs1, obs2;
536 
537   // Mock tick clock starts off at 1000.
538   task_runner_->FastForwardBy(base::TimeDelta::FromMicroseconds(9010));
539   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs1, false);
540   EXPECT_BEGIN_FRAME_USED_MISSED(obs1, source_->source_id(), 1, 10000, 20000,
541                                  10000);
542   source_->AddObserver(&obs1);  // Should cause the last tick to be sent
543   // No tasks should need to be run for this to occur.
544 
545   EXPECT_BEGIN_FRAME_USED(obs1, source_->source_id(), 2, 20000, 30000, 10000);
546   task_runner_->FastForwardBy(base::TimeDelta::FromMicroseconds(10000));
547 
548   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs2, false);
549   // Sequence number unchanged for missed frame with time of last normal frame.
550   EXPECT_BEGIN_FRAME_USED_MISSED(obs2, source_->source_id(), 2, 20000, 30000,
551                                  10000);
552   source_->AddObserver(&obs2);  // Should cause the last tick to be sent
553   // No tasks should need to be run for this to occur.
554 
555   EXPECT_BEGIN_FRAME_USED(obs1, source_->source_id(), 3, 30000, 40000, 10000);
556   EXPECT_BEGIN_FRAME_USED(obs2, source_->source_id(), 3, 30000, 40000, 10000);
557   task_runner_->FastForwardBy(base::TimeDelta::FromMicroseconds(10000));
558 
559   source_->RemoveObserver(&obs1);
560 
561   EXPECT_BEGIN_FRAME_USED(obs2, source_->source_id(), 4, 40000, 50000, 10000);
562   task_runner_->FastForwardBy(base::TimeDelta::FromMicroseconds(10000));
563 
564   source_->RemoveObserver(&obs2);
565   task_runner_->FastForwardTo(TicksFromMicroseconds(50000));
566   EXPECT_FALSE(task_runner_->HasPendingTask());
567 }
568 
TEST_F(DelayBasedBeginFrameSourceTest,DoubleTick)569 TEST_F(DelayBasedBeginFrameSourceTest, DoubleTick) {
570   NiceMock<MockBeginFrameObserver> obs;
571 
572   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
573   EXPECT_BEGIN_FRAME_USED_MISSED(obs, source_->source_id(), 1, 0, 10000, 10000);
574   source_->AddObserver(&obs);
575 
576   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(5000),
577                                    base::TimeDelta::FromMicroseconds(10000));
578   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(4000));
579 
580   // No begin frame received.
581   task_runner_->RunUntilIdle();
582 
583   // Begin frame received.
584   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(10000),
585                                    base::TimeDelta::FromMicroseconds(10000));
586   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(5000));
587   EXPECT_BEGIN_FRAME_USED(obs, source_->source_id(), 2, 10000, 20000, 10000);
588   task_runner_->RunUntilIdle();
589 }
590 
TEST_F(DelayBasedBeginFrameSourceTest,DoubleTickMissedFrame)591 TEST_F(DelayBasedBeginFrameSourceTest, DoubleTickMissedFrame) {
592   NiceMock<MockBeginFrameObserver> obs;
593 
594   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
595   EXPECT_BEGIN_FRAME_USED_MISSED(obs, source_->source_id(), 1, 0, 10000, 10000);
596   source_->AddObserver(&obs);
597   source_->RemoveObserver(&obs);
598 
599   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(5000),
600                                    base::TimeDelta::FromMicroseconds(10000));
601   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(4000));
602 
603   // No missed frame received.
604   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
605   // This does not cause a missed BeginFrame because of double ticking
606   // prevention. It does not produce a new sequence number.
607   source_->AddObserver(&obs);
608   source_->RemoveObserver(&obs);
609 
610   // Missed frame received.
611   source_->OnUpdateVSyncParameters(TicksFromMicroseconds(10000),
612                                    base::TimeDelta::FromMicroseconds(10000));
613   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(5000));
614   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
615   // Sequence number is incremented again, because sufficient time has passed.
616   EXPECT_BEGIN_FRAME_USED_MISSED(obs, source_->source_id(), 2, 10000, 20000,
617                                  10000);
618   source_->AddObserver(&obs);
619   source_->RemoveObserver(&obs);
620 }
621 
TEST_F(DelayBasedBeginFrameSourceTest,MultipleArgsInSameInterval)622 TEST_F(DelayBasedBeginFrameSourceTest, MultipleArgsInSameInterval) {
623   NiceMock<MockBeginFrameObserver> obs;
624   NiceMock<MockBeginFrameObserver> obs2;
625 
626   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
627   EXPECT_BEGIN_FRAME_USED_MISSED(obs, source_->source_id(), 1, 0, 10000, 10000);
628   source_->AddObserver(&obs);
629   task_runner_->RunUntilIdle();
630 
631   EXPECT_BEGIN_FRAME_USED(obs, source_->source_id(), 2, 10000, 20000, 10000);
632   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(9000));
633   task_runner_->RunUntilIdle();
634 
635   // Sequence number should stay the same within same interval.
636   EXPECT_BEGIN_FRAME_USED_MISSED(obs2, source_->source_id(), 2, 10000, 20000,
637                                  10000);
638   source_->AddObserver(&obs2);
639 
640   EXPECT_BEGIN_FRAME_USED(obs, source_->source_id(), 3, 20000, 30000, 10000);
641   EXPECT_BEGIN_FRAME_USED(obs2, source_->source_id(), 3, 20000, 30000, 10000);
642   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(10000));
643   task_runner_->RunUntilIdle();
644 }
645 
TEST_F(DelayBasedBeginFrameSourceTest,ConsecutiveArgsDelayedByMultipleVsyncs)646 TEST_F(DelayBasedBeginFrameSourceTest, ConsecutiveArgsDelayedByMultipleVsyncs) {
647   NiceMock<MockBeginFrameObserver> obs;
648 
649   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
650   EXPECT_BEGIN_FRAME_USED_MISSED(obs, source_->source_id(), 1, 0, 10000, 10000);
651   source_->AddObserver(&obs);
652   task_runner_->RunUntilIdle();
653 
654   EXPECT_BEGIN_FRAME_USED(obs, source_->source_id(), 2, 10000, 20000, 10000);
655   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(9000));
656   task_runner_->RunUntilIdle();
657   source_->RemoveObserver(&obs);
658 
659   // New args created 8 intervals later.
660   // Sequence number should increase bt this much.
661   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(obs, false);
662   EXPECT_BEGIN_FRAME_USED_MISSED(obs, source_->source_id(), 10, 90000, 100000,
663                                  10000);
664   task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMicroseconds(80000));
665   source_->AddObserver(&obs);
666 }
667 
668 // ExternalBeginFrameSource testing
669 // --------------------------------------------
670 class MockExternalBeginFrameSourceClient
671     : public ExternalBeginFrameSourceClient {
672  public:
673   MockExternalBeginFrameSourceClient() = default;
674   virtual ~MockExternalBeginFrameSourceClient() = default;
675 
676   MOCK_METHOD1(OnNeedsBeginFrames, void(bool));
677 };
678 
679 class ExternalBeginFrameSourceTest : public ::testing::Test {
680  public:
SetUp()681   void SetUp() override {
682     client_ = std::make_unique<MockExternalBeginFrameSourceClient>();
683     source_ = std::make_unique<ExternalBeginFrameSource>(
684         client_.get(), BeginFrameSource::kNotRestartableId);
685     obs_ = std::make_unique<MockBeginFrameObserver>();
686   }
687 
TearDown()688   void TearDown() override {
689     client_.reset();
690     obs_.reset();
691   }
692 
693   std::unique_ptr<MockExternalBeginFrameSourceClient> client_;
694   std::unique_ptr<ExternalBeginFrameSource> source_;
695   std::unique_ptr<MockBeginFrameObserver> obs_;
696 };
697 
TEST_F(ExternalBeginFrameSourceTest,OnAnimateOnlyBeginFrameOptIn)698 TEST_F(ExternalBeginFrameSourceTest, OnAnimateOnlyBeginFrameOptIn) {
699   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
700   EXPECT_CALL((*client_), OnNeedsBeginFrames(true)).Times(1);
701   source_->AddObserver(obs_.get());
702 
703   // By default, an observer doesn't receive animate_only BeginFrames.
704   BeginFrameArgs args = CreateBeginFrameArgsForTesting(
705       BEGINFRAME_FROM_HERE, 0, 2, TicksFromMicroseconds(10000));
706   args.animate_only = true;
707   source_->OnBeginFrame(args);
708 
709   // When opting in, an observer receives animate_only BeginFrames.
710   args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 3,
711                                         TicksFromMicroseconds(10001));
712   args.animate_only = true;
713   EXPECT_CALL(*obs_, WantsAnimateOnlyBeginFrames())
714       .WillOnce(::testing::Return(true));
715   EXPECT_BEGIN_FRAME_ARGS_USED(*obs_, args);
716   source_->OnBeginFrame(args);
717 
718   EXPECT_CALL((*client_), OnNeedsBeginFrames(false)).Times(1);
719   source_->RemoveObserver(obs_.get());
720 }
721 
TEST_F(ExternalBeginFrameSourceTest,OnBeginFrameChecksBeginFrameContinuity)722 TEST_F(ExternalBeginFrameSourceTest, OnBeginFrameChecksBeginFrameContinuity) {
723   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
724   EXPECT_CALL((*client_), OnNeedsBeginFrames(true)).Times(1);
725   source_->AddObserver(obs_.get());
726 
727   BeginFrameArgs args = CreateBeginFrameArgsForTesting(
728       BEGINFRAME_FROM_HERE, 0, 2, TicksFromMicroseconds(10000));
729   EXPECT_BEGIN_FRAME_ARGS_USED(*obs_, args);
730   source_->OnBeginFrame(args);
731 
732   // Providing same args again to OnBeginFrame() should not notify observer.
733   source_->OnBeginFrame(args);
734 
735   // Providing same args through a different ExternalBeginFrameSource also
736   // does not notify observer.
737   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
738   EXPECT_CALL((*client_), OnNeedsBeginFrames(true)).Times(1);
739   ExternalBeginFrameSource source2(client_.get());
740   source2.AddObserver(obs_.get());
741   source2.OnBeginFrame(args);
742 
743   EXPECT_CALL((*client_), OnNeedsBeginFrames(false)).Times(2);
744   source_->RemoveObserver(obs_.get());
745   source2.RemoveObserver(obs_.get());
746 }
747 
TEST_F(ExternalBeginFrameSourceTest,GetMissedBeginFrameArgs)748 TEST_F(ExternalBeginFrameSourceTest, GetMissedBeginFrameArgs) {
749   BeginFrameArgs args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0,
750                                                        2, 10000, 10100, 100);
751   source_->OnBeginFrame(args);
752 
753   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
754   EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, 0, 2, 10000, 10100, 100);
755   source_->AddObserver(obs_.get());
756   source_->RemoveObserver(obs_.get());
757 
758   // Out of order frame_time. This might not be valid but still shouldn't
759   // cause a DCHECK in ExternalBeginFrameSource code.
760   args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2, 9999, 10100,
761                                         101);
762   source_->OnBeginFrame(args);
763 
764   EXPECT_CALL((*client_), OnNeedsBeginFrames(true)).Times(1);
765   EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
766   EXPECT_CALL(*obs_, OnBeginFrame(_)).Times(0);
767   source_->AddObserver(obs_.get());
768 
769   EXPECT_CALL((*client_), OnNeedsBeginFrames(false)).Times(1);
770   source_->RemoveObserver(obs_.get());
771 }
772 
773 // Tests that an observer which returns true from IsRoot is notified after
774 // observers which return false.
TEST_F(ExternalBeginFrameSourceTest,RootsNotifiedLast)775 TEST_F(ExternalBeginFrameSourceTest, RootsNotifiedLast) {
776   using ::testing::InSequence;
777 
778   NiceMock<MockBeginFrameObserver> obs1, obs2;
779   source_->AddObserver(&obs1);
780   source_->AddObserver(&obs2);
781 
782   {
783     BeginFrameArgs args = CreateBeginFrameArgsForTesting(
784         BEGINFRAME_FROM_HERE, 0, 1, 10000, 10100, 100);
785     // Set obs1 to root, obs2 to child.
786     EXPECT_CALL(obs1, IsRoot()).WillRepeatedly(::testing::Return(true));
787     EXPECT_CALL(obs2, IsRoot()).WillRepeatedly(::testing::Return(false));
788     {
789       // Ensure that OnBeginFrame delivers the calls in the right order.
790       InSequence s;
791       EXPECT_CALL(obs2, OnBeginFrame(args))
792           .WillOnce(::testing::SaveArg<0>(&(obs2.last_begin_frame_args)));
793       EXPECT_CALL(obs1, OnBeginFrame(args))
794           .WillOnce(::testing::SaveArg<0>(&(obs1.last_begin_frame_args)));
795       source_->OnBeginFrame(args);
796     }
797   }
798 
799   {
800     BeginFrameArgs args = CreateBeginFrameArgsForTesting(
801         BEGINFRAME_FROM_HERE, 0, 2, 10001, 10101, 100);
802     // Set obs2 to root, obs1 to child.
803     EXPECT_CALL(obs1, IsRoot()).WillRepeatedly(::testing::Return(false));
804     EXPECT_CALL(obs2, IsRoot()).WillRepeatedly(::testing::Return(true));
805     {
806       // Ensure that OnBeginFrame delivers the calls in the right order.
807       InSequence s;
808       EXPECT_CALL(obs1, OnBeginFrame(args))
809           .WillOnce(::testing::SaveArg<0>(&(obs1.last_begin_frame_args)));
810       EXPECT_CALL(obs2, OnBeginFrame(args))
811           .WillOnce(::testing::SaveArg<0>(&(obs2.last_begin_frame_args)));
812       source_->OnBeginFrame(args);
813     }
814   }
815 
816   source_->RemoveObserver(&obs1);
817   source_->RemoveObserver(&obs2);
818 }
819 
820 }  // namespace
821 }  // namespace viz
822