Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / cc / scheduler / begin_frame_source_unittest.cc
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 <deque>
6 #include <string>
7
8 #include "base/basictypes.h"
9 #include "base/gtest_prod_util.h"
10 #include "base/test/test_simple_task_runner.h"
11 #include "cc/scheduler/begin_frame_source.h"
12 #include "cc/test/begin_frame_args_test.h"
13 #include "cc/test/scheduler_test_common.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 // Macros to help set up expected calls on the MockBeginFrameObserver.
18 #define EXPECT_BEGIN_FRAME_DROP(obs, frame_time, deadline, interval) \
19   {                                                                  \
20     ::testing::Expectation exp =                                     \
21         EXPECT_CALL((obs),                                           \
22                     OnBeginFrame(CreateBeginFrameArgsForTesting(     \
23                         frame_time, deadline, interval)))            \
24             .InSequence((obs).sequence);                             \
25   }
26
27 #define EXPECT_BEGIN_FRAME_USED(obs, frame_time, deadline, interval)       \
28   {                                                                        \
29     BeginFrameArgs args =                                                  \
30         CreateBeginFrameArgsForTesting(frame_time, deadline, interval);    \
31     ::testing::Expectation exp =                                           \
32         EXPECT_CALL((obs), OnBeginFrame(args)).InSequence((obs).sequence); \
33     EXPECT_CALL((obs), LastUsedBeginFrameArgs())                           \
34         .Times(::testing::AnyNumber())                                     \
35         .After(exp)                                                        \
36         .WillRepeatedly(::testing::Return(args));                          \
37   }
38
39 // Macros to send BeginFrameArgs on a FakeBeginFrameSink (and verify resulting
40 // observer behaviour).
41 #define SEND_BEGIN_FRAME(                                               \
42     args_equal_to, source, frame_time, deadline, interval)              \
43   {                                                                     \
44     BeginFrameArgs old_args = (source).TestLastUsedBeginFrameArgs();    \
45     BeginFrameArgs new_args =                                           \
46         CreateBeginFrameArgsForTesting(frame_time, deadline, interval); \
47     ASSERT_TRUE(!(old_args == new_args));                               \
48     (source).TestOnBeginFrame(new_args);                                \
49     EXPECT_EQ(args_equal_to, (source).TestLastUsedBeginFrameArgs());    \
50   }
51
52 // When dropping LastUsedBeginFrameArgs **shouldn't** change.
53 #define SEND_BEGIN_FRAME_DROP(source, frame_time, deadline, interval) \
54   SEND_BEGIN_FRAME(old_args, source, frame_time, deadline, interval);
55
56 // When used LastUsedBeginFrameArgs **should** be updated.
57 #define SEND_BEGIN_FRAME_USED(source, frame_time, deadline, interval) \
58   SEND_BEGIN_FRAME(new_args, source, frame_time, deadline, interval);
59
60 namespace cc {
61 namespace {
62
63 class MockBeginFrameObserver : public BeginFrameObserver {
64  public:
65   MOCK_METHOD1(OnBeginFrame, void(const BeginFrameArgs&));
66   MOCK_CONST_METHOD0(LastUsedBeginFrameArgs, const BeginFrameArgs());
67
68   virtual void AsValueInto(base::debug::TracedValue* dict) const {
69     dict->SetString("type", "MockBeginFrameObserver");
70     dict->BeginDictionary("last_begin_frame_args");
71     LastUsedBeginFrameArgs().AsValueInto(dict);
72     dict->EndDictionary();
73   }
74
75   // A value different from the normal default returned by a BeginFrameObserver
76   // so it is easiable traced back here.
77   static const BeginFrameArgs kDefaultBeginFrameArgs;
78
79   MockBeginFrameObserver() {
80     // Set a "default" value returned by LastUsedBeginFrameArgs so that gMock
81     // doesn't fail an assert and instead returns useful information.
82     EXPECT_CALL(*this, LastUsedBeginFrameArgs())
83         .Times(::testing::AnyNumber())
84         .InSequence(sequence)
85         .WillRepeatedly(::testing::Return(kDefaultBeginFrameArgs));
86   }
87   virtual ~MockBeginFrameObserver() {}
88
89   ::testing::Sequence sequence;
90 };
91
92 TEST(MockBeginFrameObserverTest, ExpectOnBeginFrame) {
93   ::testing::NiceMock<MockBeginFrameObserver> obs;
94   EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
95   EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
96   EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
97
98   EXPECT_EQ(obs.LastUsedBeginFrameArgs(),
99             MockBeginFrameObserver::kDefaultBeginFrameArgs);
100
101   obs.OnBeginFrame(CreateBeginFrameArgsForTesting(
102       100, 200, 300));  // One call to LastUsedBeginFrameArgs
103   EXPECT_EQ(obs.LastUsedBeginFrameArgs(),
104             CreateBeginFrameArgsForTesting(100, 200, 300));
105
106   obs.OnBeginFrame(CreateBeginFrameArgsForTesting(
107       400, 600, 300));  // Multiple calls to LastUsedBeginFrameArgs
108   EXPECT_EQ(obs.LastUsedBeginFrameArgs(),
109             CreateBeginFrameArgsForTesting(400, 600, 300));
110   EXPECT_EQ(obs.LastUsedBeginFrameArgs(),
111             CreateBeginFrameArgsForTesting(400, 600, 300));
112
113   obs.OnBeginFrame(CreateBeginFrameArgsForTesting(
114       700, 900, 300));  // No calls to LastUsedBeginFrameArgs
115 }
116
117 TEST(MockBeginFrameObserverTest, ExpectOnBeginFrameStatus) {
118   ::testing::NiceMock<MockBeginFrameObserver> obs;
119   EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
120   EXPECT_BEGIN_FRAME_DROP(obs, 400, 600, 300);
121   EXPECT_BEGIN_FRAME_DROP(obs, 450, 650, 300);
122   EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
123
124   EXPECT_EQ(obs.LastUsedBeginFrameArgs(),
125             MockBeginFrameObserver::kDefaultBeginFrameArgs);
126
127   // Used
128   obs.OnBeginFrame(CreateBeginFrameArgsForTesting(100, 200, 300));
129   EXPECT_EQ(obs.LastUsedBeginFrameArgs(),
130             CreateBeginFrameArgsForTesting(100, 200, 300));
131
132   // Dropped
133   obs.OnBeginFrame(CreateBeginFrameArgsForTesting(400, 600, 300));
134   EXPECT_EQ(obs.LastUsedBeginFrameArgs(),
135             CreateBeginFrameArgsForTesting(100, 200, 300));
136
137   // Dropped
138   obs.OnBeginFrame(CreateBeginFrameArgsForTesting(450, 650, 300));
139   EXPECT_EQ(obs.LastUsedBeginFrameArgs(),
140             CreateBeginFrameArgsForTesting(100, 200, 300));
141
142   // Used
143   obs.OnBeginFrame(CreateBeginFrameArgsForTesting(700, 900, 300));
144   EXPECT_EQ(obs.LastUsedBeginFrameArgs(),
145             CreateBeginFrameArgsForTesting(700, 900, 300));
146 }
147
148 const BeginFrameArgs MockBeginFrameObserver::kDefaultBeginFrameArgs =
149     CreateBeginFrameArgsForTesting(-1, -1, -1);
150
151 // BeginFrameObserverMixIn testing ---------------------------------------
152 class MockMinimalBeginFrameObserverMixIn : public BeginFrameObserverMixIn {
153  public:
154   MOCK_METHOD1(OnBeginFrameMixInDelegate, bool(const BeginFrameArgs&));
155   int64_t dropped_begin_frame_args() const { return dropped_begin_frame_args_; }
156 };
157
158 TEST(BeginFrameObserverMixInTest, OnBeginFrameImplementation) {
159   using ::testing::Return;
160   MockMinimalBeginFrameObserverMixIn obs;
161   ::testing::InSequence ordered;  // These calls should be ordered
162
163   // Initial conditions
164   EXPECT_EQ(BeginFrameArgs(), obs.LastUsedBeginFrameArgs());
165   EXPECT_EQ(0, obs.dropped_begin_frame_args());
166
167 #ifndef NDEBUG
168   EXPECT_DEATH({ obs.OnBeginFrame(BeginFrameArgs()); }, "");
169 #endif
170
171   BeginFrameArgs args1 = CreateBeginFrameArgsForTesting(100, 200, 300);
172   EXPECT_CALL(obs, OnBeginFrameMixInDelegate(args1)).WillOnce(Return(true));
173   obs.OnBeginFrame(args1);
174   EXPECT_EQ(args1, obs.LastUsedBeginFrameArgs());
175   EXPECT_EQ(0, obs.dropped_begin_frame_args());
176
177 #ifndef NDEBUG
178   EXPECT_DEATH(
179       { obs.OnBeginFrame(CreateBeginFrameArgsForTesting(50, 200, 300)); }, "");
180 #endif
181
182   // Returning false shouldn't update the LastUsedBeginFrameArgs value.
183   BeginFrameArgs args2 = CreateBeginFrameArgsForTesting(200, 300, 400);
184   EXPECT_CALL(obs, OnBeginFrameMixInDelegate(args2)).WillOnce(Return(false));
185   obs.OnBeginFrame(args2);
186   EXPECT_EQ(args1, obs.LastUsedBeginFrameArgs());
187   EXPECT_EQ(1, obs.dropped_begin_frame_args());
188
189   BeginFrameArgs args3 = CreateBeginFrameArgsForTesting(150, 300, 400);
190   EXPECT_CALL(obs, OnBeginFrameMixInDelegate(args3)).WillOnce(Return(true));
191   obs.OnBeginFrame(args3);
192   EXPECT_EQ(args3, obs.LastUsedBeginFrameArgs());
193   EXPECT_EQ(1, obs.dropped_begin_frame_args());
194 }
195
196 // BeginFrameSource testing ----------------------------------------------
197 TEST(BeginFrameSourceMixInTest, ObserverManipulation) {
198   MockBeginFrameObserver obs;
199   MockBeginFrameObserver otherObs;
200   FakeBeginFrameSource source;
201
202   source.AddObserver(&obs);
203   EXPECT_EQ(&obs, source.GetObserver());
204
205 #ifndef NDEBUG
206   // Adding an observer when an observer already exists should DCHECK fail.
207   EXPECT_DEATH({ source.AddObserver(&otherObs); }, "");
208
209   // Removing wrong observer should DCHECK fail.
210   EXPECT_DEATH({ source.RemoveObserver(&otherObs); }, "");
211
212   // Removing an observer when there is no observer should DCHECK fail.
213   EXPECT_DEATH({
214                  source.RemoveObserver(&obs);
215                  source.RemoveObserver(&obs);
216                },
217                "");
218 #endif
219   source.RemoveObserver(&obs);
220
221   source.AddObserver(&otherObs);
222   EXPECT_EQ(&otherObs, source.GetObserver());
223   source.RemoveObserver(&otherObs);
224 }
225
226 TEST(BeginFrameSourceMixInTest, Observer) {
227   FakeBeginFrameSource source;
228   MockBeginFrameObserver obs;
229   source.AddObserver(&obs);
230   EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
231   EXPECT_BEGIN_FRAME_DROP(obs, 400, 600, 300);
232   EXPECT_BEGIN_FRAME_DROP(obs, 450, 650, 300);
233   EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
234
235   SEND_BEGIN_FRAME_USED(source, 100, 200, 300);
236   SEND_BEGIN_FRAME_DROP(source, 400, 600, 300);
237   SEND_BEGIN_FRAME_DROP(source, 450, 650, 300);
238   SEND_BEGIN_FRAME_USED(source, 700, 900, 300);
239 }
240
241 TEST(BeginFrameSourceMixInTest, NoObserver) {
242   FakeBeginFrameSource source;
243   SEND_BEGIN_FRAME_DROP(source, 100, 200, 300);
244 }
245
246 TEST(BeginFrameSourceMixInTest, NeedsBeginFrames) {
247   FakeBeginFrameSource source;
248   EXPECT_FALSE(source.NeedsBeginFrames());
249   source.SetNeedsBeginFrames(true);
250   EXPECT_TRUE(source.NeedsBeginFrames());
251   source.SetNeedsBeginFrames(false);
252   EXPECT_FALSE(source.NeedsBeginFrames());
253 }
254
255 class LoopingBeginFrameObserver : public BeginFrameObserverMixIn {
256  public:
257   BeginFrameSource* source_;
258
259   void AsValueInto(base::debug::TracedValue* dict) const override {
260     dict->SetString("type", "LoopingBeginFrameObserver");
261     dict->BeginDictionary("source");
262     source_->AsValueInto(dict);
263     dict->EndDictionary();
264   }
265
266  protected:
267   // BeginFrameObserverMixIn
268   bool OnBeginFrameMixInDelegate(const BeginFrameArgs& args) override {
269     return true;
270   }
271 };
272
273 TEST(BeginFrameSourceMixInTest, DetectAsValueIntoLoop) {
274   LoopingBeginFrameObserver obs;
275   FakeBeginFrameSource source;
276
277   obs.source_ = &source;
278   source.AddObserver(&obs);
279
280   scoped_refptr<base::debug::TracedValue> state =
281       new base::debug::TracedValue();
282   source.AsValueInto(state.get());
283 }
284
285 // BackToBackBeginFrameSource testing -----------------------------------------
286 class TestBackToBackBeginFrameSource : public BackToBackBeginFrameSource {
287  public:
288   static scoped_ptr<TestBackToBackBeginFrameSource> Create(
289       scoped_refptr<TestNowSource> now_src,
290       base::SingleThreadTaskRunner* task_runner) {
291     return make_scoped_ptr(
292         new TestBackToBackBeginFrameSource(now_src, task_runner));
293   }
294
295  protected:
296   TestBackToBackBeginFrameSource(scoped_refptr<TestNowSource> now_src,
297                                  base::SingleThreadTaskRunner* task_runner)
298       : BackToBackBeginFrameSource(task_runner), now_src_(now_src) {}
299
300   base::TimeTicks Now() override { return now_src_->Now(); }
301
302   scoped_refptr<TestNowSource> now_src_;
303 };
304
305 class BackToBackBeginFrameSourceTest : public ::testing::Test {
306  public:
307   static const int64_t kDeadline;
308   static const int64_t kInterval;
309
310   scoped_refptr<TestNowSource> now_src_;
311   scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
312   scoped_ptr<TestBackToBackBeginFrameSource> source_;
313   scoped_ptr<MockBeginFrameObserver> obs_;
314
315   virtual void SetUp() override {
316     now_src_ = TestNowSource::Create(1000);
317     task_runner_ =
318         make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_, false));
319     task_runner_->SetRunTaskLimit(1);
320     source_ =
321         TestBackToBackBeginFrameSource::Create(now_src_, task_runner_.get());
322     obs_ = make_scoped_ptr(new ::testing::StrictMock<MockBeginFrameObserver>());
323     source_->AddObserver(obs_.get());
324   }
325
326   virtual void TearDown() override { obs_.reset(); }
327 };
328
329 const int64_t BackToBackBeginFrameSourceTest::kDeadline =
330     BeginFrameArgs::DefaultInterval().ToInternalValue();
331
332 const int64_t BackToBackBeginFrameSourceTest::kInterval =
333     BeginFrameArgs::DefaultInterval().ToInternalValue();
334
335 TEST_F(BackToBackBeginFrameSourceTest, SetNeedsBeginFramesSendsBeginFrame) {
336   EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
337   source_->SetNeedsBeginFrames(true);
338   EXPECT_TRUE(task_runner_->HasPendingTasks());
339   task_runner_->RunUntilIdle();
340
341   EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval);
342   now_src_->AdvanceNowMicroseconds(100);
343   source_->DidFinishFrame(0);
344   task_runner_->RunUntilIdle();
345 }
346
347 TEST_F(BackToBackBeginFrameSourceTest,
348        DidFinishFrameThenSetNeedsBeginFramesProducesNoFrame) {
349   EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
350   source_->SetNeedsBeginFrames(true);
351   task_runner_->RunUntilIdle();
352
353   source_->SetNeedsBeginFrames(false);
354   source_->DidFinishFrame(0);
355
356   EXPECT_FALSE(task_runner_->HasPendingTasks());
357 }
358
359 TEST_F(BackToBackBeginFrameSourceTest,
360        SetNeedsBeginFramesThenDidFinishFrameProducesNoFrame) {
361   EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
362   source_->SetNeedsBeginFrames(true);
363   task_runner_->RunUntilIdle();
364
365   now_src_->AdvanceNowMicroseconds(100);
366   source_->DidFinishFrame(0);
367   source_->SetNeedsBeginFrames(false);
368
369   EXPECT_TRUE(task_runner_->HasPendingTasks());
370   task_runner_->RunUntilIdle();
371 }
372
373 TEST_F(BackToBackBeginFrameSourceTest,
374        DidFinishFrameThenTogglingSetNeedsBeginFramesProducesCorrectFrame) {
375   EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
376   source_->SetNeedsBeginFrames(true);
377   task_runner_->RunUntilIdle();
378
379   now_src_->AdvanceNowMicroseconds(100);
380
381   source_->SetNeedsBeginFrames(false);
382   now_src_->AdvanceNowMicroseconds(10);
383   source_->DidFinishFrame(0);
384   now_src_->AdvanceNowMicroseconds(10);
385   source_->SetNeedsBeginFrames(false);
386   now_src_->AdvanceNowMicroseconds(10);
387   source_->SetNeedsBeginFrames(true);
388
389   EXPECT_BEGIN_FRAME_USED(*obs_, 1130, 1130 + kDeadline, kInterval);
390   EXPECT_TRUE(task_runner_->HasPendingTasks());
391   task_runner_->RunUntilIdle();
392 }
393
394 TEST_F(BackToBackBeginFrameSourceTest,
395        TogglingSetNeedsBeginFramesThenDidFinishFrameProducesCorrectFrame) {
396   EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
397   source_->SetNeedsBeginFrames(true);
398   task_runner_->RunUntilIdle();
399
400   now_src_->AdvanceNowMicroseconds(100);
401   source_->DidFinishFrame(0);
402   now_src_->AdvanceNowMicroseconds(10);
403   source_->SetNeedsBeginFrames(false);
404   now_src_->AdvanceNowMicroseconds(10);
405   source_->SetNeedsBeginFrames(true);
406   now_src_->AdvanceNowMicroseconds(10);
407
408   EXPECT_BEGIN_FRAME_USED(*obs_, 1130, 1130 + kDeadline, kInterval);
409   EXPECT_TRUE(task_runner_->HasPendingTasks());
410   task_runner_->RunUntilIdle();
411 }
412
413 TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameNeedsBeginFrameFalse) {
414   source_->SetNeedsBeginFrames(false);
415   source_->DidFinishFrame(0);
416   EXPECT_FALSE(task_runner_->RunPendingTasks());
417 }
418
419 TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameRemainingFrames) {
420   EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
421   source_->SetNeedsBeginFrames(true);
422   task_runner_->RunUntilIdle();
423
424   now_src_->AdvanceNowMicroseconds(100);
425
426   source_->DidFinishFrame(3);
427   EXPECT_FALSE(task_runner_->HasPendingTasks());
428   source_->DidFinishFrame(2);
429   EXPECT_FALSE(task_runner_->HasPendingTasks());
430   source_->DidFinishFrame(1);
431   EXPECT_FALSE(task_runner_->HasPendingTasks());
432
433   EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval);
434   source_->DidFinishFrame(0);
435   EXPECT_EQ(base::TimeDelta(), task_runner_->DelayToNextTaskTime());
436   task_runner_->RunUntilIdle();
437 }
438
439 TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameMultipleCallsIdempotent) {
440   source_->SetNeedsBeginFrames(true);
441   EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
442   task_runner_->RunUntilIdle();
443
444   now_src_->AdvanceNowMicroseconds(100);
445   source_->DidFinishFrame(0);
446   source_->DidFinishFrame(0);
447   source_->DidFinishFrame(0);
448   EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval);
449   task_runner_->RunUntilIdle();
450
451   now_src_->AdvanceNowMicroseconds(100);
452   source_->DidFinishFrame(0);
453   source_->DidFinishFrame(0);
454   source_->DidFinishFrame(0);
455   EXPECT_BEGIN_FRAME_USED(*obs_, 1200, 1200 + kDeadline, kInterval);
456   task_runner_->RunUntilIdle();
457 }
458
459 TEST_F(BackToBackBeginFrameSourceTest, DelayInPostedTaskProducesCorrectFrame) {
460   EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
461   source_->SetNeedsBeginFrames(true);
462   task_runner_->RunUntilIdle();
463
464   now_src_->AdvanceNowMicroseconds(100);
465   source_->DidFinishFrame(0);
466   now_src_->AdvanceNowMicroseconds(50);
467   EXPECT_BEGIN_FRAME_USED(*obs_, 1150, 1150 + kDeadline, kInterval);
468
469   EXPECT_TRUE(task_runner_->HasPendingTasks());
470   task_runner_->RunUntilIdle();
471 }
472
473 // SyntheticBeginFrameSource testing ------------------------------------------
474 class SyntheticBeginFrameSourceTest : public ::testing::Test {
475  public:
476   scoped_refptr<TestNowSource> now_src_;
477   scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
478   scoped_ptr<TestSyntheticBeginFrameSource> source_;
479   scoped_ptr<MockBeginFrameObserver> obs_;
480
481   virtual void SetUp() override {
482     now_src_ = TestNowSource::Create(1000);
483     task_runner_ =
484         make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_, false));
485     source_ = TestSyntheticBeginFrameSource::Create(
486         now_src_, task_runner_.get(), base::TimeDelta::FromMicroseconds(10000));
487     obs_ = make_scoped_ptr(new MockBeginFrameObserver());
488     source_->AddObserver(obs_.get());
489   }
490
491   virtual void TearDown() override { obs_.reset(); }
492 };
493
494 TEST_F(SyntheticBeginFrameSourceTest,
495        SetNeedsBeginFramesCallsOnBeginFrameWithMissedTick) {
496   now_src_->SetNowMicroseconds(10010);
497   EXPECT_CALL((*obs_),
498               OnBeginFrame(CreateTypedBeginFrameArgsForTesting(
499                   10000, 20000, 10000, BeginFrameArgs::MISSED)));
500   source_->SetNeedsBeginFrames(true);  // Should cause the last tick to be sent
501   // No tasks should need to be run for this to occur.
502 }
503
504 TEST_F(SyntheticBeginFrameSourceTest,
505        SetNeedsBeginFramesCallsCausesOnBeginFrame) {
506   source_->SetNeedsBeginFrames(true);
507   EXPECT_EQ(10000, task_runner_->NextTaskTime().ToInternalValue());
508
509   EXPECT_BEGIN_FRAME_USED(*obs_, 10000, 20000, 10000);
510   now_src_->SetNowMicroseconds(10010);
511   task_runner_->RunPendingTasks();
512 }
513
514 TEST_F(SyntheticBeginFrameSourceTest, BasicOperation) {
515   task_runner_->SetAutoAdvanceNowToPendingTasks(true);
516
517   source_->SetNeedsBeginFrames(true);
518   EXPECT_BEGIN_FRAME_USED(*obs_, 10000, 20000, 10000);
519   EXPECT_BEGIN_FRAME_USED(*obs_, 20000, 30000, 10000);
520   EXPECT_BEGIN_FRAME_USED(*obs_, 30000, 40000, 10000);
521   task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(30001));
522
523   source_->SetNeedsBeginFrames(false);
524   // No new frames....
525   task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60000));
526 }
527
528 TEST_F(SyntheticBeginFrameSourceTest, VSyncChanges) {
529   task_runner_->SetAutoAdvanceNowToPendingTasks(true);
530   source_->SetNeedsBeginFrames(true);
531
532   EXPECT_BEGIN_FRAME_USED(*obs_, 10000, 20000, 10000);
533   EXPECT_BEGIN_FRAME_USED(*obs_, 20000, 30000, 10000);
534   EXPECT_BEGIN_FRAME_USED(*obs_, 30000, 40000, 10000);
535   task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(30001));
536
537   // Update the vsync information
538   source_->OnUpdateVSyncParameters(base::TimeTicks::FromInternalValue(27500),
539                                    base::TimeDelta::FromMicroseconds(10001));
540
541   EXPECT_BEGIN_FRAME_USED(*obs_, 40000, 47502, 10001);
542   EXPECT_BEGIN_FRAME_USED(*obs_, 47502, 57503, 10001);
543   EXPECT_BEGIN_FRAME_USED(*obs_, 57503, 67504, 10001);
544   task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60000));
545 }
546
547 // BeginFrameSourceMultiplexer testing -----------------------------------
548 class BeginFrameSourceMultiplexerTest : public ::testing::Test {
549  protected:
550   virtual void SetUp() override {
551     mux_ = BeginFrameSourceMultiplexer::Create();
552
553     source1_store_ = make_scoped_ptr(new FakeBeginFrameSource());
554     source2_store_ = make_scoped_ptr(new FakeBeginFrameSource());
555     source3_store_ = make_scoped_ptr(new FakeBeginFrameSource());
556
557     source1_ = source1_store_.get();
558     source2_ = source2_store_.get();
559     source3_ = source3_store_.get();
560   }
561
562   virtual void TearDown() override {
563     // Make sure the mux is torn down before the sources.
564     mux_.reset();
565   }
566
567   scoped_ptr<BeginFrameSourceMultiplexer> mux_;
568   FakeBeginFrameSource* source1_;
569   FakeBeginFrameSource* source2_;
570   FakeBeginFrameSource* source3_;
571
572  private:
573   scoped_ptr<FakeBeginFrameSource> source1_store_;
574   scoped_ptr<FakeBeginFrameSource> source2_store_;
575   scoped_ptr<FakeBeginFrameSource> source3_store_;
576 };
577
578 TEST_F(BeginFrameSourceMultiplexerTest, SourcesManipulation) {
579   EXPECT_EQ(NULL, mux_->ActiveSource());
580
581   mux_->AddSource(source1_);
582   EXPECT_EQ(source1_, mux_->ActiveSource());
583
584   mux_->SetActiveSource(NULL);
585   EXPECT_EQ(NULL, mux_->ActiveSource());
586
587   mux_->SetActiveSource(source1_);
588
589 #ifndef NDEBUG
590   // Setting a source which isn't in the mux as active should DCHECK fail.
591   EXPECT_DEATH({ mux_->SetActiveSource(source2_); }, "");
592
593   // Adding a source which is already added should DCHECK fail.
594   EXPECT_DEATH({ mux_->AddSource(source1_); }, "");
595
596   // Removing a source which isn't in the mux should DCHECK fail.
597   EXPECT_DEATH({ mux_->RemoveSource(source2_); }, "");
598
599   // Removing the active source fails
600   EXPECT_DEATH({ mux_->RemoveSource(source1_); }, "");
601 #endif
602
603   // Test manipulation doesn't segfault.
604   mux_->AddSource(source2_);
605   mux_->RemoveSource(source2_);
606
607   mux_->AddSource(source2_);
608   mux_->SetActiveSource(source2_);
609   EXPECT_EQ(source2_, mux_->ActiveSource());
610
611   mux_->RemoveSource(source1_);
612 }
613
614 TEST_F(BeginFrameSourceMultiplexerTest, NeedsBeginFrames) {
615   mux_->AddSource(source1_);
616   mux_->AddSource(source2_);
617   mux_->SetActiveSource(source1_);
618   EXPECT_EQ(source1_->NeedsBeginFrames(), false);
619   EXPECT_EQ(source2_->NeedsBeginFrames(), false);
620
621   // Check SetNeedsFrames works
622   mux_->SetNeedsBeginFrames(true);
623   EXPECT_EQ(source1_->NeedsBeginFrames(), true);
624   EXPECT_EQ(source2_->NeedsBeginFrames(), false);
625
626   mux_->SetNeedsBeginFrames(false);
627   EXPECT_EQ(source1_->NeedsBeginFrames(), false);
628   EXPECT_EQ(source2_->NeedsBeginFrames(), false);
629
630   // Checking that switching the source makes SetNeedsFrames on the
631   // subsources correctly.
632   mux_->SetNeedsBeginFrames(true);
633
634   mux_->SetActiveSource(source1_);
635   EXPECT_EQ(source1_->NeedsBeginFrames(), true);
636   EXPECT_EQ(source2_->NeedsBeginFrames(), false);
637
638   mux_->SetActiveSource(source2_);
639   EXPECT_EQ(source1_->NeedsBeginFrames(), false);
640   EXPECT_EQ(source2_->NeedsBeginFrames(), true);
641 }
642
643 TEST_F(BeginFrameSourceMultiplexerTest, BeginFramesSimple) {
644   mux_->AddSource(source1_);
645   mux_->AddSource(source2_);
646   mux_->SetActiveSource(source1_);
647
648   MockBeginFrameObserver obs;
649   mux_->AddObserver(&obs);
650   EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
651   EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
652
653   mux_->SetActiveSource(source1_);
654
655   SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 300);
656   SEND_BEGIN_FRAME_DROP(*source2_, 200, 500, 300);
657
658   mux_->SetActiveSource(source2_);
659   SEND_BEGIN_FRAME_USED(*source2_, 400, 600, 300);
660   SEND_BEGIN_FRAME_DROP(*source1_, 500, 700, 300);
661 }
662
663 TEST_F(BeginFrameSourceMultiplexerTest, BeginFramesBackwardsProtection) {
664   mux_->AddSource(source1_);
665   mux_->AddSource(source2_);
666
667   MockBeginFrameObserver obs;
668   mux_->AddObserver(&obs);
669   EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
670   EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
671   EXPECT_BEGIN_FRAME_USED(obs, 1000, 1200, 300);
672   EXPECT_BEGIN_FRAME_USED(obs, 1001, 1201, 301);
673
674   mux_->SetActiveSource(source1_);
675   SEND_BEGIN_FRAME_USED(*source1_, 400, 600, 300);
676   SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
677
678   mux_->SetActiveSource(source2_);
679   SEND_BEGIN_FRAME_DROP(*source2_, 699, 899, 300);
680   SEND_BEGIN_FRAME_USED(*source2_, 1000, 1200, 300);
681
682   mux_->SetActiveSource(source1_);
683   SEND_BEGIN_FRAME_USED(*source1_, 1001, 1201, 301);
684 }
685
686 TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalNegativeFails) {
687 #ifndef NDEBUG
688   EXPECT_DEATH(
689       { mux_->SetMinimumInterval(base::TimeDelta::FromInternalValue(-100)); },
690       "");
691 #endif
692 }
693
694 TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalZero) {
695   mux_->SetMinimumInterval(base::TimeDelta());
696   mux_->AddSource(source1_);
697
698   MockBeginFrameObserver obs;
699   mux_->AddObserver(&obs);
700   EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
701   EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
702   EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
703
704   SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 300);
705   SEND_BEGIN_FRAME_USED(*source1_, 400, 600, 300);
706   SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
707 }
708
709 TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalBasic) {
710   mux_->SetMinimumInterval(base::TimeDelta::FromInternalValue(600));
711   mux_->AddSource(source1_);
712
713   MockBeginFrameObserver obs;
714   mux_->AddObserver(&obs);
715   EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
716   EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
717
718   SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 300);
719   SEND_BEGIN_FRAME_DROP(*source1_, 400, 600, 300);
720   SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
721 }
722
723 TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalWithMultipleSources) {
724   mux_->SetMinimumInterval(base::TimeDelta::FromMicroseconds(150));
725   mux_->AddSource(source1_);
726   mux_->AddSource(source2_);
727
728   MockBeginFrameObserver obs;
729   mux_->AddObserver(&obs);
730   EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
731   EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
732   EXPECT_BEGIN_FRAME_USED(obs, 1050, 1250, 300);
733
734   mux_->SetActiveSource(source1_);
735   SEND_BEGIN_FRAME_USED(*source1_, 400, 600, 300);
736   SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
737
738   mux_->SetActiveSource(source2_);
739   SEND_BEGIN_FRAME_DROP(*source2_, 750, 1050, 300);
740   SEND_BEGIN_FRAME_USED(*source2_, 1050, 1250, 300);
741
742   mux_->SetActiveSource(source1_);
743   SEND_BEGIN_FRAME_DROP(*source2_, 1100, 1400, 300);
744 }
745
746 }  // namespace
747 }  // namespace cc