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