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.
5 #include "cc/scheduler/scheduler.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/numerics/safe_conversions.h"
14 #include "base/run_loop.h"
15 #include "base/time/time.h"
16 #include "base/trace_event/trace_event.h"
17 #include "cc/test/begin_frame_args_test.h"
18 #include "cc/test/ordered_simple_task_runner.h"
19 #include "cc/test/scheduler_test_common.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \
25 EXPECT_EQ(expected_num_actions, client->num_actions_()); \
26 if (action_index >= 0) { \
27 ASSERT_LT(action_index, client->num_actions_()) << scheduler_.get(); \
28 EXPECT_STREQ(action, client->Action(action_index)); \
30 for (int i = expected_num_actions; i < client->num_actions_(); ++i) \
31 ADD_FAILURE() << "Unexpected action: " << client->Action(i) \
32 << " with state:\n" << client->StateForAction(i); \
35 #define EXPECT_NO_ACTION(client) EXPECT_ACTION("", client, -1, 0)
37 #define EXPECT_SINGLE_ACTION(action, client) \
38 EXPECT_ACTION(action, client, 0, 1)
40 #define EXPECT_SCOPED(statements) \
49 class FakeSchedulerClient
: public SchedulerClient
{
52 : automatic_swap_ack_(true),
60 draw_will_happen_
= true;
61 swap_will_happen_if_draw_happens_
= true;
63 begin_frame_args_sent_to_children_
= BeginFrameArgs();
66 void set_scheduler(TestScheduler
* scheduler
) { scheduler_
= scheduler
; }
68 bool needs_begin_frames() {
69 return scheduler_
->frame_source().NeedsBeginFrames();
71 int num_draws() const { return num_draws_
; }
72 int num_actions_() const { return static_cast<int>(actions_
.size()); }
73 const char* Action(int i
) const { return actions_
[i
]; }
74 std::string
StateForAction(int i
) const { return states_
[i
]->ToString(); }
75 base::TimeTicks
posted_begin_impl_frame_deadline() const {
76 return posted_begin_impl_frame_deadline_
;
79 int ActionIndex(const char* action
) const {
80 for (size_t i
= 0; i
< actions_
.size(); i
++)
81 if (!strcmp(actions_
[i
], action
))
82 return base::checked_cast
<int>(i
);
86 bool HasAction(const char* action
) const {
87 return ActionIndex(action
) >= 0;
90 void SetDrawWillHappen(bool draw_will_happen
) {
91 draw_will_happen_
= draw_will_happen
;
93 void SetSwapWillHappenIfDrawHappens(bool swap_will_happen_if_draw_happens
) {
94 swap_will_happen_if_draw_happens_
= swap_will_happen_if_draw_happens
;
96 void SetAutomaticSwapAck(bool automatic_swap_ack
) {
97 automatic_swap_ack_
= automatic_swap_ack
;
99 // SchedulerClient implementation.
100 void WillBeginImplFrame(const BeginFrameArgs
& args
) override
{
101 PushAction("WillBeginImplFrame");
103 void DidFinishImplFrame() override
{}
105 void ScheduledActionSendBeginMainFrame() override
{
106 PushAction("ScheduledActionSendBeginMainFrame");
108 void ScheduledActionAnimate() override
{
109 PushAction("ScheduledActionAnimate");
111 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
112 PushAction("ScheduledActionDrawAndSwapIfPossible");
115 draw_will_happen_
? DRAW_SUCCESS
: DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
116 bool swap_will_happen
=
117 draw_will_happen_
&& swap_will_happen_if_draw_happens_
;
118 if (swap_will_happen
) {
119 scheduler_
->DidSwapBuffers();
121 if (automatic_swap_ack_
)
122 scheduler_
->DidSwapBuffersComplete();
126 DrawResult
ScheduledActionDrawAndSwapForced() override
{
127 PushAction("ScheduledActionDrawAndSwapForced");
130 void ScheduledActionCommit() override
{
131 PushAction("ScheduledActionCommit");
132 scheduler_
->DidCommit();
134 void ScheduledActionActivateSyncTree() override
{
135 PushAction("ScheduledActionActivateSyncTree");
137 void ScheduledActionBeginOutputSurfaceCreation() override
{
138 PushAction("ScheduledActionBeginOutputSurfaceCreation");
140 void ScheduledActionPrepareTiles() override
{
141 PushAction("ScheduledActionPrepareTiles");
142 scheduler_
->WillPrepareTiles();
143 scheduler_
->DidPrepareTiles();
145 void ScheduledActionInvalidateOutputSurface() override
{
146 actions_
.push_back("ScheduledActionInvalidateOutputSurface");
147 states_
.push_back(scheduler_
->AsValue());
150 void SendBeginFramesToChildren(const BeginFrameArgs
& args
) override
{
151 begin_frame_args_sent_to_children_
= args
;
154 void SendBeginMainFrameNotExpectedSoon() override
{
155 PushAction("SendBeginMainFrameNotExpectedSoon");
158 base::Callback
<bool(void)> ImplFrameDeadlinePending(bool state
) {
159 return base::Bind(&FakeSchedulerClient::ImplFrameDeadlinePendingCallback
,
160 base::Unretained(this),
164 bool begin_frame_is_sent_to_children() const {
165 return begin_frame_args_sent_to_children_
.IsValid();
168 const BeginFrameArgs
& begin_frame_args_sent_to_children() const {
169 return begin_frame_args_sent_to_children_
;
172 void PushAction(const char* description
) {
173 actions_
.push_back(description
);
174 states_
.push_back(scheduler_
->AsValue());
178 bool ImplFrameDeadlinePendingCallback(bool state
) {
179 return scheduler_
->BeginImplFrameDeadlinePending() == state
;
182 bool draw_will_happen_
;
183 bool swap_will_happen_if_draw_happens_
;
184 bool automatic_swap_ack_
;
186 BeginFrameArgs begin_frame_args_sent_to_children_
;
187 base::TimeTicks posted_begin_impl_frame_deadline_
;
188 std::vector
<const char*> actions_
;
189 std::vector
<scoped_refptr
<base::trace_event::ConvertableToTraceFormat
>>
191 TestScheduler
* scheduler_
;
194 class FakeExternalBeginFrameSource
: public BeginFrameSourceBase
{
196 explicit FakeExternalBeginFrameSource(FakeSchedulerClient
* client
)
198 ~FakeExternalBeginFrameSource() override
{}
200 void OnNeedsBeginFramesChange(bool needs_begin_frames
) override
{
201 if (needs_begin_frames
) {
202 client_
->PushAction("SetNeedsBeginFrames(true)");
204 client_
->PushAction("SetNeedsBeginFrames(false)");
208 void TestOnBeginFrame(const BeginFrameArgs
& args
) {
209 return CallOnBeginFrame(args
);
213 FakeSchedulerClient
* client_
;
216 class SchedulerTest
: public testing::Test
{
219 : now_src_(new base::SimpleTestTickClock()),
220 task_runner_(new OrderedSimpleTaskRunner(now_src_
.get(), true)),
221 fake_external_begin_frame_source_(nullptr) {
222 now_src_
->Advance(base::TimeDelta::FromMicroseconds(10000));
223 // A bunch of tests require NowTicks()
224 // to be > BeginFrameArgs::DefaultInterval()
225 now_src_
->Advance(base::TimeDelta::FromMilliseconds(100));
226 // Fail if we need to run 100 tasks in a row.
227 task_runner_
->SetRunTaskLimit(100);
230 ~SchedulerTest() override
{}
233 TestScheduler
* CreateScheduler() {
234 if (scheduler_settings_
.use_external_begin_frame_source
) {
235 fake_external_begin_frame_source_
.reset(
236 new FakeExternalBeginFrameSource(client_
.get()));
239 scoped_ptr
<FakeCompositorTimingHistory
> fake_compositor_timing_history
=
240 FakeCompositorTimingHistory::Create();
241 fake_compositor_timing_history_
= fake_compositor_timing_history
.get();
243 scheduler_
= TestScheduler::Create(
244 now_src_
.get(), client_
.get(), scheduler_settings_
, 0,
245 task_runner_
.get(), fake_external_begin_frame_source_
.get(),
246 fake_compositor_timing_history
.Pass());
248 client_
->set_scheduler(scheduler_
.get());
250 // Use large estimates by default to avoid latency recovery
252 base::TimeDelta slow_duration
= base::TimeDelta::FromSeconds(1);
253 fake_compositor_timing_history_
->SetAllEstimatesTo(slow_duration
);
255 return scheduler_
.get();
258 void CreateSchedulerAndInitSurface() {
260 EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit());
263 void SetUpScheduler(bool initSurface
) {
264 SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient
), initSurface
);
267 void SetUpScheduler(scoped_ptr
<FakeSchedulerClient
> client
,
269 client_
= client
.Pass();
271 CreateSchedulerAndInitSurface();
276 OrderedSimpleTaskRunner
& task_runner() { return *task_runner_
; }
277 base::SimpleTestTickClock
* now_src() { return now_src_
.get(); }
279 // As this function contains EXPECT macros, to allow debugging it should be
280 // called inside EXPECT_SCOPED like so;
281 // EXPECT_SCOPED(client.InitializeOutputSurfaceAndFirstCommit(scheduler));
282 void InitializeOutputSurfaceAndFirstCommit() {
284 "SchedulerUnitTest::InitializeOutputSurfaceAndFirstCommit");
287 // Check the client doesn't have any actions queued when calling this
289 EXPECT_NO_ACTION(client_
);
290 EXPECT_FALSE(client_
->needs_begin_frames());
292 // Start the initial output surface creation.
293 EXPECT_FALSE(scheduler_
->CanStart());
294 scheduler_
->SetCanStart();
295 scheduler_
->SetVisible(true);
296 scheduler_
->SetCanDraw(true);
297 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
);
301 // We don't see anything happening until the first impl frame.
302 scheduler_
->DidCreateAndInitializeOutputSurface();
303 scheduler_
->SetNeedsBeginMainFrame();
304 EXPECT_TRUE(client_
->needs_begin_frames());
305 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
309 SCOPED_TRACE("Do first frame to commit after initialize.");
312 scheduler_
->NotifyBeginMainFrameStarted();
313 scheduler_
->NotifyReadyToCommit();
314 scheduler_
->NotifyReadyToActivate();
315 scheduler_
->NotifyReadyToDraw();
317 EXPECT_FALSE(scheduler_
->CommitPending());
319 if (scheduler_settings_
.using_synchronous_renderer_compositor
) {
320 scheduler_
->SetNeedsRedraw();
321 scheduler_
->OnDrawForOutputSurface();
323 // Run the posted deadline task.
324 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
325 task_runner_
->RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
328 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
335 "Run second frame so Scheduler calls SetNeedsBeginFrame(false).");
338 if (!scheduler_settings_
.using_synchronous_renderer_compositor
) {
339 // Run the posted deadline task.
340 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
341 task_runner_
->RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
344 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
347 EXPECT_FALSE(client_
->needs_begin_frames());
351 // As this function contains EXPECT macros, to allow debugging it should be
352 // called inside EXPECT_SCOPED like so;
353 // EXPECT_SCOPED(client.AdvanceFrame());
354 void AdvanceFrame() {
355 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
356 "FakeSchedulerClient::AdvanceFrame");
357 // Consume any previous deadline first, if no deadline is currently
358 // pending, ImplFrameDeadlinePending will return false straight away and we
359 // will run no tasks.
360 task_runner_
->RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
361 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
363 // Send the next BeginFrame message if using an external source, otherwise
364 // it will be already in the task queue.
365 if (scheduler_
->settings().use_external_begin_frame_source
&&
366 scheduler_
->FrameProductionThrottled()) {
367 EXPECT_TRUE(client_
->needs_begin_frames());
368 SendNextBeginFrame();
371 if (!scheduler_
->settings().using_synchronous_renderer_compositor
) {
372 // Then run tasks until new deadline is scheduled.
373 EXPECT_TRUE(task_runner_
->RunTasksWhile(
374 client_
->ImplFrameDeadlinePending(false)));
375 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
379 BeginFrameArgs
SendNextBeginFrame() {
380 DCHECK(scheduler_
->settings().use_external_begin_frame_source
);
381 // Creep the time forward so that any BeginFrameArgs is not equal to the
382 // last one otherwise we violate the BeginFrameSource contract.
383 now_src_
->Advance(BeginFrameArgs::DefaultInterval());
384 BeginFrameArgs args
=
385 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
386 fake_external_begin_frame_source_
->TestOnBeginFrame(args
);
390 FakeExternalBeginFrameSource
* fake_external_begin_frame_source() const {
391 return fake_external_begin_frame_source_
.get();
394 void CheckMainFrameSkippedAfterLateCommit(bool expect_send_begin_main_frame
);
395 void ImplFrameSkippedAfterLateSwapAck(bool swap_ack_before_deadline
);
396 void ImplFrameIsNotSkippedAfterLateSwapAck();
397 void BeginFramesNotFromClient(bool use_external_begin_frame_source
,
398 bool throttle_frame_production
);
399 void BeginFramesNotFromClient_SwapThrottled(
400 bool use_external_begin_frame_source
,
401 bool throttle_frame_production
);
403 scoped_ptr
<base::SimpleTestTickClock
> now_src_
;
404 scoped_refptr
<OrderedSimpleTaskRunner
> task_runner_
;
405 scoped_ptr
<FakeExternalBeginFrameSource
> fake_external_begin_frame_source_
;
406 SchedulerSettings scheduler_settings_
;
407 scoped_ptr
<FakeSchedulerClient
> client_
;
408 scoped_ptr
<TestScheduler
> scheduler_
;
409 FakeCompositorTimingHistory
* fake_compositor_timing_history_
;
412 TEST_F(SchedulerTest
, InitializeOutputSurfaceDoesNotBeginImplFrame
) {
413 scheduler_settings_
.use_external_begin_frame_source
= true;
414 SetUpScheduler(false);
415 scheduler_
->SetCanStart();
416 scheduler_
->SetVisible(true);
417 scheduler_
->SetCanDraw(true);
419 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
);
421 scheduler_
->DidCreateAndInitializeOutputSurface();
422 EXPECT_NO_ACTION(client_
);
425 TEST_F(SchedulerTest
, SendBeginFramesToChildren
) {
426 scheduler_settings_
.use_external_begin_frame_source
= true;
427 SetUpScheduler(true);
429 EXPECT_FALSE(client_
->begin_frame_is_sent_to_children());
430 scheduler_
->SetNeedsBeginMainFrame();
431 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
432 EXPECT_TRUE(client_
->needs_begin_frames());
434 scheduler_
->SetChildrenNeedBeginFrames(true);
437 EXPECT_SCOPED(AdvanceFrame());
438 EXPECT_TRUE(client_
->begin_frame_is_sent_to_children());
439 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
440 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
441 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
442 EXPECT_TRUE(client_
->needs_begin_frames());
445 TEST_F(SchedulerTest
, SendBeginFramesToChildrenWithoutCommit
) {
446 scheduler_settings_
.use_external_begin_frame_source
= true;
447 SetUpScheduler(true);
449 EXPECT_FALSE(client_
->needs_begin_frames());
450 scheduler_
->SetChildrenNeedBeginFrames(true);
451 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
452 EXPECT_TRUE(client_
->needs_begin_frames());
455 EXPECT_SCOPED(AdvanceFrame());
456 EXPECT_TRUE(client_
->begin_frame_is_sent_to_children());
459 TEST_F(SchedulerTest
, SendBeginFramesToChildrenDeadlineNotAdjusted
) {
460 // Set up client with specified estimates.
461 scheduler_settings_
.use_external_begin_frame_source
= true;
462 SetUpScheduler(true);
464 fake_compositor_timing_history_
->SetBeginMainFrameToCommitDurationEstimate(
465 base::TimeDelta::FromMilliseconds(2));
466 fake_compositor_timing_history_
->SetCommitToReadyToActivateDurationEstimate(
467 base::TimeDelta::FromMilliseconds(4));
468 fake_compositor_timing_history_
->SetDrawDurationEstimate(
469 base::TimeDelta::FromMilliseconds(1));
471 EXPECT_FALSE(client_
->needs_begin_frames());
472 scheduler_
->SetChildrenNeedBeginFrames(true);
473 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
474 EXPECT_TRUE(client_
->needs_begin_frames());
478 BeginFrameArgs frame_args
=
479 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
480 fake_external_begin_frame_source()->TestOnBeginFrame(frame_args
);
482 EXPECT_TRUE(client_
->begin_frame_is_sent_to_children());
483 EXPECT_EQ(client_
->begin_frame_args_sent_to_children().deadline
,
484 frame_args
.deadline
);
487 TEST_F(SchedulerTest
, VideoNeedsBeginFrames
) {
488 scheduler_settings_
.use_external_begin_frame_source
= true;
489 SetUpScheduler(true);
491 scheduler_
->SetVideoNeedsBeginFrames(true);
492 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
493 EXPECT_TRUE(client_
->needs_begin_frames());
496 EXPECT_SCOPED(AdvanceFrame());
497 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
498 // WillBeginImplFrame is responsible for sending BeginFrames to video.
499 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
502 EXPECT_SCOPED(AdvanceFrame());
503 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
504 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
507 scheduler_
->SetVideoNeedsBeginFrames(false);
508 EXPECT_NO_ACTION(client_
);
511 task_runner_
->RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
512 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
513 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
514 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
515 EXPECT_FALSE(client_
->needs_begin_frames());
518 TEST_F(SchedulerTest
, RequestCommit
) {
519 scheduler_settings_
.use_external_begin_frame_source
= true;
520 SetUpScheduler(true);
522 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
523 scheduler_
->SetNeedsBeginMainFrame();
524 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
527 EXPECT_SCOPED(AdvanceFrame());
528 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
529 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
530 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
531 EXPECT_TRUE(client_
->needs_begin_frames());
534 // If we don't swap on the deadline, we wait for the next BeginFrame.
535 task_runner().RunPendingTasks(); // Run posted deadline.
536 EXPECT_NO_ACTION(client_
);
537 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
538 EXPECT_TRUE(client_
->needs_begin_frames());
541 // NotifyReadyToCommit should trigger the commit.
542 scheduler_
->NotifyBeginMainFrameStarted();
543 scheduler_
->NotifyReadyToCommit();
544 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
545 EXPECT_TRUE(client_
->needs_begin_frames());
548 // NotifyReadyToActivate should trigger the activation.
549 scheduler_
->NotifyReadyToActivate();
550 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
551 EXPECT_TRUE(client_
->needs_begin_frames());
554 // BeginImplFrame should prepare the draw.
555 EXPECT_SCOPED(AdvanceFrame());
556 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
557 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
558 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
559 EXPECT_TRUE(client_
->needs_begin_frames());
562 // BeginImplFrame deadline should draw.
563 task_runner().RunPendingTasks(); // Run posted deadline.
564 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
565 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
566 EXPECT_TRUE(client_
->needs_begin_frames());
569 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
570 // to avoid excessive toggles.
571 EXPECT_SCOPED(AdvanceFrame());
572 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
573 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
576 task_runner().RunPendingTasks(); // Run posted deadline.
577 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
578 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
582 TEST_F(SchedulerTest
, RequestCommitAfterSetDeferCommit
) {
583 scheduler_settings_
.use_external_begin_frame_source
= true;
584 SetUpScheduler(true);
586 scheduler_
->SetDeferCommits(true);
588 scheduler_
->SetNeedsBeginMainFrame();
589 EXPECT_NO_ACTION(client_
);
592 task_runner().RunPendingTasks();
593 // There are no pending tasks or actions.
594 EXPECT_NO_ACTION(client_
);
595 EXPECT_FALSE(client_
->needs_begin_frames());
598 scheduler_
->SetDeferCommits(false);
599 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
601 // Start new BeginMainFrame after defer commit is off.
603 EXPECT_SCOPED(AdvanceFrame());
604 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
605 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
606 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
609 TEST_F(SchedulerTest
, DeferCommitWithRedraw
) {
610 scheduler_settings_
.use_external_begin_frame_source
= true;
611 SetUpScheduler(true);
613 scheduler_
->SetDeferCommits(true);
615 scheduler_
->SetNeedsBeginMainFrame();
616 EXPECT_NO_ACTION(client_
);
618 // The SetNeedsRedraw will override the SetDeferCommits(true), to allow a
619 // begin frame to be needed.
621 scheduler_
->SetNeedsRedraw();
622 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
626 // BeginMainFrame is not sent during the defer commit is on.
627 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
628 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
631 task_runner().RunPendingTasks(); // Run posted deadline.
632 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
633 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
634 EXPECT_TRUE(client_
->needs_begin_frames());
638 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
641 TEST_F(SchedulerTest
, RequestCommitAfterBeginMainFrameSent
) {
642 scheduler_settings_
.use_external_begin_frame_source
= true;
643 SetUpScheduler(true);
645 // SetNeedsBeginMainFrame should begin the frame.
646 scheduler_
->SetNeedsBeginMainFrame();
647 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
650 EXPECT_SCOPED(AdvanceFrame());
651 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
652 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
653 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
655 EXPECT_TRUE(client_
->needs_begin_frames());
658 // Now SetNeedsBeginMainFrame again. Calling here means we need a second
660 scheduler_
->SetNeedsBeginMainFrame();
661 EXPECT_EQ(client_
->num_actions_(), 0);
664 // Finish the first commit.
665 scheduler_
->NotifyBeginMainFrameStarted();
666 scheduler_
->NotifyReadyToCommit();
667 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
668 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
672 scheduler_
->NotifyReadyToActivate();
673 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
674 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
677 task_runner().RunPendingTasks(); // Run posted deadline.
678 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
679 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
680 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
682 // Because we just swapped, the Scheduler should also request the next
683 // BeginImplFrame from the OutputSurface.
684 EXPECT_TRUE(client_
->needs_begin_frames());
686 // Since another commit is needed, the next BeginImplFrame should initiate
687 // the second commit.
688 EXPECT_SCOPED(AdvanceFrame());
689 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
690 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
691 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
694 // Finishing the commit before the deadline should post a new deadline task
695 // to trigger the deadline early.
696 scheduler_
->NotifyBeginMainFrameStarted();
697 scheduler_
->NotifyReadyToCommit();
698 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
699 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
701 scheduler_
->NotifyReadyToActivate();
702 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
703 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
705 task_runner().RunPendingTasks(); // Run posted deadline.
706 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
707 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
708 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
709 EXPECT_TRUE(client_
->needs_begin_frames());
712 // On the next BeginImplFrame, verify we go back to a quiescent state and
713 // no longer request BeginImplFrames.
714 EXPECT_SCOPED(AdvanceFrame());
715 task_runner().RunPendingTasks(); // Run posted deadline.
716 EXPECT_FALSE(client_
->needs_begin_frames());
720 class SchedulerClientThatsetNeedsDrawInsideDraw
: public FakeSchedulerClient
{
722 SchedulerClientThatsetNeedsDrawInsideDraw()
723 : FakeSchedulerClient(), request_redraws_(false) {}
725 void SetRequestRedrawsInsideDraw(bool enable
) { request_redraws_
= enable
; }
727 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
728 // Only SetNeedsRedraw the first time this is called
729 if (request_redraws_
) {
730 scheduler_
->SetNeedsRedraw();
732 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
735 DrawResult
ScheduledActionDrawAndSwapForced() override
{
741 bool request_redraws_
;
744 // Tests for two different situations:
745 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside
746 // a ScheduledActionDrawAndSwap
747 // 2. the scheduler drawing twice inside a single tick
748 TEST_F(SchedulerTest
, RequestRedrawInsideDraw
) {
749 SchedulerClientThatsetNeedsDrawInsideDraw
* client
=
750 new SchedulerClientThatsetNeedsDrawInsideDraw
;
751 scheduler_settings_
.use_external_begin_frame_source
= true;
752 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
753 client
->SetRequestRedrawsInsideDraw(true);
755 scheduler_
->SetNeedsRedraw();
756 EXPECT_TRUE(scheduler_
->RedrawPending());
757 EXPECT_TRUE(client
->needs_begin_frames());
758 EXPECT_EQ(0, client
->num_draws());
760 EXPECT_SCOPED(AdvanceFrame());
761 task_runner().RunPendingTasks(); // Run posted deadline.
762 EXPECT_EQ(1, client
->num_draws());
763 EXPECT_TRUE(scheduler_
->RedrawPending());
764 EXPECT_TRUE(client
->needs_begin_frames());
766 client
->SetRequestRedrawsInsideDraw(false);
768 EXPECT_SCOPED(AdvanceFrame());
769 task_runner().RunPendingTasks(); // Run posted deadline.
770 EXPECT_EQ(2, client_
->num_draws());
771 EXPECT_FALSE(scheduler_
->RedrawPending());
772 EXPECT_TRUE(client
->needs_begin_frames());
774 // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
776 EXPECT_SCOPED(AdvanceFrame());
777 task_runner().RunPendingTasks(); // Run posted deadline.
778 EXPECT_EQ(2, client
->num_draws());
779 EXPECT_FALSE(scheduler_
->RedrawPending());
780 EXPECT_FALSE(client
->needs_begin_frames());
783 // Test that requesting redraw inside a failed draw doesn't lose the request.
784 TEST_F(SchedulerTest
, RequestRedrawInsideFailedDraw
) {
785 SchedulerClientThatsetNeedsDrawInsideDraw
* client
=
786 new SchedulerClientThatsetNeedsDrawInsideDraw
;
787 scheduler_settings_
.use_external_begin_frame_source
= true;
788 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
790 client
->SetRequestRedrawsInsideDraw(true);
791 client
->SetDrawWillHappen(false);
793 scheduler_
->SetNeedsRedraw();
794 EXPECT_TRUE(scheduler_
->RedrawPending());
795 EXPECT_TRUE(client
->needs_begin_frames());
796 EXPECT_EQ(0, client
->num_draws());
799 EXPECT_SCOPED(AdvanceFrame());
800 task_runner().RunPendingTasks(); // Run posted deadline.
801 EXPECT_EQ(1, client
->num_draws());
803 // We have a commit pending and the draw failed, and we didn't lose the redraw
805 EXPECT_TRUE(scheduler_
->CommitPending());
806 EXPECT_TRUE(scheduler_
->RedrawPending());
807 EXPECT_TRUE(client
->needs_begin_frames());
809 client
->SetRequestRedrawsInsideDraw(false);
811 // Fail the draw again.
812 EXPECT_SCOPED(AdvanceFrame());
813 task_runner().RunPendingTasks(); // Run posted deadline.
814 EXPECT_EQ(2, client
->num_draws());
815 EXPECT_TRUE(scheduler_
->CommitPending());
816 EXPECT_TRUE(scheduler_
->RedrawPending());
817 EXPECT_TRUE(client
->needs_begin_frames());
819 // Draw successfully.
820 client
->SetDrawWillHappen(true);
821 EXPECT_SCOPED(AdvanceFrame());
822 task_runner().RunPendingTasks(); // Run posted deadline.
823 EXPECT_EQ(3, client
->num_draws());
824 EXPECT_TRUE(scheduler_
->CommitPending());
825 EXPECT_FALSE(scheduler_
->RedrawPending());
826 EXPECT_TRUE(client
->needs_begin_frames());
829 class SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
830 : public FakeSchedulerClient
{
832 SchedulerClientThatSetNeedsBeginMainFrameInsideDraw()
833 : set_needs_commit_on_next_draw_(false) {}
835 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
836 // Only SetNeedsBeginMainFrame the first time this is called
837 if (set_needs_commit_on_next_draw_
) {
838 scheduler_
->SetNeedsBeginMainFrame();
839 set_needs_commit_on_next_draw_
= false;
841 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
844 DrawResult
ScheduledActionDrawAndSwapForced() override
{
849 void SetNeedsBeginMainFrameOnNextDraw() {
850 set_needs_commit_on_next_draw_
= true;
854 bool set_needs_commit_on_next_draw_
;
857 // Tests for the scheduler infinite-looping on SetNeedsBeginMainFrame requests
858 // that happen inside a ScheduledActionDrawAndSwap
859 TEST_F(SchedulerTest
, RequestCommitInsideDraw
) {
860 SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
* client
=
861 new SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
;
863 scheduler_settings_
.use_external_begin_frame_source
= true;
864 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
866 EXPECT_FALSE(client
->needs_begin_frames());
867 scheduler_
->SetNeedsRedraw();
868 EXPECT_TRUE(scheduler_
->RedrawPending());
869 EXPECT_EQ(0, client
->num_draws());
870 EXPECT_TRUE(client
->needs_begin_frames());
872 client
->SetNeedsBeginMainFrameOnNextDraw();
873 EXPECT_SCOPED(AdvanceFrame());
874 client
->SetNeedsBeginMainFrameOnNextDraw();
875 task_runner().RunPendingTasks(); // Run posted deadline.
876 EXPECT_EQ(1, client
->num_draws());
877 EXPECT_TRUE(scheduler_
->CommitPending());
878 EXPECT_TRUE(client
->needs_begin_frames());
879 scheduler_
->NotifyBeginMainFrameStarted();
880 scheduler_
->NotifyReadyToCommit();
881 scheduler_
->NotifyReadyToActivate();
883 EXPECT_SCOPED(AdvanceFrame());
884 task_runner().RunPendingTasks(); // Run posted deadline.
885 EXPECT_EQ(2, client
->num_draws());
887 EXPECT_FALSE(scheduler_
->RedrawPending());
888 EXPECT_FALSE(scheduler_
->CommitPending());
889 EXPECT_TRUE(client
->needs_begin_frames());
891 // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
893 EXPECT_SCOPED(AdvanceFrame());
894 task_runner().RunPendingTasks(); // Run posted deadline.
895 EXPECT_EQ(2, client
->num_draws());
896 EXPECT_FALSE(scheduler_
->RedrawPending());
897 EXPECT_FALSE(scheduler_
->CommitPending());
898 EXPECT_FALSE(client
->needs_begin_frames());
901 // Tests that when a draw fails then the pending commit should not be dropped.
902 TEST_F(SchedulerTest
, RequestCommitInsideFailedDraw
) {
903 SchedulerClientThatsetNeedsDrawInsideDraw
* client
=
904 new SchedulerClientThatsetNeedsDrawInsideDraw
;
905 scheduler_settings_
.use_external_begin_frame_source
= true;
906 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
908 client
->SetDrawWillHappen(false);
910 scheduler_
->SetNeedsRedraw();
911 EXPECT_TRUE(scheduler_
->RedrawPending());
912 EXPECT_TRUE(client
->needs_begin_frames());
913 EXPECT_EQ(0, client
->num_draws());
916 EXPECT_SCOPED(AdvanceFrame());
917 task_runner().RunPendingTasks(); // Run posted deadline.
918 EXPECT_EQ(1, client
->num_draws());
920 // We have a commit pending and the draw failed, and we didn't lose the commit
922 EXPECT_TRUE(scheduler_
->CommitPending());
923 EXPECT_TRUE(scheduler_
->RedrawPending());
924 EXPECT_TRUE(client
->needs_begin_frames());
926 // Fail the draw again.
927 EXPECT_SCOPED(AdvanceFrame());
929 task_runner().RunPendingTasks(); // Run posted deadline.
930 EXPECT_EQ(2, client
->num_draws());
931 EXPECT_TRUE(scheduler_
->CommitPending());
932 EXPECT_TRUE(scheduler_
->RedrawPending());
933 EXPECT_TRUE(client
->needs_begin_frames());
935 // Draw successfully.
936 client
->SetDrawWillHappen(true);
937 EXPECT_SCOPED(AdvanceFrame());
938 task_runner().RunPendingTasks(); // Run posted deadline.
939 EXPECT_EQ(3, client
->num_draws());
940 EXPECT_TRUE(scheduler_
->CommitPending());
941 EXPECT_FALSE(scheduler_
->RedrawPending());
942 EXPECT_TRUE(client
->needs_begin_frames());
945 TEST_F(SchedulerTest
, NoSwapWhenDrawFails
) {
946 SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
* client
=
947 new SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
;
948 scheduler_settings_
.use_external_begin_frame_source
= true;
949 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
951 scheduler_
->SetNeedsRedraw();
952 EXPECT_TRUE(scheduler_
->RedrawPending());
953 EXPECT_TRUE(client
->needs_begin_frames());
954 EXPECT_EQ(0, client
->num_draws());
956 // Draw successfully, this starts a new frame.
957 client
->SetNeedsBeginMainFrameOnNextDraw();
958 EXPECT_SCOPED(AdvanceFrame());
959 task_runner().RunPendingTasks(); // Run posted deadline.
960 EXPECT_EQ(1, client
->num_draws());
962 scheduler_
->SetNeedsRedraw();
963 EXPECT_TRUE(scheduler_
->RedrawPending());
964 EXPECT_TRUE(client
->needs_begin_frames());
966 // Fail to draw, this should not start a frame.
967 client
->SetDrawWillHappen(false);
968 client
->SetNeedsBeginMainFrameOnNextDraw();
969 EXPECT_SCOPED(AdvanceFrame());
970 task_runner().RunPendingTasks(); // Run posted deadline.
971 EXPECT_EQ(2, client
->num_draws());
974 class SchedulerClientNeedsPrepareTilesInDraw
: public FakeSchedulerClient
{
976 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
977 scheduler_
->SetNeedsPrepareTiles();
978 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
982 // Test prepare tiles is independant of draws.
983 TEST_F(SchedulerTest
, PrepareTiles
) {
984 SchedulerClientNeedsPrepareTilesInDraw
* client
=
985 new SchedulerClientNeedsPrepareTilesInDraw
;
986 scheduler_settings_
.use_external_begin_frame_source
= true;
987 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
989 // Request both draw and prepare tiles. PrepareTiles shouldn't
990 // be trigged until BeginImplFrame.
992 scheduler_
->SetNeedsPrepareTiles();
993 scheduler_
->SetNeedsRedraw();
994 EXPECT_TRUE(scheduler_
->RedrawPending());
995 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
996 EXPECT_TRUE(client
->needs_begin_frames());
997 EXPECT_EQ(0, client
->num_draws());
998 EXPECT_FALSE(client
->HasAction("ScheduledActionPrepareTiles"));
999 EXPECT_FALSE(client
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1001 // We have no immediate actions to perform, so the BeginImplFrame should post
1002 // the deadline task.
1004 EXPECT_SCOPED(AdvanceFrame());
1005 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1006 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1007 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1009 // On the deadline, he actions should have occured in the right order.
1011 task_runner().RunPendingTasks(); // Run posted deadline.
1012 EXPECT_EQ(1, client
->num_draws());
1013 EXPECT_TRUE(client
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1014 EXPECT_TRUE(client
->HasAction("ScheduledActionPrepareTiles"));
1015 EXPECT_LT(client
->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
1016 client
->ActionIndex("ScheduledActionPrepareTiles"));
1017 EXPECT_FALSE(scheduler_
->RedrawPending());
1018 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1019 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1021 // Request a draw. We don't need a PrepareTiles yet.
1023 scheduler_
->SetNeedsRedraw();
1024 EXPECT_TRUE(scheduler_
->RedrawPending());
1025 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1026 EXPECT_TRUE(client
->needs_begin_frames());
1027 EXPECT_EQ(0, client
->num_draws());
1029 // We have no immediate actions to perform, so the BeginImplFrame should post
1030 // the deadline task.
1032 EXPECT_SCOPED(AdvanceFrame());
1033 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1034 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1035 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1037 // Draw. The draw will trigger SetNeedsPrepareTiles, and
1038 // then the PrepareTiles action will be triggered after the Draw.
1039 // Afterwards, neither a draw nor PrepareTiles are pending.
1041 task_runner().RunPendingTasks(); // Run posted deadline.
1042 EXPECT_EQ(1, client
->num_draws());
1043 EXPECT_TRUE(client
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1044 EXPECT_TRUE(client
->HasAction("ScheduledActionPrepareTiles"));
1045 EXPECT_LT(client
->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
1046 client
->ActionIndex("ScheduledActionPrepareTiles"));
1047 EXPECT_FALSE(scheduler_
->RedrawPending());
1048 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1049 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1051 // We need a BeginImplFrame where we don't swap to go idle.
1053 EXPECT_SCOPED(AdvanceFrame());
1054 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
1055 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1057 task_runner().RunPendingTasks(); // Run posted deadline.
1058 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
1059 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
1060 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1061 EXPECT_EQ(0, client
->num_draws());
1063 // Now trigger a PrepareTiles outside of a draw. We will then need
1064 // a begin-frame for the PrepareTiles, but we don't need a draw.
1066 EXPECT_FALSE(client
->needs_begin_frames());
1067 scheduler_
->SetNeedsPrepareTiles();
1068 EXPECT_TRUE(client
->needs_begin_frames());
1069 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
1070 EXPECT_FALSE(scheduler_
->RedrawPending());
1072 // BeginImplFrame. There will be no draw, only PrepareTiles.
1074 EXPECT_SCOPED(AdvanceFrame());
1075 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
1076 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1078 task_runner().RunPendingTasks(); // Run posted deadline.
1079 EXPECT_EQ(0, client
->num_draws());
1080 EXPECT_FALSE(client
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1081 EXPECT_TRUE(client
->HasAction("ScheduledActionPrepareTiles"));
1082 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1085 // Test that PrepareTiles only happens once per frame. If an external caller
1086 // initiates it, then the state machine should not PrepareTiles on that frame.
1087 TEST_F(SchedulerTest
, PrepareTilesOncePerFrame
) {
1088 scheduler_settings_
.use_external_begin_frame_source
= true;
1089 SetUpScheduler(true);
1091 // If DidPrepareTiles during a frame, then PrepareTiles should not occur
1093 scheduler_
->SetNeedsPrepareTiles();
1094 scheduler_
->SetNeedsRedraw();
1096 EXPECT_SCOPED(AdvanceFrame());
1097 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1098 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1099 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1101 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
1102 scheduler_
->WillPrepareTiles();
1103 scheduler_
->DidPrepareTiles(); // An explicit PrepareTiles.
1104 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1107 task_runner().RunPendingTasks(); // Run posted deadline.
1108 EXPECT_EQ(1, client_
->num_draws());
1109 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1110 EXPECT_FALSE(client_
->HasAction("ScheduledActionPrepareTiles"));
1111 EXPECT_FALSE(scheduler_
->RedrawPending());
1112 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1113 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1115 // Next frame without DidPrepareTiles should PrepareTiles with draw.
1116 scheduler_
->SetNeedsPrepareTiles();
1117 scheduler_
->SetNeedsRedraw();
1119 EXPECT_SCOPED(AdvanceFrame());
1120 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1121 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1122 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1125 task_runner().RunPendingTasks(); // Run posted deadline.
1126 EXPECT_EQ(1, client_
->num_draws());
1127 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1128 EXPECT_TRUE(client_
->HasAction("ScheduledActionPrepareTiles"));
1129 EXPECT_LT(client_
->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
1130 client_
->ActionIndex("ScheduledActionPrepareTiles"));
1131 EXPECT_FALSE(scheduler_
->RedrawPending());
1132 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1133 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1135 // If we get another DidPrepareTiles within the same frame, we should
1136 // not PrepareTiles on the next frame.
1137 scheduler_
->WillPrepareTiles();
1138 scheduler_
->DidPrepareTiles(); // An explicit PrepareTiles.
1139 scheduler_
->SetNeedsPrepareTiles();
1140 scheduler_
->SetNeedsRedraw();
1142 EXPECT_SCOPED(AdvanceFrame());
1143 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1144 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1145 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1147 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
1150 task_runner().RunPendingTasks(); // Run posted deadline.
1151 EXPECT_EQ(1, client_
->num_draws());
1152 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1153 EXPECT_FALSE(client_
->HasAction("ScheduledActionPrepareTiles"));
1154 EXPECT_FALSE(scheduler_
->RedrawPending());
1155 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1157 // If we get another DidPrepareTiles, we should not PrepareTiles on the next
1158 // frame. This verifies we don't alternate calling PrepareTiles once and
1160 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
1161 scheduler_
->WillPrepareTiles();
1162 scheduler_
->DidPrepareTiles(); // An explicit PrepareTiles.
1163 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1164 scheduler_
->SetNeedsPrepareTiles();
1165 scheduler_
->SetNeedsRedraw();
1167 EXPECT_SCOPED(AdvanceFrame());
1168 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1169 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1170 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1172 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
1175 task_runner().RunPendingTasks(); // Run posted deadline.
1176 EXPECT_EQ(1, client_
->num_draws());
1177 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1178 EXPECT_FALSE(client_
->HasAction("ScheduledActionPrepareTiles"));
1179 EXPECT_FALSE(scheduler_
->RedrawPending());
1180 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1182 // Next frame without DidPrepareTiles should PrepareTiles with draw.
1183 scheduler_
->SetNeedsPrepareTiles();
1184 scheduler_
->SetNeedsRedraw();
1186 EXPECT_SCOPED(AdvanceFrame());
1187 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1188 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1189 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1192 task_runner().RunPendingTasks(); // Run posted deadline.
1193 EXPECT_EQ(1, client_
->num_draws());
1194 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1195 EXPECT_TRUE(client_
->HasAction("ScheduledActionPrepareTiles"));
1196 EXPECT_LT(client_
->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
1197 client_
->ActionIndex("ScheduledActionPrepareTiles"));
1198 EXPECT_FALSE(scheduler_
->RedrawPending());
1199 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1200 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1203 TEST_F(SchedulerTest
, PrepareTilesFunnelResetOnVisibilityChange
) {
1204 scoped_ptr
<SchedulerClientNeedsPrepareTilesInDraw
> client
=
1205 make_scoped_ptr(new SchedulerClientNeedsPrepareTilesInDraw
);
1206 scheduler_settings_
.use_external_begin_frame_source
= true;
1207 SetUpScheduler(client
.Pass(), true);
1209 // Simulate a few visibility changes and associated PrepareTiles.
1210 for (int i
= 0; i
< 10; i
++) {
1211 scheduler_
->SetVisible(false);
1212 scheduler_
->WillPrepareTiles();
1213 scheduler_
->DidPrepareTiles();
1215 scheduler_
->SetVisible(true);
1216 scheduler_
->WillPrepareTiles();
1217 scheduler_
->DidPrepareTiles();
1221 scheduler_
->SetNeedsRedraw();
1222 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
1226 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1227 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1228 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1231 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1232 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1233 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 2);
1234 EXPECT_ACTION("ScheduledActionPrepareTiles", client_
, 1, 2);
1237 TEST_F(SchedulerTest
, TriggerBeginFrameDeadlineEarly
) {
1238 SchedulerClientNeedsPrepareTilesInDraw
* client
=
1239 new SchedulerClientNeedsPrepareTilesInDraw
;
1240 scheduler_settings_
.use_external_begin_frame_source
= true;
1241 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
1243 scheduler_
->SetNeedsRedraw();
1244 EXPECT_SCOPED(AdvanceFrame());
1246 // The deadline should be zero since there is no work other than drawing
1248 EXPECT_EQ(base::TimeTicks(), client
->posted_begin_impl_frame_deadline());
1251 TEST_F(SchedulerTest
, WaitForReadyToDrawDoNotPostDeadline
) {
1252 SchedulerClientNeedsPrepareTilesInDraw
* client
=
1253 new SchedulerClientNeedsPrepareTilesInDraw
;
1254 scheduler_settings_
.use_external_begin_frame_source
= true;
1255 scheduler_settings_
.commit_to_active_tree
= true;
1256 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
1258 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
1259 scheduler_
->SetNeedsBeginMainFrame();
1260 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
1264 EXPECT_SCOPED(AdvanceFrame());
1265 scheduler_
->NotifyBeginMainFrameStarted();
1266 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1267 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
1270 scheduler_
->NotifyReadyToCommit();
1271 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
1274 scheduler_
->NotifyReadyToActivate();
1275 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
1277 // Scheduler won't post deadline in the mode.
1279 task_runner().RunPendingTasks(); // Try to run posted deadline.
1280 // There is no posted deadline.
1281 EXPECT_NO_ACTION(client_
);
1283 // Scheduler received ready to draw signal, and posted deadline.
1284 scheduler_
->NotifyReadyToDraw();
1286 task_runner().RunPendingTasks(); // Run posted deadline.
1287 EXPECT_EQ(1, client_
->num_draws());
1288 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1291 TEST_F(SchedulerTest
, WaitForReadyToDrawCancelledWhenLostOutputSurface
) {
1292 SchedulerClientNeedsPrepareTilesInDraw
* client
=
1293 new SchedulerClientNeedsPrepareTilesInDraw
;
1294 scheduler_settings_
.use_external_begin_frame_source
= true;
1295 scheduler_settings_
.commit_to_active_tree
= true;
1296 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
1298 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
1299 scheduler_
->SetNeedsBeginMainFrame();
1300 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
1304 EXPECT_SCOPED(AdvanceFrame());
1305 scheduler_
->NotifyBeginMainFrameStarted();
1306 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1307 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
1310 scheduler_
->NotifyReadyToCommit();
1311 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
1314 scheduler_
->NotifyReadyToActivate();
1315 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
1317 // Scheduler won't post deadline in the mode.
1319 task_runner().RunPendingTasks(); // Try to run posted deadline.
1320 // There is no posted deadline.
1321 EXPECT_NO_ACTION(client_
);
1323 // Scheduler loses output surface, and stops waiting for ready to draw signal.
1325 scheduler_
->DidLoseOutputSurface();
1326 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1327 task_runner().RunPendingTasks(); // Run posted deadline.
1328 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
1329 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
1330 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
1333 void SchedulerTest::CheckMainFrameSkippedAfterLateCommit(
1334 bool expect_send_begin_main_frame
) {
1335 // Impl thread hits deadline before commit finishes.
1336 scheduler_
->SetNeedsBeginMainFrame();
1337 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1338 EXPECT_SCOPED(AdvanceFrame());
1339 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1340 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1341 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1342 scheduler_
->NotifyBeginMainFrameStarted();
1343 scheduler_
->NotifyReadyToCommit();
1344 scheduler_
->NotifyReadyToActivate();
1345 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 5);
1346 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 5);
1347 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 5);
1348 EXPECT_ACTION("ScheduledActionCommit", client_
, 3, 5);
1349 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 4, 5);
1350 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1353 scheduler_
->SetNeedsBeginMainFrame();
1354 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1355 EXPECT_SCOPED(AdvanceFrame());
1356 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1357 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1358 EXPECT_EQ(expect_send_begin_main_frame
,
1359 scheduler_
->MainThreadMissedLastDeadline());
1360 EXPECT_EQ(expect_send_begin_main_frame
,
1361 client_
->HasAction("ScheduledActionSendBeginMainFrame"));
1364 TEST_F(SchedulerTest
, MainFrameSkippedAfterLateCommit
) {
1365 scheduler_settings_
.use_external_begin_frame_source
= true;
1366 SetUpScheduler(true);
1368 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1369 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1371 bool expect_send_begin_main_frame
= false;
1373 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1376 TEST_F(SchedulerTest
,
1377 MainFrameNotSkippedAfterLateCommitInPreferImplLatencyMode
) {
1378 scheduler_settings_
.use_external_begin_frame_source
= true;
1379 SetUpScheduler(true);
1380 scheduler_
->SetImplLatencyTakesPriority(true);
1382 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1383 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1385 bool expect_send_begin_main_frame
= true;
1387 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1390 TEST_F(SchedulerTest
,
1391 MainFrameNotSkippedAfterLateCommit_CommitEstimateTooLong
) {
1392 scheduler_settings_
.use_external_begin_frame_source
= true;
1393 SetUpScheduler(true);
1394 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1395 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1396 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1397 fake_compositor_timing_history_
->SetBeginMainFrameToCommitDurationEstimate(
1400 bool expect_send_begin_main_frame
= true;
1402 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1405 TEST_F(SchedulerTest
,
1406 MainFrameNotSkippedAfterLateCommit_ReadyToActivateEstimateTooLong
) {
1407 scheduler_settings_
.use_external_begin_frame_source
= true;
1408 SetUpScheduler(true);
1409 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1410 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1411 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1412 fake_compositor_timing_history_
->SetCommitToReadyToActivateDurationEstimate(
1415 bool expect_send_begin_main_frame
= true;
1417 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1420 TEST_F(SchedulerTest
,
1421 MainFrameNotSkippedAfterLateCommit_ActivateEstimateTooLong
) {
1422 scheduler_settings_
.use_external_begin_frame_source
= true;
1423 SetUpScheduler(true);
1424 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1425 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1426 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1427 fake_compositor_timing_history_
->SetActivateDurationEstimate(slow_duration
);
1429 bool expect_send_begin_main_frame
= true;
1431 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1434 TEST_F(SchedulerTest
, MainFrameNotSkippedAfterLateCommit_DrawEstimateTooLong
) {
1435 scheduler_settings_
.use_external_begin_frame_source
= true;
1436 SetUpScheduler(true);
1437 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1438 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1439 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1440 fake_compositor_timing_history_
->SetDrawDurationEstimate(slow_duration
);
1442 bool expect_send_begin_main_frame
= true;
1444 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1447 void SchedulerTest::ImplFrameSkippedAfterLateSwapAck(
1448 bool swap_ack_before_deadline
) {
1449 // To get into a high latency state, this test disables automatic swap acks.
1450 scheduler_
->SetMaxSwapsPending(1);
1451 client_
->SetAutomaticSwapAck(false);
1453 // Draw and swap for first BeginFrame
1455 scheduler_
->SetNeedsBeginMainFrame();
1456 scheduler_
->SetNeedsRedraw();
1457 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1458 SendNextBeginFrame();
1459 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 4);
1460 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 4);
1461 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 4);
1462 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 3, 4);
1465 scheduler_
->NotifyBeginMainFrameStarted();
1466 scheduler_
->NotifyReadyToCommit();
1467 scheduler_
->NotifyReadyToActivate();
1468 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1469 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1470 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 4);
1471 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 4);
1472 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 4);
1473 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 4);
1475 // Verify we skip every other frame if the swap ack consistently
1477 for (int i
= 0; i
< 10; i
++) {
1478 // Not calling scheduler_->DidSwapBuffersComplete() until after next
1479 // BeginImplFrame puts the impl thread in high latency mode.
1481 scheduler_
->SetNeedsBeginMainFrame();
1482 scheduler_
->SetNeedsRedraw();
1483 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1484 SendNextBeginFrame();
1485 // Verify that we skip the BeginImplFrame
1486 EXPECT_NO_ACTION(client_
);
1487 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1488 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1490 // Verify that we do not perform any actions after we are no longer
1493 if (swap_ack_before_deadline
) {
1494 // It shouldn't matter if the swap ack comes back before the deadline...
1495 scheduler_
->DidSwapBuffersComplete();
1496 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1498 // ... or after the deadline.
1499 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1500 scheduler_
->DidSwapBuffersComplete();
1502 EXPECT_NO_ACTION(client_
);
1504 // Verify that we start the next BeginImplFrame and continue normally
1505 // after having just skipped a BeginImplFrame.
1507 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1508 SendNextBeginFrame();
1509 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
1510 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
1511 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 3);
1514 scheduler_
->NotifyBeginMainFrameStarted();
1515 scheduler_
->NotifyReadyToCommit();
1516 scheduler_
->NotifyReadyToActivate();
1517 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1518 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 4);
1519 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 4);
1520 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 4);
1521 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 4);
1525 TEST_F(SchedulerTest
,
1526 ImplFrameSkippedAfterLateSwapAck_FastEstimates_SwapAckThenDeadline
) {
1527 scheduler_settings_
.use_external_begin_frame_source
= true;
1528 SetUpScheduler(true);
1530 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1531 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1533 bool swap_ack_before_deadline
= true;
1534 EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline
));
1537 TEST_F(SchedulerTest
,
1538 ImplFrameSkippedAfterLateSwapAck_FastEstimates_DeadlineThenSwapAck
) {
1539 scheduler_settings_
.use_external_begin_frame_source
= true;
1540 SetUpScheduler(true);
1542 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1543 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1545 bool swap_ack_before_deadline
= false;
1546 EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline
));
1549 TEST_F(SchedulerTest
,
1550 ImplFrameSkippedAfterLateSwapAck_ImplLatencyTakesPriority
) {
1551 scheduler_settings_
.use_external_begin_frame_source
= true;
1552 SetUpScheduler(true);
1554 // Even if every estimate related to the main thread is slow, we should
1555 // still expect to recover impl thread latency if the draw is fast and we
1556 // are in impl latency takes priority.
1557 scheduler_
->SetImplLatencyTakesPriority(true);
1558 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1559 fake_compositor_timing_history_
->SetAllEstimatesTo(slow_duration
);
1560 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1561 fake_compositor_timing_history_
->SetDrawDurationEstimate(fast_duration
);
1563 bool swap_ack_before_deadline
= false;
1564 EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline
));
1567 TEST_F(SchedulerTest
,
1568 ImplFrameSkippedAfterLateSwapAck_OnlyImplSideUpdatesExpected
) {
1569 // This tests that we recover impl thread latency when there are no commits.
1570 scheduler_settings_
.use_external_begin_frame_source
= true;
1571 SetUpScheduler(true);
1573 // To get into a high latency state, this test disables automatic swap acks.
1574 scheduler_
->SetMaxSwapsPending(1);
1575 client_
->SetAutomaticSwapAck(false);
1577 // Even if every estimate related to the main thread is slow, we should
1578 // still expect to recover impl thread latency if there are no commits from
1580 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1581 fake_compositor_timing_history_
->SetAllEstimatesTo(slow_duration
);
1582 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1583 fake_compositor_timing_history_
->SetDrawDurationEstimate(fast_duration
);
1585 // Draw and swap for first BeginFrame
1587 scheduler_
->SetNeedsRedraw();
1588 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1589 SendNextBeginFrame();
1590 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 3);
1591 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 3);
1592 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 3);
1595 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1596 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1597 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
1599 // Verify we skip every other frame if the swap ack consistently
1601 for (int i
= 0; i
< 10; i
++) {
1602 // Not calling scheduler_->DidSwapBuffersComplete() until after next
1603 // BeginImplFrame puts the impl thread in high latency mode.
1605 scheduler_
->SetNeedsRedraw();
1606 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1607 SendNextBeginFrame();
1608 // Verify that we skip the BeginImplFrame
1609 EXPECT_NO_ACTION(client_
);
1610 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1611 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1613 // Verify that we do not perform any actions after we are no longer
1616 scheduler_
->DidSwapBuffersComplete();
1617 EXPECT_NO_ACTION(client_
);
1619 // Verify that we start the next BeginImplFrame and continue normally
1620 // after having just skipped a BeginImplFrame.
1622 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1623 SendNextBeginFrame();
1624 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1625 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1628 // Deadline should be immediate.
1629 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1630 task_runner().RunUntilTime(now_src_
->NowTicks());
1631 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1632 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
1636 void SchedulerTest::ImplFrameIsNotSkippedAfterLateSwapAck() {
1637 // To get into a high latency state, this test disables automatic swap acks.
1638 scheduler_
->SetMaxSwapsPending(1);
1639 client_
->SetAutomaticSwapAck(false);
1641 // Draw and swap for first BeginFrame
1643 scheduler_
->SetNeedsBeginMainFrame();
1644 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1645 SendNextBeginFrame();
1646 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 3);
1647 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 3);
1648 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 3);
1651 scheduler_
->NotifyBeginMainFrameStarted();
1652 scheduler_
->NotifyReadyToCommit();
1653 scheduler_
->NotifyReadyToActivate();
1654 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1655 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1656 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 4);
1657 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 4);
1658 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 4);
1659 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 4);
1661 // Verify impl thread consistently operates in high latency mode
1662 // without skipping any frames.
1663 for (int i
= 0; i
< 10; i
++) {
1664 // Not calling scheduler_->DidSwapBuffersComplete() until after next frame
1665 // puts the impl thread in high latency mode.
1667 scheduler_
->SetNeedsBeginMainFrame();
1668 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1669 SendNextBeginFrame();
1670 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
1671 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1672 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1675 scheduler_
->DidSwapBuffersComplete();
1676 scheduler_
->NotifyBeginMainFrameStarted();
1677 scheduler_
->NotifyReadyToCommit();
1678 scheduler_
->NotifyReadyToActivate();
1679 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1681 // Verify that we don't skip the actions of the BeginImplFrame
1682 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 0, 5);
1683 EXPECT_ACTION("ScheduledActionCommit", client_
, 1, 5);
1684 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 2, 5);
1685 EXPECT_ACTION("ScheduledActionAnimate", client_
, 3, 5);
1686 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 4, 5);
1690 TEST_F(SchedulerTest
,
1691 ImplFrameIsNotSkippedAfterLateSwapAck_CommitEstimateTooLong
) {
1692 scheduler_settings_
.use_external_begin_frame_source
= true;
1693 SetUpScheduler(true);
1694 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1695 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1696 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1697 fake_compositor_timing_history_
->SetBeginMainFrameToCommitDurationEstimate(
1699 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1702 TEST_F(SchedulerTest
,
1703 ImplFrameIsNotSkippedAfterLateSwapAck_ReadyToActivateEstimateTooLong
) {
1704 scheduler_settings_
.use_external_begin_frame_source
= true;
1705 SetUpScheduler(true);
1706 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1707 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1708 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1709 fake_compositor_timing_history_
->SetCommitToReadyToActivateDurationEstimate(
1711 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1714 TEST_F(SchedulerTest
,
1715 ImplFrameIsNotSkippedAfterLateSwapAck_ActivateEstimateTooLong
) {
1716 scheduler_settings_
.use_external_begin_frame_source
= true;
1717 SetUpScheduler(true);
1718 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1719 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1720 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1721 fake_compositor_timing_history_
->SetActivateDurationEstimate(slow_duration
);
1722 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1725 TEST_F(SchedulerTest
,
1726 ImplFrameIsNotSkippedAfterLateSwapAck_DrawEstimateTooLong
) {
1727 scheduler_settings_
.use_external_begin_frame_source
= true;
1728 SetUpScheduler(true);
1729 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1730 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1731 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1732 fake_compositor_timing_history_
->SetDrawDurationEstimate(slow_duration
);
1733 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1736 TEST_F(SchedulerTest
,
1737 MainFrameThenImplFrameSkippedAfterLateCommitAndLateSwapAck
) {
1738 // Set up client with custom estimates.
1739 // This test starts off with expensive estimates to prevent latency recovery
1740 // initially, then lowers the estimates to enable it once both the main
1741 // and impl threads are in a high latency mode.
1742 scheduler_settings_
.use_external_begin_frame_source
= true;
1743 SetUpScheduler(true);
1745 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1746 fake_compositor_timing_history_
->SetAllEstimatesTo(slow_duration
);
1748 // To get into a high latency state, this test disables automatic swap acks.
1749 scheduler_
->SetMaxSwapsPending(1);
1750 client_
->SetAutomaticSwapAck(false);
1752 // Impl thread hits deadline before commit finishes to make
1753 // MainThreadMissedLastDeadline true
1755 scheduler_
->SetNeedsBeginMainFrame();
1756 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1757 EXPECT_SCOPED(AdvanceFrame());
1758 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1759 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1760 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1761 scheduler_
->NotifyBeginMainFrameStarted();
1762 scheduler_
->NotifyReadyToCommit();
1763 scheduler_
->NotifyReadyToActivate();
1764 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1766 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 5);
1767 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 5);
1768 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 5);
1769 EXPECT_ACTION("ScheduledActionCommit", client_
, 3, 5);
1770 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 4, 5);
1772 // Draw and swap for first commit, start second commit.
1774 scheduler_
->SetNeedsBeginMainFrame();
1775 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1776 EXPECT_SCOPED(AdvanceFrame());
1777 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1778 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1779 scheduler_
->NotifyBeginMainFrameStarted();
1780 scheduler_
->NotifyReadyToCommit();
1781 scheduler_
->NotifyReadyToActivate();
1783 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 6);
1784 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 6);
1785 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 6);
1786 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 6);
1787 EXPECT_ACTION("ScheduledActionCommit", client_
, 4, 6);
1788 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 5, 6);
1790 // Don't call scheduler_->DidSwapBuffersComplete() until after next frame
1791 // to put the impl thread in a high latency mode.
1793 scheduler_
->SetNeedsBeginMainFrame();
1794 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1795 EXPECT_SCOPED(AdvanceFrame());
1796 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1797 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1799 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1800 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1801 // Note: BeginMainFrame and swap are skipped here because of
1802 // swap ack backpressure, not because of latency recovery.
1803 EXPECT_FALSE(client_
->HasAction("ScheduledActionSendBeginMainFrame"));
1804 EXPECT_FALSE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1805 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1807 // Lower estimates so that the scheduler will attempt latency recovery.
1808 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1809 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1811 // Now that both threads are in a high latency mode, make sure we
1812 // skip the BeginMainFrame, then the BeginImplFrame, but not both
1813 // at the same time.
1815 // Verify we skip BeginMainFrame first.
1817 // Previous commit request is still outstanding.
1818 EXPECT_TRUE(scheduler_
->NeedsBeginMainFrame());
1819 EXPECT_TRUE(scheduler_
->SwapThrottled());
1820 SendNextBeginFrame();
1821 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1822 scheduler_
->DidSwapBuffersComplete();
1823 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1825 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1826 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
1827 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
1828 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 2, 3);
1830 // Verify we skip the BeginImplFrame second.
1832 // Previous commit request is still outstanding.
1833 EXPECT_TRUE(scheduler_
->NeedsBeginMainFrame());
1834 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1835 SendNextBeginFrame();
1836 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1837 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1838 scheduler_
->DidSwapBuffersComplete();
1839 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1841 EXPECT_NO_ACTION(client_
);
1843 // Then verify we operate in a low latency mode.
1845 // Previous commit request is still outstanding.
1846 EXPECT_TRUE(scheduler_
->NeedsBeginMainFrame());
1847 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1848 SendNextBeginFrame();
1849 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1850 scheduler_
->NotifyBeginMainFrameStarted();
1851 scheduler_
->NotifyReadyToCommit();
1852 scheduler_
->NotifyReadyToActivate();
1853 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1854 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1855 scheduler_
->DidSwapBuffersComplete();
1856 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1858 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 6);
1859 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 6);
1860 EXPECT_ACTION("ScheduledActionCommit", client_
, 2, 6);
1861 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 3, 6);
1862 EXPECT_ACTION("ScheduledActionAnimate", client_
, 4, 6);
1863 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 5, 6);
1868 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw
) {
1869 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main
1870 // thread. This prevents the scheduler from receiving any pending swap acks.
1872 scheduler_settings_
.use_external_begin_frame_source
= true;
1873 scheduler_settings_
.main_frame_while_swap_throttled_enabled
= true;
1874 SetUpScheduler(true);
1876 // Disables automatic swap acks so this test can force swap ack throttling
1877 // to simulate a blocked Browser ui thread.
1878 scheduler_
->SetMaxSwapsPending(1);
1879 client_
->SetAutomaticSwapAck(false);
1881 // Get a new active tree in main-thread high latency mode and put us
1882 // in a swap throttled state.
1884 EXPECT_FALSE(scheduler_
->CommitPending());
1885 scheduler_
->SetNeedsBeginMainFrame();
1886 scheduler_
->SetNeedsRedraw();
1887 EXPECT_SCOPED(AdvanceFrame());
1888 EXPECT_TRUE(scheduler_
->CommitPending());
1889 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1890 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1891 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1892 scheduler_
->NotifyBeginMainFrameStarted();
1893 scheduler_
->NotifyReadyToCommit();
1894 scheduler_
->NotifyReadyToActivate();
1895 EXPECT_FALSE(scheduler_
->CommitPending());
1896 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 7);
1897 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 7);
1898 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 7);
1899 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 3, 7);
1900 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 4, 7);
1901 EXPECT_ACTION("ScheduledActionCommit", client_
, 5, 7);
1902 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 6, 7);
1904 // Make sure that we can finish the next commit even while swap throttled.
1906 EXPECT_FALSE(scheduler_
->CommitPending());
1907 scheduler_
->SetNeedsBeginMainFrame();
1908 EXPECT_SCOPED(AdvanceFrame());
1909 scheduler_
->NotifyBeginMainFrameStarted();
1910 scheduler_
->NotifyReadyToCommit();
1911 scheduler_
->NotifyReadyToActivate();
1912 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1913 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1914 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1915 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 5);
1916 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 5);
1917 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 5);
1918 EXPECT_ACTION("ScheduledActionCommit", client_
, 3, 5);
1919 EXPECT_ACTION("ScheduledActionAnimate", client_
, 4, 5);
1921 // Make sure we do not send a BeginMainFrame while swap throttled and
1922 // we have both a pending tree and an active tree.
1924 EXPECT_FALSE(scheduler_
->CommitPending());
1925 scheduler_
->SetNeedsBeginMainFrame();
1926 EXPECT_SCOPED(AdvanceFrame());
1927 EXPECT_FALSE(scheduler_
->CommitPending());
1928 task_runner().RunPendingTasks(); // Run posted deadline.
1929 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1930 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1933 TEST_F(SchedulerTest
,
1934 Deadlock_NoBeginMainFrameWhileSwapTrottledAndPipelineFull
) {
1935 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main
1936 // thread. This prevents the scheduler from receiving any pending swap acks.
1938 // This particular test makes sure we do not send a BeginMainFrame while
1939 // swap trottled and we have a pending tree and active tree that
1940 // still needs to be drawn for the first time.
1942 scheduler_settings_
.use_external_begin_frame_source
= true;
1943 scheduler_settings_
.main_frame_while_swap_throttled_enabled
= true;
1944 scheduler_settings_
.main_frame_before_activation_enabled
= true;
1945 SetUpScheduler(true);
1947 // Disables automatic swap acks so this test can force swap ack throttling
1948 // to simulate a blocked Browser ui thread.
1949 scheduler_
->SetMaxSwapsPending(1);
1950 client_
->SetAutomaticSwapAck(false);
1952 // Start a new commit in main-thread high latency mode and hold off on
1955 EXPECT_FALSE(scheduler_
->CommitPending());
1956 scheduler_
->SetNeedsBeginMainFrame();
1957 scheduler_
->SetNeedsRedraw();
1958 EXPECT_SCOPED(AdvanceFrame());
1959 EXPECT_TRUE(scheduler_
->CommitPending());
1960 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1961 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1962 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1963 scheduler_
->DidSwapBuffersComplete();
1964 scheduler_
->NotifyBeginMainFrameStarted();
1965 scheduler_
->NotifyReadyToCommit();
1966 EXPECT_FALSE(scheduler_
->CommitPending());
1967 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 6);
1968 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 6);
1969 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 6);
1970 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 3, 6);
1971 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 4, 6);
1972 EXPECT_ACTION("ScheduledActionCommit", client_
, 5, 6);
1974 // Start another commit while we still have aa pending tree.
1975 // Enter a swap throttled state.
1977 EXPECT_FALSE(scheduler_
->CommitPending());
1978 scheduler_
->SetNeedsBeginMainFrame();
1979 scheduler_
->SetNeedsRedraw();
1980 EXPECT_SCOPED(AdvanceFrame());
1981 EXPECT_TRUE(scheduler_
->CommitPending());
1982 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1983 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1984 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1985 scheduler_
->NotifyBeginMainFrameStarted();
1986 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 4);
1987 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 4);
1988 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 4);
1989 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 4);
1991 // Can't commit yet because there's still a pending tree.
1993 scheduler_
->NotifyReadyToCommit();
1994 EXPECT_NO_ACTION(client_
);
1996 // Activate the pending tree, which also unblocks the commit immediately.
1998 scheduler_
->NotifyReadyToActivate();
1999 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 0, 2);
2000 EXPECT_ACTION("ScheduledActionCommit", client_
, 1, 2);
2002 // Make sure we do not send a BeginMainFrame while swap throttled and
2003 // we have both a pending tree and an active tree that still needs
2006 EXPECT_FALSE(scheduler_
->CommitPending());
2007 scheduler_
->SetNeedsBeginMainFrame();
2008 EXPECT_SCOPED(AdvanceFrame());
2009 EXPECT_FALSE(scheduler_
->CommitPending());
2010 task_runner().RunPendingTasks(); // Run posted deadline.
2011 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2012 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2017 CommitMakesProgressWhenIdleAndHasPendingTreeAndActiveTreeNeedsFirstDraw
) {
2018 // This verifies we don't block commits longer than we need to
2019 // for performance reasons - not deadlock reasons.
2021 // Since we are simulating a long commit, set up a client with draw duration
2022 // estimates that prevent skipping main frames to get to low latency mode.
2023 scheduler_settings_
.use_external_begin_frame_source
= true;
2024 scheduler_settings_
.main_frame_while_swap_throttled_enabled
= true;
2025 scheduler_settings_
.main_frame_before_activation_enabled
= true;
2026 SetUpScheduler(true);
2028 // Disables automatic swap acks so this test can force swap ack throttling
2029 // to simulate a blocked Browser ui thread.
2030 scheduler_
->SetMaxSwapsPending(1);
2031 client_
->SetAutomaticSwapAck(false);
2033 // Start a new commit in main-thread high latency mode and hold off on
2036 EXPECT_FALSE(scheduler_
->CommitPending());
2037 scheduler_
->SetNeedsBeginMainFrame();
2038 scheduler_
->SetNeedsRedraw();
2039 EXPECT_SCOPED(AdvanceFrame());
2040 EXPECT_TRUE(scheduler_
->CommitPending());
2041 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2042 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2043 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2044 scheduler_
->DidSwapBuffersComplete();
2045 scheduler_
->NotifyBeginMainFrameStarted();
2046 scheduler_
->NotifyReadyToCommit();
2047 EXPECT_FALSE(scheduler_
->CommitPending());
2048 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 6);
2049 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 6);
2050 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 6);
2051 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 3, 6);
2052 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 4, 6);
2053 EXPECT_ACTION("ScheduledActionCommit", client_
, 5, 6);
2055 // Start another commit while we still have an active tree.
2057 EXPECT_FALSE(scheduler_
->CommitPending());
2058 scheduler_
->SetNeedsBeginMainFrame();
2059 scheduler_
->SetNeedsRedraw();
2060 EXPECT_SCOPED(AdvanceFrame());
2061 EXPECT_TRUE(scheduler_
->CommitPending());
2062 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2063 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2064 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2065 scheduler_
->DidSwapBuffersComplete();
2066 scheduler_
->NotifyBeginMainFrameStarted();
2067 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 4);
2068 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 4);
2069 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 4);
2070 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 4);
2072 // Can't commit yet because there's still a pending tree.
2074 scheduler_
->NotifyReadyToCommit();
2075 EXPECT_NO_ACTION(client_
);
2077 // Activate the pending tree, which also unblocks the commit immediately
2078 // while we are in an idle state.
2080 scheduler_
->NotifyReadyToActivate();
2081 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 0, 2);
2082 EXPECT_ACTION("ScheduledActionCommit", client_
, 1, 2);
2085 TEST_F(SchedulerTest
, BeginRetroFrame
) {
2086 scheduler_settings_
.use_external_begin_frame_source
= true;
2087 SetUpScheduler(true);
2089 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2090 scheduler_
->SetNeedsBeginMainFrame();
2091 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2094 // Create a BeginFrame with a long deadline to avoid race conditions.
2095 // This is the first BeginFrame, which will be handled immediately.
2096 BeginFrameArgs args
=
2097 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
2098 args
.deadline
+= base::TimeDelta::FromHours(1);
2099 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2100 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2101 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2102 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2103 EXPECT_TRUE(client_
->needs_begin_frames());
2106 // Queue BeginFrames while we are still handling the previous BeginFrame.
2107 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2108 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2109 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2110 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2112 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
2113 task_runner().RunPendingTasks(); // Run posted deadline.
2114 EXPECT_NO_ACTION(client_
);
2115 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2116 EXPECT_TRUE(client_
->needs_begin_frames());
2119 // NotifyReadyToCommit should trigger the commit.
2120 scheduler_
->NotifyBeginMainFrameStarted();
2121 scheduler_
->NotifyReadyToCommit();
2122 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2123 EXPECT_TRUE(client_
->needs_begin_frames());
2126 // NotifyReadyToActivate should trigger the activation.
2127 scheduler_
->NotifyReadyToActivate();
2128 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2129 EXPECT_TRUE(client_
->needs_begin_frames());
2132 // BeginImplFrame should prepare the draw.
2133 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
2134 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2135 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2136 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2137 EXPECT_TRUE(client_
->needs_begin_frames());
2140 // BeginImplFrame deadline should draw.
2141 task_runner().RunPendingTasks(); // Run posted deadline.
2142 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
2143 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2144 EXPECT_TRUE(client_
->needs_begin_frames());
2147 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
2148 // to avoid excessive toggles.
2149 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
2150 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
2151 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2154 task_runner().RunPendingTasks(); // Run posted deadline.
2155 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
2156 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
2160 TEST_F(SchedulerTest
, BeginRetroFrame_SwapThrottled
) {
2161 scheduler_settings_
.use_external_begin_frame_source
= true;
2162 SetUpScheduler(true);
2164 scheduler_
->SetEstimatedParentDrawTime(base::TimeDelta::FromMicroseconds(1));
2166 // To test swap ack throttling, this test disables automatic swap acks.
2167 scheduler_
->SetMaxSwapsPending(1);
2168 client_
->SetAutomaticSwapAck(false);
2170 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2172 scheduler_
->SetNeedsBeginMainFrame();
2173 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2176 EXPECT_SCOPED(AdvanceFrame());
2177 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2178 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2179 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2180 EXPECT_TRUE(client_
->needs_begin_frames());
2183 // Queue BeginFrame while we are still handling the previous BeginFrame.
2184 SendNextBeginFrame();
2185 EXPECT_NO_ACTION(client_
);
2186 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2187 EXPECT_TRUE(client_
->needs_begin_frames());
2190 // NotifyReadyToCommit should trigger the pending commit.
2191 scheduler_
->NotifyBeginMainFrameStarted();
2192 scheduler_
->NotifyReadyToCommit();
2193 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2194 EXPECT_TRUE(client_
->needs_begin_frames());
2197 // NotifyReadyToActivate should trigger the activation and draw.
2198 scheduler_
->NotifyReadyToActivate();
2199 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2200 EXPECT_TRUE(client_
->needs_begin_frames());
2203 // Swapping will put us into a swap throttled state.
2204 // Run posted deadline.
2205 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2206 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
2207 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
2208 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2209 EXPECT_TRUE(client_
->needs_begin_frames());
2212 // While swap throttled, BeginRetroFrames should trigger BeginImplFrames
2213 // but not a BeginMainFrame or draw.
2214 scheduler_
->SetNeedsBeginMainFrame();
2215 scheduler_
->SetNeedsRedraw();
2216 // Run posted BeginRetroFrame.
2217 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(false));
2218 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2219 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2220 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2221 EXPECT_TRUE(client_
->needs_begin_frames());
2224 // Let time pass sufficiently beyond the regular deadline but not beyond the
2226 now_src()->Advance(BeginFrameArgs::DefaultInterval() -
2227 base::TimeDelta::FromMicroseconds(1));
2228 task_runner().RunUntilTime(now_src()->NowTicks());
2229 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2231 // Take us out of a swap throttled state.
2232 scheduler_
->DidSwapBuffersComplete();
2233 EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_
);
2234 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2235 EXPECT_TRUE(client_
->needs_begin_frames());
2238 // Verify that the deadline was rescheduled.
2239 task_runner().RunUntilTime(now_src()->NowTicks());
2240 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
2241 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2242 EXPECT_TRUE(client_
->needs_begin_frames());
2246 TEST_F(SchedulerTest
, RetroFrameDoesNotExpireTooEarly
) {
2247 scheduler_settings_
.use_external_begin_frame_source
= true;
2248 SetUpScheduler(true);
2250 scheduler_
->SetNeedsBeginMainFrame();
2251 EXPECT_TRUE(client_
->needs_begin_frames());
2252 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2255 EXPECT_SCOPED(AdvanceFrame());
2256 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2257 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2258 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2261 scheduler_
->NotifyBeginMainFrameStarted();
2264 BeginFrameArgs retro_frame_args
= SendNextBeginFrame();
2265 // This BeginFrame is queued up as a retro frame.
2266 EXPECT_NO_ACTION(client_
);
2267 // The previous deadline is still pending.
2268 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2271 // This main frame activating should schedule the (previous) deadline to
2272 // trigger immediately.
2273 scheduler_
->NotifyReadyToCommit();
2274 scheduler_
->NotifyReadyToActivate();
2275 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 2);
2276 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 2);
2279 // The deadline task should trigger causing a draw.
2280 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2281 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2282 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
2283 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
2287 scheduler_
->SetNeedsAnimate();
2288 scheduler_
->SetNeedsRedraw();
2289 EXPECT_NO_ACTION(client_
);
2291 // Let's advance to the retro frame's deadline.
2292 now_src()->Advance(retro_frame_args
.deadline
- now_src()->NowTicks());
2294 // The retro frame hasn't expired yet.
2295 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(false));
2296 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2297 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2298 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2300 // This is an immediate deadline case.
2302 task_runner().RunPendingTasks();
2303 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2304 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
2307 TEST_F(SchedulerTest
, RetroFrameExpiresOnTime
) {
2308 scheduler_settings_
.use_external_begin_frame_source
= true;
2309 SetUpScheduler(true);
2311 scheduler_
->SetNeedsBeginMainFrame();
2312 EXPECT_TRUE(client_
->needs_begin_frames());
2313 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2316 EXPECT_SCOPED(AdvanceFrame());
2317 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2318 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2319 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2322 scheduler_
->NotifyBeginMainFrameStarted();
2325 BeginFrameArgs retro_frame_args
= SendNextBeginFrame();
2326 // This BeginFrame is queued up as a retro frame.
2327 EXPECT_NO_ACTION(client_
);
2328 // The previous deadline is still pending.
2329 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2332 // This main frame activating should schedule the (previous) deadline to
2333 // trigger immediately.
2334 scheduler_
->NotifyReadyToCommit();
2335 scheduler_
->NotifyReadyToActivate();
2336 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 2);
2337 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 2);
2340 // The deadline task should trigger causing a draw.
2341 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2342 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2343 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
2344 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
2348 scheduler_
->SetNeedsAnimate();
2349 scheduler_
->SetNeedsRedraw();
2350 EXPECT_NO_ACTION(client_
);
2352 // Let's advance sufficiently past the retro frame's deadline.
2353 now_src()->Advance(retro_frame_args
.deadline
- now_src()->NowTicks() +
2354 base::TimeDelta::FromMicroseconds(1));
2356 // The retro frame should've expired.
2357 EXPECT_NO_ACTION(client_
);
2360 TEST_F(SchedulerTest
, MissedFrameDoesNotExpireTooEarly
) {
2361 scheduler_settings_
.use_external_begin_frame_source
= true;
2362 SetUpScheduler(true);
2364 scheduler_
->SetNeedsBeginMainFrame();
2365 EXPECT_TRUE(client_
->needs_begin_frames());
2366 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2368 BeginFrameArgs missed_frame_args
=
2369 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
2370 missed_frame_args
.type
= BeginFrameArgs::MISSED
;
2372 // Advance to the deadline.
2373 now_src()->Advance(missed_frame_args
.deadline
- now_src()->NowTicks());
2375 // Missed frame is handled because it's on time.
2377 fake_external_begin_frame_source_
->TestOnBeginFrame(missed_frame_args
);
2379 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(false)));
2380 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2381 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2382 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2385 TEST_F(SchedulerTest
, MissedFrameExpiresOnTime
) {
2386 scheduler_settings_
.use_external_begin_frame_source
= true;
2387 SetUpScheduler(true);
2389 scheduler_
->SetNeedsBeginMainFrame();
2390 EXPECT_TRUE(client_
->needs_begin_frames());
2391 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2393 BeginFrameArgs missed_frame_args
=
2394 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
2395 missed_frame_args
.type
= BeginFrameArgs::MISSED
;
2397 // Advance sufficiently past the deadline.
2398 now_src()->Advance(missed_frame_args
.deadline
- now_src()->NowTicks() +
2399 base::TimeDelta::FromMicroseconds(1));
2401 // Missed frame is dropped because it's too late.
2403 fake_external_begin_frame_source_
->TestOnBeginFrame(missed_frame_args
);
2405 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(false)));
2406 EXPECT_NO_ACTION(client_
);
2407 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2410 void SchedulerTest::BeginFramesNotFromClient(
2411 bool use_external_begin_frame_source
,
2412 bool throttle_frame_production
) {
2413 scheduler_settings_
.use_external_begin_frame_source
=
2414 use_external_begin_frame_source
;
2415 scheduler_settings_
.throttle_frame_production
= throttle_frame_production
;
2416 SetUpScheduler(true);
2418 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame
2419 // without calling SetNeedsBeginFrame.
2420 scheduler_
->SetNeedsBeginMainFrame();
2421 EXPECT_NO_ACTION(client_
);
2424 // When the client-driven BeginFrame are disabled, the scheduler posts it's
2425 // own BeginFrame tasks.
2426 task_runner().RunPendingTasks(); // Run posted BeginFrame.
2427 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2428 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2429 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2432 // If we don't swap on the deadline, we wait for the next BeginFrame.
2433 task_runner().RunPendingTasks(); // Run posted deadline.
2434 EXPECT_NO_ACTION(client_
);
2435 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2438 // NotifyReadyToCommit should trigger the commit.
2439 scheduler_
->NotifyBeginMainFrameStarted();
2440 scheduler_
->NotifyReadyToCommit();
2441 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2444 // NotifyReadyToActivate should trigger the activation.
2445 scheduler_
->NotifyReadyToActivate();
2446 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2449 // BeginImplFrame should prepare the draw.
2450 task_runner().RunPendingTasks(); // Run posted BeginFrame.
2451 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2452 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2453 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2456 // BeginImplFrame deadline should draw.
2457 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2458 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
2459 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2462 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
2463 // to avoid excessive toggles.
2464 task_runner().RunPendingTasks(); // Run posted BeginFrame.
2465 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
2466 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2469 // Make sure SetNeedsBeginFrame isn't called on the client
2470 // when the BeginFrame is no longer needed.
2471 task_runner().RunPendingTasks(); // Run posted deadline.
2472 EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_
);
2476 TEST_F(SchedulerTest
, SyntheticBeginFrames
) {
2477 bool use_external_begin_frame_source
= false;
2478 bool throttle_frame_production
= true;
2479 BeginFramesNotFromClient(use_external_begin_frame_source
,
2480 throttle_frame_production
);
2483 TEST_F(SchedulerTest
, VSyncThrottlingDisabled
) {
2484 bool use_external_begin_frame_source
= true;
2485 bool throttle_frame_production
= false;
2486 BeginFramesNotFromClient(use_external_begin_frame_source
,
2487 throttle_frame_production
);
2490 TEST_F(SchedulerTest
, SyntheticBeginFrames_And_VSyncThrottlingDisabled
) {
2491 bool use_external_begin_frame_source
= false;
2492 bool throttle_frame_production
= false;
2493 BeginFramesNotFromClient(use_external_begin_frame_source
,
2494 throttle_frame_production
);
2497 void SchedulerTest::BeginFramesNotFromClient_SwapThrottled(
2498 bool use_external_begin_frame_source
,
2499 bool throttle_frame_production
) {
2500 scheduler_settings_
.use_external_begin_frame_source
=
2501 use_external_begin_frame_source
;
2502 scheduler_settings_
.throttle_frame_production
= throttle_frame_production
;
2503 SetUpScheduler(true);
2505 scheduler_
->SetEstimatedParentDrawTime(base::TimeDelta::FromMicroseconds(1));
2507 // To test swap ack throttling, this test disables automatic swap acks.
2508 scheduler_
->SetMaxSwapsPending(1);
2509 client_
->SetAutomaticSwapAck(false);
2511 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2513 scheduler_
->SetNeedsBeginMainFrame();
2514 EXPECT_NO_ACTION(client_
);
2517 // Trigger the first BeginImplFrame and BeginMainFrame
2518 EXPECT_SCOPED(AdvanceFrame());
2519 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2520 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2521 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2524 // NotifyReadyToCommit should trigger the pending commit.
2525 scheduler_
->NotifyBeginMainFrameStarted();
2526 scheduler_
->NotifyReadyToCommit();
2527 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2530 // NotifyReadyToActivate should trigger the activation and draw.
2531 scheduler_
->NotifyReadyToActivate();
2532 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2535 // Swapping will put us into a swap throttled state.
2536 // Run posted deadline.
2537 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2538 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
2539 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
2540 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2543 // While swap throttled, BeginFrames should trigger BeginImplFrames,
2544 // but not a BeginMainFrame or draw.
2545 scheduler_
->SetNeedsBeginMainFrame();
2546 scheduler_
->SetNeedsRedraw();
2547 EXPECT_SCOPED(AdvanceFrame()); // Run posted BeginFrame.
2548 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2549 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2550 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2553 // Let time pass sufficiently beyond the regular deadline but not beyond the
2555 now_src()->Advance(BeginFrameArgs::DefaultInterval() -
2556 base::TimeDelta::FromMicroseconds(1));
2557 task_runner().RunUntilTime(now_src()->NowTicks());
2558 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2560 // Take us out of a swap throttled state.
2561 scheduler_
->DidSwapBuffersComplete();
2562 EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_
);
2563 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2566 // Verify that the deadline was rescheduled.
2567 // We can't use RunUntilTime(now) here because the next frame is also
2568 // scheduled if throttle_frame_production = false.
2569 base::TimeTicks before_deadline
= now_src()->NowTicks();
2570 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2571 base::TimeTicks after_deadline
= now_src()->NowTicks();
2572 EXPECT_EQ(after_deadline
, before_deadline
);
2573 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2577 TEST_F(SchedulerTest
, SyntheticBeginFrames_SwapThrottled
) {
2578 bool use_external_begin_frame_source
= false;
2579 bool throttle_frame_production
= true;
2580 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source
,
2581 throttle_frame_production
);
2584 TEST_F(SchedulerTest
, VSyncThrottlingDisabled_SwapThrottled
) {
2585 bool use_external_begin_frame_source
= true;
2586 bool throttle_frame_production
= false;
2587 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source
,
2588 throttle_frame_production
);
2591 TEST_F(SchedulerTest
,
2592 SyntheticBeginFrames_And_VSyncThrottlingDisabled_SwapThrottled
) {
2593 bool use_external_begin_frame_source
= false;
2594 bool throttle_frame_production
= false;
2595 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source
,
2596 throttle_frame_production
);
2599 TEST_F(SchedulerTest
, DidLoseOutputSurfaceAfterOutputSurfaceIsInitialized
) {
2600 scheduler_settings_
.use_external_begin_frame_source
= true;
2601 SetUpScheduler(false);
2603 scheduler_
->SetCanStart();
2604 scheduler_
->SetVisible(true);
2605 scheduler_
->SetCanDraw(true);
2607 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
);
2609 scheduler_
->DidCreateAndInitializeOutputSurface();
2610 EXPECT_NO_ACTION(client_
);
2612 scheduler_
->DidLoseOutputSurface();
2613 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
);
2616 TEST_F(SchedulerTest
, DidLoseOutputSurfaceAfterBeginFrameStarted
) {
2617 scheduler_settings_
.use_external_begin_frame_source
= true;
2618 SetUpScheduler(true);
2620 // SetNeedsBeginMainFrame should begin the frame.
2621 scheduler_
->SetNeedsBeginMainFrame();
2622 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2625 EXPECT_SCOPED(AdvanceFrame());
2626 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2627 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2628 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2631 scheduler_
->DidLoseOutputSurface();
2632 // SetNeedsBeginFrames(false) is not called until the end of the frame.
2633 EXPECT_NO_ACTION(client_
);
2636 scheduler_
->NotifyBeginMainFrameStarted();
2637 scheduler_
->NotifyReadyToCommit();
2638 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 2);
2639 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 2);
2642 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2643 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
2644 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2645 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2648 TEST_F(SchedulerTest
,
2649 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency
) {
2650 scheduler_settings_
.use_external_begin_frame_source
= true;
2651 SetUpScheduler(true);
2653 // SetNeedsBeginMainFrame should begin the frame.
2654 scheduler_
->SetNeedsBeginMainFrame();
2655 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2658 EXPECT_SCOPED(AdvanceFrame());
2659 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2660 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2661 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2664 scheduler_
->DidLoseOutputSurface();
2665 // Do nothing when impl frame is in deadine pending state.
2666 EXPECT_NO_ACTION(client_
);
2669 // Run posted deadline.
2670 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2671 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2672 // OnBeginImplFrameDeadline didn't schedule output surface creation because
2673 // main frame is not yet completed.
2674 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
2675 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
2676 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2678 // BeginImplFrame is not started.
2680 task_runner().RunUntilTime(now_src()->NowTicks() +
2681 base::TimeDelta::FromMilliseconds(10));
2682 EXPECT_NO_ACTION(client_
);
2683 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2686 scheduler_
->NotifyBeginMainFrameStarted();
2687 scheduler_
->NotifyReadyToCommit();
2688 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 3);
2689 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 3);
2690 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 2, 3);
2693 TEST_F(SchedulerTest
, DidLoseOutputSurfaceAfterReadyToCommit
) {
2694 scheduler_settings_
.use_external_begin_frame_source
= true;
2695 SetUpScheduler(true);
2697 // SetNeedsBeginMainFrame should begin the frame.
2698 scheduler_
->SetNeedsBeginMainFrame();
2699 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2702 EXPECT_SCOPED(AdvanceFrame());
2703 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2704 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2705 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2708 scheduler_
->NotifyBeginMainFrameStarted();
2709 scheduler_
->NotifyReadyToCommit();
2710 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2713 scheduler_
->DidLoseOutputSurface();
2714 // Sync tree should be forced to activate.
2715 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2717 // SetNeedsBeginFrames(false) is not called until the end of the frame.
2719 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2720 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
2721 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2722 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2725 TEST_F(SchedulerTest
, DidLoseOutputSurfaceAfterSetNeedsPrepareTiles
) {
2726 scheduler_settings_
.use_external_begin_frame_source
= true;
2727 SetUpScheduler(true);
2729 scheduler_
->SetNeedsPrepareTiles();
2730 scheduler_
->SetNeedsRedraw();
2731 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2734 EXPECT_SCOPED(AdvanceFrame());
2735 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2736 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2737 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2740 scheduler_
->DidLoseOutputSurface();
2741 // SetNeedsBeginFrames(false) is not called until the end of the frame.
2742 EXPECT_NO_ACTION(client_
);
2745 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2746 EXPECT_ACTION("ScheduledActionPrepareTiles", client_
, 0, 4);
2747 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 1, 4);
2748 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 2, 4);
2749 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 3, 4);
2752 TEST_F(SchedulerTest
, DidLoseOutputSurfaceAfterBeginRetroFramePosted
) {
2753 scheduler_settings_
.use_external_begin_frame_source
= true;
2754 SetUpScheduler(true);
2756 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2757 scheduler_
->SetNeedsBeginMainFrame();
2758 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2760 // Create a BeginFrame with a long deadline to avoid race conditions.
2761 // This is the first BeginFrame, which will be handled immediately.
2763 BeginFrameArgs args
=
2764 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
2765 args
.deadline
+= base::TimeDelta::FromHours(1);
2766 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2767 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2768 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2769 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2770 EXPECT_TRUE(client_
->needs_begin_frames());
2772 // Queue BeginFrames while we are still handling the previous BeginFrame.
2773 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2774 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2775 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2776 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2778 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
2780 task_runner().RunPendingTasks(); // Run posted deadline.
2781 EXPECT_NO_ACTION(client_
);
2782 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2783 EXPECT_TRUE(client_
->needs_begin_frames());
2785 // NotifyReadyToCommit should trigger the commit.
2787 scheduler_
->NotifyBeginMainFrameStarted();
2788 scheduler_
->NotifyReadyToCommit();
2789 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2790 EXPECT_TRUE(client_
->needs_begin_frames());
2792 // NotifyReadyToActivate should trigger the activation.
2794 scheduler_
->NotifyReadyToActivate();
2795 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2796 EXPECT_TRUE(client_
->needs_begin_frames());
2799 EXPECT_FALSE(scheduler_
->IsBeginRetroFrameArgsEmpty());
2800 scheduler_
->DidLoseOutputSurface();
2801 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
2802 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2803 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2804 EXPECT_TRUE(scheduler_
->IsBeginRetroFrameArgsEmpty());
2806 // Posted BeginRetroFrame is aborted.
2808 task_runner().RunPendingTasks();
2809 EXPECT_NO_ACTION(client_
);
2812 TEST_F(SchedulerTest
, DidLoseOutputSurfaceDuringBeginRetroFrameRunning
) {
2813 scheduler_settings_
.use_external_begin_frame_source
= true;
2814 SetUpScheduler(true);
2816 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2817 scheduler_
->SetNeedsBeginMainFrame();
2818 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2820 // Create a BeginFrame with a long deadline to avoid race conditions.
2821 // This is the first BeginFrame, which will be handled immediately.
2823 BeginFrameArgs args
=
2824 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
2825 args
.deadline
+= base::TimeDelta::FromHours(1);
2826 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2827 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2828 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2829 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2830 EXPECT_TRUE(client_
->needs_begin_frames());
2832 // Queue BeginFrames while we are still handling the previous BeginFrame.
2833 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2834 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2835 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2836 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2838 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
2840 task_runner().RunPendingTasks(); // Run posted deadline.
2841 EXPECT_NO_ACTION(client_
);
2842 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2843 EXPECT_TRUE(client_
->needs_begin_frames());
2845 // NotifyReadyToCommit should trigger the commit.
2847 scheduler_
->NotifyBeginMainFrameStarted();
2848 scheduler_
->NotifyReadyToCommit();
2849 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2850 EXPECT_TRUE(client_
->needs_begin_frames());
2852 // NotifyReadyToActivate should trigger the activation.
2854 scheduler_
->NotifyReadyToActivate();
2855 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2856 EXPECT_TRUE(client_
->needs_begin_frames());
2858 // BeginImplFrame should prepare the draw.
2860 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
2861 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2862 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2863 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2864 EXPECT_TRUE(client_
->needs_begin_frames());
2867 EXPECT_FALSE(scheduler_
->IsBeginRetroFrameArgsEmpty());
2868 scheduler_
->DidLoseOutputSurface();
2869 EXPECT_NO_ACTION(client_
);
2870 EXPECT_TRUE(scheduler_
->IsBeginRetroFrameArgsEmpty());
2872 // BeginImplFrame deadline should abort drawing.
2874 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2875 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
2876 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2877 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2878 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2879 EXPECT_FALSE(client_
->needs_begin_frames());
2881 // No more BeginRetroFrame because BeginRetroFrame queue is cleared.
2883 task_runner().RunPendingTasks();
2884 EXPECT_NO_ACTION(client_
);
2887 TEST_F(SchedulerTest
, DidLoseOutputSurfaceWithSyntheticBeginFrameSource
) {
2888 SetUpScheduler(true);
2890 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2891 EXPECT_FALSE(scheduler_
->frame_source().NeedsBeginFrames());
2892 scheduler_
->SetNeedsBeginMainFrame();
2893 EXPECT_TRUE(scheduler_
->frame_source().NeedsBeginFrames());
2897 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2898 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2899 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2900 EXPECT_TRUE(scheduler_
->frame_source().NeedsBeginFrames());
2902 // NotifyReadyToCommit should trigger the commit.
2904 scheduler_
->NotifyBeginMainFrameStarted();
2905 scheduler_
->NotifyReadyToCommit();
2906 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2907 EXPECT_TRUE(scheduler_
->frame_source().NeedsBeginFrames());
2909 // NotifyReadyToActivate should trigger the activation.
2911 scheduler_
->NotifyReadyToActivate();
2912 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2913 EXPECT_TRUE(scheduler_
->frame_source().NeedsBeginFrames());
2916 scheduler_
->DidLoseOutputSurface();
2917 // SetNeedsBeginFrames(false) is not called until the end of the frame.
2918 EXPECT_NO_ACTION(client_
);
2919 EXPECT_TRUE(scheduler_
->frame_source().NeedsBeginFrames());
2922 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2923 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 2);
2924 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
2925 EXPECT_FALSE(scheduler_
->frame_source().NeedsBeginFrames());
2928 TEST_F(SchedulerTest
, DidLoseOutputSurfaceWhenIdle
) {
2929 scheduler_settings_
.use_external_begin_frame_source
= true;
2930 SetUpScheduler(true);
2932 // SetNeedsBeginMainFrame should begin the frame.
2933 scheduler_
->SetNeedsBeginMainFrame();
2934 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2937 EXPECT_SCOPED(AdvanceFrame());
2938 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2939 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2940 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2943 scheduler_
->NotifyBeginMainFrameStarted();
2944 scheduler_
->NotifyReadyToCommit();
2945 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2948 scheduler_
->NotifyReadyToActivate();
2949 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2952 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2953 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
2954 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
2956 // Idle time between BeginFrames.
2958 scheduler_
->DidLoseOutputSurface();
2959 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
2960 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2961 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2964 TEST_F(SchedulerTest
, ScheduledActionActivateAfterBecomingInvisible
) {
2965 scheduler_settings_
.use_external_begin_frame_source
= true;
2966 SetUpScheduler(true);
2968 // SetNeedsBeginMainFrame should begin the frame.
2969 scheduler_
->SetNeedsBeginMainFrame();
2970 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2973 EXPECT_SCOPED(AdvanceFrame());
2974 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2975 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2976 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2979 scheduler_
->NotifyBeginMainFrameStarted();
2980 scheduler_
->NotifyReadyToCommit();
2981 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2982 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2985 scheduler_
->SetVisible(false);
2986 task_runner().RunPendingTasks(); // Run posted deadline.
2988 // Sync tree should be forced to activate.
2989 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 0, 3);
2990 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2991 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2994 // Tests to ensure frame sources can be successfully changed while drawing.
2995 TEST_F(SchedulerTest
, SwitchFrameSourceToUnthrottled
) {
2996 scheduler_settings_
.use_external_begin_frame_source
= true;
2997 SetUpScheduler(true);
2999 // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
3000 scheduler_
->SetNeedsRedraw();
3001 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3004 EXPECT_SCOPED(AdvanceFrame());
3005 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3006 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
3007 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3008 EXPECT_TRUE(client_
->needs_begin_frames());
3010 task_runner().RunPendingTasks(); // Run posted deadline.
3011 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
3012 scheduler_
->SetNeedsRedraw();
3014 // Switch to an unthrottled frame source.
3015 scheduler_
->SetThrottleFrameProduction(false);
3018 // Unthrottled frame source will immediately begin a new frame.
3019 task_runner().RunPendingTasks(); // Run posted BeginFrame.
3020 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3021 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
3022 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3025 // If we don't swap on the deadline, we wait for the next BeginFrame.
3026 task_runner().RunPendingTasks(); // Run posted deadline.
3027 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
3028 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3032 // Tests to ensure frame sources can be successfully changed while a frame
3033 // deadline is pending.
3034 TEST_F(SchedulerTest
, SwitchFrameSourceToUnthrottledBeforeDeadline
) {
3035 scheduler_settings_
.use_external_begin_frame_source
= true;
3036 SetUpScheduler(true);
3038 // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
3039 scheduler_
->SetNeedsRedraw();
3040 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3043 EXPECT_SCOPED(AdvanceFrame());
3044 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3045 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
3047 // Switch to an unthrottled frame source before the frame deadline is hit.
3048 scheduler_
->SetThrottleFrameProduction(false);
3051 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3052 EXPECT_TRUE(client_
->needs_begin_frames());
3055 task_runner().RunPendingTasks(); // Run posted deadline and BeginFrame.
3056 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 2);
3057 // Unthrottled frame source will immediately begin a new frame.
3058 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 2);
3059 scheduler_
->SetNeedsRedraw();
3062 task_runner().RunPendingTasks(); // Run posted deadline.
3063 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
3064 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
3065 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3069 // Tests to ensure that the active frame source can successfully be changed from
3070 // unthrottled to throttled.
3071 TEST_F(SchedulerTest
, SwitchFrameSourceToThrottled
) {
3072 scheduler_settings_
.throttle_frame_production
= false;
3073 scheduler_settings_
.use_external_begin_frame_source
= true;
3074 SetUpScheduler(true);
3076 scheduler_
->SetNeedsRedraw();
3077 EXPECT_NO_ACTION(client_
);
3080 task_runner().RunPendingTasks(); // Run posted BeginFrame.
3081 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3082 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
3083 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3086 task_runner().RunPendingTasks(); // Run posted deadline.
3087 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
3088 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3091 // Switch to a throttled frame source.
3092 scheduler_
->SetThrottleFrameProduction(true);
3095 // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
3096 scheduler_
->SetNeedsRedraw();
3097 task_runner().RunPendingTasks();
3098 EXPECT_NO_ACTION(client_
);
3101 EXPECT_SCOPED(AdvanceFrame());
3102 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3103 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
3104 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3105 EXPECT_TRUE(client_
->needs_begin_frames());
3107 task_runner().RunPendingTasks(); // Run posted deadline.
3108 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
3111 // Tests to ensure that we send a BeginMainFrameNotExpectedSoon when expected.
3112 TEST_F(SchedulerTest
, SendBeginMainFrameNotExpectedSoon
) {
3113 scheduler_settings_
.use_external_begin_frame_source
= true;
3114 SetUpScheduler(true);
3116 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
3117 scheduler_
->SetNeedsBeginMainFrame();
3118 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3121 // Trigger a frame draw.
3122 EXPECT_SCOPED(AdvanceFrame());
3123 scheduler_
->NotifyBeginMainFrameStarted();
3124 scheduler_
->NotifyReadyToCommit();
3125 scheduler_
->NotifyReadyToActivate();
3126 task_runner().RunPendingTasks();
3127 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 6);
3128 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 6);
3129 EXPECT_ACTION("ScheduledActionCommit", client_
, 2, 6);
3130 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 3, 6);
3131 EXPECT_ACTION("ScheduledActionAnimate", client_
, 4, 6);
3132 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 5, 6);
3135 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
3136 // and send a SendBeginMainFrameNotExpectedSoon.
3137 EXPECT_SCOPED(AdvanceFrame());
3138 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
3139 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3142 task_runner().RunPendingTasks(); // Run posted deadline.
3143 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
3144 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
3148 TEST_F(SchedulerTest
, SynchronousCompositorAnimation
) {
3149 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3150 scheduler_settings_
.use_external_begin_frame_source
= true;
3151 SetUpScheduler(true);
3153 scheduler_
->SetNeedsAnimate();
3154 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3159 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3160 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3161 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3162 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3165 // Continue with animation.
3166 scheduler_
->SetNeedsAnimate();
3167 EXPECT_NO_ACTION(client_
);
3170 scheduler_
->SetNeedsRedraw();
3171 scheduler_
->OnDrawForOutputSurface();
3172 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
3173 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3178 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3179 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3180 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3181 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3185 scheduler_
->SetNeedsRedraw();
3186 scheduler_
->OnDrawForOutputSurface();
3187 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
3188 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3191 // Idle on next vsync.
3193 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3194 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
3195 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
3196 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3200 TEST_F(SchedulerTest
, SynchronousCompositorOnDrawDuringIdle
) {
3201 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3202 scheduler_settings_
.use_external_begin_frame_source
= true;
3203 SetUpScheduler(true);
3205 scheduler_
->SetNeedsRedraw();
3206 scheduler_
->OnDrawForOutputSurface();
3207 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 3);
3208 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3209 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 2, 3);
3210 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3213 // Idle on next vsync.
3215 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3216 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
3217 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
3218 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3222 TEST_F(SchedulerTest
, SynchronousCompositorCommit
) {
3223 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3224 scheduler_settings_
.use_external_begin_frame_source
= true;
3225 SetUpScheduler(true);
3227 scheduler_
->SetNeedsBeginMainFrame();
3228 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3233 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3234 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
3235 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3238 scheduler_
->NotifyBeginMainFrameStarted();
3239 EXPECT_NO_ACTION(client_
);
3243 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
3244 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3247 scheduler_
->NotifyReadyToCommit();
3248 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
3251 scheduler_
->NotifyReadyToActivate();
3252 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
3257 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3258 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3259 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3260 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3264 scheduler_
->SetNeedsRedraw();
3265 scheduler_
->OnDrawForOutputSurface();
3266 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
3267 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3270 // Idle on next vsync.
3272 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3273 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
3274 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
3275 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3279 TEST_F(SchedulerTest
, SynchronousCompositorDoubleCommitWithoutDraw
) {
3280 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3281 scheduler_settings_
.use_external_begin_frame_source
= true;
3282 SetUpScheduler(true);
3284 scheduler_
->SetNeedsBeginMainFrame();
3285 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3290 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3291 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
3292 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3295 scheduler_
->NotifyBeginMainFrameStarted();
3296 EXPECT_NO_ACTION(client_
);
3298 scheduler_
->NotifyReadyToCommit();
3299 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
3302 scheduler_
->NotifyReadyToActivate();
3303 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
3306 // Ask for another commit.
3307 scheduler_
->SetNeedsBeginMainFrame();
3310 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 4);
3311 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 4);
3312 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 4);
3313 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 3, 4);
3314 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3317 scheduler_
->NotifyBeginMainFrameStarted();
3318 EXPECT_NO_ACTION(client_
);
3320 // Allow new commit even though previous commit hasn't been drawn.
3321 scheduler_
->NotifyReadyToCommit();
3322 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
3326 class SchedulerClientSetNeedsPrepareTilesOnDraw
: public FakeSchedulerClient
{
3328 SchedulerClientSetNeedsPrepareTilesOnDraw() : FakeSchedulerClient() {}
3331 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
3332 scheduler_
->SetNeedsPrepareTiles();
3333 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
3337 TEST_F(SchedulerTest
, SynchronousCompositorPrepareTilesOnDraw
) {
3338 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3339 scheduler_settings_
.use_external_begin_frame_source
= true;
3341 scoped_ptr
<FakeSchedulerClient
> client
=
3342 make_scoped_ptr(new SchedulerClientSetNeedsPrepareTilesOnDraw
);
3343 SetUpScheduler(client
.Pass(), true);
3345 scheduler_
->SetNeedsRedraw();
3346 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3350 EXPECT_SCOPED(AdvanceFrame());
3351 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3352 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3353 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3357 scheduler_
->SetNeedsRedraw();
3358 scheduler_
->OnDrawForOutputSurface();
3359 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 2);
3360 EXPECT_ACTION("ScheduledActionPrepareTiles", client_
, 1, 2);
3361 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3362 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
3366 scheduler_
->SetNeedsRedraw();
3367 scheduler_
->OnDrawForOutputSurface();
3368 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 2);
3369 EXPECT_ACTION("ScheduledActionPrepareTiles", client_
, 1, 2);
3370 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3371 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
3375 EXPECT_SCOPED(AdvanceFrame());
3376 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
3377 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3378 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
3379 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
3380 EXPECT_FALSE(client_
->needs_begin_frames());
3384 TEST_F(SchedulerTest
, SynchronousCompositorSendBeginMainFrameWhileIdle
) {
3385 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3386 scheduler_settings_
.use_external_begin_frame_source
= true;
3388 SetUpScheduler(true);
3390 scheduler_
->SetNeedsRedraw();
3391 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3395 EXPECT_SCOPED(AdvanceFrame());
3396 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3397 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3398 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3402 scheduler_
->SetNeedsRedraw();
3403 scheduler_
->OnDrawForOutputSurface();
3404 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
3405 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3406 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
3409 // Simulate SetNeedsBeginMainFrame due to input event.
3410 scheduler_
->SetNeedsBeginMainFrame();
3411 EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_
);
3414 scheduler_
->NotifyBeginMainFrameStarted();
3415 scheduler_
->NotifyReadyToCommit();
3416 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
3419 scheduler_
->NotifyReadyToActivate();
3420 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
3424 EXPECT_SCOPED(AdvanceFrame());
3425 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3426 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3427 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3431 scheduler_
->SetNeedsRedraw();
3432 scheduler_
->OnDrawForOutputSurface();
3433 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
3434 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3435 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
3438 // Simulate SetNeedsBeginMainFrame due to input event.
3439 scheduler_
->SetNeedsBeginMainFrame();
3440 EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_
);
3444 TEST_F(SchedulerTest
, AuthoritativeVSyncInterval
) {
3445 SetUpScheduler(true);
3446 base::TimeDelta initial_interval
= scheduler_
->BeginImplFrameInterval();
3447 base::TimeDelta authoritative_interval
=
3448 base::TimeDelta::FromMilliseconds(33);
3450 scheduler_
->SetNeedsBeginMainFrame();
3451 EXPECT_SCOPED(AdvanceFrame());
3453 EXPECT_EQ(initial_interval
, scheduler_
->BeginImplFrameInterval());
3455 scheduler_
->NotifyBeginMainFrameStarted();
3456 scheduler_
->NotifyReadyToCommit();
3457 scheduler_
->NotifyReadyToActivate();
3458 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
3460 scheduler_
->SetAuthoritativeVSyncInterval(authoritative_interval
);
3462 EXPECT_SCOPED(AdvanceFrame());
3464 // At the next BeginFrame, authoritative interval is used instead of previous
3466 EXPECT_NE(initial_interval
, scheduler_
->BeginImplFrameInterval());
3467 EXPECT_EQ(authoritative_interval
, scheduler_
->BeginImplFrameInterval());
3470 TEST_F(SchedulerTest
, ImplLatencyTakesPriority
) {
3471 SetUpScheduler(true);
3472 scheduler_
->SetImplLatencyTakesPriority(true);
3473 EXPECT_TRUE(scheduler_
->ImplLatencyTakesPriority());
3475 scheduler_
->SetImplLatencyTakesPriority(false);
3476 EXPECT_FALSE(scheduler_
->ImplLatencyTakesPriority());
3479 TEST_F(SchedulerTest
, BeginFrameArgs_OnCriticalPath
) {
3480 scheduler_settings_
.use_external_begin_frame_source
= true;
3481 SetUpScheduler(true);
3483 scheduler_
->SetImplLatencyTakesPriority(false);
3484 scheduler_
->SetChildrenNeedBeginFrames(true);
3486 EXPECT_SCOPED(AdvanceFrame());
3487 EXPECT_TRUE(client_
->begin_frame_is_sent_to_children());
3488 EXPECT_TRUE(client_
->begin_frame_args_sent_to_children().on_critical_path
);
3491 TEST_F(SchedulerTest
, BeginFrameArgs_NotOnCriticalPath
) {
3492 scheduler_settings_
.use_external_begin_frame_source
= true;
3493 SetUpScheduler(true);
3495 scheduler_
->SetImplLatencyTakesPriority(true);
3496 scheduler_
->SetChildrenNeedBeginFrames(true);
3498 EXPECT_SCOPED(AdvanceFrame());
3499 EXPECT_TRUE(client_
->begin_frame_is_sent_to_children());
3500 EXPECT_FALSE(client_
->begin_frame_args_sent_to_children().on_critical_path
);