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/message_loop/message_loop.h"
12 #include "base/numerics/safe_conversions.h"
13 #include "base/run_loop.h"
14 #include "base/time/time.h"
15 #include "base/trace_event/trace_event.h"
16 #include "cc/test/begin_frame_args_test.h"
17 #include "cc/test/ordered_simple_task_runner.h"
18 #include "cc/test/scheduler_test_common.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \
24 EXPECT_EQ(expected_num_actions, client->num_actions_()); \
25 if (action_index >= 0) { \
26 ASSERT_LT(action_index, client->num_actions_()) << scheduler_.get(); \
27 EXPECT_STREQ(action, client->Action(action_index)); \
29 for (int i = expected_num_actions; i < client->num_actions_(); ++i) \
30 ADD_FAILURE() << "Unexpected action: " << client->Action(i) \
31 << " with state:\n" << client->StateForAction(i); \
34 #define EXPECT_NO_ACTION(client) EXPECT_ACTION("", client, -1, 0)
36 #define EXPECT_SINGLE_ACTION(action, client) \
37 EXPECT_ACTION(action, client, 0, 1)
39 #define EXPECT_SCOPED(statements) \
48 class FakeSchedulerClient
: public SchedulerClient
{
51 : automatic_swap_ack_(true),
59 draw_will_happen_
= true;
60 swap_will_happen_if_draw_happens_
= true;
62 begin_frame_args_sent_to_children_
= BeginFrameArgs();
65 void set_scheduler(TestScheduler
* scheduler
) { scheduler_
= scheduler
; }
67 bool needs_begin_frames() {
68 return scheduler_
->frame_source().NeedsBeginFrames();
70 int num_draws() const { return num_draws_
; }
71 int num_actions_() const { return static_cast<int>(actions_
.size()); }
72 const char* Action(int i
) const { return actions_
[i
]; }
73 std::string
StateForAction(int i
) const { return states_
[i
]->ToString(); }
74 base::TimeTicks
posted_begin_impl_frame_deadline() const {
75 return posted_begin_impl_frame_deadline_
;
78 int ActionIndex(const char* action
) const {
79 for (size_t i
= 0; i
< actions_
.size(); i
++)
80 if (!strcmp(actions_
[i
], action
))
81 return base::checked_cast
<int>(i
);
85 bool HasAction(const char* action
) const {
86 return ActionIndex(action
) >= 0;
89 void SetDrawWillHappen(bool draw_will_happen
) {
90 draw_will_happen_
= draw_will_happen
;
92 void SetSwapWillHappenIfDrawHappens(bool swap_will_happen_if_draw_happens
) {
93 swap_will_happen_if_draw_happens_
= swap_will_happen_if_draw_happens
;
95 void SetAutomaticSwapAck(bool automatic_swap_ack
) {
96 automatic_swap_ack_
= automatic_swap_ack
;
98 // SchedulerClient implementation.
99 void WillBeginImplFrame(const BeginFrameArgs
& args
) override
{
100 PushAction("WillBeginImplFrame");
102 void DidFinishImplFrame() override
{}
104 void ScheduledActionSendBeginMainFrame() override
{
105 PushAction("ScheduledActionSendBeginMainFrame");
107 void ScheduledActionAnimate() override
{
108 PushAction("ScheduledActionAnimate");
110 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
111 PushAction("ScheduledActionDrawAndSwapIfPossible");
114 draw_will_happen_
? DRAW_SUCCESS
: DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
115 bool swap_will_happen
=
116 draw_will_happen_
&& swap_will_happen_if_draw_happens_
;
117 if (swap_will_happen
) {
118 scheduler_
->DidSwapBuffers();
120 if (automatic_swap_ack_
)
121 scheduler_
->DidSwapBuffersComplete();
125 DrawResult
ScheduledActionDrawAndSwapForced() override
{
126 PushAction("ScheduledActionDrawAndSwapForced");
129 void ScheduledActionCommit() override
{
130 PushAction("ScheduledActionCommit");
131 scheduler_
->DidCommit();
133 void ScheduledActionActivateSyncTree() override
{
134 PushAction("ScheduledActionActivateSyncTree");
136 void ScheduledActionBeginOutputSurfaceCreation() override
{
137 PushAction("ScheduledActionBeginOutputSurfaceCreation");
139 void ScheduledActionPrepareTiles() override
{
140 PushAction("ScheduledActionPrepareTiles");
141 scheduler_
->WillPrepareTiles();
142 scheduler_
->DidPrepareTiles();
144 void ScheduledActionInvalidateOutputSurface() override
{
145 actions_
.push_back("ScheduledActionInvalidateOutputSurface");
146 states_
.push_back(scheduler_
->AsValue());
149 void SendBeginFramesToChildren(const BeginFrameArgs
& args
) override
{
150 begin_frame_args_sent_to_children_
= args
;
153 void SendBeginMainFrameNotExpectedSoon() override
{
154 PushAction("SendBeginMainFrameNotExpectedSoon");
157 base::Callback
<bool(void)> ImplFrameDeadlinePending(bool state
) {
158 return base::Bind(&FakeSchedulerClient::ImplFrameDeadlinePendingCallback
,
159 base::Unretained(this),
163 bool begin_frame_is_sent_to_children() const {
164 return begin_frame_args_sent_to_children_
.IsValid();
167 const BeginFrameArgs
& begin_frame_args_sent_to_children() const {
168 return begin_frame_args_sent_to_children_
;
171 void PushAction(const char* description
) {
172 actions_
.push_back(description
);
173 states_
.push_back(scheduler_
->AsValue());
177 bool ImplFrameDeadlinePendingCallback(bool state
) {
178 return scheduler_
->BeginImplFrameDeadlinePending() == state
;
181 bool draw_will_happen_
;
182 bool swap_will_happen_if_draw_happens_
;
183 bool automatic_swap_ack_
;
185 BeginFrameArgs begin_frame_args_sent_to_children_
;
186 base::TimeTicks posted_begin_impl_frame_deadline_
;
187 std::vector
<const char*> actions_
;
188 std::vector
<scoped_refptr
<base::trace_event::ConvertableToTraceFormat
>>
190 TestScheduler
* scheduler_
;
193 class FakeExternalBeginFrameSource
: public BeginFrameSourceBase
{
195 explicit FakeExternalBeginFrameSource(FakeSchedulerClient
* client
)
197 ~FakeExternalBeginFrameSource() override
{}
199 void OnNeedsBeginFramesChange(bool needs_begin_frames
) override
{
200 if (needs_begin_frames
) {
201 client_
->PushAction("SetNeedsBeginFrames(true)");
203 client_
->PushAction("SetNeedsBeginFrames(false)");
207 void TestOnBeginFrame(const BeginFrameArgs
& args
) {
208 return CallOnBeginFrame(args
);
212 FakeSchedulerClient
* client_
;
215 class SchedulerTest
: public testing::Test
{
218 : now_src_(new base::SimpleTestTickClock()),
219 task_runner_(new OrderedSimpleTaskRunner(now_src_
.get(), true)),
220 fake_external_begin_frame_source_(nullptr) {
221 now_src_
->Advance(base::TimeDelta::FromMicroseconds(10000));
222 // A bunch of tests require NowTicks()
223 // to be > BeginFrameArgs::DefaultInterval()
224 now_src_
->Advance(base::TimeDelta::FromMilliseconds(100));
225 // Fail if we need to run 100 tasks in a row.
226 task_runner_
->SetRunTaskLimit(100);
229 ~SchedulerTest() override
{}
232 TestScheduler
* CreateScheduler() {
233 if (scheduler_settings_
.use_external_begin_frame_source
) {
234 fake_external_begin_frame_source_
.reset(
235 new FakeExternalBeginFrameSource(client_
.get()));
238 scoped_ptr
<FakeCompositorTimingHistory
> fake_compositor_timing_history
=
239 FakeCompositorTimingHistory::Create();
240 fake_compositor_timing_history_
= fake_compositor_timing_history
.get();
242 scheduler_
= TestScheduler::Create(
243 now_src_
.get(), client_
.get(), scheduler_settings_
, 0,
244 task_runner_
.get(), fake_external_begin_frame_source_
.get(),
245 fake_compositor_timing_history
.Pass());
247 client_
->set_scheduler(scheduler_
.get());
249 // Use large estimates by default to avoid latency recovery
251 base::TimeDelta slow_duration
= base::TimeDelta::FromSeconds(1);
252 fake_compositor_timing_history_
->SetAllEstimatesTo(slow_duration
);
254 return scheduler_
.get();
257 void CreateSchedulerAndInitSurface() {
259 EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit());
262 void SetUpScheduler(bool initSurface
) {
263 SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient
), initSurface
);
266 void SetUpScheduler(scoped_ptr
<FakeSchedulerClient
> client
,
268 client_
= client
.Pass();
270 CreateSchedulerAndInitSurface();
275 OrderedSimpleTaskRunner
& task_runner() { return *task_runner_
; }
276 base::SimpleTestTickClock
* now_src() { return now_src_
.get(); }
278 // As this function contains EXPECT macros, to allow debugging it should be
279 // called inside EXPECT_SCOPED like so;
280 // EXPECT_SCOPED(client.InitializeOutputSurfaceAndFirstCommit(scheduler));
281 void InitializeOutputSurfaceAndFirstCommit() {
283 "SchedulerUnitTest::InitializeOutputSurfaceAndFirstCommit");
286 // Check the client doesn't have any actions queued when calling this
288 EXPECT_NO_ACTION(client_
);
289 EXPECT_FALSE(client_
->needs_begin_frames());
291 // Start the initial output surface creation.
292 EXPECT_FALSE(scheduler_
->CanStart());
293 scheduler_
->SetCanStart();
294 scheduler_
->SetVisible(true);
295 scheduler_
->SetCanDraw(true);
296 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
);
300 // We don't see anything happening until the first impl frame.
301 scheduler_
->DidCreateAndInitializeOutputSurface();
302 scheduler_
->SetNeedsBeginMainFrame();
303 EXPECT_TRUE(client_
->needs_begin_frames());
304 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
308 SCOPED_TRACE("Do first frame to commit after initialize.");
311 scheduler_
->NotifyBeginMainFrameStarted();
312 scheduler_
->NotifyReadyToCommit();
313 scheduler_
->NotifyReadyToActivate();
314 scheduler_
->NotifyReadyToDraw();
316 EXPECT_FALSE(scheduler_
->CommitPending());
318 if (scheduler_settings_
.using_synchronous_renderer_compositor
) {
319 scheduler_
->SetNeedsRedraw();
320 scheduler_
->OnDrawForOutputSurface();
322 // Run the posted deadline task.
323 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
324 task_runner_
->RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
327 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
334 "Run second frame so Scheduler calls SetNeedsBeginFrame(false).");
337 if (!scheduler_settings_
.using_synchronous_renderer_compositor
) {
338 // Run the posted deadline task.
339 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
340 task_runner_
->RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
343 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
346 EXPECT_FALSE(client_
->needs_begin_frames());
350 // As this function contains EXPECT macros, to allow debugging it should be
351 // called inside EXPECT_SCOPED like so;
352 // EXPECT_SCOPED(client.AdvanceFrame());
353 void AdvanceFrame() {
354 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
355 "FakeSchedulerClient::AdvanceFrame");
356 // Consume any previous deadline first, if no deadline is currently
357 // pending, ImplFrameDeadlinePending will return false straight away and we
358 // will run no tasks.
359 task_runner_
->RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
360 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
362 // Send the next BeginFrame message if using an external source, otherwise
363 // it will be already in the task queue.
364 if (scheduler_
->settings().use_external_begin_frame_source
&&
365 scheduler_
->FrameProductionThrottled()) {
366 EXPECT_TRUE(client_
->needs_begin_frames());
367 SendNextBeginFrame();
370 if (!scheduler_
->settings().using_synchronous_renderer_compositor
) {
371 // Then run tasks until new deadline is scheduled.
372 EXPECT_TRUE(task_runner_
->RunTasksWhile(
373 client_
->ImplFrameDeadlinePending(false)));
374 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
378 BeginFrameArgs
SendNextBeginFrame() {
379 DCHECK(scheduler_
->settings().use_external_begin_frame_source
);
380 // Creep the time forward so that any BeginFrameArgs is not equal to the
381 // last one otherwise we violate the BeginFrameSource contract.
382 now_src_
->Advance(BeginFrameArgs::DefaultInterval());
383 BeginFrameArgs args
=
384 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
385 fake_external_begin_frame_source_
->TestOnBeginFrame(args
);
389 FakeExternalBeginFrameSource
* fake_external_begin_frame_source() const {
390 return fake_external_begin_frame_source_
.get();
393 void CheckMainFrameSkippedAfterLateCommit(bool expect_send_begin_main_frame
);
394 void ImplFrameSkippedAfterLateSwapAck(bool swap_ack_before_deadline
);
395 void ImplFrameIsNotSkippedAfterLateSwapAck();
396 void BeginFramesNotFromClient(bool use_external_begin_frame_source
,
397 bool throttle_frame_production
);
398 void BeginFramesNotFromClient_SwapThrottled(
399 bool use_external_begin_frame_source
,
400 bool throttle_frame_production
);
402 scoped_ptr
<base::SimpleTestTickClock
> now_src_
;
403 scoped_refptr
<OrderedSimpleTaskRunner
> task_runner_
;
404 scoped_ptr
<FakeExternalBeginFrameSource
> fake_external_begin_frame_source_
;
405 SchedulerSettings scheduler_settings_
;
406 scoped_ptr
<FakeSchedulerClient
> client_
;
407 scoped_ptr
<TestScheduler
> scheduler_
;
408 FakeCompositorTimingHistory
* fake_compositor_timing_history_
;
411 TEST_F(SchedulerTest
, InitializeOutputSurfaceDoesNotBeginImplFrame
) {
412 scheduler_settings_
.use_external_begin_frame_source
= true;
413 SetUpScheduler(false);
414 scheduler_
->SetCanStart();
415 scheduler_
->SetVisible(true);
416 scheduler_
->SetCanDraw(true);
418 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
);
420 scheduler_
->DidCreateAndInitializeOutputSurface();
421 EXPECT_NO_ACTION(client_
);
424 TEST_F(SchedulerTest
, SendBeginFramesToChildren
) {
425 scheduler_settings_
.use_external_begin_frame_source
= true;
426 SetUpScheduler(true);
428 EXPECT_FALSE(client_
->begin_frame_is_sent_to_children());
429 scheduler_
->SetNeedsBeginMainFrame();
430 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
431 EXPECT_TRUE(client_
->needs_begin_frames());
433 scheduler_
->SetChildrenNeedBeginFrames(true);
436 EXPECT_SCOPED(AdvanceFrame());
437 EXPECT_TRUE(client_
->begin_frame_is_sent_to_children());
438 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
439 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
440 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
441 EXPECT_TRUE(client_
->needs_begin_frames());
444 TEST_F(SchedulerTest
, SendBeginFramesToChildrenWithoutCommit
) {
445 scheduler_settings_
.use_external_begin_frame_source
= true;
446 SetUpScheduler(true);
448 EXPECT_FALSE(client_
->needs_begin_frames());
449 scheduler_
->SetChildrenNeedBeginFrames(true);
450 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
451 EXPECT_TRUE(client_
->needs_begin_frames());
454 EXPECT_SCOPED(AdvanceFrame());
455 EXPECT_TRUE(client_
->begin_frame_is_sent_to_children());
458 TEST_F(SchedulerTest
, SendBeginFramesToChildrenDeadlineNotAdjusted
) {
459 // Set up client with specified estimates.
460 scheduler_settings_
.use_external_begin_frame_source
= true;
461 SetUpScheduler(true);
463 fake_compositor_timing_history_
->SetBeginMainFrameToCommitDurationEstimate(
464 base::TimeDelta::FromMilliseconds(2));
465 fake_compositor_timing_history_
->SetCommitToReadyToActivateDurationEstimate(
466 base::TimeDelta::FromMilliseconds(4));
467 fake_compositor_timing_history_
->SetDrawDurationEstimate(
468 base::TimeDelta::FromMilliseconds(1));
470 EXPECT_FALSE(client_
->needs_begin_frames());
471 scheduler_
->SetChildrenNeedBeginFrames(true);
472 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
473 EXPECT_TRUE(client_
->needs_begin_frames());
477 BeginFrameArgs frame_args
=
478 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
479 fake_external_begin_frame_source()->TestOnBeginFrame(frame_args
);
481 EXPECT_TRUE(client_
->begin_frame_is_sent_to_children());
482 EXPECT_EQ(client_
->begin_frame_args_sent_to_children().deadline
,
483 frame_args
.deadline
);
486 TEST_F(SchedulerTest
, VideoNeedsBeginFrames
) {
487 scheduler_settings_
.use_external_begin_frame_source
= true;
488 SetUpScheduler(true);
490 scheduler_
->SetVideoNeedsBeginFrames(true);
491 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
492 EXPECT_TRUE(client_
->needs_begin_frames());
495 EXPECT_SCOPED(AdvanceFrame());
496 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
497 // WillBeginImplFrame is responsible for sending BeginFrames to video.
498 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
501 EXPECT_SCOPED(AdvanceFrame());
502 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
503 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
506 scheduler_
->SetVideoNeedsBeginFrames(false);
507 EXPECT_NO_ACTION(client_
);
510 task_runner_
->RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
511 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
512 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
513 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
514 EXPECT_FALSE(client_
->needs_begin_frames());
517 TEST_F(SchedulerTest
, RequestCommit
) {
518 scheduler_settings_
.use_external_begin_frame_source
= true;
519 SetUpScheduler(true);
521 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
522 scheduler_
->SetNeedsBeginMainFrame();
523 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
526 EXPECT_SCOPED(AdvanceFrame());
527 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
528 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
529 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
530 EXPECT_TRUE(client_
->needs_begin_frames());
533 // If we don't swap on the deadline, we wait for the next BeginFrame.
534 task_runner().RunPendingTasks(); // Run posted deadline.
535 EXPECT_NO_ACTION(client_
);
536 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
537 EXPECT_TRUE(client_
->needs_begin_frames());
540 // NotifyReadyToCommit should trigger the commit.
541 scheduler_
->NotifyBeginMainFrameStarted();
542 scheduler_
->NotifyReadyToCommit();
543 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
544 EXPECT_TRUE(client_
->needs_begin_frames());
547 // NotifyReadyToActivate should trigger the activation.
548 scheduler_
->NotifyReadyToActivate();
549 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
550 EXPECT_TRUE(client_
->needs_begin_frames());
553 // BeginImplFrame should prepare the draw.
554 EXPECT_SCOPED(AdvanceFrame());
555 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
556 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
557 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
558 EXPECT_TRUE(client_
->needs_begin_frames());
561 // BeginImplFrame deadline should draw.
562 task_runner().RunPendingTasks(); // Run posted deadline.
563 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
564 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
565 EXPECT_TRUE(client_
->needs_begin_frames());
568 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
569 // to avoid excessive toggles.
570 EXPECT_SCOPED(AdvanceFrame());
571 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
572 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
575 task_runner().RunPendingTasks(); // Run posted deadline.
576 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
577 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
581 TEST_F(SchedulerTest
, RequestCommitAfterSetDeferCommit
) {
582 scheduler_settings_
.use_external_begin_frame_source
= true;
583 SetUpScheduler(true);
585 scheduler_
->SetDeferCommits(true);
587 scheduler_
->SetNeedsBeginMainFrame();
588 EXPECT_NO_ACTION(client_
);
591 task_runner().RunPendingTasks();
592 // There are no pending tasks or actions.
593 EXPECT_NO_ACTION(client_
);
594 EXPECT_FALSE(client_
->needs_begin_frames());
597 scheduler_
->SetDeferCommits(false);
598 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
600 // Start new BeginMainFrame after defer commit is off.
602 EXPECT_SCOPED(AdvanceFrame());
603 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
604 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
605 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
608 TEST_F(SchedulerTest
, DeferCommitWithRedraw
) {
609 scheduler_settings_
.use_external_begin_frame_source
= true;
610 SetUpScheduler(true);
612 scheduler_
->SetDeferCommits(true);
614 scheduler_
->SetNeedsBeginMainFrame();
615 EXPECT_NO_ACTION(client_
);
617 // The SetNeedsRedraw will override the SetDeferCommits(true), to allow a
618 // begin frame to be needed.
620 scheduler_
->SetNeedsRedraw();
621 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
625 // BeginMainFrame is not sent during the defer commit is on.
626 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
627 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
630 task_runner().RunPendingTasks(); // Run posted deadline.
631 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
632 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
633 EXPECT_TRUE(client_
->needs_begin_frames());
637 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
640 TEST_F(SchedulerTest
, RequestCommitAfterBeginMainFrameSent
) {
641 scheduler_settings_
.use_external_begin_frame_source
= true;
642 SetUpScheduler(true);
644 // SetNeedsBeginMainFrame should begin the frame.
645 scheduler_
->SetNeedsBeginMainFrame();
646 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
649 EXPECT_SCOPED(AdvanceFrame());
650 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
651 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
652 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
654 EXPECT_TRUE(client_
->needs_begin_frames());
657 // Now SetNeedsBeginMainFrame again. Calling here means we need a second
659 scheduler_
->SetNeedsBeginMainFrame();
660 EXPECT_EQ(client_
->num_actions_(), 0);
663 // Finish the first commit.
664 scheduler_
->NotifyBeginMainFrameStarted();
665 scheduler_
->NotifyReadyToCommit();
666 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
667 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
671 scheduler_
->NotifyReadyToActivate();
672 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
673 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
676 task_runner().RunPendingTasks(); // Run posted deadline.
677 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
678 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
679 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
681 // Because we just swapped, the Scheduler should also request the next
682 // BeginImplFrame from the OutputSurface.
683 EXPECT_TRUE(client_
->needs_begin_frames());
685 // Since another commit is needed, the next BeginImplFrame should initiate
686 // the second commit.
687 EXPECT_SCOPED(AdvanceFrame());
688 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
689 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
690 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
693 // Finishing the commit before the deadline should post a new deadline task
694 // to trigger the deadline early.
695 scheduler_
->NotifyBeginMainFrameStarted();
696 scheduler_
->NotifyReadyToCommit();
697 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
698 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
700 scheduler_
->NotifyReadyToActivate();
701 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
702 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
704 task_runner().RunPendingTasks(); // Run posted deadline.
705 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
706 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
707 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
708 EXPECT_TRUE(client_
->needs_begin_frames());
711 // On the next BeginImplFrame, verify we go back to a quiescent state and
712 // no longer request BeginImplFrames.
713 EXPECT_SCOPED(AdvanceFrame());
714 task_runner().RunPendingTasks(); // Run posted deadline.
715 EXPECT_FALSE(client_
->needs_begin_frames());
719 class SchedulerClientThatsetNeedsDrawInsideDraw
: public FakeSchedulerClient
{
721 SchedulerClientThatsetNeedsDrawInsideDraw()
722 : FakeSchedulerClient(), request_redraws_(false) {}
724 void SetRequestRedrawsInsideDraw(bool enable
) { request_redraws_
= enable
; }
726 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
727 // Only SetNeedsRedraw the first time this is called
728 if (request_redraws_
) {
729 scheduler_
->SetNeedsRedraw();
731 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
734 DrawResult
ScheduledActionDrawAndSwapForced() override
{
740 bool request_redraws_
;
743 // Tests for two different situations:
744 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside
745 // a ScheduledActionDrawAndSwap
746 // 2. the scheduler drawing twice inside a single tick
747 TEST_F(SchedulerTest
, RequestRedrawInsideDraw
) {
748 SchedulerClientThatsetNeedsDrawInsideDraw
* client
=
749 new SchedulerClientThatsetNeedsDrawInsideDraw
;
750 scheduler_settings_
.use_external_begin_frame_source
= true;
751 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
752 client
->SetRequestRedrawsInsideDraw(true);
754 scheduler_
->SetNeedsRedraw();
755 EXPECT_TRUE(scheduler_
->RedrawPending());
756 EXPECT_TRUE(client
->needs_begin_frames());
757 EXPECT_EQ(0, client
->num_draws());
759 EXPECT_SCOPED(AdvanceFrame());
760 task_runner().RunPendingTasks(); // Run posted deadline.
761 EXPECT_EQ(1, client
->num_draws());
762 EXPECT_TRUE(scheduler_
->RedrawPending());
763 EXPECT_TRUE(client
->needs_begin_frames());
765 client
->SetRequestRedrawsInsideDraw(false);
767 EXPECT_SCOPED(AdvanceFrame());
768 task_runner().RunPendingTasks(); // Run posted deadline.
769 EXPECT_EQ(2, client_
->num_draws());
770 EXPECT_FALSE(scheduler_
->RedrawPending());
771 EXPECT_TRUE(client
->needs_begin_frames());
773 // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
775 EXPECT_SCOPED(AdvanceFrame());
776 task_runner().RunPendingTasks(); // Run posted deadline.
777 EXPECT_EQ(2, client
->num_draws());
778 EXPECT_FALSE(scheduler_
->RedrawPending());
779 EXPECT_FALSE(client
->needs_begin_frames());
782 // Test that requesting redraw inside a failed draw doesn't lose the request.
783 TEST_F(SchedulerTest
, RequestRedrawInsideFailedDraw
) {
784 SchedulerClientThatsetNeedsDrawInsideDraw
* client
=
785 new SchedulerClientThatsetNeedsDrawInsideDraw
;
786 scheduler_settings_
.use_external_begin_frame_source
= true;
787 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
789 client
->SetRequestRedrawsInsideDraw(true);
790 client
->SetDrawWillHappen(false);
792 scheduler_
->SetNeedsRedraw();
793 EXPECT_TRUE(scheduler_
->RedrawPending());
794 EXPECT_TRUE(client
->needs_begin_frames());
795 EXPECT_EQ(0, client
->num_draws());
798 EXPECT_SCOPED(AdvanceFrame());
799 task_runner().RunPendingTasks(); // Run posted deadline.
800 EXPECT_EQ(1, client
->num_draws());
802 // We have a commit pending and the draw failed, and we didn't lose the redraw
804 EXPECT_TRUE(scheduler_
->CommitPending());
805 EXPECT_TRUE(scheduler_
->RedrawPending());
806 EXPECT_TRUE(client
->needs_begin_frames());
808 client
->SetRequestRedrawsInsideDraw(false);
810 // Fail the draw again.
811 EXPECT_SCOPED(AdvanceFrame());
812 task_runner().RunPendingTasks(); // Run posted deadline.
813 EXPECT_EQ(2, client
->num_draws());
814 EXPECT_TRUE(scheduler_
->CommitPending());
815 EXPECT_TRUE(scheduler_
->RedrawPending());
816 EXPECT_TRUE(client
->needs_begin_frames());
818 // Draw successfully.
819 client
->SetDrawWillHappen(true);
820 EXPECT_SCOPED(AdvanceFrame());
821 task_runner().RunPendingTasks(); // Run posted deadline.
822 EXPECT_EQ(3, client
->num_draws());
823 EXPECT_TRUE(scheduler_
->CommitPending());
824 EXPECT_FALSE(scheduler_
->RedrawPending());
825 EXPECT_TRUE(client
->needs_begin_frames());
828 class SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
829 : public FakeSchedulerClient
{
831 SchedulerClientThatSetNeedsBeginMainFrameInsideDraw()
832 : set_needs_commit_on_next_draw_(false) {}
834 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
835 // Only SetNeedsBeginMainFrame the first time this is called
836 if (set_needs_commit_on_next_draw_
) {
837 scheduler_
->SetNeedsBeginMainFrame();
838 set_needs_commit_on_next_draw_
= false;
840 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
843 DrawResult
ScheduledActionDrawAndSwapForced() override
{
848 void SetNeedsBeginMainFrameOnNextDraw() {
849 set_needs_commit_on_next_draw_
= true;
853 bool set_needs_commit_on_next_draw_
;
856 // Tests for the scheduler infinite-looping on SetNeedsBeginMainFrame requests
857 // that happen inside a ScheduledActionDrawAndSwap
858 TEST_F(SchedulerTest
, RequestCommitInsideDraw
) {
859 SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
* client
=
860 new SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
;
862 scheduler_settings_
.use_external_begin_frame_source
= true;
863 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
865 EXPECT_FALSE(client
->needs_begin_frames());
866 scheduler_
->SetNeedsRedraw();
867 EXPECT_TRUE(scheduler_
->RedrawPending());
868 EXPECT_EQ(0, client
->num_draws());
869 EXPECT_TRUE(client
->needs_begin_frames());
871 client
->SetNeedsBeginMainFrameOnNextDraw();
872 EXPECT_SCOPED(AdvanceFrame());
873 client
->SetNeedsBeginMainFrameOnNextDraw();
874 task_runner().RunPendingTasks(); // Run posted deadline.
875 EXPECT_EQ(1, client
->num_draws());
876 EXPECT_TRUE(scheduler_
->CommitPending());
877 EXPECT_TRUE(client
->needs_begin_frames());
878 scheduler_
->NotifyBeginMainFrameStarted();
879 scheduler_
->NotifyReadyToCommit();
880 scheduler_
->NotifyReadyToActivate();
882 EXPECT_SCOPED(AdvanceFrame());
883 task_runner().RunPendingTasks(); // Run posted deadline.
884 EXPECT_EQ(2, client
->num_draws());
886 EXPECT_FALSE(scheduler_
->RedrawPending());
887 EXPECT_FALSE(scheduler_
->CommitPending());
888 EXPECT_TRUE(client
->needs_begin_frames());
890 // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
892 EXPECT_SCOPED(AdvanceFrame());
893 task_runner().RunPendingTasks(); // Run posted deadline.
894 EXPECT_EQ(2, client
->num_draws());
895 EXPECT_FALSE(scheduler_
->RedrawPending());
896 EXPECT_FALSE(scheduler_
->CommitPending());
897 EXPECT_FALSE(client
->needs_begin_frames());
900 // Tests that when a draw fails then the pending commit should not be dropped.
901 TEST_F(SchedulerTest
, RequestCommitInsideFailedDraw
) {
902 SchedulerClientThatsetNeedsDrawInsideDraw
* client
=
903 new SchedulerClientThatsetNeedsDrawInsideDraw
;
904 scheduler_settings_
.use_external_begin_frame_source
= true;
905 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
907 client
->SetDrawWillHappen(false);
909 scheduler_
->SetNeedsRedraw();
910 EXPECT_TRUE(scheduler_
->RedrawPending());
911 EXPECT_TRUE(client
->needs_begin_frames());
912 EXPECT_EQ(0, client
->num_draws());
915 EXPECT_SCOPED(AdvanceFrame());
916 task_runner().RunPendingTasks(); // Run posted deadline.
917 EXPECT_EQ(1, client
->num_draws());
919 // We have a commit pending and the draw failed, and we didn't lose the commit
921 EXPECT_TRUE(scheduler_
->CommitPending());
922 EXPECT_TRUE(scheduler_
->RedrawPending());
923 EXPECT_TRUE(client
->needs_begin_frames());
925 // Fail the draw again.
926 EXPECT_SCOPED(AdvanceFrame());
928 task_runner().RunPendingTasks(); // Run posted deadline.
929 EXPECT_EQ(2, client
->num_draws());
930 EXPECT_TRUE(scheduler_
->CommitPending());
931 EXPECT_TRUE(scheduler_
->RedrawPending());
932 EXPECT_TRUE(client
->needs_begin_frames());
934 // Draw successfully.
935 client
->SetDrawWillHappen(true);
936 EXPECT_SCOPED(AdvanceFrame());
937 task_runner().RunPendingTasks(); // Run posted deadline.
938 EXPECT_EQ(3, client
->num_draws());
939 EXPECT_TRUE(scheduler_
->CommitPending());
940 EXPECT_FALSE(scheduler_
->RedrawPending());
941 EXPECT_TRUE(client
->needs_begin_frames());
944 TEST_F(SchedulerTest
, NoSwapWhenDrawFails
) {
945 SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
* client
=
946 new SchedulerClientThatSetNeedsBeginMainFrameInsideDraw
;
947 scheduler_settings_
.use_external_begin_frame_source
= true;
948 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
950 scheduler_
->SetNeedsRedraw();
951 EXPECT_TRUE(scheduler_
->RedrawPending());
952 EXPECT_TRUE(client
->needs_begin_frames());
953 EXPECT_EQ(0, client
->num_draws());
955 // Draw successfully, this starts a new frame.
956 client
->SetNeedsBeginMainFrameOnNextDraw();
957 EXPECT_SCOPED(AdvanceFrame());
958 task_runner().RunPendingTasks(); // Run posted deadline.
959 EXPECT_EQ(1, client
->num_draws());
961 scheduler_
->SetNeedsRedraw();
962 EXPECT_TRUE(scheduler_
->RedrawPending());
963 EXPECT_TRUE(client
->needs_begin_frames());
965 // Fail to draw, this should not start a frame.
966 client
->SetDrawWillHappen(false);
967 client
->SetNeedsBeginMainFrameOnNextDraw();
968 EXPECT_SCOPED(AdvanceFrame());
969 task_runner().RunPendingTasks(); // Run posted deadline.
970 EXPECT_EQ(2, client
->num_draws());
973 class SchedulerClientNeedsPrepareTilesInDraw
: public FakeSchedulerClient
{
975 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
976 scheduler_
->SetNeedsPrepareTiles();
977 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
981 // Test prepare tiles is independant of draws.
982 TEST_F(SchedulerTest
, PrepareTiles
) {
983 SchedulerClientNeedsPrepareTilesInDraw
* client
=
984 new SchedulerClientNeedsPrepareTilesInDraw
;
985 scheduler_settings_
.use_external_begin_frame_source
= true;
986 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
988 // Request both draw and prepare tiles. PrepareTiles shouldn't
989 // be trigged until BeginImplFrame.
991 scheduler_
->SetNeedsPrepareTiles();
992 scheduler_
->SetNeedsRedraw();
993 EXPECT_TRUE(scheduler_
->RedrawPending());
994 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
995 EXPECT_TRUE(client
->needs_begin_frames());
996 EXPECT_EQ(0, client
->num_draws());
997 EXPECT_FALSE(client
->HasAction("ScheduledActionPrepareTiles"));
998 EXPECT_FALSE(client
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1000 // We have no immediate actions to perform, so the BeginImplFrame should post
1001 // the deadline task.
1003 EXPECT_SCOPED(AdvanceFrame());
1004 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1005 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1006 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1008 // On the deadline, he actions should have occured in the right order.
1010 task_runner().RunPendingTasks(); // Run posted deadline.
1011 EXPECT_EQ(1, client
->num_draws());
1012 EXPECT_TRUE(client
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1013 EXPECT_TRUE(client
->HasAction("ScheduledActionPrepareTiles"));
1014 EXPECT_LT(client
->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
1015 client
->ActionIndex("ScheduledActionPrepareTiles"));
1016 EXPECT_FALSE(scheduler_
->RedrawPending());
1017 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1018 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1020 // Request a draw. We don't need a PrepareTiles yet.
1022 scheduler_
->SetNeedsRedraw();
1023 EXPECT_TRUE(scheduler_
->RedrawPending());
1024 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1025 EXPECT_TRUE(client
->needs_begin_frames());
1026 EXPECT_EQ(0, client
->num_draws());
1028 // We have no immediate actions to perform, so the BeginImplFrame should post
1029 // the deadline task.
1031 EXPECT_SCOPED(AdvanceFrame());
1032 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1033 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1034 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1036 // Draw. The draw will trigger SetNeedsPrepareTiles, and
1037 // then the PrepareTiles action will be triggered after the Draw.
1038 // Afterwards, neither a draw nor PrepareTiles are pending.
1040 task_runner().RunPendingTasks(); // Run posted deadline.
1041 EXPECT_EQ(1, client
->num_draws());
1042 EXPECT_TRUE(client
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1043 EXPECT_TRUE(client
->HasAction("ScheduledActionPrepareTiles"));
1044 EXPECT_LT(client
->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
1045 client
->ActionIndex("ScheduledActionPrepareTiles"));
1046 EXPECT_FALSE(scheduler_
->RedrawPending());
1047 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1048 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1050 // We need a BeginImplFrame where we don't swap to go idle.
1052 EXPECT_SCOPED(AdvanceFrame());
1053 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
1054 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1056 task_runner().RunPendingTasks(); // Run posted deadline.
1057 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
1058 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
1059 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1060 EXPECT_EQ(0, client
->num_draws());
1062 // Now trigger a PrepareTiles outside of a draw. We will then need
1063 // a begin-frame for the PrepareTiles, but we don't need a draw.
1065 EXPECT_FALSE(client
->needs_begin_frames());
1066 scheduler_
->SetNeedsPrepareTiles();
1067 EXPECT_TRUE(client
->needs_begin_frames());
1068 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
1069 EXPECT_FALSE(scheduler_
->RedrawPending());
1071 // BeginImplFrame. There will be no draw, only PrepareTiles.
1073 EXPECT_SCOPED(AdvanceFrame());
1074 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
1075 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1077 task_runner().RunPendingTasks(); // Run posted deadline.
1078 EXPECT_EQ(0, client
->num_draws());
1079 EXPECT_FALSE(client
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1080 EXPECT_TRUE(client
->HasAction("ScheduledActionPrepareTiles"));
1081 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1084 // Test that PrepareTiles only happens once per frame. If an external caller
1085 // initiates it, then the state machine should not PrepareTiles on that frame.
1086 TEST_F(SchedulerTest
, PrepareTilesOncePerFrame
) {
1087 scheduler_settings_
.use_external_begin_frame_source
= true;
1088 SetUpScheduler(true);
1090 // If DidPrepareTiles during a frame, then PrepareTiles should not occur
1092 scheduler_
->SetNeedsPrepareTiles();
1093 scheduler_
->SetNeedsRedraw();
1095 EXPECT_SCOPED(AdvanceFrame());
1096 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1097 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1098 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1100 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
1101 scheduler_
->WillPrepareTiles();
1102 scheduler_
->DidPrepareTiles(); // An explicit PrepareTiles.
1103 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1106 task_runner().RunPendingTasks(); // Run posted deadline.
1107 EXPECT_EQ(1, client_
->num_draws());
1108 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1109 EXPECT_FALSE(client_
->HasAction("ScheduledActionPrepareTiles"));
1110 EXPECT_FALSE(scheduler_
->RedrawPending());
1111 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1112 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1114 // Next frame without DidPrepareTiles should PrepareTiles with draw.
1115 scheduler_
->SetNeedsPrepareTiles();
1116 scheduler_
->SetNeedsRedraw();
1118 EXPECT_SCOPED(AdvanceFrame());
1119 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1120 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1121 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1124 task_runner().RunPendingTasks(); // Run posted deadline.
1125 EXPECT_EQ(1, client_
->num_draws());
1126 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1127 EXPECT_TRUE(client_
->HasAction("ScheduledActionPrepareTiles"));
1128 EXPECT_LT(client_
->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
1129 client_
->ActionIndex("ScheduledActionPrepareTiles"));
1130 EXPECT_FALSE(scheduler_
->RedrawPending());
1131 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1132 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1134 // If we get another DidPrepareTiles within the same frame, we should
1135 // not PrepareTiles on the next frame.
1136 scheduler_
->WillPrepareTiles();
1137 scheduler_
->DidPrepareTiles(); // An explicit PrepareTiles.
1138 scheduler_
->SetNeedsPrepareTiles();
1139 scheduler_
->SetNeedsRedraw();
1141 EXPECT_SCOPED(AdvanceFrame());
1142 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1143 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1144 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1146 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
1149 task_runner().RunPendingTasks(); // Run posted deadline.
1150 EXPECT_EQ(1, client_
->num_draws());
1151 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1152 EXPECT_FALSE(client_
->HasAction("ScheduledActionPrepareTiles"));
1153 EXPECT_FALSE(scheduler_
->RedrawPending());
1154 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1156 // If we get another DidPrepareTiles, we should not PrepareTiles on the next
1157 // frame. This verifies we don't alternate calling PrepareTiles once and
1159 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
1160 scheduler_
->WillPrepareTiles();
1161 scheduler_
->DidPrepareTiles(); // An explicit PrepareTiles.
1162 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1163 scheduler_
->SetNeedsPrepareTiles();
1164 scheduler_
->SetNeedsRedraw();
1166 EXPECT_SCOPED(AdvanceFrame());
1167 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1168 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1169 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1171 EXPECT_TRUE(scheduler_
->PrepareTilesPending());
1174 task_runner().RunPendingTasks(); // Run posted deadline.
1175 EXPECT_EQ(1, client_
->num_draws());
1176 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1177 EXPECT_FALSE(client_
->HasAction("ScheduledActionPrepareTiles"));
1178 EXPECT_FALSE(scheduler_
->RedrawPending());
1179 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1181 // Next frame without DidPrepareTiles should PrepareTiles with draw.
1182 scheduler_
->SetNeedsPrepareTiles();
1183 scheduler_
->SetNeedsRedraw();
1185 EXPECT_SCOPED(AdvanceFrame());
1186 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1187 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1188 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1191 task_runner().RunPendingTasks(); // Run posted deadline.
1192 EXPECT_EQ(1, client_
->num_draws());
1193 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1194 EXPECT_TRUE(client_
->HasAction("ScheduledActionPrepareTiles"));
1195 EXPECT_LT(client_
->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
1196 client_
->ActionIndex("ScheduledActionPrepareTiles"));
1197 EXPECT_FALSE(scheduler_
->RedrawPending());
1198 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
1199 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1202 TEST_F(SchedulerTest
, PrepareTilesFunnelResetOnVisibilityChange
) {
1203 scoped_ptr
<SchedulerClientNeedsPrepareTilesInDraw
> client
=
1204 make_scoped_ptr(new SchedulerClientNeedsPrepareTilesInDraw
);
1205 scheduler_settings_
.use_external_begin_frame_source
= true;
1206 SetUpScheduler(client
.Pass(), true);
1208 // Simulate a few visibility changes and associated PrepareTiles.
1209 for (int i
= 0; i
< 10; i
++) {
1210 scheduler_
->SetVisible(false);
1211 scheduler_
->WillPrepareTiles();
1212 scheduler_
->DidPrepareTiles();
1214 scheduler_
->SetVisible(true);
1215 scheduler_
->WillPrepareTiles();
1216 scheduler_
->DidPrepareTiles();
1220 scheduler_
->SetNeedsRedraw();
1221 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
1225 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1226 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1227 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1230 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1231 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1232 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 2);
1233 EXPECT_ACTION("ScheduledActionPrepareTiles", client_
, 1, 2);
1236 TEST_F(SchedulerTest
, TriggerBeginFrameDeadlineEarly
) {
1237 SchedulerClientNeedsPrepareTilesInDraw
* client
=
1238 new SchedulerClientNeedsPrepareTilesInDraw
;
1239 scheduler_settings_
.use_external_begin_frame_source
= true;
1240 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
1242 scheduler_
->SetNeedsRedraw();
1243 EXPECT_SCOPED(AdvanceFrame());
1245 // The deadline should be zero since there is no work other than drawing
1247 EXPECT_EQ(base::TimeTicks(), client
->posted_begin_impl_frame_deadline());
1250 TEST_F(SchedulerTest
, WaitForReadyToDrawDoNotPostDeadline
) {
1251 SchedulerClientNeedsPrepareTilesInDraw
* client
=
1252 new SchedulerClientNeedsPrepareTilesInDraw
;
1253 scheduler_settings_
.use_external_begin_frame_source
= true;
1254 scheduler_settings_
.commit_to_active_tree
= true;
1255 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
1257 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
1258 scheduler_
->SetNeedsBeginMainFrame();
1259 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
1263 EXPECT_SCOPED(AdvanceFrame());
1264 scheduler_
->NotifyBeginMainFrameStarted();
1265 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1266 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
1269 scheduler_
->NotifyReadyToCommit();
1270 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
1273 scheduler_
->NotifyReadyToActivate();
1274 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
1276 // Scheduler won't post deadline in the mode.
1278 task_runner().RunPendingTasks(); // Try to run posted deadline.
1279 // There is no posted deadline.
1280 EXPECT_NO_ACTION(client_
);
1282 // Scheduler received ready to draw signal, and posted deadline.
1283 scheduler_
->NotifyReadyToDraw();
1285 task_runner().RunPendingTasks(); // Run posted deadline.
1286 EXPECT_EQ(1, client_
->num_draws());
1287 EXPECT_TRUE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1290 TEST_F(SchedulerTest
, WaitForReadyToDrawCancelledWhenLostOutputSurface
) {
1291 SchedulerClientNeedsPrepareTilesInDraw
* client
=
1292 new SchedulerClientNeedsPrepareTilesInDraw
;
1293 scheduler_settings_
.use_external_begin_frame_source
= true;
1294 scheduler_settings_
.commit_to_active_tree
= true;
1295 SetUpScheduler(make_scoped_ptr(client
).Pass(), true);
1297 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
1298 scheduler_
->SetNeedsBeginMainFrame();
1299 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
1303 EXPECT_SCOPED(AdvanceFrame());
1304 scheduler_
->NotifyBeginMainFrameStarted();
1305 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1306 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
1309 scheduler_
->NotifyReadyToCommit();
1310 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
1313 scheduler_
->NotifyReadyToActivate();
1314 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
1316 // Scheduler won't post deadline in the mode.
1318 task_runner().RunPendingTasks(); // Try to run posted deadline.
1319 // There is no posted deadline.
1320 EXPECT_NO_ACTION(client_
);
1322 // Scheduler loses output surface, and stops waiting for ready to draw signal.
1324 scheduler_
->DidLoseOutputSurface();
1325 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1326 task_runner().RunPendingTasks(); // Run posted deadline.
1327 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
1328 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
1329 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
1332 void SchedulerTest::CheckMainFrameSkippedAfterLateCommit(
1333 bool expect_send_begin_main_frame
) {
1334 // Impl thread hits deadline before commit finishes.
1335 scheduler_
->SetNeedsBeginMainFrame();
1336 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1337 EXPECT_SCOPED(AdvanceFrame());
1338 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1339 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1340 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1341 scheduler_
->NotifyBeginMainFrameStarted();
1342 scheduler_
->NotifyReadyToCommit();
1343 scheduler_
->NotifyReadyToActivate();
1344 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 5);
1345 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 5);
1346 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 5);
1347 EXPECT_ACTION("ScheduledActionCommit", client_
, 3, 5);
1348 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 4, 5);
1349 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1352 scheduler_
->SetNeedsBeginMainFrame();
1353 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1354 EXPECT_SCOPED(AdvanceFrame());
1355 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1356 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1357 EXPECT_EQ(expect_send_begin_main_frame
,
1358 scheduler_
->MainThreadMissedLastDeadline());
1359 EXPECT_EQ(expect_send_begin_main_frame
,
1360 client_
->HasAction("ScheduledActionSendBeginMainFrame"));
1363 TEST_F(SchedulerTest
, MainFrameSkippedAfterLateCommit
) {
1364 scheduler_settings_
.use_external_begin_frame_source
= true;
1365 SetUpScheduler(true);
1367 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1368 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1370 bool expect_send_begin_main_frame
= false;
1372 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1375 TEST_F(SchedulerTest
,
1376 MainFrameNotSkippedAfterLateCommitInPreferImplLatencyMode
) {
1377 scheduler_settings_
.use_external_begin_frame_source
= true;
1378 SetUpScheduler(true);
1379 scheduler_
->SetImplLatencyTakesPriority(true);
1381 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1382 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1384 bool expect_send_begin_main_frame
= true;
1386 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1389 TEST_F(SchedulerTest
,
1390 MainFrameNotSkippedAfterLateCommit_CommitEstimateTooLong
) {
1391 scheduler_settings_
.use_external_begin_frame_source
= true;
1392 SetUpScheduler(true);
1393 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1394 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1395 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1396 fake_compositor_timing_history_
->SetBeginMainFrameToCommitDurationEstimate(
1399 bool expect_send_begin_main_frame
= true;
1401 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1404 TEST_F(SchedulerTest
,
1405 MainFrameNotSkippedAfterLateCommit_ReadyToActivateEstimateTooLong
) {
1406 scheduler_settings_
.use_external_begin_frame_source
= true;
1407 SetUpScheduler(true);
1408 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1409 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1410 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1411 fake_compositor_timing_history_
->SetCommitToReadyToActivateDurationEstimate(
1414 bool expect_send_begin_main_frame
= true;
1416 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1419 TEST_F(SchedulerTest
,
1420 MainFrameNotSkippedAfterLateCommit_ActivateEstimateTooLong
) {
1421 scheduler_settings_
.use_external_begin_frame_source
= true;
1422 SetUpScheduler(true);
1423 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1424 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1425 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1426 fake_compositor_timing_history_
->SetActivateDurationEstimate(slow_duration
);
1428 bool expect_send_begin_main_frame
= true;
1430 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1433 TEST_F(SchedulerTest
, MainFrameNotSkippedAfterLateCommit_DrawEstimateTooLong
) {
1434 scheduler_settings_
.use_external_begin_frame_source
= true;
1435 SetUpScheduler(true);
1436 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1437 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1438 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1439 fake_compositor_timing_history_
->SetDrawDurationEstimate(slow_duration
);
1441 bool expect_send_begin_main_frame
= true;
1443 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame
));
1446 void SchedulerTest::ImplFrameSkippedAfterLateSwapAck(
1447 bool swap_ack_before_deadline
) {
1448 // To get into a high latency state, this test disables automatic swap acks.
1449 scheduler_
->SetMaxSwapsPending(1);
1450 client_
->SetAutomaticSwapAck(false);
1452 // Draw and swap for first BeginFrame
1454 scheduler_
->SetNeedsBeginMainFrame();
1455 scheduler_
->SetNeedsRedraw();
1456 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1457 SendNextBeginFrame();
1458 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 4);
1459 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 4);
1460 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 4);
1461 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 3, 4);
1464 scheduler_
->NotifyBeginMainFrameStarted();
1465 scheduler_
->NotifyReadyToCommit();
1466 scheduler_
->NotifyReadyToActivate();
1467 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1468 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1469 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 4);
1470 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 4);
1471 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 4);
1472 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 4);
1474 // Verify we skip every other frame if the swap ack consistently
1476 for (int i
= 0; i
< 10; i
++) {
1477 // Not calling scheduler_->DidSwapBuffersComplete() until after next
1478 // BeginImplFrame puts the impl thread in high latency mode.
1480 scheduler_
->SetNeedsBeginMainFrame();
1481 scheduler_
->SetNeedsRedraw();
1482 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1483 SendNextBeginFrame();
1484 // Verify that we skip the BeginImplFrame
1485 EXPECT_NO_ACTION(client_
);
1486 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1487 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1489 // Verify that we do not perform any actions after we are no longer
1492 if (swap_ack_before_deadline
) {
1493 // It shouldn't matter if the swap ack comes back before the deadline...
1494 scheduler_
->DidSwapBuffersComplete();
1495 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1497 // ... or after the deadline.
1498 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1499 scheduler_
->DidSwapBuffersComplete();
1501 EXPECT_NO_ACTION(client_
);
1503 // Verify that we start the next BeginImplFrame and continue normally
1504 // after having just skipped a BeginImplFrame.
1506 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1507 SendNextBeginFrame();
1508 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
1509 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
1510 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 3);
1513 scheduler_
->NotifyBeginMainFrameStarted();
1514 scheduler_
->NotifyReadyToCommit();
1515 scheduler_
->NotifyReadyToActivate();
1516 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1517 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 4);
1518 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 4);
1519 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 4);
1520 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 4);
1524 TEST_F(SchedulerTest
,
1525 ImplFrameSkippedAfterLateSwapAck_FastEstimates_SwapAckThenDeadline
) {
1526 scheduler_settings_
.use_external_begin_frame_source
= true;
1527 SetUpScheduler(true);
1529 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1530 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1532 bool swap_ack_before_deadline
= true;
1533 EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline
));
1536 TEST_F(SchedulerTest
,
1537 ImplFrameSkippedAfterLateSwapAck_FastEstimates_DeadlineThenSwapAck
) {
1538 scheduler_settings_
.use_external_begin_frame_source
= true;
1539 SetUpScheduler(true);
1541 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1542 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1544 bool swap_ack_before_deadline
= false;
1545 EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline
));
1548 TEST_F(SchedulerTest
,
1549 ImplFrameSkippedAfterLateSwapAck_ImplLatencyTakesPriority
) {
1550 scheduler_settings_
.use_external_begin_frame_source
= true;
1551 SetUpScheduler(true);
1553 // Even if every estimate related to the main thread is slow, we should
1554 // still expect to recover impl thread latency if the draw is fast and we
1555 // are in impl latency takes priority.
1556 scheduler_
->SetImplLatencyTakesPriority(true);
1557 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1558 fake_compositor_timing_history_
->SetAllEstimatesTo(slow_duration
);
1559 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1560 fake_compositor_timing_history_
->SetDrawDurationEstimate(fast_duration
);
1562 bool swap_ack_before_deadline
= false;
1563 EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline
));
1566 TEST_F(SchedulerTest
,
1567 ImplFrameSkippedAfterLateSwapAck_OnlyImplSideUpdatesExpected
) {
1568 // This tests that we recover impl thread latency when there are no commits.
1569 scheduler_settings_
.use_external_begin_frame_source
= true;
1570 SetUpScheduler(true);
1572 // To get into a high latency state, this test disables automatic swap acks.
1573 scheduler_
->SetMaxSwapsPending(1);
1574 client_
->SetAutomaticSwapAck(false);
1576 // Even if every estimate related to the main thread is slow, we should
1577 // still expect to recover impl thread latency if there are no commits from
1579 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1580 fake_compositor_timing_history_
->SetAllEstimatesTo(slow_duration
);
1581 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1582 fake_compositor_timing_history_
->SetDrawDurationEstimate(fast_duration
);
1584 // Draw and swap for first BeginFrame
1586 scheduler_
->SetNeedsRedraw();
1587 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1588 SendNextBeginFrame();
1589 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 3);
1590 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 3);
1591 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 3);
1594 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1595 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1596 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
1598 // Verify we skip every other frame if the swap ack consistently
1600 for (int i
= 0; i
< 10; i
++) {
1601 // Not calling scheduler_->DidSwapBuffersComplete() until after next
1602 // BeginImplFrame puts the impl thread in high latency mode.
1604 scheduler_
->SetNeedsRedraw();
1605 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1606 SendNextBeginFrame();
1607 // Verify that we skip the BeginImplFrame
1608 EXPECT_NO_ACTION(client_
);
1609 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1610 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1612 // Verify that we do not perform any actions after we are no longer
1615 scheduler_
->DidSwapBuffersComplete();
1616 EXPECT_NO_ACTION(client_
);
1618 // Verify that we start the next BeginImplFrame and continue normally
1619 // after having just skipped a BeginImplFrame.
1621 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1622 SendNextBeginFrame();
1623 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1624 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1627 // Deadline should be immediate.
1628 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1629 task_runner().RunUntilTime(now_src_
->NowTicks());
1630 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1631 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
1635 void SchedulerTest::ImplFrameIsNotSkippedAfterLateSwapAck() {
1636 // To get into a high latency state, this test disables automatic swap acks.
1637 scheduler_
->SetMaxSwapsPending(1);
1638 client_
->SetAutomaticSwapAck(false);
1640 // Draw and swap for first BeginFrame
1642 scheduler_
->SetNeedsBeginMainFrame();
1643 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1644 SendNextBeginFrame();
1645 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 3);
1646 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 3);
1647 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 3);
1650 scheduler_
->NotifyBeginMainFrameStarted();
1651 scheduler_
->NotifyReadyToCommit();
1652 scheduler_
->NotifyReadyToActivate();
1653 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1654 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1655 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 4);
1656 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 4);
1657 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 4);
1658 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 4);
1660 // Verify impl thread consistently operates in high latency mode
1661 // without skipping any frames.
1662 for (int i
= 0; i
< 10; i
++) {
1663 // Not calling scheduler_->DidSwapBuffersComplete() until after next frame
1664 // puts the impl thread in high latency mode.
1666 scheduler_
->SetNeedsBeginMainFrame();
1667 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1668 SendNextBeginFrame();
1669 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
1670 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1671 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1674 scheduler_
->DidSwapBuffersComplete();
1675 scheduler_
->NotifyBeginMainFrameStarted();
1676 scheduler_
->NotifyReadyToCommit();
1677 scheduler_
->NotifyReadyToActivate();
1678 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1680 // Verify that we don't skip the actions of the BeginImplFrame
1681 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 0, 5);
1682 EXPECT_ACTION("ScheduledActionCommit", client_
, 1, 5);
1683 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 2, 5);
1684 EXPECT_ACTION("ScheduledActionAnimate", client_
, 3, 5);
1685 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 4, 5);
1689 TEST_F(SchedulerTest
,
1690 ImplFrameIsNotSkippedAfterLateSwapAck_CommitEstimateTooLong
) {
1691 scheduler_settings_
.use_external_begin_frame_source
= true;
1692 SetUpScheduler(true);
1693 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1694 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1695 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1696 fake_compositor_timing_history_
->SetBeginMainFrameToCommitDurationEstimate(
1698 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1701 TEST_F(SchedulerTest
,
1702 ImplFrameIsNotSkippedAfterLateSwapAck_ReadyToActivateEstimateTooLong
) {
1703 scheduler_settings_
.use_external_begin_frame_source
= true;
1704 SetUpScheduler(true);
1705 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1706 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1707 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1708 fake_compositor_timing_history_
->SetCommitToReadyToActivateDurationEstimate(
1710 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1713 TEST_F(SchedulerTest
,
1714 ImplFrameIsNotSkippedAfterLateSwapAck_ActivateEstimateTooLong
) {
1715 scheduler_settings_
.use_external_begin_frame_source
= true;
1716 SetUpScheduler(true);
1717 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1718 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1719 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1720 fake_compositor_timing_history_
->SetActivateDurationEstimate(slow_duration
);
1721 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1724 TEST_F(SchedulerTest
,
1725 ImplFrameIsNotSkippedAfterLateSwapAck_DrawEstimateTooLong
) {
1726 scheduler_settings_
.use_external_begin_frame_source
= true;
1727 SetUpScheduler(true);
1728 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1729 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1730 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1731 fake_compositor_timing_history_
->SetDrawDurationEstimate(slow_duration
);
1732 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1735 TEST_F(SchedulerTest
,
1736 MainFrameThenImplFrameSkippedAfterLateCommitAndLateSwapAck
) {
1737 // Set up client with custom estimates.
1738 // This test starts off with expensive estimates to prevent latency recovery
1739 // initially, then lowers the estimates to enable it once both the main
1740 // and impl threads are in a high latency mode.
1741 scheduler_settings_
.use_external_begin_frame_source
= true;
1742 SetUpScheduler(true);
1744 auto slow_duration
= base::TimeDelta::FromSeconds(1);
1745 fake_compositor_timing_history_
->SetAllEstimatesTo(slow_duration
);
1747 // To get into a high latency state, this test disables automatic swap acks.
1748 scheduler_
->SetMaxSwapsPending(1);
1749 client_
->SetAutomaticSwapAck(false);
1751 // Impl thread hits deadline before commit finishes to make
1752 // MainThreadMissedLastDeadline true
1754 scheduler_
->SetNeedsBeginMainFrame();
1755 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1756 EXPECT_SCOPED(AdvanceFrame());
1757 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1758 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1759 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1760 scheduler_
->NotifyBeginMainFrameStarted();
1761 scheduler_
->NotifyReadyToCommit();
1762 scheduler_
->NotifyReadyToActivate();
1763 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1765 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 5);
1766 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 5);
1767 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 5);
1768 EXPECT_ACTION("ScheduledActionCommit", client_
, 3, 5);
1769 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 4, 5);
1771 // Draw and swap for first commit, start second commit.
1773 scheduler_
->SetNeedsBeginMainFrame();
1774 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1775 EXPECT_SCOPED(AdvanceFrame());
1776 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1777 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1778 scheduler_
->NotifyBeginMainFrameStarted();
1779 scheduler_
->NotifyReadyToCommit();
1780 scheduler_
->NotifyReadyToActivate();
1782 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 6);
1783 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 6);
1784 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 6);
1785 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 6);
1786 EXPECT_ACTION("ScheduledActionCommit", client_
, 4, 6);
1787 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 5, 6);
1789 // Don't call scheduler_->DidSwapBuffersComplete() until after next frame
1790 // to put the impl thread in a high latency mode.
1792 scheduler_
->SetNeedsBeginMainFrame();
1793 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1794 EXPECT_SCOPED(AdvanceFrame());
1795 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1796 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1798 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1799 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1800 // Note: BeginMainFrame and swap are skipped here because of
1801 // swap ack backpressure, not because of latency recovery.
1802 EXPECT_FALSE(client_
->HasAction("ScheduledActionSendBeginMainFrame"));
1803 EXPECT_FALSE(client_
->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1804 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1806 // Lower estimates so that the scheduler will attempt latency recovery.
1807 auto fast_duration
= base::TimeDelta::FromMilliseconds(1);
1808 fake_compositor_timing_history_
->SetAllEstimatesTo(fast_duration
);
1810 // Now that both threads are in a high latency mode, make sure we
1811 // skip the BeginMainFrame, then the BeginImplFrame, but not both
1812 // at the same time.
1814 // Verify we skip BeginMainFrame first.
1816 // Previous commit request is still outstanding.
1817 EXPECT_TRUE(scheduler_
->NeedsBeginMainFrame());
1818 EXPECT_TRUE(scheduler_
->SwapThrottled());
1819 SendNextBeginFrame();
1820 EXPECT_TRUE(scheduler_
->MainThreadMissedLastDeadline());
1821 scheduler_
->DidSwapBuffersComplete();
1822 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1824 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1825 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
1826 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
1827 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 2, 3);
1829 // Verify we skip the BeginImplFrame second.
1831 // Previous commit request is still outstanding.
1832 EXPECT_TRUE(scheduler_
->NeedsBeginMainFrame());
1833 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1834 SendNextBeginFrame();
1835 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1836 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1837 scheduler_
->DidSwapBuffersComplete();
1838 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1840 EXPECT_NO_ACTION(client_
);
1842 // Then verify we operate in a low latency mode.
1844 // Previous commit request is still outstanding.
1845 EXPECT_TRUE(scheduler_
->NeedsBeginMainFrame());
1846 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1847 SendNextBeginFrame();
1848 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1849 scheduler_
->NotifyBeginMainFrameStarted();
1850 scheduler_
->NotifyReadyToCommit();
1851 scheduler_
->NotifyReadyToActivate();
1852 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1853 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1854 scheduler_
->DidSwapBuffersComplete();
1855 EXPECT_FALSE(scheduler_
->MainThreadMissedLastDeadline());
1857 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 6);
1858 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 6);
1859 EXPECT_ACTION("ScheduledActionCommit", client_
, 2, 6);
1860 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 3, 6);
1861 EXPECT_ACTION("ScheduledActionAnimate", client_
, 4, 6);
1862 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 5, 6);
1867 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw
) {
1868 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main
1869 // thread. This prevents the scheduler from receiving any pending swap acks.
1871 scheduler_settings_
.use_external_begin_frame_source
= true;
1872 scheduler_settings_
.main_frame_while_swap_throttled_enabled
= true;
1873 SetUpScheduler(true);
1875 // Disables automatic swap acks so this test can force swap ack throttling
1876 // to simulate a blocked Browser ui thread.
1877 scheduler_
->SetMaxSwapsPending(1);
1878 client_
->SetAutomaticSwapAck(false);
1880 // Get a new active tree in main-thread high latency mode and put us
1881 // in a swap throttled state.
1883 EXPECT_FALSE(scheduler_
->CommitPending());
1884 scheduler_
->SetNeedsBeginMainFrame();
1885 scheduler_
->SetNeedsRedraw();
1886 EXPECT_SCOPED(AdvanceFrame());
1887 EXPECT_TRUE(scheduler_
->CommitPending());
1888 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1889 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1890 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1891 scheduler_
->NotifyBeginMainFrameStarted();
1892 scheduler_
->NotifyReadyToCommit();
1893 scheduler_
->NotifyReadyToActivate();
1894 EXPECT_FALSE(scheduler_
->CommitPending());
1895 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 7);
1896 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 7);
1897 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 7);
1898 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 3, 7);
1899 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 4, 7);
1900 EXPECT_ACTION("ScheduledActionCommit", client_
, 5, 7);
1901 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 6, 7);
1903 // Make sure that we can finish the next commit even while swap throttled.
1905 EXPECT_FALSE(scheduler_
->CommitPending());
1906 scheduler_
->SetNeedsBeginMainFrame();
1907 EXPECT_SCOPED(AdvanceFrame());
1908 scheduler_
->NotifyBeginMainFrameStarted();
1909 scheduler_
->NotifyReadyToCommit();
1910 scheduler_
->NotifyReadyToActivate();
1911 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1912 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1913 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1914 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 5);
1915 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 5);
1916 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 5);
1917 EXPECT_ACTION("ScheduledActionCommit", client_
, 3, 5);
1918 EXPECT_ACTION("ScheduledActionAnimate", client_
, 4, 5);
1920 // Make sure we do not send a BeginMainFrame while swap throttled and
1921 // we have both a pending tree and an active tree.
1923 EXPECT_FALSE(scheduler_
->CommitPending());
1924 scheduler_
->SetNeedsBeginMainFrame();
1925 EXPECT_SCOPED(AdvanceFrame());
1926 EXPECT_FALSE(scheduler_
->CommitPending());
1927 task_runner().RunPendingTasks(); // Run posted deadline.
1928 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
1929 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
1932 TEST_F(SchedulerTest
,
1933 Deadlock_NoBeginMainFrameWhileSwapTrottledAndPipelineFull
) {
1934 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main
1935 // thread. This prevents the scheduler from receiving any pending swap acks.
1937 // This particular test makes sure we do not send a BeginMainFrame while
1938 // swap trottled and we have a pending tree and active tree that
1939 // still needs to be drawn for the first time.
1941 scheduler_settings_
.use_external_begin_frame_source
= true;
1942 scheduler_settings_
.main_frame_while_swap_throttled_enabled
= true;
1943 scheduler_settings_
.main_frame_before_activation_enabled
= true;
1944 SetUpScheduler(true);
1946 // Disables automatic swap acks so this test can force swap ack throttling
1947 // to simulate a blocked Browser ui thread.
1948 scheduler_
->SetMaxSwapsPending(1);
1949 client_
->SetAutomaticSwapAck(false);
1951 // Start a new commit in main-thread high latency mode and hold off on
1954 EXPECT_FALSE(scheduler_
->CommitPending());
1955 scheduler_
->SetNeedsBeginMainFrame();
1956 scheduler_
->SetNeedsRedraw();
1957 EXPECT_SCOPED(AdvanceFrame());
1958 EXPECT_TRUE(scheduler_
->CommitPending());
1959 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1960 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1961 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1962 scheduler_
->DidSwapBuffersComplete();
1963 scheduler_
->NotifyBeginMainFrameStarted();
1964 scheduler_
->NotifyReadyToCommit();
1965 EXPECT_FALSE(scheduler_
->CommitPending());
1966 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 6);
1967 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 6);
1968 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 6);
1969 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 3, 6);
1970 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 4, 6);
1971 EXPECT_ACTION("ScheduledActionCommit", client_
, 5, 6);
1973 // Start another commit while we still have aa pending tree.
1974 // Enter a swap throttled state.
1976 EXPECT_FALSE(scheduler_
->CommitPending());
1977 scheduler_
->SetNeedsBeginMainFrame();
1978 scheduler_
->SetNeedsRedraw();
1979 EXPECT_SCOPED(AdvanceFrame());
1980 EXPECT_TRUE(scheduler_
->CommitPending());
1981 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
1982 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
1983 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
1984 scheduler_
->NotifyBeginMainFrameStarted();
1985 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 4);
1986 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 4);
1987 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 4);
1988 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 4);
1990 // Can't commit yet because there's still a pending tree.
1992 scheduler_
->NotifyReadyToCommit();
1993 EXPECT_NO_ACTION(client_
);
1995 // Activate the pending tree, which also unblocks the commit immediately.
1997 scheduler_
->NotifyReadyToActivate();
1998 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 0, 2);
1999 EXPECT_ACTION("ScheduledActionCommit", client_
, 1, 2);
2001 // Make sure we do not send a BeginMainFrame while swap throttled and
2002 // we have both a pending tree and an active tree that still needs
2005 EXPECT_FALSE(scheduler_
->CommitPending());
2006 scheduler_
->SetNeedsBeginMainFrame();
2007 EXPECT_SCOPED(AdvanceFrame());
2008 EXPECT_FALSE(scheduler_
->CommitPending());
2009 task_runner().RunPendingTasks(); // Run posted deadline.
2010 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2011 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2016 CommitMakesProgressWhenIdleAndHasPendingTreeAndActiveTreeNeedsFirstDraw
) {
2017 // This verifies we don't block commits longer than we need to
2018 // for performance reasons - not deadlock reasons.
2020 // Since we are simulating a long commit, set up a client with draw duration
2021 // estimates that prevent skipping main frames to get to low latency mode.
2022 scheduler_settings_
.use_external_begin_frame_source
= true;
2023 scheduler_settings_
.main_frame_while_swap_throttled_enabled
= true;
2024 scheduler_settings_
.main_frame_before_activation_enabled
= true;
2025 SetUpScheduler(true);
2027 // Disables automatic swap acks so this test can force swap ack throttling
2028 // to simulate a blocked Browser ui thread.
2029 scheduler_
->SetMaxSwapsPending(1);
2030 client_
->SetAutomaticSwapAck(false);
2032 // Start a new commit in main-thread high latency mode and hold off on
2035 EXPECT_FALSE(scheduler_
->CommitPending());
2036 scheduler_
->SetNeedsBeginMainFrame();
2037 scheduler_
->SetNeedsRedraw();
2038 EXPECT_SCOPED(AdvanceFrame());
2039 EXPECT_TRUE(scheduler_
->CommitPending());
2040 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2041 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2042 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2043 scheduler_
->DidSwapBuffersComplete();
2044 scheduler_
->NotifyBeginMainFrameStarted();
2045 scheduler_
->NotifyReadyToCommit();
2046 EXPECT_FALSE(scheduler_
->CommitPending());
2047 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 6);
2048 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 6);
2049 EXPECT_ACTION("ScheduledActionAnimate", client_
, 2, 6);
2050 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 3, 6);
2051 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 4, 6);
2052 EXPECT_ACTION("ScheduledActionCommit", client_
, 5, 6);
2054 // Start another commit while we still have an active tree.
2056 EXPECT_FALSE(scheduler_
->CommitPending());
2057 scheduler_
->SetNeedsBeginMainFrame();
2058 scheduler_
->SetNeedsRedraw();
2059 EXPECT_SCOPED(AdvanceFrame());
2060 EXPECT_TRUE(scheduler_
->CommitPending());
2061 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2062 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2063 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2064 scheduler_
->DidSwapBuffersComplete();
2065 scheduler_
->NotifyBeginMainFrameStarted();
2066 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 4);
2067 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 4);
2068 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 4);
2069 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 3, 4);
2071 // Can't commit yet because there's still a pending tree.
2073 scheduler_
->NotifyReadyToCommit();
2074 EXPECT_NO_ACTION(client_
);
2076 // Activate the pending tree, which also unblocks the commit immediately
2077 // while we are in an idle state.
2079 scheduler_
->NotifyReadyToActivate();
2080 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 0, 2);
2081 EXPECT_ACTION("ScheduledActionCommit", client_
, 1, 2);
2084 TEST_F(SchedulerTest
, BeginRetroFrame
) {
2085 scheduler_settings_
.use_external_begin_frame_source
= true;
2086 SetUpScheduler(true);
2088 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2089 scheduler_
->SetNeedsBeginMainFrame();
2090 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2093 // Create a BeginFrame with a long deadline to avoid race conditions.
2094 // This is the first BeginFrame, which will be handled immediately.
2095 BeginFrameArgs args
=
2096 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
2097 args
.deadline
+= base::TimeDelta::FromHours(1);
2098 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2099 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2100 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2101 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2102 EXPECT_TRUE(client_
->needs_begin_frames());
2105 // Queue BeginFrames while we are still handling the previous BeginFrame.
2106 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2107 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2108 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2109 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2111 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
2112 task_runner().RunPendingTasks(); // Run posted deadline.
2113 EXPECT_NO_ACTION(client_
);
2114 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2115 EXPECT_TRUE(client_
->needs_begin_frames());
2118 // NotifyReadyToCommit should trigger the commit.
2119 scheduler_
->NotifyBeginMainFrameStarted();
2120 scheduler_
->NotifyReadyToCommit();
2121 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2122 EXPECT_TRUE(client_
->needs_begin_frames());
2125 // NotifyReadyToActivate should trigger the activation.
2126 scheduler_
->NotifyReadyToActivate();
2127 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2128 EXPECT_TRUE(client_
->needs_begin_frames());
2131 // BeginImplFrame should prepare the draw.
2132 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
2133 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2134 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2135 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2136 EXPECT_TRUE(client_
->needs_begin_frames());
2139 // BeginImplFrame deadline should draw.
2140 task_runner().RunPendingTasks(); // Run posted deadline.
2141 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
2142 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2143 EXPECT_TRUE(client_
->needs_begin_frames());
2146 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
2147 // to avoid excessive toggles.
2148 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
2149 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
2150 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2153 task_runner().RunPendingTasks(); // Run posted deadline.
2154 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
2155 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
2159 TEST_F(SchedulerTest
, BeginRetroFrame_SwapThrottled
) {
2160 scheduler_settings_
.use_external_begin_frame_source
= true;
2161 SetUpScheduler(true);
2163 scheduler_
->SetEstimatedParentDrawTime(base::TimeDelta::FromMicroseconds(1));
2165 // To test swap ack throttling, this test disables automatic swap acks.
2166 scheduler_
->SetMaxSwapsPending(1);
2167 client_
->SetAutomaticSwapAck(false);
2169 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2171 scheduler_
->SetNeedsBeginMainFrame();
2172 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2175 EXPECT_SCOPED(AdvanceFrame());
2176 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2177 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2178 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2179 EXPECT_TRUE(client_
->needs_begin_frames());
2182 // Queue BeginFrame while we are still handling the previous BeginFrame.
2183 SendNextBeginFrame();
2184 EXPECT_NO_ACTION(client_
);
2185 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2186 EXPECT_TRUE(client_
->needs_begin_frames());
2189 // NotifyReadyToCommit should trigger the pending commit.
2190 scheduler_
->NotifyBeginMainFrameStarted();
2191 scheduler_
->NotifyReadyToCommit();
2192 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2193 EXPECT_TRUE(client_
->needs_begin_frames());
2196 // NotifyReadyToActivate should trigger the activation and draw.
2197 scheduler_
->NotifyReadyToActivate();
2198 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2199 EXPECT_TRUE(client_
->needs_begin_frames());
2202 // Swapping will put us into a swap throttled state.
2203 // Run posted deadline.
2204 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2205 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
2206 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
2207 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2208 EXPECT_TRUE(client_
->needs_begin_frames());
2211 // While swap throttled, BeginRetroFrames should trigger BeginImplFrames
2212 // but not a BeginMainFrame or draw.
2213 scheduler_
->SetNeedsBeginMainFrame();
2214 scheduler_
->SetNeedsRedraw();
2215 // Run posted BeginRetroFrame.
2216 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(false));
2217 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2218 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2219 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2220 EXPECT_TRUE(client_
->needs_begin_frames());
2223 // Let time pass sufficiently beyond the regular deadline but not beyond the
2225 now_src()->Advance(BeginFrameArgs::DefaultInterval() -
2226 base::TimeDelta::FromMicroseconds(1));
2227 task_runner().RunUntilTime(now_src()->NowTicks());
2228 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2230 // Take us out of a swap throttled state.
2231 scheduler_
->DidSwapBuffersComplete();
2232 EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_
);
2233 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2234 EXPECT_TRUE(client_
->needs_begin_frames());
2237 // Verify that the deadline was rescheduled.
2238 task_runner().RunUntilTime(now_src()->NowTicks());
2239 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
2240 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2241 EXPECT_TRUE(client_
->needs_begin_frames());
2245 TEST_F(SchedulerTest
, RetroFrameDoesNotExpireTooEarly
) {
2246 scheduler_settings_
.use_external_begin_frame_source
= true;
2247 SetUpScheduler(true);
2249 scheduler_
->SetNeedsBeginMainFrame();
2250 EXPECT_TRUE(client_
->needs_begin_frames());
2251 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2254 EXPECT_SCOPED(AdvanceFrame());
2255 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2256 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2257 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2260 scheduler_
->NotifyBeginMainFrameStarted();
2263 BeginFrameArgs retro_frame_args
= SendNextBeginFrame();
2264 // This BeginFrame is queued up as a retro frame.
2265 EXPECT_NO_ACTION(client_
);
2266 // The previous deadline is still pending.
2267 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2270 // This main frame activating should schedule the (previous) deadline to
2271 // trigger immediately.
2272 scheduler_
->NotifyReadyToCommit();
2273 scheduler_
->NotifyReadyToActivate();
2274 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 2);
2275 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 2);
2278 // The deadline task should trigger causing a draw.
2279 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2280 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2281 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
2282 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
2286 scheduler_
->SetNeedsAnimate();
2287 scheduler_
->SetNeedsRedraw();
2288 EXPECT_NO_ACTION(client_
);
2290 // Let's advance to the retro frame's deadline.
2291 now_src()->Advance(retro_frame_args
.deadline
- now_src()->NowTicks());
2293 // The retro frame hasn't expired yet.
2294 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(false));
2295 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2296 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2297 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2299 // This is an immediate deadline case.
2301 task_runner().RunPendingTasks();
2302 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2303 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
2306 TEST_F(SchedulerTest
, RetroFrameExpiresOnTime
) {
2307 scheduler_settings_
.use_external_begin_frame_source
= true;
2308 SetUpScheduler(true);
2310 scheduler_
->SetNeedsBeginMainFrame();
2311 EXPECT_TRUE(client_
->needs_begin_frames());
2312 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2315 EXPECT_SCOPED(AdvanceFrame());
2316 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2317 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2318 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2321 scheduler_
->NotifyBeginMainFrameStarted();
2324 BeginFrameArgs retro_frame_args
= SendNextBeginFrame();
2325 // This BeginFrame is queued up as a retro frame.
2326 EXPECT_NO_ACTION(client_
);
2327 // The previous deadline is still pending.
2328 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2331 // This main frame activating should schedule the (previous) deadline to
2332 // trigger immediately.
2333 scheduler_
->NotifyReadyToCommit();
2334 scheduler_
->NotifyReadyToActivate();
2335 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 2);
2336 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 2);
2339 // The deadline task should trigger causing a draw.
2340 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2341 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2342 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
2343 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
2347 scheduler_
->SetNeedsAnimate();
2348 scheduler_
->SetNeedsRedraw();
2349 EXPECT_NO_ACTION(client_
);
2351 // Let's advance sufficiently past the retro frame's deadline.
2352 now_src()->Advance(retro_frame_args
.deadline
- now_src()->NowTicks() +
2353 base::TimeDelta::FromMicroseconds(1));
2355 // The retro frame should've expired.
2356 EXPECT_NO_ACTION(client_
);
2359 TEST_F(SchedulerTest
, MissedFrameDoesNotExpireTooEarly
) {
2360 scheduler_settings_
.use_external_begin_frame_source
= true;
2361 SetUpScheduler(true);
2363 scheduler_
->SetNeedsBeginMainFrame();
2364 EXPECT_TRUE(client_
->needs_begin_frames());
2365 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2367 BeginFrameArgs missed_frame_args
=
2368 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
2369 missed_frame_args
.type
= BeginFrameArgs::MISSED
;
2371 // Advance to the deadline.
2372 now_src()->Advance(missed_frame_args
.deadline
- now_src()->NowTicks());
2374 // Missed frame is handled because it's on time.
2376 fake_external_begin_frame_source_
->TestOnBeginFrame(missed_frame_args
);
2378 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(false)));
2379 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2380 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2381 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2384 TEST_F(SchedulerTest
, MissedFrameExpiresOnTime
) {
2385 scheduler_settings_
.use_external_begin_frame_source
= true;
2386 SetUpScheduler(true);
2388 scheduler_
->SetNeedsBeginMainFrame();
2389 EXPECT_TRUE(client_
->needs_begin_frames());
2390 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2392 BeginFrameArgs missed_frame_args
=
2393 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
2394 missed_frame_args
.type
= BeginFrameArgs::MISSED
;
2396 // Advance sufficiently past the deadline.
2397 now_src()->Advance(missed_frame_args
.deadline
- now_src()->NowTicks() +
2398 base::TimeDelta::FromMicroseconds(1));
2400 // Missed frame is dropped because it's too late.
2402 fake_external_begin_frame_source_
->TestOnBeginFrame(missed_frame_args
);
2404 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(false)));
2405 EXPECT_NO_ACTION(client_
);
2406 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2409 void SchedulerTest::BeginFramesNotFromClient(
2410 bool use_external_begin_frame_source
,
2411 bool throttle_frame_production
) {
2412 scheduler_settings_
.use_external_begin_frame_source
=
2413 use_external_begin_frame_source
;
2414 scheduler_settings_
.throttle_frame_production
= throttle_frame_production
;
2415 SetUpScheduler(true);
2417 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame
2418 // without calling SetNeedsBeginFrame.
2419 scheduler_
->SetNeedsBeginMainFrame();
2420 EXPECT_NO_ACTION(client_
);
2423 // When the client-driven BeginFrame are disabled, the scheduler posts it's
2424 // own BeginFrame tasks.
2425 task_runner().RunPendingTasks(); // Run posted BeginFrame.
2426 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2427 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2428 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2431 // If we don't swap on the deadline, we wait for the next BeginFrame.
2432 task_runner().RunPendingTasks(); // Run posted deadline.
2433 EXPECT_NO_ACTION(client_
);
2434 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2437 // NotifyReadyToCommit should trigger the commit.
2438 scheduler_
->NotifyBeginMainFrameStarted();
2439 scheduler_
->NotifyReadyToCommit();
2440 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2443 // NotifyReadyToActivate should trigger the activation.
2444 scheduler_
->NotifyReadyToActivate();
2445 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2448 // BeginImplFrame should prepare the draw.
2449 task_runner().RunPendingTasks(); // Run posted BeginFrame.
2450 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2451 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2452 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2455 // BeginImplFrame deadline should draw.
2456 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2457 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
2458 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2461 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
2462 // to avoid excessive toggles.
2463 task_runner().RunPendingTasks(); // Run posted BeginFrame.
2464 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
2465 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2468 // Make sure SetNeedsBeginFrame isn't called on the client
2469 // when the BeginFrame is no longer needed.
2470 task_runner().RunPendingTasks(); // Run posted deadline.
2471 EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_
);
2475 TEST_F(SchedulerTest
, SyntheticBeginFrames
) {
2476 bool use_external_begin_frame_source
= false;
2477 bool throttle_frame_production
= true;
2478 BeginFramesNotFromClient(use_external_begin_frame_source
,
2479 throttle_frame_production
);
2482 TEST_F(SchedulerTest
, VSyncThrottlingDisabled
) {
2483 bool use_external_begin_frame_source
= true;
2484 bool throttle_frame_production
= false;
2485 BeginFramesNotFromClient(use_external_begin_frame_source
,
2486 throttle_frame_production
);
2489 TEST_F(SchedulerTest
, SyntheticBeginFrames_And_VSyncThrottlingDisabled
) {
2490 bool use_external_begin_frame_source
= false;
2491 bool throttle_frame_production
= false;
2492 BeginFramesNotFromClient(use_external_begin_frame_source
,
2493 throttle_frame_production
);
2496 void SchedulerTest::BeginFramesNotFromClient_SwapThrottled(
2497 bool use_external_begin_frame_source
,
2498 bool throttle_frame_production
) {
2499 scheduler_settings_
.use_external_begin_frame_source
=
2500 use_external_begin_frame_source
;
2501 scheduler_settings_
.throttle_frame_production
= throttle_frame_production
;
2502 SetUpScheduler(true);
2504 scheduler_
->SetEstimatedParentDrawTime(base::TimeDelta::FromMicroseconds(1));
2506 // To test swap ack throttling, this test disables automatic swap acks.
2507 scheduler_
->SetMaxSwapsPending(1);
2508 client_
->SetAutomaticSwapAck(false);
2510 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2512 scheduler_
->SetNeedsBeginMainFrame();
2513 EXPECT_NO_ACTION(client_
);
2516 // Trigger the first BeginImplFrame and BeginMainFrame
2517 EXPECT_SCOPED(AdvanceFrame());
2518 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2519 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2520 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2523 // NotifyReadyToCommit should trigger the pending commit.
2524 scheduler_
->NotifyBeginMainFrameStarted();
2525 scheduler_
->NotifyReadyToCommit();
2526 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2529 // NotifyReadyToActivate should trigger the activation and draw.
2530 scheduler_
->NotifyReadyToActivate();
2531 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2534 // Swapping will put us into a swap throttled state.
2535 // Run posted deadline.
2536 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2537 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
2538 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
2539 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2542 // While swap throttled, BeginFrames should trigger BeginImplFrames,
2543 // but not a BeginMainFrame or draw.
2544 scheduler_
->SetNeedsBeginMainFrame();
2545 scheduler_
->SetNeedsRedraw();
2546 EXPECT_SCOPED(AdvanceFrame()); // Run posted BeginFrame.
2547 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2548 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2549 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2552 // Let time pass sufficiently beyond the regular deadline but not beyond the
2554 now_src()->Advance(BeginFrameArgs::DefaultInterval() -
2555 base::TimeDelta::FromMicroseconds(1));
2556 task_runner().RunUntilTime(now_src()->NowTicks());
2557 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2559 // Take us out of a swap throttled state.
2560 scheduler_
->DidSwapBuffersComplete();
2561 EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_
);
2562 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2565 // Verify that the deadline was rescheduled.
2566 // We can't use RunUntilTime(now) here because the next frame is also
2567 // scheduled if throttle_frame_production = false.
2568 base::TimeTicks before_deadline
= now_src()->NowTicks();
2569 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2570 base::TimeTicks after_deadline
= now_src()->NowTicks();
2571 EXPECT_EQ(after_deadline
, before_deadline
);
2572 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2576 TEST_F(SchedulerTest
, SyntheticBeginFrames_SwapThrottled
) {
2577 bool use_external_begin_frame_source
= false;
2578 bool throttle_frame_production
= true;
2579 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source
,
2580 throttle_frame_production
);
2583 TEST_F(SchedulerTest
, VSyncThrottlingDisabled_SwapThrottled
) {
2584 bool use_external_begin_frame_source
= true;
2585 bool throttle_frame_production
= false;
2586 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source
,
2587 throttle_frame_production
);
2590 TEST_F(SchedulerTest
,
2591 SyntheticBeginFrames_And_VSyncThrottlingDisabled_SwapThrottled
) {
2592 bool use_external_begin_frame_source
= false;
2593 bool throttle_frame_production
= false;
2594 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source
,
2595 throttle_frame_production
);
2598 TEST_F(SchedulerTest
, DidLoseOutputSurfaceAfterOutputSurfaceIsInitialized
) {
2599 scheduler_settings_
.use_external_begin_frame_source
= true;
2600 SetUpScheduler(false);
2602 scheduler_
->SetCanStart();
2603 scheduler_
->SetVisible(true);
2604 scheduler_
->SetCanDraw(true);
2606 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
);
2608 scheduler_
->DidCreateAndInitializeOutputSurface();
2609 EXPECT_NO_ACTION(client_
);
2611 scheduler_
->DidLoseOutputSurface();
2612 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
);
2615 TEST_F(SchedulerTest
, DidLoseOutputSurfaceAfterBeginFrameStarted
) {
2616 scheduler_settings_
.use_external_begin_frame_source
= true;
2617 SetUpScheduler(true);
2619 // SetNeedsBeginMainFrame should begin the frame.
2620 scheduler_
->SetNeedsBeginMainFrame();
2621 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2624 EXPECT_SCOPED(AdvanceFrame());
2625 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2626 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2627 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2630 scheduler_
->DidLoseOutputSurface();
2631 // SetNeedsBeginFrames(false) is not called until the end of the frame.
2632 EXPECT_NO_ACTION(client_
);
2635 scheduler_
->NotifyBeginMainFrameStarted();
2636 scheduler_
->NotifyReadyToCommit();
2637 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 2);
2638 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 2);
2641 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2642 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
2643 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2644 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2647 TEST_F(SchedulerTest
,
2648 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency
) {
2649 scheduler_settings_
.use_external_begin_frame_source
= true;
2650 SetUpScheduler(true);
2652 // SetNeedsBeginMainFrame should begin the frame.
2653 scheduler_
->SetNeedsBeginMainFrame();
2654 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2657 EXPECT_SCOPED(AdvanceFrame());
2658 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2659 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2660 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2663 scheduler_
->DidLoseOutputSurface();
2664 // Do nothing when impl frame is in deadine pending state.
2665 EXPECT_NO_ACTION(client_
);
2668 // Run posted deadline.
2669 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2670 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2671 // OnBeginImplFrameDeadline didn't schedule output surface creation because
2672 // main frame is not yet completed.
2673 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
2674 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
2675 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2677 // BeginImplFrame is not started.
2679 task_runner().RunUntilTime(now_src()->NowTicks() +
2680 base::TimeDelta::FromMilliseconds(10));
2681 EXPECT_NO_ACTION(client_
);
2682 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2685 scheduler_
->NotifyBeginMainFrameStarted();
2686 scheduler_
->NotifyReadyToCommit();
2687 EXPECT_ACTION("ScheduledActionCommit", client_
, 0, 3);
2688 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 1, 3);
2689 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 2, 3);
2692 TEST_F(SchedulerTest
, DidLoseOutputSurfaceAfterReadyToCommit
) {
2693 scheduler_settings_
.use_external_begin_frame_source
= true;
2694 SetUpScheduler(true);
2696 // SetNeedsBeginMainFrame should begin the frame.
2697 scheduler_
->SetNeedsBeginMainFrame();
2698 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2701 EXPECT_SCOPED(AdvanceFrame());
2702 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2703 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2704 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2707 scheduler_
->NotifyBeginMainFrameStarted();
2708 scheduler_
->NotifyReadyToCommit();
2709 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2712 scheduler_
->DidLoseOutputSurface();
2713 // Sync tree should be forced to activate.
2714 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2716 // SetNeedsBeginFrames(false) is not called until the end of the frame.
2718 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2719 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
2720 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2721 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2724 TEST_F(SchedulerTest
, DidLoseOutputSurfaceAfterSetNeedsPrepareTiles
) {
2725 scheduler_settings_
.use_external_begin_frame_source
= true;
2726 SetUpScheduler(true);
2728 scheduler_
->SetNeedsPrepareTiles();
2729 scheduler_
->SetNeedsRedraw();
2730 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2733 EXPECT_SCOPED(AdvanceFrame());
2734 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2735 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2736 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2739 scheduler_
->DidLoseOutputSurface();
2740 // SetNeedsBeginFrames(false) is not called until the end of the frame.
2741 EXPECT_NO_ACTION(client_
);
2744 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2745 EXPECT_ACTION("ScheduledActionPrepareTiles", client_
, 0, 4);
2746 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 1, 4);
2747 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 2, 4);
2748 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 3, 4);
2751 TEST_F(SchedulerTest
, DidLoseOutputSurfaceAfterBeginRetroFramePosted
) {
2752 scheduler_settings_
.use_external_begin_frame_source
= true;
2753 SetUpScheduler(true);
2755 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2756 scheduler_
->SetNeedsBeginMainFrame();
2757 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2759 // Create a BeginFrame with a long deadline to avoid race conditions.
2760 // This is the first BeginFrame, which will be handled immediately.
2762 BeginFrameArgs args
=
2763 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
2764 args
.deadline
+= base::TimeDelta::FromHours(1);
2765 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2766 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2767 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2768 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2769 EXPECT_TRUE(client_
->needs_begin_frames());
2771 // Queue BeginFrames while we are still handling the previous BeginFrame.
2772 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2773 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2774 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2775 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2777 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
2779 task_runner().RunPendingTasks(); // Run posted deadline.
2780 EXPECT_NO_ACTION(client_
);
2781 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2782 EXPECT_TRUE(client_
->needs_begin_frames());
2784 // NotifyReadyToCommit should trigger the commit.
2786 scheduler_
->NotifyBeginMainFrameStarted();
2787 scheduler_
->NotifyReadyToCommit();
2788 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2789 EXPECT_TRUE(client_
->needs_begin_frames());
2791 // NotifyReadyToActivate should trigger the activation.
2793 scheduler_
->NotifyReadyToActivate();
2794 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2795 EXPECT_TRUE(client_
->needs_begin_frames());
2798 EXPECT_FALSE(scheduler_
->IsBeginRetroFrameArgsEmpty());
2799 scheduler_
->DidLoseOutputSurface();
2800 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
2801 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2802 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2803 EXPECT_TRUE(scheduler_
->IsBeginRetroFrameArgsEmpty());
2805 // Posted BeginRetroFrame is aborted.
2807 task_runner().RunPendingTasks();
2808 EXPECT_NO_ACTION(client_
);
2811 TEST_F(SchedulerTest
, DidLoseOutputSurfaceDuringBeginRetroFrameRunning
) {
2812 scheduler_settings_
.use_external_begin_frame_source
= true;
2813 SetUpScheduler(true);
2815 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2816 scheduler_
->SetNeedsBeginMainFrame();
2817 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2819 // Create a BeginFrame with a long deadline to avoid race conditions.
2820 // This is the first BeginFrame, which will be handled immediately.
2822 BeginFrameArgs args
=
2823 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE
, now_src());
2824 args
.deadline
+= base::TimeDelta::FromHours(1);
2825 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2826 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2827 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2828 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2829 EXPECT_TRUE(client_
->needs_begin_frames());
2831 // Queue BeginFrames while we are still handling the previous BeginFrame.
2832 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2833 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2834 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
2835 fake_external_begin_frame_source()->TestOnBeginFrame(args
);
2837 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
2839 task_runner().RunPendingTasks(); // Run posted deadline.
2840 EXPECT_NO_ACTION(client_
);
2841 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2842 EXPECT_TRUE(client_
->needs_begin_frames());
2844 // NotifyReadyToCommit should trigger the commit.
2846 scheduler_
->NotifyBeginMainFrameStarted();
2847 scheduler_
->NotifyReadyToCommit();
2848 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2849 EXPECT_TRUE(client_
->needs_begin_frames());
2851 // NotifyReadyToActivate should trigger the activation.
2853 scheduler_
->NotifyReadyToActivate();
2854 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2855 EXPECT_TRUE(client_
->needs_begin_frames());
2857 // BeginImplFrame should prepare the draw.
2859 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
2860 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2861 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
2862 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2863 EXPECT_TRUE(client_
->needs_begin_frames());
2866 EXPECT_FALSE(scheduler_
->IsBeginRetroFrameArgsEmpty());
2867 scheduler_
->DidLoseOutputSurface();
2868 EXPECT_NO_ACTION(client_
);
2869 EXPECT_TRUE(scheduler_
->IsBeginRetroFrameArgsEmpty());
2871 // BeginImplFrame deadline should abort drawing.
2873 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2874 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
2875 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2876 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2877 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
2878 EXPECT_FALSE(client_
->needs_begin_frames());
2880 // No more BeginRetroFrame because BeginRetroFrame queue is cleared.
2882 task_runner().RunPendingTasks();
2883 EXPECT_NO_ACTION(client_
);
2886 TEST_F(SchedulerTest
, DidLoseOutputSurfaceWithSyntheticBeginFrameSource
) {
2887 SetUpScheduler(true);
2889 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
2890 EXPECT_FALSE(scheduler_
->frame_source().NeedsBeginFrames());
2891 scheduler_
->SetNeedsBeginMainFrame();
2892 EXPECT_TRUE(scheduler_
->frame_source().NeedsBeginFrames());
2896 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2897 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2898 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2899 EXPECT_TRUE(scheduler_
->frame_source().NeedsBeginFrames());
2901 // NotifyReadyToCommit should trigger the commit.
2903 scheduler_
->NotifyBeginMainFrameStarted();
2904 scheduler_
->NotifyReadyToCommit();
2905 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2906 EXPECT_TRUE(scheduler_
->frame_source().NeedsBeginFrames());
2908 // NotifyReadyToActivate should trigger the activation.
2910 scheduler_
->NotifyReadyToActivate();
2911 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2912 EXPECT_TRUE(scheduler_
->frame_source().NeedsBeginFrames());
2915 scheduler_
->DidLoseOutputSurface();
2916 // SetNeedsBeginFrames(false) is not called until the end of the frame.
2917 EXPECT_NO_ACTION(client_
);
2918 EXPECT_TRUE(scheduler_
->frame_source().NeedsBeginFrames());
2921 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2922 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 2);
2923 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
2924 EXPECT_FALSE(scheduler_
->frame_source().NeedsBeginFrames());
2927 TEST_F(SchedulerTest
, DidLoseOutputSurfaceWhenIdle
) {
2928 scheduler_settings_
.use_external_begin_frame_source
= true;
2929 SetUpScheduler(true);
2931 // SetNeedsBeginMainFrame should begin the frame.
2932 scheduler_
->SetNeedsBeginMainFrame();
2933 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2936 EXPECT_SCOPED(AdvanceFrame());
2937 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2938 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2939 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2942 scheduler_
->NotifyBeginMainFrameStarted();
2943 scheduler_
->NotifyReadyToCommit();
2944 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2947 scheduler_
->NotifyReadyToActivate();
2948 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
2951 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
2952 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
2953 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
2955 // Idle time between BeginFrames.
2957 scheduler_
->DidLoseOutputSurface();
2958 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_
, 0, 3);
2959 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2960 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2963 TEST_F(SchedulerTest
, ScheduledActionActivateAfterBecomingInvisible
) {
2964 scheduler_settings_
.use_external_begin_frame_source
= true;
2965 SetUpScheduler(true);
2967 // SetNeedsBeginMainFrame should begin the frame.
2968 scheduler_
->SetNeedsBeginMainFrame();
2969 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
2972 EXPECT_SCOPED(AdvanceFrame());
2973 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
2974 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
2975 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2978 scheduler_
->NotifyBeginMainFrameStarted();
2979 scheduler_
->NotifyReadyToCommit();
2980 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
2981 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
2984 scheduler_
->SetVisible(false);
2985 task_runner().RunPendingTasks(); // Run posted deadline.
2987 // Sync tree should be forced to activate.
2988 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 0, 3);
2989 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
2990 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
2993 // Tests to ensure frame sources can be successfully changed while drawing.
2994 TEST_F(SchedulerTest
, SwitchFrameSourceToUnthrottled
) {
2995 scheduler_settings_
.use_external_begin_frame_source
= true;
2996 SetUpScheduler(true);
2998 // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
2999 scheduler_
->SetNeedsRedraw();
3000 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3003 EXPECT_SCOPED(AdvanceFrame());
3004 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3005 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
3006 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3007 EXPECT_TRUE(client_
->needs_begin_frames());
3009 task_runner().RunPendingTasks(); // Run posted deadline.
3010 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
3011 scheduler_
->SetNeedsRedraw();
3013 // Switch to an unthrottled frame source.
3014 scheduler_
->SetThrottleFrameProduction(false);
3017 // Unthrottled frame source will immediately begin a new frame.
3018 task_runner().RunPendingTasks(); // Run posted BeginFrame.
3019 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3020 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
3021 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3024 // If we don't swap on the deadline, we wait for the next BeginFrame.
3025 task_runner().RunPendingTasks(); // Run posted deadline.
3026 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
3027 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3031 // Tests to ensure frame sources can be successfully changed while a frame
3032 // deadline is pending.
3033 TEST_F(SchedulerTest
, SwitchFrameSourceToUnthrottledBeforeDeadline
) {
3034 scheduler_settings_
.use_external_begin_frame_source
= true;
3035 SetUpScheduler(true);
3037 // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
3038 scheduler_
->SetNeedsRedraw();
3039 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3042 EXPECT_SCOPED(AdvanceFrame());
3043 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3044 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
3046 // Switch to an unthrottled frame source before the frame deadline is hit.
3047 scheduler_
->SetThrottleFrameProduction(false);
3050 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3051 EXPECT_TRUE(client_
->needs_begin_frames());
3054 task_runner().RunPendingTasks(); // Run posted deadline and BeginFrame.
3055 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 2);
3056 // Unthrottled frame source will immediately begin a new frame.
3057 EXPECT_ACTION("WillBeginImplFrame", client_
, 1, 2);
3058 scheduler_
->SetNeedsRedraw();
3061 task_runner().RunPendingTasks(); // Run posted deadline.
3062 EXPECT_ACTION("ScheduledActionAnimate", client_
, 0, 2);
3063 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 1, 2);
3064 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3068 // Tests to ensure that the active frame source can successfully be changed from
3069 // unthrottled to throttled.
3070 TEST_F(SchedulerTest
, SwitchFrameSourceToThrottled
) {
3071 scheduler_settings_
.throttle_frame_production
= false;
3072 scheduler_settings_
.use_external_begin_frame_source
= true;
3073 SetUpScheduler(true);
3075 scheduler_
->SetNeedsRedraw();
3076 EXPECT_NO_ACTION(client_
);
3079 task_runner().RunPendingTasks(); // Run posted BeginFrame.
3080 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3081 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
3082 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3085 task_runner().RunPendingTasks(); // Run posted deadline.
3086 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
3087 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3090 // Switch to a throttled frame source.
3091 scheduler_
->SetThrottleFrameProduction(true);
3094 // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
3095 scheduler_
->SetNeedsRedraw();
3096 task_runner().RunPendingTasks();
3097 EXPECT_NO_ACTION(client_
);
3100 EXPECT_SCOPED(AdvanceFrame());
3101 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3102 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 2);
3103 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3104 EXPECT_TRUE(client_
->needs_begin_frames());
3106 task_runner().RunPendingTasks(); // Run posted deadline.
3107 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 1);
3110 // Tests to ensure that we send a BeginMainFrameNotExpectedSoon when expected.
3111 TEST_F(SchedulerTest
, SendBeginMainFrameNotExpectedSoon
) {
3112 scheduler_settings_
.use_external_begin_frame_source
= true;
3113 SetUpScheduler(true);
3115 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame.
3116 scheduler_
->SetNeedsBeginMainFrame();
3117 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3120 // Trigger a frame draw.
3121 EXPECT_SCOPED(AdvanceFrame());
3122 scheduler_
->NotifyBeginMainFrameStarted();
3123 scheduler_
->NotifyReadyToCommit();
3124 scheduler_
->NotifyReadyToActivate();
3125 task_runner().RunPendingTasks();
3126 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 6);
3127 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 6);
3128 EXPECT_ACTION("ScheduledActionCommit", client_
, 2, 6);
3129 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_
, 3, 6);
3130 EXPECT_ACTION("ScheduledActionAnimate", client_
, 4, 6);
3131 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 5, 6);
3134 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
3135 // and send a SendBeginMainFrameNotExpectedSoon.
3136 EXPECT_SCOPED(AdvanceFrame());
3137 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
3138 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
3141 task_runner().RunPendingTasks(); // Run posted deadline.
3142 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 0, 2);
3143 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 1, 2);
3147 TEST_F(SchedulerTest
, SynchronousCompositorAnimation
) {
3148 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3149 scheduler_settings_
.use_external_begin_frame_source
= true;
3150 SetUpScheduler(true);
3152 scheduler_
->SetNeedsAnimate();
3153 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3158 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3159 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3160 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3161 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3164 // Continue with animation.
3165 scheduler_
->SetNeedsAnimate();
3166 EXPECT_NO_ACTION(client_
);
3169 scheduler_
->SetNeedsRedraw();
3170 scheduler_
->OnDrawForOutputSurface();
3171 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
3172 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3177 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3178 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3179 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3180 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3184 scheduler_
->SetNeedsRedraw();
3185 scheduler_
->OnDrawForOutputSurface();
3186 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
3187 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3190 // Idle on next vsync.
3192 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3193 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
3194 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
3195 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3199 TEST_F(SchedulerTest
, SynchronousCompositorOnDrawDuringIdle
) {
3200 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3201 scheduler_settings_
.use_external_begin_frame_source
= true;
3202 SetUpScheduler(true);
3204 scheduler_
->SetNeedsRedraw();
3205 scheduler_
->OnDrawForOutputSurface();
3206 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_
, 0, 3);
3207 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3208 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 2, 3);
3209 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3212 // Idle on next vsync.
3214 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3215 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
3216 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
3217 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3221 TEST_F(SchedulerTest
, SynchronousCompositorCommit
) {
3222 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3223 scheduler_settings_
.use_external_begin_frame_source
= true;
3224 SetUpScheduler(true);
3226 scheduler_
->SetNeedsBeginMainFrame();
3227 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3232 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3233 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
3234 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3237 scheduler_
->NotifyBeginMainFrameStarted();
3238 EXPECT_NO_ACTION(client_
);
3242 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_
);
3243 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3246 scheduler_
->NotifyReadyToCommit();
3247 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
3250 scheduler_
->NotifyReadyToActivate();
3251 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
3256 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3257 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3258 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3259 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3263 scheduler_
->SetNeedsRedraw();
3264 scheduler_
->OnDrawForOutputSurface();
3265 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
3266 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3269 // Idle on next vsync.
3271 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3272 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
3273 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
3274 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3278 TEST_F(SchedulerTest
, SynchronousCompositorDoubleCommitWithoutDraw
) {
3279 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3280 scheduler_settings_
.use_external_begin_frame_source
= true;
3281 SetUpScheduler(true);
3283 scheduler_
->SetNeedsBeginMainFrame();
3284 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3289 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 2);
3290 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 1, 2);
3291 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3294 scheduler_
->NotifyBeginMainFrameStarted();
3295 EXPECT_NO_ACTION(client_
);
3297 scheduler_
->NotifyReadyToCommit();
3298 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
3301 scheduler_
->NotifyReadyToActivate();
3302 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
3305 // Ask for another commit.
3306 scheduler_
->SetNeedsBeginMainFrame();
3309 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 4);
3310 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 4);
3311 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_
, 2, 4);
3312 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 3, 4);
3313 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3316 scheduler_
->NotifyBeginMainFrameStarted();
3317 EXPECT_NO_ACTION(client_
);
3319 // Allow new commit even though previous commit hasn't been drawn.
3320 scheduler_
->NotifyReadyToCommit();
3321 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
3325 class SchedulerClientSetNeedsPrepareTilesOnDraw
: public FakeSchedulerClient
{
3327 SchedulerClientSetNeedsPrepareTilesOnDraw() : FakeSchedulerClient() {}
3330 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
3331 scheduler_
->SetNeedsPrepareTiles();
3332 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
3336 TEST_F(SchedulerTest
, SynchronousCompositorPrepareTilesOnDraw
) {
3337 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3338 scheduler_settings_
.use_external_begin_frame_source
= true;
3340 scoped_ptr
<FakeSchedulerClient
> client
=
3341 make_scoped_ptr(new SchedulerClientSetNeedsPrepareTilesOnDraw
);
3342 SetUpScheduler(client
.Pass(), true);
3344 scheduler_
->SetNeedsRedraw();
3345 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3349 EXPECT_SCOPED(AdvanceFrame());
3350 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3351 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3352 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3356 scheduler_
->SetNeedsRedraw();
3357 scheduler_
->OnDrawForOutputSurface();
3358 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 2);
3359 EXPECT_ACTION("ScheduledActionPrepareTiles", client_
, 1, 2);
3360 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3361 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
3365 scheduler_
->SetNeedsRedraw();
3366 scheduler_
->OnDrawForOutputSurface();
3367 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
, 0, 2);
3368 EXPECT_ACTION("ScheduledActionPrepareTiles", client_
, 1, 2);
3369 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3370 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
3374 EXPECT_SCOPED(AdvanceFrame());
3375 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
3376 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3377 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_
, 1, 3);
3378 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_
, 2, 3);
3379 EXPECT_FALSE(client_
->needs_begin_frames());
3383 TEST_F(SchedulerTest
, SynchronousCompositorSendBeginMainFrameWhileIdle
) {
3384 scheduler_settings_
.using_synchronous_renderer_compositor
= true;
3385 scheduler_settings_
.use_external_begin_frame_source
= true;
3387 SetUpScheduler(true);
3389 scheduler_
->SetNeedsRedraw();
3390 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_
);
3394 EXPECT_SCOPED(AdvanceFrame());
3395 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3396 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3397 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3401 scheduler_
->SetNeedsRedraw();
3402 scheduler_
->OnDrawForOutputSurface();
3403 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
3404 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3405 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
3408 // Simulate SetNeedsBeginMainFrame due to input event.
3409 scheduler_
->SetNeedsBeginMainFrame();
3410 EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_
);
3413 scheduler_
->NotifyBeginMainFrameStarted();
3414 scheduler_
->NotifyReadyToCommit();
3415 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_
);
3418 scheduler_
->NotifyReadyToActivate();
3419 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_
);
3423 EXPECT_SCOPED(AdvanceFrame());
3424 EXPECT_ACTION("WillBeginImplFrame", client_
, 0, 3);
3425 EXPECT_ACTION("ScheduledActionAnimate", client_
, 1, 3);
3426 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_
, 2, 3);
3430 scheduler_
->SetNeedsRedraw();
3431 scheduler_
->OnDrawForOutputSurface();
3432 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_
);
3433 EXPECT_FALSE(scheduler_
->BeginImplFrameDeadlinePending());
3434 EXPECT_FALSE(scheduler_
->PrepareTilesPending());
3437 // Simulate SetNeedsBeginMainFrame due to input event.
3438 scheduler_
->SetNeedsBeginMainFrame();
3439 EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_
);
3443 TEST_F(SchedulerTest
, AuthoritativeVSyncInterval
) {
3444 SetUpScheduler(true);
3445 base::TimeDelta initial_interval
= scheduler_
->BeginImplFrameInterval();
3446 base::TimeDelta authoritative_interval
=
3447 base::TimeDelta::FromMilliseconds(33);
3449 scheduler_
->SetNeedsBeginMainFrame();
3450 EXPECT_SCOPED(AdvanceFrame());
3452 EXPECT_EQ(initial_interval
, scheduler_
->BeginImplFrameInterval());
3454 scheduler_
->NotifyBeginMainFrameStarted();
3455 scheduler_
->NotifyReadyToCommit();
3456 scheduler_
->NotifyReadyToActivate();
3457 task_runner().RunTasksWhile(client_
->ImplFrameDeadlinePending(true));
3459 scheduler_
->SetAuthoritativeVSyncInterval(authoritative_interval
);
3461 EXPECT_SCOPED(AdvanceFrame());
3463 // At the next BeginFrame, authoritative interval is used instead of previous
3465 EXPECT_NE(initial_interval
, scheduler_
->BeginImplFrameInterval());
3466 EXPECT_EQ(authoritative_interval
, scheduler_
->BeginImplFrameInterval());
3469 TEST_F(SchedulerTest
, ImplLatencyTakesPriority
) {
3470 SetUpScheduler(true);
3471 scheduler_
->SetImplLatencyTakesPriority(true);
3472 EXPECT_TRUE(scheduler_
->ImplLatencyTakesPriority());
3474 scheduler_
->SetImplLatencyTakesPriority(false);
3475 EXPECT_FALSE(scheduler_
->ImplLatencyTakesPriority());
3478 TEST_F(SchedulerTest
, BeginFrameArgs_OnCriticalPath
) {
3479 scheduler_settings_
.use_external_begin_frame_source
= true;
3480 SetUpScheduler(true);
3482 scheduler_
->SetImplLatencyTakesPriority(false);
3483 scheduler_
->SetChildrenNeedBeginFrames(true);
3485 EXPECT_SCOPED(AdvanceFrame());
3486 EXPECT_TRUE(client_
->begin_frame_is_sent_to_children());
3487 EXPECT_TRUE(client_
->begin_frame_args_sent_to_children().on_critical_path
);
3490 TEST_F(SchedulerTest
, BeginFrameArgs_NotOnCriticalPath
) {
3491 scheduler_settings_
.use_external_begin_frame_source
= true;
3492 SetUpScheduler(true);
3494 scheduler_
->SetImplLatencyTakesPriority(true);
3495 scheduler_
->SetChildrenNeedBeginFrames(true);
3497 EXPECT_SCOPED(AdvanceFrame());
3498 EXPECT_TRUE(client_
->begin_frame_is_sent_to_children());
3499 EXPECT_FALSE(client_
->begin_frame_args_sent_to_children().on_critical_path
);