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/debug/trace_event.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_vector.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/power_monitor/power_monitor.h"
15 #include "base/power_monitor/power_monitor_source.h"
16 #include "base/run_loop.h"
17 #include "base/time/time.h"
18 #include "cc/test/begin_frame_args_test.h"
19 #include "cc/test/ordered_simple_task_runner.h"
20 #include "cc/test/scheduler_test_common.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \
26 EXPECT_EQ(expected_num_actions, client.num_actions_()); \
27 if (action_index >= 0) { \
28 ASSERT_LT(action_index, client.num_actions_()) << scheduler; \
29 EXPECT_STREQ(action, client.Action(action_index)); \
31 for (int i = expected_num_actions; i < client.num_actions_(); ++i) \
32 ADD_FAILURE() << "Unexpected action: " << client.Action(i) \
33 << " with state:\n" << client.StateForAction(i); \
36 #define EXPECT_NO_ACTION(client) EXPECT_ACTION("", client, -1, 0)
38 #define EXPECT_SINGLE_ACTION(action, client) \
39 EXPECT_ACTION(action, client, 0, 1)
44 class FakeSchedulerClient
;
46 void InitializeOutputSurfaceAndFirstCommit(Scheduler
* scheduler
,
47 FakeSchedulerClient
* client
);
49 class FakeSchedulerClient
: public SchedulerClient
{
51 class FakeExternalBeginFrameSource
: public BeginFrameSourceMixIn
{
53 explicit FakeExternalBeginFrameSource(FakeSchedulerClient
* client
)
55 virtual ~FakeExternalBeginFrameSource() {}
57 void OnNeedsBeginFramesChange(bool needs_begin_frames
) override
{
58 if (needs_begin_frames
) {
59 client_
->actions_
.push_back("SetNeedsBeginFrames(true)");
61 client_
->actions_
.push_back("SetNeedsBeginFrames(false)");
63 client_
->states_
.push_back(client_
->scheduler_
->AsValue());
66 void TestOnBeginFrame(const BeginFrameArgs
& args
) {
67 return CallOnBeginFrame(args
);
71 FakeSchedulerClient
* client_
;
74 class FakePowerMonitorSource
: public base::PowerMonitorSource
{
76 FakePowerMonitorSource() {}
77 ~FakePowerMonitorSource() override
{}
78 void GeneratePowerStateEvent(bool on_battery_power
) {
79 on_battery_power_impl_
= on_battery_power
;
80 ProcessPowerEvent(POWER_STATE_EVENT
);
81 base::MessageLoop::current()->RunUntilIdle();
83 bool IsOnBatteryPowerImpl() override
{ return on_battery_power_impl_
; }
86 bool on_battery_power_impl_
;
90 : automatic_swap_ack_(true),
91 now_src_(TestNowSource::Create()),
92 task_runner_(new OrderedSimpleTaskRunner(now_src_
, true)),
93 fake_external_begin_frame_source_(nullptr),
94 fake_power_monitor_source_(new FakePowerMonitorSource
),
95 power_monitor_(make_scoped_ptr
<base::PowerMonitorSource
>(
96 fake_power_monitor_source_
)),
98 // A bunch of tests require Now() to be > BeginFrameArgs::DefaultInterval()
99 now_src_
->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
100 // Fail if we need to run 100 tasks in a row.
101 task_runner_
->SetRunTaskLimit(100);
108 draw_will_happen_
= true;
109 swap_will_happen_if_draw_happens_
= true;
111 log_anticipated_draw_time_change_
= false;
114 TestScheduler
* CreateScheduler(const SchedulerSettings
& settings
) {
115 scoped_ptr
<FakeExternalBeginFrameSource
> fake_external_begin_frame_source
;
116 if (settings
.use_external_begin_frame_source
&&
117 settings
.throttle_frame_production
) {
118 fake_external_begin_frame_source
.reset(
119 new FakeExternalBeginFrameSource(this));
120 fake_external_begin_frame_source_
=
121 fake_external_begin_frame_source
.get();
123 scheduler_
= TestScheduler::Create(now_src_
,
129 fake_external_begin_frame_source
.Pass());
131 return scheduler_
.get();
134 // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it
135 // for tests that do.
136 void set_log_anticipated_draw_time_change(bool log
) {
137 log_anticipated_draw_time_change_
= log
;
139 bool needs_begin_frames() {
140 DCHECK(ExternalBeginFrame());
141 return fake_external_begin_frame_source_
->NeedsBeginFrames();
143 int num_draws() const { return num_draws_
; }
144 int num_actions_() const { return static_cast<int>(actions_
.size()); }
145 const char* Action(int i
) const { return actions_
[i
]; }
146 std::string
StateForAction(int i
) const { return states_
[i
]->ToString(); }
147 base::TimeTicks
posted_begin_impl_frame_deadline() const {
148 return posted_begin_impl_frame_deadline_
;
151 bool ExternalBeginFrame() {
152 return scheduler_
->settings().use_external_begin_frame_source
&&
153 scheduler_
->settings().throttle_frame_production
;
156 FakeExternalBeginFrameSource
* fake_external_begin_frame_source() const {
157 return fake_external_begin_frame_source_
;
160 base::PowerMonitor
* PowerMonitor() { return &power_monitor_
; }
162 FakePowerMonitorSource
* PowerMonitorSource() {
163 return fake_power_monitor_source_
;
166 void AdvanceFrame() {
167 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
168 "FakeSchedulerClient::AdvanceFrame");
169 if (ExternalBeginFrame()) {
170 // Creep the time forward so that any BeginFrameArgs is not equal to the
171 // last one otherwise we violate the BeginFrameSource contract.
172 now_src_
->AdvanceNowMicroseconds(1);
173 fake_external_begin_frame_source_
->TestOnBeginFrame(
174 CreateBeginFrameArgsForTesting(now_src_
));
175 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
178 EXPECT_TRUE(task_runner().RunTasksWhile(ImplFrameDeadlinePending(false)));
179 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
182 OrderedSimpleTaskRunner
& task_runner() { return *task_runner_
; }
183 TestNowSource
* now_src() { return now_src_
.get(); }
185 int ActionIndex(const char* action
) const {
186 for (size_t i
= 0; i
< actions_
.size(); i
++)
187 if (!strcmp(actions_
[i
], action
))
192 bool HasAction(const char* action
) const {
193 return ActionIndex(action
) >= 0;
196 void SetDrawWillHappen(bool draw_will_happen
) {
197 draw_will_happen_
= draw_will_happen
;
199 void SetSwapWillHappenIfDrawHappens(bool swap_will_happen_if_draw_happens
) {
200 swap_will_happen_if_draw_happens_
= swap_will_happen_if_draw_happens
;
202 void SetAutomaticSwapAck(bool automatic_swap_ack
) {
203 automatic_swap_ack_
= automatic_swap_ack
;
205 // SchedulerClient implementation.
206 void WillBeginImplFrame(const BeginFrameArgs
& args
) override
{
207 actions_
.push_back("WillBeginImplFrame");
208 states_
.push_back(scheduler_
->AsValue());
210 void ScheduledActionSendBeginMainFrame() override
{
211 actions_
.push_back("ScheduledActionSendBeginMainFrame");
212 states_
.push_back(scheduler_
->AsValue());
214 void ScheduledActionAnimate() override
{
215 actions_
.push_back("ScheduledActionAnimate");
216 states_
.push_back(scheduler_
->AsValue());
218 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
219 actions_
.push_back("ScheduledActionDrawAndSwapIfPossible");
220 states_
.push_back(scheduler_
->AsValue());
223 draw_will_happen_
? DRAW_SUCCESS
: DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
224 bool swap_will_happen
=
225 draw_will_happen_
&& swap_will_happen_if_draw_happens_
;
226 if (swap_will_happen
) {
227 scheduler_
->DidSwapBuffers();
229 if (automatic_swap_ack_
)
230 scheduler_
->DidSwapBuffersComplete();
234 DrawResult
ScheduledActionDrawAndSwapForced() override
{
235 actions_
.push_back("ScheduledActionDrawAndSwapForced");
236 states_
.push_back(scheduler_
->AsValue());
239 void ScheduledActionCommit() override
{
240 actions_
.push_back("ScheduledActionCommit");
241 states_
.push_back(scheduler_
->AsValue());
243 void ScheduledActionActivateSyncTree() override
{
244 actions_
.push_back("ScheduledActionActivateSyncTree");
245 states_
.push_back(scheduler_
->AsValue());
247 void ScheduledActionBeginOutputSurfaceCreation() override
{
248 actions_
.push_back("ScheduledActionBeginOutputSurfaceCreation");
249 states_
.push_back(scheduler_
->AsValue());
251 void ScheduledActionManageTiles() override
{
252 actions_
.push_back("ScheduledActionManageTiles");
253 states_
.push_back(scheduler_
->AsValue());
255 void DidAnticipatedDrawTimeChange(base::TimeTicks
) override
{
256 if (log_anticipated_draw_time_change_
)
257 actions_
.push_back("DidAnticipatedDrawTimeChange");
259 base::TimeDelta
DrawDurationEstimate() override
{ return base::TimeDelta(); }
260 base::TimeDelta
BeginMainFrameToCommitDurationEstimate() override
{
261 return base::TimeDelta();
263 base::TimeDelta
CommitToActivateDurationEstimate() override
{
264 return base::TimeDelta();
267 void DidBeginImplFrameDeadline() override
{}
269 base::Callback
<bool(void)> ImplFrameDeadlinePending(bool state
) {
270 return base::Bind(&FakeSchedulerClient::ImplFrameDeadlinePendingCallback
,
271 base::Unretained(this),
276 bool ImplFrameDeadlinePendingCallback(bool state
) {
277 return scheduler_
->BeginImplFrameDeadlinePending() == state
;
280 bool draw_will_happen_
;
281 bool swap_will_happen_if_draw_happens_
;
282 bool automatic_swap_ack_
;
284 bool log_anticipated_draw_time_change_
;
285 base::TimeTicks posted_begin_impl_frame_deadline_
;
286 std::vector
<const char*> actions_
;
287 std::vector
<scoped_refptr
<base::debug::ConvertableToTraceFormat
>> states_
;
288 scoped_refptr
<TestNowSource
> now_src_
;
289 scoped_refptr
<OrderedSimpleTaskRunner
> task_runner_
;
290 FakeExternalBeginFrameSource
* fake_external_begin_frame_source_
;
291 FakePowerMonitorSource
* fake_power_monitor_source_
;
292 base::PowerMonitor power_monitor_
;
293 scoped_ptr
<TestScheduler
> scheduler_
;
296 void InitializeOutputSurfaceAndFirstCommit(Scheduler
* scheduler
,
297 FakeSchedulerClient
* client
) {
299 "SchedulerUnitTest::InitializeOutputSurfaceAndFirstCommit");
301 scheduler
->DidCreateAndInitializeOutputSurface();
302 scheduler
->SetNeedsCommit();
303 scheduler
->NotifyBeginMainFrameStarted();
304 scheduler
->NotifyReadyToCommit();
305 if (scheduler
->settings().impl_side_painting
)
306 scheduler
->NotifyReadyToActivate();
309 SCOPED_TRACE("Go through the motions to draw the commit");
310 client
->AdvanceFrame();
313 // Run the posted deadline task.
314 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
315 client
->task_runner().RunTasksWhile(client
->ImplFrameDeadlinePending(true));
316 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
320 "We need another BeginImplFrame so Scheduler calls "
321 "SetNeedsBeginFrame(false).");
322 client
->AdvanceFrame();
325 // Run the posted deadline task.
326 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
327 client
->task_runner().RunTasksWhile(client
->ImplFrameDeadlinePending(true));
328 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
331 TEST(SchedulerTest
, InitializeOutputSurfaceDoesNotBeginImplFrame
) {
332 FakeSchedulerClient client
;
333 SchedulerSettings scheduler_settings
;
334 scheduler_settings
.use_external_begin_frame_source
= true;
335 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
336 scheduler
->SetCanStart();
337 scheduler
->SetVisible(true);
338 scheduler
->SetCanDraw(true);
340 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
342 scheduler
->DidCreateAndInitializeOutputSurface();
343 EXPECT_NO_ACTION(client
);
346 TEST(SchedulerTest
, RequestCommit
) {
347 FakeSchedulerClient client
;
348 SchedulerSettings scheduler_settings
;
349 scheduler_settings
.use_external_begin_frame_source
= true;
350 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
351 scheduler
->SetCanStart();
352 scheduler
->SetVisible(true);
353 scheduler
->SetCanDraw(true);
355 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
356 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
358 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
360 scheduler
->SetNeedsCommit();
361 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
364 client
.AdvanceFrame();
365 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
366 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
367 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
368 EXPECT_TRUE(client
.needs_begin_frames());
371 // If we don't swap on the deadline, we wait for the next BeginFrame.
372 client
.task_runner().RunPendingTasks(); // Run posted deadline.
373 EXPECT_NO_ACTION(client
);
374 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
375 EXPECT_TRUE(client
.needs_begin_frames());
378 // NotifyReadyToCommit should trigger the commit.
379 scheduler
->NotifyBeginMainFrameStarted();
380 scheduler
->NotifyReadyToCommit();
381 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
382 EXPECT_TRUE(client
.needs_begin_frames());
385 // BeginImplFrame should prepare the draw.
386 client
.AdvanceFrame();
387 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
388 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
389 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
390 EXPECT_TRUE(client
.needs_begin_frames());
393 // BeginImplFrame deadline should draw.
394 client
.task_runner().RunPendingTasks(); // Run posted deadline.
395 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 0, 1);
396 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
397 EXPECT_TRUE(client
.needs_begin_frames());
400 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
401 // to avoid excessive toggles.
402 client
.AdvanceFrame();
403 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
404 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
407 client
.task_runner().RunPendingTasks(); // Run posted deadline.
408 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
412 TEST(SchedulerTest
, RequestCommitAfterBeginMainFrameSent
) {
413 FakeSchedulerClient client
;
414 SchedulerSettings scheduler_settings
;
415 scheduler_settings
.use_external_begin_frame_source
= true;
416 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
417 scheduler
->SetCanStart();
418 scheduler
->SetVisible(true);
419 scheduler
->SetCanDraw(true);
421 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
422 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
425 // SetNeedsCommit should begin the frame.
426 scheduler
->SetNeedsCommit();
427 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
430 client
.AdvanceFrame();
431 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
432 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
433 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
435 EXPECT_TRUE(client
.needs_begin_frames());
438 // Now SetNeedsCommit again. Calling here means we need a second commit.
439 scheduler
->SetNeedsCommit();
440 EXPECT_EQ(client
.num_actions_(), 0);
443 // Finish the first commit.
444 scheduler
->NotifyBeginMainFrameStarted();
445 scheduler
->NotifyReadyToCommit();
446 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
447 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
449 client
.task_runner().RunPendingTasks(); // Run posted deadline.
450 EXPECT_ACTION("ScheduledActionAnimate", client
, 0, 2);
451 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 1, 2);
452 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
454 // Because we just swapped, the Scheduler should also request the next
455 // BeginImplFrame from the OutputSurface.
456 EXPECT_TRUE(client
.needs_begin_frames());
458 // Since another commit is needed, the next BeginImplFrame should initiate
459 // the second commit.
460 client
.AdvanceFrame();
461 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
462 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
463 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
466 // Finishing the commit before the deadline should post a new deadline task
467 // to trigger the deadline early.
468 scheduler
->NotifyBeginMainFrameStarted();
469 scheduler
->NotifyReadyToCommit();
470 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
471 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
473 client
.task_runner().RunPendingTasks(); // Run posted deadline.
474 EXPECT_ACTION("ScheduledActionAnimate", client
, 0, 2);
475 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 1, 2);
476 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
477 EXPECT_TRUE(client
.needs_begin_frames());
480 // On the next BeginImplFrame, verify we go back to a quiescent state and
481 // no longer request BeginImplFrames.
482 client
.AdvanceFrame();
483 client
.task_runner().RunPendingTasks(); // Run posted deadline.
484 EXPECT_FALSE(client
.needs_begin_frames());
488 class SchedulerClientThatsetNeedsDrawInsideDraw
: public FakeSchedulerClient
{
490 void ScheduledActionSendBeginMainFrame() override
{}
491 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
492 // Only SetNeedsRedraw the first time this is called
494 scheduler_
->SetNeedsRedraw();
495 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
498 DrawResult
ScheduledActionDrawAndSwapForced() override
{
503 void ScheduledActionCommit() override
{}
504 void ScheduledActionBeginOutputSurfaceCreation() override
{}
505 void DidAnticipatedDrawTimeChange(base::TimeTicks
) override
{}
508 // Tests for two different situations:
509 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside
510 // a ScheduledActionDrawAndSwap
511 // 2. the scheduler drawing twice inside a single tick
512 TEST(SchedulerTest
, RequestRedrawInsideDraw
) {
513 SchedulerClientThatsetNeedsDrawInsideDraw client
;
514 SchedulerSettings scheduler_settings
;
515 scheduler_settings
.use_external_begin_frame_source
= true;
516 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
517 scheduler
->SetCanStart();
518 scheduler
->SetVisible(true);
519 scheduler
->SetCanDraw(true);
520 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
523 scheduler
->SetNeedsRedraw();
524 EXPECT_TRUE(scheduler
->RedrawPending());
525 EXPECT_TRUE(client
.needs_begin_frames());
526 EXPECT_EQ(0, client
.num_draws());
528 client
.AdvanceFrame();
529 client
.task_runner().RunPendingTasks(); // Run posted deadline.
530 EXPECT_EQ(1, client
.num_draws());
531 EXPECT_TRUE(scheduler
->RedrawPending());
532 EXPECT_TRUE(client
.needs_begin_frames());
534 client
.AdvanceFrame();
535 client
.task_runner().RunPendingTasks(); // Run posted deadline.
536 EXPECT_EQ(2, client
.num_draws());
537 EXPECT_FALSE(scheduler
->RedrawPending());
538 EXPECT_TRUE(client
.needs_begin_frames());
540 // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
542 client
.AdvanceFrame();
543 client
.task_runner().RunPendingTasks(); // Run posted deadline.
544 EXPECT_EQ(2, client
.num_draws());
545 EXPECT_FALSE(scheduler
->RedrawPending());
546 EXPECT_FALSE(client
.needs_begin_frames());
549 // Test that requesting redraw inside a failed draw doesn't lose the request.
550 TEST(SchedulerTest
, RequestRedrawInsideFailedDraw
) {
551 SchedulerClientThatsetNeedsDrawInsideDraw client
;
552 SchedulerSettings scheduler_settings
;
553 scheduler_settings
.use_external_begin_frame_source
= true;
554 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
555 scheduler
->SetCanStart();
556 scheduler
->SetVisible(true);
557 scheduler
->SetCanDraw(true);
558 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
561 client
.SetDrawWillHappen(false);
563 scheduler
->SetNeedsRedraw();
564 EXPECT_TRUE(scheduler
->RedrawPending());
565 EXPECT_TRUE(client
.needs_begin_frames());
566 EXPECT_EQ(0, client
.num_draws());
569 client
.AdvanceFrame();
570 client
.task_runner().RunPendingTasks(); // Run posted deadline.
571 EXPECT_EQ(1, client
.num_draws());
573 // We have a commit pending and the draw failed, and we didn't lose the redraw
575 EXPECT_TRUE(scheduler
->CommitPending());
576 EXPECT_TRUE(scheduler
->RedrawPending());
577 EXPECT_TRUE(client
.needs_begin_frames());
579 // Fail the draw again.
580 client
.AdvanceFrame();
581 client
.task_runner().RunPendingTasks(); // Run posted deadline.
582 EXPECT_EQ(2, client
.num_draws());
583 EXPECT_TRUE(scheduler
->CommitPending());
584 EXPECT_TRUE(scheduler
->RedrawPending());
585 EXPECT_TRUE(client
.needs_begin_frames());
587 // Draw successfully.
588 client
.SetDrawWillHappen(true);
589 client
.AdvanceFrame();
590 client
.task_runner().RunPendingTasks(); // Run posted deadline.
591 EXPECT_EQ(3, client
.num_draws());
592 EXPECT_TRUE(scheduler
->CommitPending());
593 EXPECT_FALSE(scheduler
->RedrawPending());
594 EXPECT_TRUE(client
.needs_begin_frames());
597 class SchedulerClientThatSetNeedsCommitInsideDraw
: public FakeSchedulerClient
{
599 SchedulerClientThatSetNeedsCommitInsideDraw()
600 : set_needs_commit_on_next_draw_(false) {}
602 void ScheduledActionSendBeginMainFrame() override
{}
603 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
604 // Only SetNeedsCommit the first time this is called
605 if (set_needs_commit_on_next_draw_
) {
606 scheduler_
->SetNeedsCommit();
607 set_needs_commit_on_next_draw_
= false;
609 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
612 DrawResult
ScheduledActionDrawAndSwapForced() override
{
617 void ScheduledActionCommit() override
{}
618 void ScheduledActionBeginOutputSurfaceCreation() override
{}
619 void DidAnticipatedDrawTimeChange(base::TimeTicks
) override
{}
621 void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_
= true; }
624 bool set_needs_commit_on_next_draw_
;
627 // Tests for the scheduler infinite-looping on SetNeedsCommit requests that
628 // happen inside a ScheduledActionDrawAndSwap
629 TEST(SchedulerTest
, RequestCommitInsideDraw
) {
630 SchedulerClientThatSetNeedsCommitInsideDraw client
;
631 SchedulerSettings scheduler_settings
;
632 scheduler_settings
.use_external_begin_frame_source
= true;
633 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
634 scheduler
->SetCanStart();
635 scheduler
->SetVisible(true);
636 scheduler
->SetCanDraw(true);
637 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
640 EXPECT_FALSE(client
.needs_begin_frames());
641 scheduler
->SetNeedsRedraw();
642 EXPECT_TRUE(scheduler
->RedrawPending());
643 EXPECT_EQ(0, client
.num_draws());
644 EXPECT_TRUE(client
.needs_begin_frames());
646 client
.SetNeedsCommitOnNextDraw();
647 client
.AdvanceFrame();
648 client
.SetNeedsCommitOnNextDraw();
649 client
.task_runner().RunPendingTasks(); // Run posted deadline.
650 EXPECT_EQ(1, client
.num_draws());
651 EXPECT_TRUE(scheduler
->CommitPending());
652 EXPECT_TRUE(client
.needs_begin_frames());
653 scheduler
->NotifyBeginMainFrameStarted();
654 scheduler
->NotifyReadyToCommit();
656 client
.AdvanceFrame();
657 client
.task_runner().RunPendingTasks(); // Run posted deadline.
658 EXPECT_EQ(2, client
.num_draws());
660 EXPECT_FALSE(scheduler
->RedrawPending());
661 EXPECT_FALSE(scheduler
->CommitPending());
662 EXPECT_TRUE(client
.needs_begin_frames());
664 // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
666 client
.AdvanceFrame();
667 client
.task_runner().RunPendingTasks(); // Run posted deadline.
668 EXPECT_EQ(2, client
.num_draws());
669 EXPECT_FALSE(scheduler
->RedrawPending());
670 EXPECT_FALSE(scheduler
->CommitPending());
671 EXPECT_FALSE(client
.needs_begin_frames());
674 // Tests that when a draw fails then the pending commit should not be dropped.
675 TEST(SchedulerTest
, RequestCommitInsideFailedDraw
) {
676 SchedulerClientThatsetNeedsDrawInsideDraw client
;
677 SchedulerSettings scheduler_settings
;
678 scheduler_settings
.use_external_begin_frame_source
= true;
679 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
680 scheduler
->SetCanStart();
681 scheduler
->SetVisible(true);
682 scheduler
->SetCanDraw(true);
683 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
686 client
.SetDrawWillHappen(false);
688 scheduler
->SetNeedsRedraw();
689 EXPECT_TRUE(scheduler
->RedrawPending());
690 EXPECT_TRUE(client
.needs_begin_frames());
691 EXPECT_EQ(0, client
.num_draws());
694 client
.AdvanceFrame();
695 client
.task_runner().RunPendingTasks(); // Run posted deadline.
696 EXPECT_EQ(1, client
.num_draws());
698 // We have a commit pending and the draw failed, and we didn't lose the commit
700 EXPECT_TRUE(scheduler
->CommitPending());
701 EXPECT_TRUE(scheduler
->RedrawPending());
702 EXPECT_TRUE(client
.needs_begin_frames());
704 // Fail the draw again.
705 client
.AdvanceFrame();
707 client
.task_runner().RunPendingTasks(); // Run posted deadline.
708 EXPECT_EQ(2, client
.num_draws());
709 EXPECT_TRUE(scheduler
->CommitPending());
710 EXPECT_TRUE(scheduler
->RedrawPending());
711 EXPECT_TRUE(client
.needs_begin_frames());
713 // Draw successfully.
714 client
.SetDrawWillHappen(true);
715 client
.AdvanceFrame();
716 client
.task_runner().RunPendingTasks(); // Run posted deadline.
717 EXPECT_EQ(3, client
.num_draws());
718 EXPECT_TRUE(scheduler
->CommitPending());
719 EXPECT_FALSE(scheduler
->RedrawPending());
720 EXPECT_TRUE(client
.needs_begin_frames());
723 TEST(SchedulerTest
, NoSwapWhenDrawFails
) {
724 SchedulerClientThatSetNeedsCommitInsideDraw client
;
725 SchedulerSettings scheduler_settings
;
726 scheduler_settings
.use_external_begin_frame_source
= true;
727 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
728 scheduler
->SetCanStart();
729 scheduler
->SetVisible(true);
730 scheduler
->SetCanDraw(true);
731 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
734 scheduler
->SetNeedsRedraw();
735 EXPECT_TRUE(scheduler
->RedrawPending());
736 EXPECT_TRUE(client
.needs_begin_frames());
737 EXPECT_EQ(0, client
.num_draws());
739 // Draw successfully, this starts a new frame.
740 client
.SetNeedsCommitOnNextDraw();
741 client
.AdvanceFrame();
742 client
.task_runner().RunPendingTasks(); // Run posted deadline.
743 EXPECT_EQ(1, client
.num_draws());
745 scheduler
->SetNeedsRedraw();
746 EXPECT_TRUE(scheduler
->RedrawPending());
747 EXPECT_TRUE(client
.needs_begin_frames());
749 // Fail to draw, this should not start a frame.
750 client
.SetDrawWillHappen(false);
751 client
.SetNeedsCommitOnNextDraw();
752 client
.AdvanceFrame();
753 client
.task_runner().RunPendingTasks(); // Run posted deadline.
754 EXPECT_EQ(2, client
.num_draws());
757 class SchedulerClientNeedsManageTilesInDraw
: public FakeSchedulerClient
{
759 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
760 scheduler_
->SetNeedsManageTiles();
761 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
765 // Test manage tiles is independant of draws.
766 TEST(SchedulerTest
, ManageTiles
) {
767 SchedulerClientNeedsManageTilesInDraw client
;
768 SchedulerSettings scheduler_settings
;
769 scheduler_settings
.use_external_begin_frame_source
= true;
770 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
771 scheduler
->SetCanStart();
772 scheduler
->SetVisible(true);
773 scheduler
->SetCanDraw(true);
774 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
776 // Request both draw and manage tiles. ManageTiles shouldn't
777 // be trigged until BeginImplFrame.
779 scheduler
->SetNeedsManageTiles();
780 scheduler
->SetNeedsRedraw();
781 EXPECT_TRUE(scheduler
->RedrawPending());
782 EXPECT_TRUE(scheduler
->ManageTilesPending());
783 EXPECT_TRUE(client
.needs_begin_frames());
784 EXPECT_EQ(0, client
.num_draws());
785 EXPECT_FALSE(client
.HasAction("ScheduledActionManageTiles"));
786 EXPECT_FALSE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
788 // We have no immediate actions to perform, so the BeginImplFrame should post
789 // the deadline task.
791 client
.AdvanceFrame();
792 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
793 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
794 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
796 // On the deadline, he actions should have occured in the right order.
798 client
.task_runner().RunPendingTasks(); // Run posted deadline.
799 EXPECT_EQ(1, client
.num_draws());
800 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
801 EXPECT_TRUE(client
.HasAction("ScheduledActionManageTiles"));
802 EXPECT_LT(client
.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
803 client
.ActionIndex("ScheduledActionManageTiles"));
804 EXPECT_FALSE(scheduler
->RedrawPending());
805 EXPECT_FALSE(scheduler
->ManageTilesPending());
806 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
808 // Request a draw. We don't need a ManageTiles yet.
810 scheduler
->SetNeedsRedraw();
811 EXPECT_TRUE(scheduler
->RedrawPending());
812 EXPECT_FALSE(scheduler
->ManageTilesPending());
813 EXPECT_TRUE(client
.needs_begin_frames());
814 EXPECT_EQ(0, client
.num_draws());
816 // We have no immediate actions to perform, so the BeginImplFrame should post
817 // the deadline task.
819 client
.AdvanceFrame();
820 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
821 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
822 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
824 // Draw. The draw will trigger SetNeedsManageTiles, and
825 // then the ManageTiles action will be triggered after the Draw.
826 // Afterwards, neither a draw nor ManageTiles are pending.
828 client
.task_runner().RunPendingTasks(); // Run posted deadline.
829 EXPECT_EQ(1, client
.num_draws());
830 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
831 EXPECT_TRUE(client
.HasAction("ScheduledActionManageTiles"));
832 EXPECT_LT(client
.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
833 client
.ActionIndex("ScheduledActionManageTiles"));
834 EXPECT_FALSE(scheduler
->RedrawPending());
835 EXPECT_FALSE(scheduler
->ManageTilesPending());
836 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
838 // We need a BeginImplFrame where we don't swap to go idle.
840 client
.AdvanceFrame();
841 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
842 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
844 client
.task_runner().RunPendingTasks(); // Run posted deadline.
845 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
846 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
847 EXPECT_EQ(0, client
.num_draws());
849 // Now trigger a ManageTiles outside of a draw. We will then need
850 // a begin-frame for the ManageTiles, but we don't need a draw.
852 EXPECT_FALSE(client
.needs_begin_frames());
853 scheduler
->SetNeedsManageTiles();
854 EXPECT_TRUE(client
.needs_begin_frames());
855 EXPECT_TRUE(scheduler
->ManageTilesPending());
856 EXPECT_FALSE(scheduler
->RedrawPending());
858 // BeginImplFrame. There will be no draw, only ManageTiles.
860 client
.AdvanceFrame();
861 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
862 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
864 client
.task_runner().RunPendingTasks(); // Run posted deadline.
865 EXPECT_EQ(0, client
.num_draws());
866 EXPECT_FALSE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
867 EXPECT_TRUE(client
.HasAction("ScheduledActionManageTiles"));
868 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
871 // Test that ManageTiles only happens once per frame. If an external caller
872 // initiates it, then the state machine should not ManageTiles on that frame.
873 TEST(SchedulerTest
, ManageTilesOncePerFrame
) {
874 FakeSchedulerClient client
;
875 SchedulerSettings scheduler_settings
;
876 scheduler_settings
.use_external_begin_frame_source
= true;
877 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
878 scheduler
->SetCanStart();
879 scheduler
->SetVisible(true);
880 scheduler
->SetCanDraw(true);
881 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
883 // If DidManageTiles during a frame, then ManageTiles should not occur again.
884 scheduler
->SetNeedsManageTiles();
885 scheduler
->SetNeedsRedraw();
887 client
.AdvanceFrame();
888 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
889 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
890 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
892 EXPECT_TRUE(scheduler
->ManageTilesPending());
893 scheduler
->DidManageTiles(); // An explicit ManageTiles.
894 EXPECT_FALSE(scheduler
->ManageTilesPending());
897 client
.task_runner().RunPendingTasks(); // Run posted deadline.
898 EXPECT_EQ(1, client
.num_draws());
899 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
900 EXPECT_FALSE(client
.HasAction("ScheduledActionManageTiles"));
901 EXPECT_FALSE(scheduler
->RedrawPending());
902 EXPECT_FALSE(scheduler
->ManageTilesPending());
903 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
905 // Next frame without DidManageTiles should ManageTiles with draw.
906 scheduler
->SetNeedsManageTiles();
907 scheduler
->SetNeedsRedraw();
909 client
.AdvanceFrame();
910 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
911 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
912 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
915 client
.task_runner().RunPendingTasks(); // Run posted deadline.
916 EXPECT_EQ(1, client
.num_draws());
917 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
918 EXPECT_TRUE(client
.HasAction("ScheduledActionManageTiles"));
919 EXPECT_LT(client
.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
920 client
.ActionIndex("ScheduledActionManageTiles"));
921 EXPECT_FALSE(scheduler
->RedrawPending());
922 EXPECT_FALSE(scheduler
->ManageTilesPending());
923 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
924 scheduler
->DidManageTiles(); // Corresponds to ScheduledActionManageTiles
926 // If we get another DidManageTiles within the same frame, we should
927 // not ManageTiles on the next frame.
928 scheduler
->DidManageTiles(); // An explicit ManageTiles.
929 scheduler
->SetNeedsManageTiles();
930 scheduler
->SetNeedsRedraw();
932 client
.AdvanceFrame();
933 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
934 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
935 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
937 EXPECT_TRUE(scheduler
->ManageTilesPending());
940 client
.task_runner().RunPendingTasks(); // Run posted deadline.
941 EXPECT_EQ(1, client
.num_draws());
942 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
943 EXPECT_FALSE(client
.HasAction("ScheduledActionManageTiles"));
944 EXPECT_FALSE(scheduler
->RedrawPending());
945 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
947 // If we get another DidManageTiles, we should not ManageTiles on the next
948 // frame. This verifies we don't alternate calling ManageTiles once and twice.
949 EXPECT_TRUE(scheduler
->ManageTilesPending());
950 scheduler
->DidManageTiles(); // An explicit ManageTiles.
951 EXPECT_FALSE(scheduler
->ManageTilesPending());
952 scheduler
->SetNeedsManageTiles();
953 scheduler
->SetNeedsRedraw();
955 client
.AdvanceFrame();
956 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
957 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
958 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
960 EXPECT_TRUE(scheduler
->ManageTilesPending());
963 client
.task_runner().RunPendingTasks(); // Run posted deadline.
964 EXPECT_EQ(1, client
.num_draws());
965 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
966 EXPECT_FALSE(client
.HasAction("ScheduledActionManageTiles"));
967 EXPECT_FALSE(scheduler
->RedrawPending());
968 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
970 // Next frame without DidManageTiles should ManageTiles with draw.
971 scheduler
->SetNeedsManageTiles();
972 scheduler
->SetNeedsRedraw();
974 client
.AdvanceFrame();
975 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
976 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
977 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
980 client
.task_runner().RunPendingTasks(); // Run posted deadline.
981 EXPECT_EQ(1, client
.num_draws());
982 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
983 EXPECT_TRUE(client
.HasAction("ScheduledActionManageTiles"));
984 EXPECT_LT(client
.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
985 client
.ActionIndex("ScheduledActionManageTiles"));
986 EXPECT_FALSE(scheduler
->RedrawPending());
987 EXPECT_FALSE(scheduler
->ManageTilesPending());
988 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
989 scheduler
->DidManageTiles(); // Corresponds to ScheduledActionManageTiles
992 TEST(SchedulerTest
, TriggerBeginFrameDeadlineEarly
) {
993 SchedulerClientNeedsManageTilesInDraw client
;
994 SchedulerSettings scheduler_settings
;
995 scheduler_settings
.use_external_begin_frame_source
= true;
996 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
997 scheduler
->SetCanStart();
998 scheduler
->SetVisible(true);
999 scheduler
->SetCanDraw(true);
1000 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1003 scheduler
->SetNeedsRedraw();
1004 client
.AdvanceFrame();
1006 // The deadline should be zero since there is no work other than drawing
1008 EXPECT_EQ(base::TimeTicks(), client
.posted_begin_impl_frame_deadline());
1011 class SchedulerClientWithFixedEstimates
: public FakeSchedulerClient
{
1013 SchedulerClientWithFixedEstimates(
1014 base::TimeDelta draw_duration
,
1015 base::TimeDelta begin_main_frame_to_commit_duration
,
1016 base::TimeDelta commit_to_activate_duration
)
1017 : draw_duration_(draw_duration
),
1018 begin_main_frame_to_commit_duration_(
1019 begin_main_frame_to_commit_duration
),
1020 commit_to_activate_duration_(commit_to_activate_duration
) {}
1022 base::TimeDelta
DrawDurationEstimate() override
{ return draw_duration_
; }
1023 base::TimeDelta
BeginMainFrameToCommitDurationEstimate() override
{
1024 return begin_main_frame_to_commit_duration_
;
1026 base::TimeDelta
CommitToActivateDurationEstimate() override
{
1027 return commit_to_activate_duration_
;
1031 base::TimeDelta draw_duration_
;
1032 base::TimeDelta begin_main_frame_to_commit_duration_
;
1033 base::TimeDelta commit_to_activate_duration_
;
1036 void MainFrameInHighLatencyMode(int64 begin_main_frame_to_commit_estimate_in_ms
,
1037 int64 commit_to_activate_estimate_in_ms
,
1038 bool impl_latency_takes_priority
,
1039 bool should_send_begin_main_frame
) {
1040 // Set up client with specified estimates (draw duration is set to 1).
1041 SchedulerClientWithFixedEstimates
client(
1042 base::TimeDelta::FromMilliseconds(1),
1043 base::TimeDelta::FromMilliseconds(
1044 begin_main_frame_to_commit_estimate_in_ms
),
1045 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms
));
1046 SchedulerSettings scheduler_settings
;
1047 scheduler_settings
.use_external_begin_frame_source
= true;
1048 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1049 scheduler
->SetCanStart();
1050 scheduler
->SetVisible(true);
1051 scheduler
->SetCanDraw(true);
1052 scheduler
->SetImplLatencyTakesPriority(impl_latency_takes_priority
);
1053 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1055 // Impl thread hits deadline before commit finishes.
1057 scheduler
->SetNeedsCommit();
1058 EXPECT_FALSE(scheduler
->MainThreadIsInHighLatencyMode());
1059 client
.AdvanceFrame();
1060 EXPECT_FALSE(scheduler
->MainThreadIsInHighLatencyMode());
1061 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1062 EXPECT_TRUE(scheduler
->MainThreadIsInHighLatencyMode());
1063 scheduler
->NotifyBeginMainFrameStarted();
1064 scheduler
->NotifyReadyToCommit();
1065 EXPECT_TRUE(scheduler
->MainThreadIsInHighLatencyMode());
1066 EXPECT_TRUE(client
.HasAction("ScheduledActionSendBeginMainFrame"));
1069 scheduler
->SetNeedsCommit();
1070 EXPECT_TRUE(scheduler
->MainThreadIsInHighLatencyMode());
1071 client
.AdvanceFrame();
1072 EXPECT_TRUE(scheduler
->MainThreadIsInHighLatencyMode());
1073 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1074 EXPECT_EQ(scheduler
->MainThreadIsInHighLatencyMode(),
1075 should_send_begin_main_frame
);
1076 EXPECT_EQ(client
.HasAction("ScheduledActionSendBeginMainFrame"),
1077 should_send_begin_main_frame
);
1081 SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline
) {
1082 // Set up client so that estimates indicate that we can commit and activate
1083 // before the deadline (~8ms by default).
1084 MainFrameInHighLatencyMode(1, 1, false, false);
1087 TEST(SchedulerTest
, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong
) {
1088 // Set up client so that estimates indicate that the commit cannot finish
1089 // before the deadline (~8ms by default).
1090 MainFrameInHighLatencyMode(10, 1, false, true);
1093 TEST(SchedulerTest
, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong
) {
1094 // Set up client so that estimates indicate that the activate cannot finish
1095 // before the deadline (~8ms by default).
1096 MainFrameInHighLatencyMode(1, 10, false, true);
1099 TEST(SchedulerTest
, NotSkipMainFrameInPreferImplLatencyMode
) {
1100 // Set up client so that estimates indicate that we can commit and activate
1101 // before the deadline (~8ms by default), but also enable impl latency takes
1103 MainFrameInHighLatencyMode(1, 1, true, true);
1106 TEST(SchedulerTest
, PollForCommitCompletion
) {
1107 // Since we are simulating a long commit, set up a client with draw duration
1108 // estimates that prevent skipping main frames to get to low latency mode.
1109 SchedulerClientWithFixedEstimates
client(
1110 base::TimeDelta::FromMilliseconds(1),
1111 base::TimeDelta::FromMilliseconds(32),
1112 base::TimeDelta::FromMilliseconds(32));
1113 client
.set_log_anticipated_draw_time_change(true);
1114 SchedulerSettings scheduler_settings
;
1115 scheduler_settings
.use_external_begin_frame_source
= true;
1116 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1118 scheduler
->SetCanDraw(true);
1119 scheduler
->SetCanStart();
1120 scheduler
->SetVisible(true);
1121 scheduler
->DidCreateAndInitializeOutputSurface();
1123 scheduler
->SetNeedsCommit();
1124 EXPECT_TRUE(scheduler
->CommitPending());
1125 scheduler
->NotifyBeginMainFrameStarted();
1126 scheduler
->NotifyReadyToCommit();
1127 scheduler
->SetNeedsRedraw();
1129 BeginFrameArgs frame_args
= CreateBeginFrameArgsForTesting(client
.now_src());
1130 frame_args
.interval
= base::TimeDelta::FromMilliseconds(1000);
1131 client
.fake_external_begin_frame_source()->TestOnBeginFrame(frame_args
);
1133 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1134 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1135 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1137 scheduler
->DidSwapBuffers();
1138 scheduler
->DidSwapBuffersComplete();
1140 // At this point, we've drawn a frame. Start another commit, but hold off on
1141 // the NotifyReadyToCommit for now.
1142 EXPECT_FALSE(scheduler
->CommitPending());
1143 scheduler
->SetNeedsCommit();
1144 client
.fake_external_begin_frame_source()->TestOnBeginFrame(frame_args
);
1145 EXPECT_TRUE(scheduler
->CommitPending());
1147 // Draw and swap the frame, but don't ack the swap to simulate the Browser
1148 // blocking on the renderer.
1149 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1150 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1151 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1152 scheduler
->DidSwapBuffers();
1154 // Spin the event loop a few times and make sure we get more
1155 // DidAnticipateDrawTimeChange calls every time.
1156 int actions_so_far
= client
.num_actions_();
1158 // Does three iterations to make sure that the timer is properly repeating.
1159 for (int i
= 0; i
< 3; ++i
) {
1160 EXPECT_EQ((frame_args
.interval
* 2).InMicroseconds(),
1161 client
.task_runner().DelayToNextTaskTime().InMicroseconds())
1162 << scheduler
->AsValue()->ToString();
1163 client
.task_runner().RunPendingTasks();
1164 EXPECT_GT(client
.num_actions_(), actions_so_far
);
1165 EXPECT_STREQ(client
.Action(client
.num_actions_() - 1),
1166 "DidAnticipatedDrawTimeChange");
1167 actions_so_far
= client
.num_actions_();
1170 // Do the same thing after BeginMainFrame starts but still before activation.
1171 scheduler
->NotifyBeginMainFrameStarted();
1172 for (int i
= 0; i
< 3; ++i
) {
1173 EXPECT_EQ((frame_args
.interval
* 2).InMicroseconds(),
1174 client
.task_runner().DelayToNextTaskTime().InMicroseconds())
1175 << scheduler
->AsValue()->ToString();
1176 client
.task_runner().RunPendingTasks();
1177 EXPECT_GT(client
.num_actions_(), actions_so_far
);
1178 EXPECT_STREQ(client
.Action(client
.num_actions_() - 1),
1179 "DidAnticipatedDrawTimeChange");
1180 actions_so_far
= client
.num_actions_();
1184 TEST(SchedulerTest
, BeginRetroFrame
) {
1185 FakeSchedulerClient client
;
1186 SchedulerSettings scheduler_settings
;
1187 scheduler_settings
.use_external_begin_frame_source
= true;
1188 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1189 scheduler
->SetCanStart();
1190 scheduler
->SetVisible(true);
1191 scheduler
->SetCanDraw(true);
1192 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1194 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1196 scheduler
->SetNeedsCommit();
1197 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1200 // Create a BeginFrame with a long deadline to avoid race conditions.
1201 // This is the first BeginFrame, which will be handled immediately.
1202 BeginFrameArgs args
= CreateBeginFrameArgsForTesting(client
.now_src());
1203 args
.deadline
+= base::TimeDelta::FromHours(1);
1204 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1205 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1206 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1207 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1208 EXPECT_TRUE(client
.needs_begin_frames());
1211 // Queue BeginFrames while we are still handling the previous BeginFrame.
1212 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1213 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1214 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1215 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1217 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
1218 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1219 EXPECT_NO_ACTION(client
);
1220 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1221 EXPECT_TRUE(client
.needs_begin_frames());
1224 // NotifyReadyToCommit should trigger the commit.
1225 scheduler
->NotifyBeginMainFrameStarted();
1226 scheduler
->NotifyReadyToCommit();
1227 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1228 EXPECT_TRUE(client
.needs_begin_frames());
1231 // BeginImplFrame should prepare the draw.
1232 client
.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
1233 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1234 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1235 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1236 EXPECT_TRUE(client
.needs_begin_frames());
1239 // BeginImplFrame deadline should draw.
1240 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1241 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 0, 1);
1242 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1243 EXPECT_TRUE(client
.needs_begin_frames());
1246 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
1247 // to avoid excessive toggles.
1248 client
.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
1249 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
1250 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1253 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1254 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1258 TEST(SchedulerTest
, BeginRetroFrame_SwapThrottled
) {
1259 FakeSchedulerClient client
;
1260 SchedulerSettings scheduler_settings
;
1261 scheduler_settings
.use_external_begin_frame_source
= true;
1262 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1263 scheduler
->SetCanStart();
1264 scheduler
->SetVisible(true);
1265 scheduler
->SetCanDraw(true);
1266 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1268 // To test swap ack throttling, this test disables automatic swap acks.
1269 scheduler
->SetMaxSwapsPending(1);
1270 client
.SetAutomaticSwapAck(false);
1272 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1274 scheduler
->SetNeedsCommit();
1275 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1278 // Create a BeginFrame with a long deadline to avoid race conditions.
1279 // This is the first BeginFrame, which will be handled immediately.
1280 BeginFrameArgs args
= CreateBeginFrameArgsForTesting(client
.now_src());
1281 args
.deadline
+= base::TimeDelta::FromHours(1);
1282 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1283 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1284 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1285 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1286 EXPECT_TRUE(client
.needs_begin_frames());
1289 // Queue BeginFrame while we are still handling the previous BeginFrame.
1290 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1291 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1292 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1293 EXPECT_NO_ACTION(client
);
1294 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1297 // NotifyReadyToCommit should trigger the pending commit and draw.
1298 scheduler
->NotifyBeginMainFrameStarted();
1299 scheduler
->NotifyReadyToCommit();
1300 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1301 EXPECT_TRUE(client
.needs_begin_frames());
1304 // Swapping will put us into a swap throttled state.
1305 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1306 EXPECT_ACTION("ScheduledActionAnimate", client
, 0, 2);
1307 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 1, 2);
1308 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1309 EXPECT_TRUE(client
.needs_begin_frames());
1312 // While swap throttled, BeginRetroFrames should trigger BeginImplFrames
1313 // but not a BeginMainFrame or draw.
1314 scheduler
->SetNeedsCommit();
1315 client
.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
1316 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 1);
1317 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1318 EXPECT_TRUE(client
.needs_begin_frames());
1321 // Queue BeginFrame while we are still handling the previous BeginFrame.
1322 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1323 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1324 EXPECT_NO_ACTION(client
);
1325 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1326 EXPECT_TRUE(client
.needs_begin_frames());
1329 // Take us out of a swap throttled state.
1330 scheduler
->DidSwapBuffersComplete();
1331 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 0, 1);
1332 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1333 EXPECT_TRUE(client
.needs_begin_frames());
1336 // BeginImplFrame deadline should draw.
1337 scheduler
->SetNeedsRedraw();
1339 EXPECT_TRUE(client
.task_runner().RunTasksWhile(
1340 client
.ImplFrameDeadlinePending(true)));
1342 EXPECT_ACTION("ScheduledActionAnimate", client
, 0, 2);
1343 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 1, 2);
1344 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1345 EXPECT_TRUE(client
.needs_begin_frames());
1349 void BeginFramesNotFromClient(bool use_external_begin_frame_source
,
1350 bool throttle_frame_production
) {
1351 FakeSchedulerClient client
;
1352 SchedulerSettings scheduler_settings
;
1353 scheduler_settings
.use_external_begin_frame_source
=
1354 use_external_begin_frame_source
;
1355 scheduler_settings
.throttle_frame_production
= throttle_frame_production
;
1356 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1357 scheduler
->SetCanStart();
1358 scheduler
->SetVisible(true);
1359 scheduler
->SetCanDraw(true);
1360 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1362 DCHECK(!client
.fake_external_begin_frame_source());
1364 // SetNeedsCommit should begin the frame on the next BeginImplFrame
1365 // without calling SetNeedsBeginFrame.
1367 scheduler
->SetNeedsCommit();
1368 EXPECT_NO_ACTION(client
);
1371 // When the client-driven BeginFrame are disabled, the scheduler posts it's
1372 // own BeginFrame tasks.
1373 client
.task_runner().RunPendingTasks(); // Run posted BeginFrame.
1374 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1375 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1376 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1379 // If we don't swap on the deadline, we wait for the next BeginFrame.
1380 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1381 EXPECT_NO_ACTION(client
);
1382 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1385 // NotifyReadyToCommit should trigger the commit.
1386 scheduler
->NotifyBeginMainFrameStarted();
1387 scheduler
->NotifyReadyToCommit();
1388 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1391 // BeginImplFrame should prepare the draw.
1392 client
.task_runner().RunPendingTasks(); // Run posted BeginFrame.
1393 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1394 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1395 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1398 // BeginImplFrame deadline should draw.
1399 client
.task_runner().RunTasksWhile(client
.ImplFrameDeadlinePending(true));
1400 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 0, 1);
1401 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1404 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
1405 // to avoid excessive toggles.
1406 client
.task_runner().RunPendingTasks(); // Run posted BeginFrame.
1407 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
1408 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1411 // Make sure SetNeedsBeginFrame isn't called on the client
1412 // when the BeginFrame is no longer needed.
1413 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1414 EXPECT_NO_ACTION(client
);
1418 TEST(SchedulerTest
, SyntheticBeginFrames
) {
1419 bool use_external_begin_frame_source
= false;
1420 bool throttle_frame_production
= true;
1421 BeginFramesNotFromClient(use_external_begin_frame_source
,
1422 throttle_frame_production
);
1425 TEST(SchedulerTest
, VSyncThrottlingDisabled
) {
1426 bool use_external_begin_frame_source
= true;
1427 bool throttle_frame_production
= false;
1428 BeginFramesNotFromClient(use_external_begin_frame_source
,
1429 throttle_frame_production
);
1432 TEST(SchedulerTest
, SyntheticBeginFrames_And_VSyncThrottlingDisabled
) {
1433 bool use_external_begin_frame_source
= false;
1434 bool throttle_frame_production
= false;
1435 BeginFramesNotFromClient(use_external_begin_frame_source
,
1436 throttle_frame_production
);
1439 void BeginFramesNotFromClient_SwapThrottled(
1440 bool use_external_begin_frame_source
,
1441 bool throttle_frame_production
) {
1442 FakeSchedulerClient client
;
1443 SchedulerSettings scheduler_settings
;
1444 scheduler_settings
.use_external_begin_frame_source
=
1445 use_external_begin_frame_source
;
1446 scheduler_settings
.throttle_frame_production
= throttle_frame_production
;
1447 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1448 scheduler
->SetCanStart();
1449 scheduler
->SetVisible(true);
1450 scheduler
->SetCanDraw(true);
1451 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1453 DCHECK(!client
.fake_external_begin_frame_source());
1455 // To test swap ack throttling, this test disables automatic swap acks.
1456 scheduler
->SetMaxSwapsPending(1);
1457 client
.SetAutomaticSwapAck(false);
1459 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1461 scheduler
->SetNeedsCommit();
1462 EXPECT_NO_ACTION(client
);
1465 // Trigger the first BeginImplFrame and BeginMainFrame
1466 client
.task_runner().RunPendingTasks(); // Run posted BeginFrame.
1467 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1468 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1469 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1472 // NotifyReadyToCommit should trigger the pending commit and draw.
1473 scheduler
->NotifyBeginMainFrameStarted();
1474 scheduler
->NotifyReadyToCommit();
1475 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1478 // Swapping will put us into a swap throttled state.
1479 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1480 EXPECT_ACTION("ScheduledActionAnimate", client
, 0, 2);
1481 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 1, 2);
1482 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1485 // While swap throttled, BeginFrames should trigger BeginImplFrames,
1486 // but not a BeginMainFrame or draw.
1487 scheduler
->SetNeedsCommit();
1488 client
.task_runner().RunPendingTasks(); // Run posted BeginFrame.
1489 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 1);
1490 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1493 // Take us out of a swap throttled state.
1494 scheduler
->DidSwapBuffersComplete();
1495 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 0, 1);
1496 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1499 // BeginImplFrame deadline should draw.
1500 scheduler
->SetNeedsRedraw();
1501 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1502 EXPECT_ACTION("ScheduledActionAnimate", client
, 0, 2);
1503 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 1, 2);
1504 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1508 TEST(SchedulerTest
, SyntheticBeginFrames_SwapThrottled
) {
1509 bool use_external_begin_frame_source
= false;
1510 bool throttle_frame_production
= true;
1511 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source
,
1512 throttle_frame_production
);
1515 TEST(SchedulerTest
, VSyncThrottlingDisabled_SwapThrottled
) {
1516 bool use_external_begin_frame_source
= true;
1517 bool throttle_frame_production
= false;
1518 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source
,
1519 throttle_frame_production
);
1523 SyntheticBeginFrames_And_VSyncThrottlingDisabled_SwapThrottled
) {
1524 bool use_external_begin_frame_source
= false;
1525 bool throttle_frame_production
= false;
1526 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source
,
1527 throttle_frame_production
);
1530 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterOutputSurfaceIsInitialized
) {
1531 FakeSchedulerClient client
;
1532 SchedulerSettings scheduler_settings
;
1533 scheduler_settings
.use_external_begin_frame_source
= true;
1534 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1535 scheduler
->SetCanStart();
1536 scheduler
->SetVisible(true);
1537 scheduler
->SetCanDraw(true);
1539 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1541 scheduler
->DidCreateAndInitializeOutputSurface();
1542 EXPECT_NO_ACTION(client
);
1544 scheduler
->DidLoseOutputSurface();
1545 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1548 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterBeginFrameStarted
) {
1549 FakeSchedulerClient client
;
1550 SchedulerSettings scheduler_settings
;
1551 scheduler_settings
.use_external_begin_frame_source
= true;
1552 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1553 scheduler
->SetCanStart();
1554 scheduler
->SetVisible(true);
1555 scheduler
->SetCanDraw(true);
1557 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1558 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1559 // SetNeedsCommit should begin the frame.
1561 scheduler
->SetNeedsCommit();
1562 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1565 client
.AdvanceFrame();
1566 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1567 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1568 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1571 scheduler
->DidLoseOutputSurface();
1572 // Do nothing when impl frame is in deadine pending state.
1573 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1576 scheduler
->NotifyBeginMainFrameStarted();
1577 scheduler
->NotifyReadyToCommit();
1578 EXPECT_ACTION("ScheduledActionCommit", client
, 0, 1);
1581 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1582 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1585 void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(
1586 bool impl_side_painting
) {
1587 FakeSchedulerClient client
;
1588 SchedulerSettings scheduler_settings
;
1589 scheduler_settings
.impl_side_painting
= impl_side_painting
;
1590 scheduler_settings
.use_external_begin_frame_source
= true;
1591 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1592 scheduler
->SetCanStart();
1593 scheduler
->SetVisible(true);
1594 scheduler
->SetCanDraw(true);
1596 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1597 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1599 // SetNeedsCommit should begin the frame.
1601 scheduler
->SetNeedsCommit();
1602 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1605 client
.AdvanceFrame();
1606 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1607 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1608 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1611 scheduler
->DidLoseOutputSurface();
1612 // Do nothing when impl frame is in deadine pending state.
1613 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1616 // Run posted deadline.
1617 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1618 client
.task_runner().RunTasksWhile(client
.ImplFrameDeadlinePending(true));
1619 // OnBeginImplFrameDeadline didn't schedule any actions because main frame is
1620 // not yet completed.
1621 EXPECT_NO_ACTION(client
);
1622 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1624 // BeginImplFrame is not started.
1625 client
.task_runner().RunUntilTime(client
.now_src()->Now() +
1626 base::TimeDelta::FromMilliseconds(10));
1627 EXPECT_NO_ACTION(client
);
1628 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1631 scheduler
->NotifyBeginMainFrameStarted();
1632 scheduler
->NotifyReadyToCommit();
1633 if (impl_side_painting
) {
1634 EXPECT_ACTION("ScheduledActionCommit", client
, 0, 3);
1635 EXPECT_ACTION("ScheduledActionActivateSyncTree", client
, 1, 3);
1636 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
, 2, 3);
1638 EXPECT_ACTION("ScheduledActionCommit", client
, 0, 2);
1639 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
, 1, 2);
1643 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency
) {
1644 bool impl_side_painting
= false;
1645 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting
);
1649 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatencyWithImplPaint
) {
1650 bool impl_side_painting
= true;
1651 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting
);
1654 void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting
) {
1655 FakeSchedulerClient client
;
1656 SchedulerSettings scheduler_settings
;
1657 scheduler_settings
.impl_side_painting
= impl_side_painting
;
1658 scheduler_settings
.use_external_begin_frame_source
= true;
1659 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1660 scheduler
->SetCanStart();
1661 scheduler
->SetVisible(true);
1662 scheduler
->SetCanDraw(true);
1664 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1665 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1667 // SetNeedsCommit should begin the frame.
1669 scheduler
->SetNeedsCommit();
1670 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1673 client
.AdvanceFrame();
1674 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1675 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1676 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1679 scheduler
->NotifyBeginMainFrameStarted();
1680 scheduler
->NotifyReadyToCommit();
1681 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1684 scheduler
->DidLoseOutputSurface();
1685 if (impl_side_painting
) {
1686 // Sync tree should be forced to activate.
1687 EXPECT_ACTION("SetNeedsBeginFrames(false)", client
, 0, 2);
1688 EXPECT_ACTION("ScheduledActionActivateSyncTree", client
, 1, 2);
1690 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1694 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1695 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1698 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterReadyToCommit
) {
1699 DidLoseOutputSurfaceAfterReadyToCommit(false);
1702 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterReadyToCommitWithImplPainting
) {
1703 DidLoseOutputSurfaceAfterReadyToCommit(true);
1706 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterSetNeedsManageTiles
) {
1707 FakeSchedulerClient client
;
1708 SchedulerSettings scheduler_settings
;
1709 scheduler_settings
.use_external_begin_frame_source
= true;
1710 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1711 scheduler
->SetCanStart();
1712 scheduler
->SetVisible(true);
1713 scheduler
->SetCanDraw(true);
1714 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1717 scheduler
->SetNeedsManageTiles();
1718 scheduler
->SetNeedsRedraw();
1719 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1722 client
.AdvanceFrame();
1723 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1724 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1725 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1728 scheduler
->DidLoseOutputSurface();
1729 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1732 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1733 EXPECT_ACTION("ScheduledActionManageTiles", client
, 0, 2);
1734 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
, 1, 2);
1737 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterBeginRetroFramePosted
) {
1738 FakeSchedulerClient client
;
1739 SchedulerSettings scheduler_settings
;
1740 scheduler_settings
.use_external_begin_frame_source
= true;
1741 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1742 scheduler
->SetCanStart();
1743 scheduler
->SetVisible(true);
1744 scheduler
->SetCanDraw(true);
1745 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1747 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1749 scheduler
->SetNeedsCommit();
1750 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1752 // Create a BeginFrame with a long deadline to avoid race conditions.
1753 // This is the first BeginFrame, which will be handled immediately.
1755 BeginFrameArgs args
= CreateBeginFrameArgsForTesting(client
.now_src());
1756 args
.deadline
+= base::TimeDelta::FromHours(1);
1757 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1758 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1759 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1760 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1761 EXPECT_TRUE(client
.needs_begin_frames());
1763 // Queue BeginFrames while we are still handling the previous BeginFrame.
1764 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1765 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1766 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1767 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1769 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
1771 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1772 EXPECT_NO_ACTION(client
);
1773 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1774 EXPECT_TRUE(client
.needs_begin_frames());
1776 // NotifyReadyToCommit should trigger the commit.
1778 scheduler
->NotifyBeginMainFrameStarted();
1779 scheduler
->NotifyReadyToCommit();
1780 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1781 EXPECT_TRUE(client
.needs_begin_frames());
1784 EXPECT_FALSE(scheduler
->IsBeginRetroFrameArgsEmpty());
1785 scheduler
->DidLoseOutputSurface();
1786 EXPECT_ACTION("SetNeedsBeginFrames(false)", client
, 0, 2);
1787 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
, 1, 2);
1788 EXPECT_TRUE(scheduler
->IsBeginRetroFrameArgsEmpty());
1790 // Posted BeginRetroFrame is aborted.
1792 client
.task_runner().RunPendingTasks();
1793 EXPECT_NO_ACTION(client
);
1796 TEST(SchedulerTest
, DidLoseOutputSurfaceDuringBeginRetroFrameRunning
) {
1797 FakeSchedulerClient client
;
1798 SchedulerSettings scheduler_settings
;
1799 scheduler_settings
.use_external_begin_frame_source
= true;
1800 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1801 scheduler
->SetCanStart();
1802 scheduler
->SetVisible(true);
1803 scheduler
->SetCanDraw(true);
1804 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1806 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1808 scheduler
->SetNeedsCommit();
1809 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1811 // Create a BeginFrame with a long deadline to avoid race conditions.
1812 // This is the first BeginFrame, which will be handled immediately.
1814 BeginFrameArgs args
= CreateBeginFrameArgsForTesting(client
.now_src());
1815 args
.deadline
+= base::TimeDelta::FromHours(1);
1816 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1817 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1818 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1819 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1820 EXPECT_TRUE(client
.needs_begin_frames());
1822 // Queue BeginFrames while we are still handling the previous BeginFrame.
1823 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1824 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1825 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1826 client
.fake_external_begin_frame_source()->TestOnBeginFrame(args
);
1828 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
1830 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1831 EXPECT_NO_ACTION(client
);
1832 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1833 EXPECT_TRUE(client
.needs_begin_frames());
1835 // NotifyReadyToCommit should trigger the commit.
1837 scheduler
->NotifyBeginMainFrameStarted();
1838 scheduler
->NotifyReadyToCommit();
1839 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1840 EXPECT_TRUE(client
.needs_begin_frames());
1842 // BeginImplFrame should prepare the draw.
1844 client
.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
1845 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1846 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1847 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1848 EXPECT_TRUE(client
.needs_begin_frames());
1851 EXPECT_FALSE(scheduler
->IsBeginRetroFrameArgsEmpty());
1852 scheduler
->DidLoseOutputSurface();
1853 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1854 EXPECT_TRUE(scheduler
->IsBeginRetroFrameArgsEmpty());
1856 // BeginImplFrame deadline should abort drawing.
1858 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1859 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1860 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1861 EXPECT_FALSE(client
.needs_begin_frames());
1863 // No more BeginRetroFrame because BeginRetroFrame queue is cleared.
1865 client
.task_runner().RunPendingTasks();
1866 EXPECT_NO_ACTION(client
);
1870 StopBeginFrameAfterDidLoseOutputSurfaceWithSyntheticBeginFrameSource
) {
1871 FakeSchedulerClient client
;
1872 SchedulerSettings scheduler_settings
;
1873 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1874 scheduler
->SetCanStart();
1875 scheduler
->SetVisible(true);
1876 scheduler
->SetCanDraw(true);
1877 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1879 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1881 EXPECT_FALSE(scheduler
->frame_source().NeedsBeginFrames());
1882 scheduler
->SetNeedsCommit();
1883 EXPECT_TRUE(scheduler
->frame_source().NeedsBeginFrames());
1886 client
.task_runner().RunPendingTasks(); // Run posted Tick.
1887 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1888 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1889 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1890 EXPECT_TRUE(scheduler
->frame_source().NeedsBeginFrames());
1892 // NotifyReadyToCommit should trigger the commit.
1894 scheduler
->NotifyBeginMainFrameStarted();
1895 scheduler
->NotifyReadyToCommit();
1896 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1897 EXPECT_TRUE(scheduler
->frame_source().NeedsBeginFrames());
1900 scheduler
->DidLoseOutputSurface();
1901 EXPECT_NO_ACTION(client
);
1902 EXPECT_FALSE(scheduler
->frame_source().NeedsBeginFrames());
1905 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1906 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1907 EXPECT_FALSE(scheduler
->frame_source().NeedsBeginFrames());
1910 TEST(SchedulerTest
, ScheduledActionActivateAfterBecomingInvisible
) {
1911 FakeSchedulerClient client
;
1912 SchedulerSettings scheduler_settings
;
1913 scheduler_settings
.impl_side_painting
= true;
1914 scheduler_settings
.use_external_begin_frame_source
= true;
1915 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1916 scheduler
->SetCanStart();
1917 scheduler
->SetVisible(true);
1918 scheduler
->SetCanDraw(true);
1920 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1921 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1923 // SetNeedsCommit should begin the frame.
1925 scheduler
->SetNeedsCommit();
1926 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1929 client
.AdvanceFrame();
1930 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1931 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1932 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1935 scheduler
->NotifyBeginMainFrameStarted();
1936 scheduler
->NotifyReadyToCommit();
1937 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1940 scheduler
->SetVisible(false);
1941 // Sync tree should be forced to activate.
1942 EXPECT_ACTION("SetNeedsBeginFrames(false)", client
, 0, 2);
1943 EXPECT_ACTION("ScheduledActionActivateSyncTree", client
, 1, 2);
1946 TEST(SchedulerTest
, SchedulerPowerMonitoring
) {
1947 FakeSchedulerClient client
;
1948 SchedulerSettings settings
;
1949 settings
.disable_hi_res_timer_tasks_on_battery
= true;
1950 TestScheduler
* scheduler
= client
.CreateScheduler(settings
);
1952 base::TimeTicks before_deadline
, after_deadline
;
1954 scheduler
->SetCanStart();
1955 scheduler
->SetVisible(true);
1956 scheduler
->SetCanDraw(true);
1958 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1960 scheduler
->SetNeedsCommit();
1961 scheduler
->SetNeedsRedraw();
1964 // On non-battery power
1965 EXPECT_FALSE(client
.PowerMonitor()->IsOnBatteryPower());
1967 client
.AdvanceFrame();
1970 before_deadline
= client
.now_src()->Now();
1971 EXPECT_TRUE(client
.task_runner().RunTasksWhile(
1972 client
.ImplFrameDeadlinePending(true)));
1973 after_deadline
= client
.now_src()->Now();
1975 // We post a non-zero deadline task when not on battery
1976 EXPECT_LT(before_deadline
, after_deadline
);
1978 // Switch to battery power
1979 client
.PowerMonitorSource()->GeneratePowerStateEvent(true);
1980 EXPECT_TRUE(client
.PowerMonitor()->IsOnBatteryPower());
1982 client
.AdvanceFrame();
1983 scheduler
->SetNeedsCommit();
1984 scheduler
->SetNeedsRedraw();
1987 before_deadline
= client
.now_src()->Now();
1988 EXPECT_TRUE(client
.task_runner().RunTasksWhile(
1989 client
.ImplFrameDeadlinePending(true)));
1990 after_deadline
= client
.now_src()->Now();
1992 // We post a zero deadline task when on battery
1993 EXPECT_EQ(before_deadline
, after_deadline
);
1995 // Switch to non-battery power
1996 client
.PowerMonitorSource()->GeneratePowerStateEvent(false);
1997 EXPECT_FALSE(client
.PowerMonitor()->IsOnBatteryPower());
1999 client
.AdvanceFrame();
2000 scheduler
->SetNeedsCommit();
2001 scheduler
->SetNeedsRedraw();
2005 before_deadline
= client
.now_src()->Now();
2006 EXPECT_TRUE(client
.task_runner().RunTasksWhile(
2007 client
.ImplFrameDeadlinePending(true)));
2008 after_deadline
= client
.now_src()->Now();
2012 SimulateWindowsLowResolutionTimerOnBattery_PrioritizeImplLatencyOff
) {
2013 FakeSchedulerClient client
;
2014 SchedulerSettings settings
;
2015 settings
.use_external_begin_frame_source
= true;
2016 TestScheduler
* scheduler
= client
.CreateScheduler(settings
);
2018 scheduler
->SetCanStart();
2019 scheduler
->SetVisible(true);
2020 scheduler
->SetCanDraw(true);
2022 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
2024 // Set needs commit so that the scheduler tries to wait for the main thread
2025 scheduler
->SetNeedsCommit();
2026 // Set needs redraw so that the scheduler doesn't wait too long
2027 scheduler
->SetNeedsRedraw();
2030 // Switch to battery power
2031 client
.PowerMonitorSource()->GeneratePowerStateEvent(true);
2032 EXPECT_TRUE(client
.PowerMonitor()->IsOnBatteryPower());
2034 client
.AdvanceFrame();
2035 scheduler
->SetNeedsCommit();
2036 scheduler
->SetNeedsRedraw();
2039 // Disable auto-advancing of now_src
2040 client
.task_runner().SetAutoAdvanceNowToPendingTasks(false);
2042 // Deadline task is pending
2043 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
2044 client
.task_runner().RunPendingTasks();
2045 // Deadline task is still pending
2046 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
2048 // Advance now by 15 ms - same as windows low res timer
2049 client
.now_src()->AdvanceNowMicroseconds(15000);
2050 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
2051 client
.task_runner().RunPendingTasks();
2052 // Deadline task finally completes
2053 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
2057 SimulateWindowsLowResolutionTimerOnBattery_PrioritizeImplLatencyOn
) {
2058 FakeSchedulerClient client
;
2059 SchedulerSettings settings
;
2060 settings
.disable_hi_res_timer_tasks_on_battery
= true;
2061 settings
.use_external_begin_frame_source
= true;
2062 TestScheduler
* scheduler
= client
.CreateScheduler(settings
);
2064 scheduler
->SetCanStart();
2065 scheduler
->SetVisible(true);
2066 scheduler
->SetCanDraw(true);
2068 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
2070 // Set needs commit so that the scheduler tries to wait for the main thread
2071 scheduler
->SetNeedsCommit();
2072 // Set needs redraw so that the scheduler doesn't wait too long
2073 scheduler
->SetNeedsRedraw();
2076 // Switch to battery power
2077 client
.PowerMonitorSource()->GeneratePowerStateEvent(true);
2078 EXPECT_TRUE(client
.PowerMonitor()->IsOnBatteryPower());
2080 client
.AdvanceFrame();
2081 scheduler
->SetNeedsCommit();
2082 scheduler
->SetNeedsRedraw();
2085 // Disable auto-advancing of now_src
2086 client
.task_runner().SetAutoAdvanceNowToPendingTasks(false);
2088 // Deadline task is pending
2089 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
2090 client
.task_runner().RunPendingTasks();
2091 // Deadline task runs immediately
2092 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());