1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 #include "cc/scheduler/scheduler.h"
9 #include "base/debug/trace_event.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/power_monitor/power_monitor.h"
14 #include "base/power_monitor/power_monitor_source.h"
15 #include "base/run_loop.h"
16 #include "base/time/time.h"
17 #include "cc/test/begin_frame_args_test.h"
18 #include "cc/test/ordered_simple_task_runner.h"
19 #include "cc/test/scheduler_test_common.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \
25 EXPECT_EQ(expected_num_actions, client.num_actions_()); \
26 if (action_index >= 0) { \
27 ASSERT_LT(action_index, client.num_actions_()) << scheduler; \
28 EXPECT_STREQ(action, client.Action(action_index)); \
30 for (int i = expected_num_actions; i < client.num_actions_(); ++i) \
31 ADD_FAILURE() << "Unexpected action: " << client.Action(i) \
32 << " with state:\n" << client.StateForAction(i); \
35 #define EXPECT_NO_ACTION(client) EXPECT_ACTION("", client, -1, 0)
37 #define EXPECT_SINGLE_ACTION(action, client) \
38 EXPECT_ACTION(action, client, 0, 1)
43 class FakeSchedulerClient
;
45 void InitializeOutputSurfaceAndFirstCommit(Scheduler
* scheduler
,
46 FakeSchedulerClient
* client
);
48 class FakeSchedulerClient
: public SchedulerClient
{
50 struct FakeBeginFrameSourceForFakeSchedulerClient
51 : public FakeBeginFrameSource
{
52 FakeSchedulerClient
* client_
;
54 explicit FakeBeginFrameSourceForFakeSchedulerClient(
55 FakeSchedulerClient
* client
)
58 void OnNeedsBeginFramesChange(bool needs_begin_frames
) override
{
59 if (needs_begin_frames
) {
60 client_
->actions_
.push_back("SetNeedsBeginFrames(true)");
62 client_
->actions_
.push_back("SetNeedsBeginFrames(false)");
64 client_
->states_
.push_back(client_
->scheduler_
->AsValue());
68 class FakePowerMonitorSource
: public base::PowerMonitorSource
{
70 FakePowerMonitorSource() {}
71 ~FakePowerMonitorSource() override
{}
72 void GeneratePowerStateEvent(bool on_battery_power
) {
73 on_battery_power_impl_
= on_battery_power
;
74 ProcessPowerEvent(POWER_STATE_EVENT
);
75 base::MessageLoop::current()->RunUntilIdle();
77 bool IsOnBatteryPowerImpl() override
{ return on_battery_power_impl_
; }
80 bool on_battery_power_impl_
;
84 : automatic_swap_ack_(true),
85 swap_contains_incomplete_tile_(false),
86 redraw_will_happen_if_update_visible_tiles_happens_(false),
87 now_src_(TestNowSource::Create()),
88 task_runner_(new OrderedSimpleTaskRunner(now_src_
, true)),
89 fake_frame_source_(this),
90 fake_power_monitor_source_(new FakePowerMonitorSource
),
91 power_monitor_(make_scoped_ptr
<base::PowerMonitorSource
>(
92 fake_power_monitor_source_
)),
94 // A bunch of tests require Now() to be > BeginFrameArgs::DefaultInterval()
95 now_src_
->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
96 // Fail if we need to run 100 tasks in a row.
97 task_runner_
->SetRunTaskLimit(100);
104 draw_will_happen_
= true;
105 swap_will_happen_if_draw_happens_
= true;
107 log_anticipated_draw_time_change_
= false;
110 TestScheduler
* CreateScheduler(const SchedulerSettings
& settings
) {
111 scheduler_
= TestScheduler::Create(
112 now_src_
, this, settings
, 0, task_runner_
, &power_monitor_
);
114 return scheduler_
.get();
117 // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it
118 // for tests that do.
119 void set_log_anticipated_draw_time_change(bool log
) {
120 log_anticipated_draw_time_change_
= log
;
122 bool needs_begin_frames() { return fake_frame_source_
.NeedsBeginFrames(); }
123 int num_draws() const { return num_draws_
; }
124 int num_actions_() const { return static_cast<int>(actions_
.size()); }
125 const char* Action(int i
) const { return actions_
[i
]; }
126 std::string
StateForAction(int i
) const { return states_
[i
]->ToString(); }
127 base::TimeTicks
posted_begin_impl_frame_deadline() const {
128 return posted_begin_impl_frame_deadline_
;
131 bool ExternalBeginFrame() {
132 return scheduler_
->settings().begin_frame_scheduling_enabled
&&
133 scheduler_
->settings().throttle_frame_production
;
135 FakeBeginFrameSource
* ExternalBeginFrameSource() override
{
136 return &fake_frame_source_
;
139 base::PowerMonitor
* PowerMonitor() { return &power_monitor_
; }
141 FakePowerMonitorSource
* PowerMonitorSource() {
142 return fake_power_monitor_source_
;
145 void AdvanceFrame() {
146 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
147 "FakeSchedulerClient::AdvanceFrame");
148 // EXPECT_TRUE(needs_begin_frames());
149 if (ExternalBeginFrame()) {
150 // Creep the time forward so that any BeginFrameArgs is not equal to the
151 // last one otherwise we violate the BeginFrameSource contract.
152 now_src_
->AdvanceNowMicroseconds(1);
153 fake_frame_source_
.TestOnBeginFrame(
154 CreateBeginFrameArgsForTesting(now_src_
));
155 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
158 EXPECT_TRUE(task_runner().RunTasksWhile(ImplFrameDeadlinePending(false)));
159 EXPECT_TRUE(scheduler_
->BeginImplFrameDeadlinePending());
162 OrderedSimpleTaskRunner
& task_runner() { return *task_runner_
; }
163 TestNowSource
* now_src() { return now_src_
.get(); }
165 int ActionIndex(const char* action
) const {
166 for (size_t i
= 0; i
< actions_
.size(); i
++)
167 if (!strcmp(actions_
[i
], action
))
172 void SetSwapContainsIncompleteTile(bool contain
) {
173 swap_contains_incomplete_tile_
= contain
;
176 bool HasAction(const char* action
) const {
177 return ActionIndex(action
) >= 0;
180 void SetDrawWillHappen(bool draw_will_happen
) {
181 draw_will_happen_
= draw_will_happen
;
183 void SetSwapWillHappenIfDrawHappens(bool swap_will_happen_if_draw_happens
) {
184 swap_will_happen_if_draw_happens_
= swap_will_happen_if_draw_happens
;
186 void SetAutomaticSwapAck(bool automatic_swap_ack
) {
187 automatic_swap_ack_
= automatic_swap_ack
;
189 void SetRedrawWillHappenIfUpdateVisibleTilesHappens(bool redraw
) {
190 redraw_will_happen_if_update_visible_tiles_happens_
= redraw
;
192 // SchedulerClient implementation.
193 void WillBeginImplFrame(const BeginFrameArgs
& args
) override
{
194 actions_
.push_back("WillBeginImplFrame");
195 states_
.push_back(scheduler_
->AsValue());
197 void ScheduledActionSendBeginMainFrame() override
{
198 actions_
.push_back("ScheduledActionSendBeginMainFrame");
199 states_
.push_back(scheduler_
->AsValue());
201 void ScheduledActionAnimate() override
{
202 actions_
.push_back("ScheduledActionAnimate");
203 states_
.push_back(scheduler_
->AsValue());
205 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
206 actions_
.push_back("ScheduledActionDrawAndSwapIfPossible");
207 states_
.push_back(scheduler_
->AsValue());
210 draw_will_happen_
? DRAW_SUCCESS
: DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
;
211 bool swap_will_happen
=
212 draw_will_happen_
&& swap_will_happen_if_draw_happens_
;
213 if (swap_will_happen
) {
214 scheduler_
->DidSwapBuffers();
215 if (swap_contains_incomplete_tile_
) {
216 scheduler_
->SetSwapUsedIncompleteTile(true);
217 swap_contains_incomplete_tile_
= false;
219 scheduler_
->SetSwapUsedIncompleteTile(false);
222 if (automatic_swap_ack_
)
223 scheduler_
->DidSwapBuffersComplete();
227 DrawResult
ScheduledActionDrawAndSwapForced() override
{
228 actions_
.push_back("ScheduledActionDrawAndSwapForced");
229 states_
.push_back(scheduler_
->AsValue());
232 void ScheduledActionCommit() override
{
233 actions_
.push_back("ScheduledActionCommit");
234 states_
.push_back(scheduler_
->AsValue());
236 void ScheduledActionUpdateVisibleTiles() override
{
237 actions_
.push_back("ScheduledActionUpdateVisibleTiles");
238 states_
.push_back(scheduler_
->AsValue());
239 if (redraw_will_happen_if_update_visible_tiles_happens_
)
240 scheduler_
->SetNeedsRedraw();
242 void ScheduledActionActivateSyncTree() override
{
243 actions_
.push_back("ScheduledActionActivateSyncTree");
244 states_
.push_back(scheduler_
->AsValue());
246 void ScheduledActionBeginOutputSurfaceCreation() override
{
247 actions_
.push_back("ScheduledActionBeginOutputSurfaceCreation");
248 states_
.push_back(scheduler_
->AsValue());
250 void ScheduledActionManageTiles() override
{
251 actions_
.push_back("ScheduledActionManageTiles");
252 states_
.push_back(scheduler_
->AsValue());
254 void DidAnticipatedDrawTimeChange(base::TimeTicks
) override
{
255 if (log_anticipated_draw_time_change_
)
256 actions_
.push_back("DidAnticipatedDrawTimeChange");
258 base::TimeDelta
DrawDurationEstimate() override
{ return base::TimeDelta(); }
259 base::TimeDelta
BeginMainFrameToCommitDurationEstimate() override
{
260 return base::TimeDelta();
262 base::TimeDelta
CommitToActivateDurationEstimate() override
{
263 return base::TimeDelta();
266 void DidBeginImplFrameDeadline() override
{}
268 base::Callback
<bool(void)> ImplFrameDeadlinePending(bool state
) {
269 return base::Bind(&FakeSchedulerClient::ImplFrameDeadlinePendingCallback
,
270 base::Unretained(this),
275 bool ImplFrameDeadlinePendingCallback(bool state
) {
276 return scheduler_
->BeginImplFrameDeadlinePending() == state
;
279 bool draw_will_happen_
;
280 bool swap_will_happen_if_draw_happens_
;
281 bool automatic_swap_ack_
;
283 bool log_anticipated_draw_time_change_
;
284 bool swap_contains_incomplete_tile_
;
285 bool redraw_will_happen_if_update_visible_tiles_happens_
;
286 base::TimeTicks posted_begin_impl_frame_deadline_
;
287 std::vector
<const char*> actions_
;
288 std::vector
<scoped_refptr
<base::debug::ConvertableToTraceFormat
>> states_
;
289 scoped_refptr
<TestNowSource
> now_src_
;
290 scoped_refptr
<OrderedSimpleTaskRunner
> task_runner_
;
291 FakeBeginFrameSourceForFakeSchedulerClient fake_frame_source_
;
292 FakePowerMonitorSource
* fake_power_monitor_source_
;
293 base::PowerMonitor power_monitor_
;
294 scoped_ptr
<TestScheduler
> scheduler_
;
297 void InitializeOutputSurfaceAndFirstCommit(Scheduler
* scheduler
,
298 FakeSchedulerClient
* client
) {
300 "SchedulerUnitTest::InitializeOutputSurfaceAndFirstCommit");
302 scheduler
->DidCreateAndInitializeOutputSurface();
303 scheduler
->SetNeedsCommit();
304 scheduler
->NotifyBeginMainFrameStarted();
305 scheduler
->NotifyReadyToCommit();
306 if (scheduler
->settings().impl_side_painting
)
307 scheduler
->NotifyReadyToActivate();
310 SCOPED_TRACE("Go through the motions to draw the commit");
311 client
->AdvanceFrame();
314 // Run the posted deadline task.
315 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
316 client
->task_runner().RunTasksWhile(client
->ImplFrameDeadlinePending(true));
317 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
321 "We need another BeginImplFrame so Scheduler calls "
322 "SetNeedsBeginFrame(false).");
323 client
->AdvanceFrame();
326 // Run the posted deadline task.
327 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
328 client
->task_runner().RunTasksWhile(client
->ImplFrameDeadlinePending(true));
329 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
331 // EXPECT_FALSE(client->needs_begin_frames());
334 TEST(SchedulerTest
, InitializeOutputSurfaceDoesNotBeginImplFrame
) {
335 FakeSchedulerClient client
;
336 SchedulerSettings default_scheduler_settings
;
337 TestScheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
338 scheduler
->SetCanStart();
339 scheduler
->SetVisible(true);
340 scheduler
->SetCanDraw(true);
342 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
344 scheduler
->DidCreateAndInitializeOutputSurface();
345 EXPECT_NO_ACTION(client
);
348 TEST(SchedulerTest
, RequestCommit
) {
349 FakeSchedulerClient client
;
350 SchedulerSettings scheduler_settings
;
351 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
352 scheduler
->SetCanStart();
353 scheduler
->SetVisible(true);
354 scheduler
->SetCanDraw(true);
356 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
357 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
359 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
361 scheduler
->SetNeedsCommit();
362 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
365 client
.AdvanceFrame();
366 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
367 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
368 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
369 EXPECT_TRUE(client
.needs_begin_frames());
372 // If we don't swap on the deadline, we wait for the next BeginFrame.
373 client
.task_runner().RunPendingTasks(); // Run posted deadline.
374 EXPECT_NO_ACTION(client
);
375 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
376 EXPECT_TRUE(client
.needs_begin_frames());
379 // NotifyReadyToCommit should trigger the commit.
380 scheduler
->NotifyBeginMainFrameStarted();
381 scheduler
->NotifyReadyToCommit();
382 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
383 EXPECT_TRUE(client
.needs_begin_frames());
386 // BeginImplFrame should prepare the draw.
387 client
.AdvanceFrame();
388 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
389 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
390 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
391 EXPECT_TRUE(client
.needs_begin_frames());
394 // BeginImplFrame deadline should draw.
395 client
.task_runner().RunPendingTasks(); // Run posted deadline.
396 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 0, 1);
397 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
398 EXPECT_TRUE(client
.needs_begin_frames());
401 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
402 // to avoid excessive toggles.
403 client
.AdvanceFrame();
404 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
405 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
408 client
.task_runner().RunPendingTasks(); // Run posted deadline.
409 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
413 TEST(SchedulerTest
, RequestCommitAfterBeginMainFrameSent
) {
414 FakeSchedulerClient client
;
415 SchedulerSettings scheduler_settings
;
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 default_scheduler_settings
;
515 TestScheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
516 scheduler
->SetCanStart();
517 scheduler
->SetVisible(true);
518 scheduler
->SetCanDraw(true);
519 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
522 scheduler
->SetNeedsRedraw();
523 EXPECT_TRUE(scheduler
->RedrawPending());
524 EXPECT_TRUE(client
.needs_begin_frames());
525 EXPECT_EQ(0, client
.num_draws());
527 client
.AdvanceFrame();
528 client
.task_runner().RunPendingTasks(); // Run posted deadline.
529 EXPECT_EQ(1, client
.num_draws());
530 EXPECT_TRUE(scheduler
->RedrawPending());
531 EXPECT_TRUE(client
.needs_begin_frames());
533 client
.AdvanceFrame();
534 client
.task_runner().RunPendingTasks(); // Run posted deadline.
535 EXPECT_EQ(2, client
.num_draws());
536 EXPECT_FALSE(scheduler
->RedrawPending());
537 EXPECT_TRUE(client
.needs_begin_frames());
539 // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
541 client
.AdvanceFrame();
542 client
.task_runner().RunPendingTasks(); // Run posted deadline.
543 EXPECT_EQ(2, client
.num_draws());
544 EXPECT_FALSE(scheduler
->RedrawPending());
545 EXPECT_FALSE(client
.needs_begin_frames());
548 // Test that requesting redraw inside a failed draw doesn't lose the request.
549 TEST(SchedulerTest
, RequestRedrawInsideFailedDraw
) {
550 SchedulerClientThatsetNeedsDrawInsideDraw client
;
551 SchedulerSettings default_scheduler_settings
;
552 TestScheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
553 scheduler
->SetCanStart();
554 scheduler
->SetVisible(true);
555 scheduler
->SetCanDraw(true);
556 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
559 client
.SetDrawWillHappen(false);
561 scheduler
->SetNeedsRedraw();
562 EXPECT_TRUE(scheduler
->RedrawPending());
563 EXPECT_TRUE(client
.needs_begin_frames());
564 EXPECT_EQ(0, client
.num_draws());
567 client
.AdvanceFrame();
568 client
.task_runner().RunPendingTasks(); // Run posted deadline.
569 EXPECT_EQ(1, client
.num_draws());
571 // We have a commit pending and the draw failed, and we didn't lose the redraw
573 EXPECT_TRUE(scheduler
->CommitPending());
574 EXPECT_TRUE(scheduler
->RedrawPending());
575 EXPECT_TRUE(client
.needs_begin_frames());
577 // Fail the draw again.
578 client
.AdvanceFrame();
579 client
.task_runner().RunPendingTasks(); // Run posted deadline.
580 EXPECT_EQ(2, client
.num_draws());
581 EXPECT_TRUE(scheduler
->CommitPending());
582 EXPECT_TRUE(scheduler
->RedrawPending());
583 EXPECT_TRUE(client
.needs_begin_frames());
585 // Draw successfully.
586 client
.SetDrawWillHappen(true);
587 client
.AdvanceFrame();
588 client
.task_runner().RunPendingTasks(); // Run posted deadline.
589 EXPECT_EQ(3, client
.num_draws());
590 EXPECT_TRUE(scheduler
->CommitPending());
591 EXPECT_FALSE(scheduler
->RedrawPending());
592 EXPECT_TRUE(client
.needs_begin_frames());
595 class SchedulerClientThatSetNeedsCommitInsideDraw
: public FakeSchedulerClient
{
597 SchedulerClientThatSetNeedsCommitInsideDraw()
598 : set_needs_commit_on_next_draw_(false) {}
600 void ScheduledActionSendBeginMainFrame() override
{}
601 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
602 // Only SetNeedsCommit the first time this is called
603 if (set_needs_commit_on_next_draw_
) {
604 scheduler_
->SetNeedsCommit();
605 set_needs_commit_on_next_draw_
= false;
607 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
610 DrawResult
ScheduledActionDrawAndSwapForced() override
{
615 void ScheduledActionCommit() override
{}
616 void ScheduledActionBeginOutputSurfaceCreation() override
{}
617 void DidAnticipatedDrawTimeChange(base::TimeTicks
) override
{}
619 void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_
= true; }
622 bool set_needs_commit_on_next_draw_
;
625 // Tests for the scheduler infinite-looping on SetNeedsCommit requests that
626 // happen inside a ScheduledActionDrawAndSwap
627 TEST(SchedulerTest
, RequestCommitInsideDraw
) {
628 SchedulerClientThatSetNeedsCommitInsideDraw client
;
629 SchedulerSettings default_scheduler_settings
;
630 TestScheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
631 scheduler
->SetCanStart();
632 scheduler
->SetVisible(true);
633 scheduler
->SetCanDraw(true);
634 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
637 EXPECT_FALSE(client
.needs_begin_frames());
638 scheduler
->SetNeedsRedraw();
639 EXPECT_TRUE(scheduler
->RedrawPending());
640 EXPECT_EQ(0, client
.num_draws());
641 EXPECT_TRUE(client
.needs_begin_frames());
643 client
.SetNeedsCommitOnNextDraw();
644 client
.AdvanceFrame();
645 client
.SetNeedsCommitOnNextDraw();
646 client
.task_runner().RunPendingTasks(); // Run posted deadline.
647 EXPECT_EQ(1, client
.num_draws());
648 EXPECT_TRUE(scheduler
->CommitPending());
649 EXPECT_TRUE(client
.needs_begin_frames());
650 scheduler
->NotifyBeginMainFrameStarted();
651 scheduler
->NotifyReadyToCommit();
653 client
.AdvanceFrame();
654 client
.task_runner().RunPendingTasks(); // Run posted deadline.
655 EXPECT_EQ(2, client
.num_draws());
657 EXPECT_FALSE(scheduler
->RedrawPending());
658 EXPECT_FALSE(scheduler
->CommitPending());
659 EXPECT_TRUE(client
.needs_begin_frames());
661 // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
663 client
.AdvanceFrame();
664 client
.task_runner().RunPendingTasks(); // Run posted deadline.
665 EXPECT_EQ(2, client
.num_draws());
666 EXPECT_FALSE(scheduler
->RedrawPending());
667 EXPECT_FALSE(scheduler
->CommitPending());
668 EXPECT_FALSE(client
.needs_begin_frames());
671 // Tests that when a draw fails then the pending commit should not be dropped.
672 TEST(SchedulerTest
, RequestCommitInsideFailedDraw
) {
673 SchedulerClientThatsetNeedsDrawInsideDraw client
;
674 SchedulerSettings default_scheduler_settings
;
675 TestScheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
676 scheduler
->SetCanStart();
677 scheduler
->SetVisible(true);
678 scheduler
->SetCanDraw(true);
679 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
682 client
.SetDrawWillHappen(false);
684 scheduler
->SetNeedsRedraw();
685 EXPECT_TRUE(scheduler
->RedrawPending());
686 EXPECT_TRUE(client
.needs_begin_frames());
687 EXPECT_EQ(0, client
.num_draws());
690 client
.AdvanceFrame();
691 client
.task_runner().RunPendingTasks(); // Run posted deadline.
692 EXPECT_EQ(1, client
.num_draws());
694 // We have a commit pending and the draw failed, and we didn't lose the commit
696 EXPECT_TRUE(scheduler
->CommitPending());
697 EXPECT_TRUE(scheduler
->RedrawPending());
698 EXPECT_TRUE(client
.needs_begin_frames());
700 // Fail the draw again.
701 client
.AdvanceFrame();
703 client
.task_runner().RunPendingTasks(); // Run posted deadline.
704 EXPECT_EQ(2, client
.num_draws());
705 EXPECT_TRUE(scheduler
->CommitPending());
706 EXPECT_TRUE(scheduler
->RedrawPending());
707 EXPECT_TRUE(client
.needs_begin_frames());
709 // Draw successfully.
710 client
.SetDrawWillHappen(true);
711 client
.AdvanceFrame();
712 client
.task_runner().RunPendingTasks(); // Run posted deadline.
713 EXPECT_EQ(3, client
.num_draws());
714 EXPECT_TRUE(scheduler
->CommitPending());
715 EXPECT_FALSE(scheduler
->RedrawPending());
716 EXPECT_TRUE(client
.needs_begin_frames());
719 TEST(SchedulerTest
, NoSwapWhenDrawFails
) {
720 SchedulerClientThatSetNeedsCommitInsideDraw client
;
721 SchedulerSettings default_scheduler_settings
;
722 TestScheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
723 scheduler
->SetCanStart();
724 scheduler
->SetVisible(true);
725 scheduler
->SetCanDraw(true);
726 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
729 scheduler
->SetNeedsRedraw();
730 EXPECT_TRUE(scheduler
->RedrawPending());
731 EXPECT_TRUE(client
.needs_begin_frames());
732 EXPECT_EQ(0, client
.num_draws());
734 // Draw successfully, this starts a new frame.
735 client
.SetNeedsCommitOnNextDraw();
736 client
.AdvanceFrame();
737 client
.task_runner().RunPendingTasks(); // Run posted deadline.
738 EXPECT_EQ(1, client
.num_draws());
740 scheduler
->SetNeedsRedraw();
741 EXPECT_TRUE(scheduler
->RedrawPending());
742 EXPECT_TRUE(client
.needs_begin_frames());
744 // Fail to draw, this should not start a frame.
745 client
.SetDrawWillHappen(false);
746 client
.SetNeedsCommitOnNextDraw();
747 client
.AdvanceFrame();
748 client
.task_runner().RunPendingTasks(); // Run posted deadline.
749 EXPECT_EQ(2, client
.num_draws());
752 class SchedulerClientNeedsManageTilesInDraw
: public FakeSchedulerClient
{
754 DrawResult
ScheduledActionDrawAndSwapIfPossible() override
{
755 scheduler_
->SetNeedsManageTiles();
756 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
760 // Test manage tiles is independant of draws.
761 TEST(SchedulerTest
, ManageTiles
) {
762 SchedulerClientNeedsManageTilesInDraw client
;
763 SchedulerSettings default_scheduler_settings
;
764 TestScheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
765 scheduler
->SetCanStart();
766 scheduler
->SetVisible(true);
767 scheduler
->SetCanDraw(true);
768 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
770 // Request both draw and manage tiles. ManageTiles shouldn't
771 // be trigged until BeginImplFrame.
773 scheduler
->SetNeedsManageTiles();
774 scheduler
->SetNeedsRedraw();
775 EXPECT_TRUE(scheduler
->RedrawPending());
776 EXPECT_TRUE(scheduler
->ManageTilesPending());
777 EXPECT_TRUE(client
.needs_begin_frames());
778 EXPECT_EQ(0, client
.num_draws());
779 EXPECT_FALSE(client
.HasAction("ScheduledActionManageTiles"));
780 EXPECT_FALSE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
782 // We have no immediate actions to perform, so the BeginImplFrame should post
783 // the deadline task.
785 client
.AdvanceFrame();
786 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
787 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
788 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
790 // On the deadline, he actions should have occured in the right order.
792 client
.task_runner().RunPendingTasks(); // Run posted deadline.
793 EXPECT_EQ(1, client
.num_draws());
794 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
795 EXPECT_TRUE(client
.HasAction("ScheduledActionManageTiles"));
796 EXPECT_LT(client
.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
797 client
.ActionIndex("ScheduledActionManageTiles"));
798 EXPECT_FALSE(scheduler
->RedrawPending());
799 EXPECT_FALSE(scheduler
->ManageTilesPending());
800 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
802 // Request a draw. We don't need a ManageTiles yet.
804 scheduler
->SetNeedsRedraw();
805 EXPECT_TRUE(scheduler
->RedrawPending());
806 EXPECT_FALSE(scheduler
->ManageTilesPending());
807 EXPECT_TRUE(client
.needs_begin_frames());
808 EXPECT_EQ(0, client
.num_draws());
810 // We have no immediate actions to perform, so the BeginImplFrame should post
811 // the deadline task.
813 client
.AdvanceFrame();
814 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
815 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
816 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
818 // Draw. The draw will trigger SetNeedsManageTiles, and
819 // then the ManageTiles action will be triggered after the Draw.
820 // Afterwards, neither a draw nor ManageTiles are pending.
822 client
.task_runner().RunPendingTasks(); // Run posted deadline.
823 EXPECT_EQ(1, client
.num_draws());
824 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
825 EXPECT_TRUE(client
.HasAction("ScheduledActionManageTiles"));
826 EXPECT_LT(client
.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
827 client
.ActionIndex("ScheduledActionManageTiles"));
828 EXPECT_FALSE(scheduler
->RedrawPending());
829 EXPECT_FALSE(scheduler
->ManageTilesPending());
830 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
832 // We need a BeginImplFrame where we don't swap to go idle.
834 client
.AdvanceFrame();
835 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
836 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
838 client
.task_runner().RunPendingTasks(); // Run posted deadline.
839 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
840 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
841 EXPECT_EQ(0, client
.num_draws());
843 // Now trigger a ManageTiles outside of a draw. We will then need
844 // a begin-frame for the ManageTiles, but we don't need a draw.
846 EXPECT_FALSE(client
.needs_begin_frames());
847 scheduler
->SetNeedsManageTiles();
848 EXPECT_TRUE(client
.needs_begin_frames());
849 EXPECT_TRUE(scheduler
->ManageTilesPending());
850 EXPECT_FALSE(scheduler
->RedrawPending());
852 // BeginImplFrame. There will be no draw, only ManageTiles.
854 client
.AdvanceFrame();
855 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
856 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
858 client
.task_runner().RunPendingTasks(); // Run posted deadline.
859 EXPECT_EQ(0, client
.num_draws());
860 EXPECT_FALSE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
861 EXPECT_TRUE(client
.HasAction("ScheduledActionManageTiles"));
862 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
865 // Test that ManageTiles only happens once per frame. If an external caller
866 // initiates it, then the state machine should not ManageTiles on that frame.
867 TEST(SchedulerTest
, ManageTilesOncePerFrame
) {
868 FakeSchedulerClient client
;
869 SchedulerSettings default_scheduler_settings
;
870 TestScheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
871 scheduler
->SetCanStart();
872 scheduler
->SetVisible(true);
873 scheduler
->SetCanDraw(true);
874 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
876 // If DidManageTiles during a frame, then ManageTiles should not occur again.
877 scheduler
->SetNeedsManageTiles();
878 scheduler
->SetNeedsRedraw();
880 client
.AdvanceFrame();
881 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
882 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
883 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
885 EXPECT_TRUE(scheduler
->ManageTilesPending());
886 scheduler
->DidManageTiles(); // An explicit ManageTiles.
887 EXPECT_FALSE(scheduler
->ManageTilesPending());
890 client
.task_runner().RunPendingTasks(); // Run posted deadline.
891 EXPECT_EQ(1, client
.num_draws());
892 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
893 EXPECT_FALSE(client
.HasAction("ScheduledActionManageTiles"));
894 EXPECT_FALSE(scheduler
->RedrawPending());
895 EXPECT_FALSE(scheduler
->ManageTilesPending());
896 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
898 // Next frame without DidManageTiles should ManageTiles with draw.
899 scheduler
->SetNeedsManageTiles();
900 scheduler
->SetNeedsRedraw();
902 client
.AdvanceFrame();
903 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
904 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
905 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
908 client
.task_runner().RunPendingTasks(); // Run posted deadline.
909 EXPECT_EQ(1, client
.num_draws());
910 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
911 EXPECT_TRUE(client
.HasAction("ScheduledActionManageTiles"));
912 EXPECT_LT(client
.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
913 client
.ActionIndex("ScheduledActionManageTiles"));
914 EXPECT_FALSE(scheduler
->RedrawPending());
915 EXPECT_FALSE(scheduler
->ManageTilesPending());
916 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
917 scheduler
->DidManageTiles(); // Corresponds to ScheduledActionManageTiles
919 // If we get another DidManageTiles within the same frame, we should
920 // not ManageTiles on the next frame.
921 scheduler
->DidManageTiles(); // An explicit ManageTiles.
922 scheduler
->SetNeedsManageTiles();
923 scheduler
->SetNeedsRedraw();
925 client
.AdvanceFrame();
926 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
927 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
928 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
930 EXPECT_TRUE(scheduler
->ManageTilesPending());
933 client
.task_runner().RunPendingTasks(); // Run posted deadline.
934 EXPECT_EQ(1, client
.num_draws());
935 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
936 EXPECT_FALSE(client
.HasAction("ScheduledActionManageTiles"));
937 EXPECT_FALSE(scheduler
->RedrawPending());
938 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
940 // If we get another DidManageTiles, we should not ManageTiles on the next
941 // frame. This verifies we don't alternate calling ManageTiles once and twice.
942 EXPECT_TRUE(scheduler
->ManageTilesPending());
943 scheduler
->DidManageTiles(); // An explicit ManageTiles.
944 EXPECT_FALSE(scheduler
->ManageTilesPending());
945 scheduler
->SetNeedsManageTiles();
946 scheduler
->SetNeedsRedraw();
948 client
.AdvanceFrame();
949 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
950 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
951 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
953 EXPECT_TRUE(scheduler
->ManageTilesPending());
956 client
.task_runner().RunPendingTasks(); // Run posted deadline.
957 EXPECT_EQ(1, client
.num_draws());
958 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
959 EXPECT_FALSE(client
.HasAction("ScheduledActionManageTiles"));
960 EXPECT_FALSE(scheduler
->RedrawPending());
961 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
963 // Next frame without DidManageTiles should ManageTiles with draw.
964 scheduler
->SetNeedsManageTiles();
965 scheduler
->SetNeedsRedraw();
967 client
.AdvanceFrame();
968 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
969 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
970 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
973 client
.task_runner().RunPendingTasks(); // Run posted deadline.
974 EXPECT_EQ(1, client
.num_draws());
975 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapIfPossible"));
976 EXPECT_TRUE(client
.HasAction("ScheduledActionManageTiles"));
977 EXPECT_LT(client
.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
978 client
.ActionIndex("ScheduledActionManageTiles"));
979 EXPECT_FALSE(scheduler
->RedrawPending());
980 EXPECT_FALSE(scheduler
->ManageTilesPending());
981 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
982 scheduler
->DidManageTiles(); // Corresponds to ScheduledActionManageTiles
985 TEST(SchedulerTest
, ShouldUpdateVisibleTiles
) {
986 FakeSchedulerClient client
;
987 SchedulerSettings scheduler_settings
;
988 scheduler_settings
.impl_side_painting
= true;
989 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
990 scheduler
->SetCanStart();
991 scheduler
->SetVisible(true);
992 scheduler
->SetCanDraw(true);
993 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
995 client
.SetRedrawWillHappenIfUpdateVisibleTilesHappens(true);
997 // SetNeedsCommit should begin the frame.
999 scheduler
->SetNeedsCommit();
1000 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1003 client
.AdvanceFrame();
1004 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1005 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1006 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1009 scheduler
->NotifyBeginMainFrameStarted();
1010 scheduler
->NotifyReadyToCommit();
1011 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1014 scheduler
->NotifyReadyToActivate();
1015 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client
);
1018 client
.SetSwapContainsIncompleteTile(true);
1019 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1020 EXPECT_ACTION("ScheduledActionAnimate", client
, 0, 2);
1021 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 1, 2);
1022 EXPECT_FALSE(scheduler
->RedrawPending());
1025 client
.AdvanceFrame();
1026 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
1027 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1030 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1031 EXPECT_ACTION("ScheduledActionUpdateVisibleTiles", client
, 0, 3);
1032 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 3);
1033 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 2, 3);
1036 client
.AdvanceFrame();
1037 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
1038 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1040 // No more UpdateVisibleTiles().
1042 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1043 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1046 TEST(SchedulerTest
, TriggerBeginFrameDeadlineEarly
) {
1047 SchedulerClientNeedsManageTilesInDraw client
;
1048 SchedulerSettings default_scheduler_settings
;
1049 TestScheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
1050 scheduler
->SetCanStart();
1051 scheduler
->SetVisible(true);
1052 scheduler
->SetCanDraw(true);
1053 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1056 scheduler
->SetNeedsRedraw();
1057 client
.AdvanceFrame();
1059 // The deadline should be zero since there is no work other than drawing
1061 EXPECT_EQ(base::TimeTicks(), client
.posted_begin_impl_frame_deadline());
1064 class SchedulerClientWithFixedEstimates
: public FakeSchedulerClient
{
1066 SchedulerClientWithFixedEstimates(
1067 base::TimeDelta draw_duration
,
1068 base::TimeDelta begin_main_frame_to_commit_duration
,
1069 base::TimeDelta commit_to_activate_duration
)
1070 : draw_duration_(draw_duration
),
1071 begin_main_frame_to_commit_duration_(
1072 begin_main_frame_to_commit_duration
),
1073 commit_to_activate_duration_(commit_to_activate_duration
) {}
1075 base::TimeDelta
DrawDurationEstimate() override
{ return draw_duration_
; }
1076 base::TimeDelta
BeginMainFrameToCommitDurationEstimate() override
{
1077 return begin_main_frame_to_commit_duration_
;
1079 base::TimeDelta
CommitToActivateDurationEstimate() override
{
1080 return commit_to_activate_duration_
;
1084 base::TimeDelta draw_duration_
;
1085 base::TimeDelta begin_main_frame_to_commit_duration_
;
1086 base::TimeDelta commit_to_activate_duration_
;
1089 void MainFrameInHighLatencyMode(int64 begin_main_frame_to_commit_estimate_in_ms
,
1090 int64 commit_to_activate_estimate_in_ms
,
1091 bool impl_latency_takes_priority
,
1092 bool should_send_begin_main_frame
) {
1093 // Set up client with specified estimates (draw duration is set to 1).
1094 SchedulerClientWithFixedEstimates
client(
1095 base::TimeDelta::FromMilliseconds(1),
1096 base::TimeDelta::FromMilliseconds(
1097 begin_main_frame_to_commit_estimate_in_ms
),
1098 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms
));
1099 SchedulerSettings default_scheduler_settings
;
1100 TestScheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
1101 scheduler
->SetCanStart();
1102 scheduler
->SetVisible(true);
1103 scheduler
->SetCanDraw(true);
1104 scheduler
->SetImplLatencyTakesPriority(impl_latency_takes_priority
);
1105 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1107 // Impl thread hits deadline before commit finishes.
1109 scheduler
->SetNeedsCommit();
1110 EXPECT_FALSE(scheduler
->MainThreadIsInHighLatencyMode());
1111 client
.AdvanceFrame();
1112 EXPECT_FALSE(scheduler
->MainThreadIsInHighLatencyMode());
1113 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1114 EXPECT_TRUE(scheduler
->MainThreadIsInHighLatencyMode());
1115 scheduler
->NotifyBeginMainFrameStarted();
1116 scheduler
->NotifyReadyToCommit();
1117 EXPECT_TRUE(scheduler
->MainThreadIsInHighLatencyMode());
1118 EXPECT_TRUE(client
.HasAction("ScheduledActionSendBeginMainFrame"));
1121 scheduler
->SetNeedsCommit();
1122 EXPECT_TRUE(scheduler
->MainThreadIsInHighLatencyMode());
1123 client
.AdvanceFrame();
1124 EXPECT_TRUE(scheduler
->MainThreadIsInHighLatencyMode());
1125 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1126 EXPECT_EQ(scheduler
->MainThreadIsInHighLatencyMode(),
1127 should_send_begin_main_frame
);
1128 EXPECT_EQ(client
.HasAction("ScheduledActionSendBeginMainFrame"),
1129 should_send_begin_main_frame
);
1133 SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline
) {
1134 // Set up client so that estimates indicate that we can commit and activate
1135 // before the deadline (~8ms by default).
1136 MainFrameInHighLatencyMode(1, 1, false, false);
1139 TEST(SchedulerTest
, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong
) {
1140 // Set up client so that estimates indicate that the commit cannot finish
1141 // before the deadline (~8ms by default).
1142 MainFrameInHighLatencyMode(10, 1, false, true);
1145 TEST(SchedulerTest
, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong
) {
1146 // Set up client so that estimates indicate that the activate cannot finish
1147 // before the deadline (~8ms by default).
1148 MainFrameInHighLatencyMode(1, 10, false, true);
1151 TEST(SchedulerTest
, NotSkipMainFrameInPreferImplLatencyMode
) {
1152 // Set up client so that estimates indicate that we can commit and activate
1153 // before the deadline (~8ms by default), but also enable impl latency takes
1155 MainFrameInHighLatencyMode(1, 1, true, true);
1158 TEST(SchedulerTest
, PollForCommitCompletion
) {
1159 // Since we are simulating a long commit, set up a client with draw duration
1160 // estimates that prevent skipping main frames to get to low latency mode.
1161 SchedulerClientWithFixedEstimates
client(
1162 base::TimeDelta::FromMilliseconds(1),
1163 base::TimeDelta::FromMilliseconds(32),
1164 base::TimeDelta::FromMilliseconds(32));
1165 client
.set_log_anticipated_draw_time_change(true);
1166 SchedulerSettings default_scheduler_settings
;
1167 TestScheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
1169 scheduler
->SetCanDraw(true);
1170 scheduler
->SetCanStart();
1171 scheduler
->SetVisible(true);
1172 scheduler
->DidCreateAndInitializeOutputSurface();
1174 scheduler
->SetNeedsCommit();
1175 EXPECT_TRUE(scheduler
->CommitPending());
1176 scheduler
->NotifyBeginMainFrameStarted();
1177 scheduler
->NotifyReadyToCommit();
1178 scheduler
->SetNeedsRedraw();
1180 BeginFrameArgs frame_args
= CreateBeginFrameArgsForTesting(client
.now_src());
1181 frame_args
.interval
= base::TimeDelta::FromMilliseconds(1000);
1182 client
.ExternalBeginFrameSource()->TestOnBeginFrame(frame_args
);
1184 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1185 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1186 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1188 scheduler
->DidSwapBuffers();
1189 scheduler
->DidSwapBuffersComplete();
1191 // At this point, we've drawn a frame. Start another commit, but hold off on
1192 // the NotifyReadyToCommit for now.
1193 EXPECT_FALSE(scheduler
->CommitPending());
1194 scheduler
->SetNeedsCommit();
1195 client
.ExternalBeginFrameSource()->TestOnBeginFrame(frame_args
);
1196 EXPECT_TRUE(scheduler
->CommitPending());
1198 // Draw and swap the frame, but don't ack the swap to simulate the Browser
1199 // blocking on the renderer.
1200 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1201 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1202 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1203 scheduler
->DidSwapBuffers();
1205 // Spin the event loop a few times and make sure we get more
1206 // DidAnticipateDrawTimeChange calls every time.
1207 int actions_so_far
= client
.num_actions_();
1209 // Does three iterations to make sure that the timer is properly repeating.
1210 for (int i
= 0; i
< 3; ++i
) {
1211 EXPECT_EQ((frame_args
.interval
* 2).InMicroseconds(),
1212 client
.task_runner().DelayToNextTaskTime().InMicroseconds())
1213 << scheduler
->AsValue()->ToString();
1214 client
.task_runner().RunPendingTasks();
1215 EXPECT_GT(client
.num_actions_(), actions_so_far
);
1216 EXPECT_STREQ(client
.Action(client
.num_actions_() - 1),
1217 "DidAnticipatedDrawTimeChange");
1218 actions_so_far
= client
.num_actions_();
1221 // Do the same thing after BeginMainFrame starts but still before activation.
1222 scheduler
->NotifyBeginMainFrameStarted();
1223 for (int i
= 0; i
< 3; ++i
) {
1224 EXPECT_EQ((frame_args
.interval
* 2).InMicroseconds(),
1225 client
.task_runner().DelayToNextTaskTime().InMicroseconds())
1226 << scheduler
->AsValue()->ToString();
1227 client
.task_runner().RunPendingTasks();
1228 EXPECT_GT(client
.num_actions_(), actions_so_far
);
1229 EXPECT_STREQ(client
.Action(client
.num_actions_() - 1),
1230 "DidAnticipatedDrawTimeChange");
1231 actions_so_far
= client
.num_actions_();
1235 TEST(SchedulerTest
, BeginRetroFrame
) {
1236 FakeSchedulerClient client
;
1237 SchedulerSettings scheduler_settings
;
1238 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1239 scheduler
->SetCanStart();
1240 scheduler
->SetVisible(true);
1241 scheduler
->SetCanDraw(true);
1242 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1244 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1246 scheduler
->SetNeedsCommit();
1247 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1250 // Create a BeginFrame with a long deadline to avoid race conditions.
1251 // This is the first BeginFrame, which will be handled immediately.
1252 BeginFrameArgs args
= CreateBeginFrameArgsForTesting(client
.now_src());
1253 args
.deadline
+= base::TimeDelta::FromHours(1);
1254 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1255 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1256 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1257 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1258 EXPECT_TRUE(client
.needs_begin_frames());
1261 // Queue BeginFrames while we are still handling the previous BeginFrame.
1262 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1263 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1264 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1265 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1267 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
1268 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1269 EXPECT_NO_ACTION(client
);
1270 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1271 EXPECT_TRUE(client
.needs_begin_frames());
1274 // NotifyReadyToCommit should trigger the commit.
1275 scheduler
->NotifyBeginMainFrameStarted();
1276 scheduler
->NotifyReadyToCommit();
1277 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1278 EXPECT_TRUE(client
.needs_begin_frames());
1281 // BeginImplFrame should prepare the draw.
1282 client
.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
1283 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1284 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1285 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1286 EXPECT_TRUE(client
.needs_begin_frames());
1289 // BeginImplFrame deadline should draw.
1290 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1291 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 0, 1);
1292 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1293 EXPECT_TRUE(client
.needs_begin_frames());
1296 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
1297 // to avoid excessive toggles.
1298 client
.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
1299 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
1300 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1303 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1304 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1308 TEST(SchedulerTest
, BeginRetroFrame_SwapThrottled
) {
1309 FakeSchedulerClient client
;
1310 SchedulerSettings scheduler_settings
;
1311 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1312 scheduler
->SetCanStart();
1313 scheduler
->SetVisible(true);
1314 scheduler
->SetCanDraw(true);
1315 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1317 // To test swap ack throttling, this test disables automatic swap acks.
1318 scheduler
->SetMaxSwapsPending(1);
1319 client
.SetAutomaticSwapAck(false);
1321 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1323 scheduler
->SetNeedsCommit();
1324 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1327 // Create a BeginFrame with a long deadline to avoid race conditions.
1328 // This is the first BeginFrame, which will be handled immediately.
1329 BeginFrameArgs args
= CreateBeginFrameArgsForTesting(client
.now_src());
1330 args
.deadline
+= base::TimeDelta::FromHours(1);
1331 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1332 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1333 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1334 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1335 EXPECT_TRUE(client
.needs_begin_frames());
1338 // Queue BeginFrame while we are still handling the previous BeginFrame.
1339 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1340 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1341 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1342 EXPECT_NO_ACTION(client
);
1343 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1346 // NotifyReadyToCommit should trigger the pending commit and draw.
1347 scheduler
->NotifyBeginMainFrameStarted();
1348 scheduler
->NotifyReadyToCommit();
1349 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1350 EXPECT_TRUE(client
.needs_begin_frames());
1353 // Swapping will put us into a swap throttled state.
1354 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1355 EXPECT_ACTION("ScheduledActionAnimate", client
, 0, 2);
1356 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 1, 2);
1357 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1358 EXPECT_TRUE(client
.needs_begin_frames());
1361 // While swap throttled, BeginRetroFrames should trigger BeginImplFrames
1362 // but not a BeginMainFrame or draw.
1363 scheduler
->SetNeedsCommit();
1364 client
.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
1365 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 1);
1366 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1367 EXPECT_TRUE(client
.needs_begin_frames());
1370 // Queue BeginFrame while we are still handling the previous BeginFrame.
1371 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1372 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1373 EXPECT_NO_ACTION(client
);
1374 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1375 EXPECT_TRUE(client
.needs_begin_frames());
1378 // Take us out of a swap throttled state.
1379 scheduler
->DidSwapBuffersComplete();
1380 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 0, 1);
1381 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1382 EXPECT_TRUE(client
.needs_begin_frames());
1385 // BeginImplFrame deadline should draw.
1386 scheduler
->SetNeedsRedraw();
1388 EXPECT_TRUE(client
.task_runner().RunTasksWhile(
1389 client
.ImplFrameDeadlinePending(true)));
1391 EXPECT_ACTION("ScheduledActionAnimate", client
, 0, 2);
1392 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 1, 2);
1393 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1394 EXPECT_TRUE(client
.needs_begin_frames());
1398 void BeginFramesNotFromClient(bool begin_frame_scheduling_enabled
,
1399 bool throttle_frame_production
) {
1400 FakeSchedulerClient client
;
1401 SchedulerSettings scheduler_settings
;
1402 scheduler_settings
.begin_frame_scheduling_enabled
=
1403 begin_frame_scheduling_enabled
;
1404 scheduler_settings
.throttle_frame_production
= throttle_frame_production
;
1405 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1406 scheduler
->SetCanStart();
1407 scheduler
->SetVisible(true);
1408 scheduler
->SetCanDraw(true);
1409 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1411 // SetNeedsCommit should begin the frame on the next BeginImplFrame
1412 // without calling SetNeedsBeginFrame.
1414 scheduler
->SetNeedsCommit();
1415 EXPECT_FALSE(client
.needs_begin_frames());
1416 EXPECT_NO_ACTION(client
);
1419 // When the client-driven BeginFrame are disabled, the scheduler posts it's
1420 // own BeginFrame tasks.
1421 client
.task_runner().RunPendingTasks(); // Run posted BeginFrame.
1422 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1423 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1424 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1425 EXPECT_FALSE(client
.needs_begin_frames());
1428 // If we don't swap on the deadline, we wait for the next BeginFrame.
1429 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1430 EXPECT_NO_ACTION(client
);
1431 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1432 EXPECT_FALSE(client
.needs_begin_frames());
1435 // NotifyReadyToCommit should trigger the commit.
1436 scheduler
->NotifyBeginMainFrameStarted();
1437 scheduler
->NotifyReadyToCommit();
1438 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1439 EXPECT_FALSE(client
.needs_begin_frames());
1442 // BeginImplFrame should prepare the draw.
1443 client
.task_runner().RunPendingTasks(); // Run posted BeginFrame.
1444 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1445 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1446 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1447 EXPECT_FALSE(client
.needs_begin_frames());
1450 // BeginImplFrame deadline should draw.
1451 client
.task_runner().RunTasksWhile(client
.ImplFrameDeadlinePending(true));
1452 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 0, 1);
1453 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1454 EXPECT_FALSE(client
.needs_begin_frames());
1457 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
1458 // to avoid excessive toggles.
1459 client
.task_runner().RunPendingTasks(); // Run posted BeginFrame.
1460 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client
);
1461 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1464 // Make sure SetNeedsBeginFrame isn't called on the client
1465 // when the BeginFrame is no longer needed.
1466 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1467 EXPECT_NO_ACTION(client
);
1468 EXPECT_FALSE(client
.needs_begin_frames());
1472 TEST(SchedulerTest
, SyntheticBeginFrames
) {
1473 bool begin_frame_scheduling_enabled
= false;
1474 bool throttle_frame_production
= true;
1475 BeginFramesNotFromClient(begin_frame_scheduling_enabled
,
1476 throttle_frame_production
);
1479 TEST(SchedulerTest
, VSyncThrottlingDisabled
) {
1480 bool begin_frame_scheduling_enabled
= true;
1481 bool throttle_frame_production
= false;
1482 BeginFramesNotFromClient(begin_frame_scheduling_enabled
,
1483 throttle_frame_production
);
1486 TEST(SchedulerTest
, SyntheticBeginFrames_And_VSyncThrottlingDisabled
) {
1487 bool begin_frame_scheduling_enabled
= false;
1488 bool throttle_frame_production
= false;
1489 BeginFramesNotFromClient(begin_frame_scheduling_enabled
,
1490 throttle_frame_production
);
1493 void BeginFramesNotFromClient_SwapThrottled(bool begin_frame_scheduling_enabled
,
1494 bool throttle_frame_production
) {
1495 FakeSchedulerClient client
;
1496 SchedulerSettings scheduler_settings
;
1497 scheduler_settings
.begin_frame_scheduling_enabled
=
1498 begin_frame_scheduling_enabled
;
1499 scheduler_settings
.throttle_frame_production
= throttle_frame_production
;
1500 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1501 scheduler
->SetCanStart();
1502 scheduler
->SetVisible(true);
1503 scheduler
->SetCanDraw(true);
1504 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1506 // To test swap ack throttling, this test disables automatic swap acks.
1507 scheduler
->SetMaxSwapsPending(1);
1508 client
.SetAutomaticSwapAck(false);
1510 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1512 scheduler
->SetNeedsCommit();
1513 EXPECT_FALSE(client
.needs_begin_frames());
1514 EXPECT_NO_ACTION(client
);
1517 // Trigger the first BeginImplFrame and BeginMainFrame
1518 client
.task_runner().RunPendingTasks(); // Run posted BeginFrame.
1519 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1520 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1521 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1522 EXPECT_FALSE(client
.needs_begin_frames());
1525 // NotifyReadyToCommit should trigger the pending commit and draw.
1526 scheduler
->NotifyBeginMainFrameStarted();
1527 scheduler
->NotifyReadyToCommit();
1528 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1529 EXPECT_FALSE(client
.needs_begin_frames());
1532 // Swapping will put us into a swap throttled state.
1533 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1534 EXPECT_ACTION("ScheduledActionAnimate", client
, 0, 2);
1535 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 1, 2);
1536 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1537 EXPECT_FALSE(client
.needs_begin_frames());
1540 // While swap throttled, BeginFrames should trigger BeginImplFrames,
1541 // but not a BeginMainFrame or draw.
1542 scheduler
->SetNeedsCommit();
1543 client
.task_runner().RunPendingTasks(); // Run posted BeginFrame.
1544 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 1);
1545 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1546 EXPECT_FALSE(client
.needs_begin_frames());
1549 // Take us out of a swap throttled state.
1550 scheduler
->DidSwapBuffersComplete();
1551 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 0, 1);
1552 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1553 EXPECT_FALSE(client
.needs_begin_frames());
1556 // BeginImplFrame deadline should draw.
1557 scheduler
->SetNeedsRedraw();
1558 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1559 EXPECT_ACTION("ScheduledActionAnimate", client
, 0, 2);
1560 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 1, 2);
1561 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1562 EXPECT_FALSE(client
.needs_begin_frames());
1566 TEST(SchedulerTest
, SyntheticBeginFrames_SwapThrottled
) {
1567 bool begin_frame_scheduling_enabled
= false;
1568 bool throttle_frame_production
= true;
1569 BeginFramesNotFromClient_SwapThrottled(begin_frame_scheduling_enabled
,
1570 throttle_frame_production
);
1573 TEST(SchedulerTest
, VSyncThrottlingDisabled_SwapThrottled
) {
1574 bool begin_frame_scheduling_enabled
= true;
1575 bool throttle_frame_production
= false;
1576 BeginFramesNotFromClient_SwapThrottled(begin_frame_scheduling_enabled
,
1577 throttle_frame_production
);
1581 SyntheticBeginFrames_And_VSyncThrottlingDisabled_SwapThrottled
) {
1582 bool begin_frame_scheduling_enabled
= false;
1583 bool throttle_frame_production
= false;
1584 BeginFramesNotFromClient_SwapThrottled(begin_frame_scheduling_enabled
,
1585 throttle_frame_production
);
1588 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterOutputSurfaceIsInitialized
) {
1589 FakeSchedulerClient client
;
1590 SchedulerSettings scheduler_settings
;
1591 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1592 scheduler
->SetCanStart();
1593 scheduler
->SetVisible(true);
1594 scheduler
->SetCanDraw(true);
1596 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1598 scheduler
->DidCreateAndInitializeOutputSurface();
1599 EXPECT_NO_ACTION(client
);
1601 scheduler
->DidLoseOutputSurface();
1602 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1605 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterBeginFrameStarted
) {
1606 FakeSchedulerClient client
;
1607 SchedulerSettings scheduler_settings
;
1608 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1609 scheduler
->SetCanStart();
1610 scheduler
->SetVisible(true);
1611 scheduler
->SetCanDraw(true);
1613 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1614 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1615 // SetNeedsCommit should begin the frame.
1617 scheduler
->SetNeedsCommit();
1618 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1621 client
.AdvanceFrame();
1622 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1623 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1624 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1627 scheduler
->DidLoseOutputSurface();
1628 // Do nothing when impl frame is in deadine pending state.
1629 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1632 scheduler
->NotifyBeginMainFrameStarted();
1633 scheduler
->NotifyReadyToCommit();
1634 EXPECT_ACTION("ScheduledActionCommit", client
, 0, 1);
1637 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1638 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1641 void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(
1642 bool impl_side_painting
) {
1643 FakeSchedulerClient client
;
1644 SchedulerSettings scheduler_settings
;
1645 scheduler_settings
.impl_side_painting
= impl_side_painting
;
1646 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1647 scheduler
->SetCanStart();
1648 scheduler
->SetVisible(true);
1649 scheduler
->SetCanDraw(true);
1651 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1652 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1654 // SetNeedsCommit should begin the frame.
1656 scheduler
->SetNeedsCommit();
1657 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1660 client
.AdvanceFrame();
1661 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1662 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1663 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1666 scheduler
->DidLoseOutputSurface();
1667 // Do nothing when impl frame is in deadine pending state.
1668 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1671 // Run posted deadline.
1672 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1673 client
.task_runner().RunTasksWhile(client
.ImplFrameDeadlinePending(true));
1674 // OnBeginImplFrameDeadline didn't schedule any actions because main frame is
1675 // not yet completed.
1676 EXPECT_NO_ACTION(client
);
1677 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1679 // BeginImplFrame is not started.
1680 client
.task_runner().RunUntilTime(client
.now_src()->Now() +
1681 base::TimeDelta::FromMilliseconds(10));
1682 EXPECT_NO_ACTION(client
);
1683 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1686 scheduler
->NotifyBeginMainFrameStarted();
1687 scheduler
->NotifyReadyToCommit();
1688 if (impl_side_painting
) {
1689 EXPECT_ACTION("ScheduledActionCommit", client
, 0, 3);
1690 EXPECT_ACTION("ScheduledActionActivateSyncTree", client
, 1, 3);
1691 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
, 2, 3);
1693 EXPECT_ACTION("ScheduledActionCommit", client
, 0, 2);
1694 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
, 1, 2);
1698 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency
) {
1699 bool impl_side_painting
= false;
1700 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting
);
1704 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatencyWithImplPaint
) {
1705 bool impl_side_painting
= true;
1706 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting
);
1709 void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting
) {
1710 FakeSchedulerClient client
;
1711 SchedulerSettings scheduler_settings
;
1712 scheduler_settings
.impl_side_painting
= impl_side_painting
;
1713 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1714 scheduler
->SetCanStart();
1715 scheduler
->SetVisible(true);
1716 scheduler
->SetCanDraw(true);
1718 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1719 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1721 // SetNeedsCommit should begin the frame.
1723 scheduler
->SetNeedsCommit();
1724 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1727 client
.AdvanceFrame();
1728 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1729 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1730 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1733 scheduler
->NotifyBeginMainFrameStarted();
1734 scheduler
->NotifyReadyToCommit();
1735 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1738 scheduler
->DidLoseOutputSurface();
1739 if (impl_side_painting
) {
1740 // Sync tree should be forced to activate.
1741 EXPECT_ACTION("SetNeedsBeginFrames(false)", client
, 0, 2);
1742 EXPECT_ACTION("ScheduledActionActivateSyncTree", client
, 1, 2);
1744 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1748 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1749 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1752 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterReadyToCommit
) {
1753 DidLoseOutputSurfaceAfterReadyToCommit(false);
1756 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterReadyToCommitWithImplPainting
) {
1757 DidLoseOutputSurfaceAfterReadyToCommit(true);
1760 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterSetNeedsManageTiles
) {
1761 FakeSchedulerClient client
;
1762 SchedulerSettings scheduler_settings
;
1763 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1764 scheduler
->SetCanStart();
1765 scheduler
->SetVisible(true);
1766 scheduler
->SetCanDraw(true);
1767 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1770 scheduler
->SetNeedsManageTiles();
1771 scheduler
->SetNeedsRedraw();
1772 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1775 client
.AdvanceFrame();
1776 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1777 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1778 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1781 scheduler
->DidLoseOutputSurface();
1782 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1785 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1786 EXPECT_ACTION("ScheduledActionManageTiles", client
, 0, 2);
1787 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
, 1, 2);
1790 TEST(SchedulerTest
, DidLoseOutputSurfaceAfterBeginRetroFramePosted
) {
1791 FakeSchedulerClient client
;
1792 SchedulerSettings scheduler_settings
;
1793 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1794 scheduler
->SetCanStart();
1795 scheduler
->SetVisible(true);
1796 scheduler
->SetCanDraw(true);
1797 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1799 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1801 scheduler
->SetNeedsCommit();
1802 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1804 // Create a BeginFrame with a long deadline to avoid race conditions.
1805 // This is the first BeginFrame, which will be handled immediately.
1807 BeginFrameArgs args
= CreateBeginFrameArgsForTesting(client
.now_src());
1808 args
.deadline
+= base::TimeDelta::FromHours(1);
1809 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1810 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1811 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1812 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1813 EXPECT_TRUE(client
.needs_begin_frames());
1815 // Queue BeginFrames while we are still handling the previous BeginFrame.
1816 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1817 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1818 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1819 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1821 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
1823 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1824 EXPECT_NO_ACTION(client
);
1825 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1826 EXPECT_TRUE(client
.needs_begin_frames());
1828 // NotifyReadyToCommit should trigger the commit.
1830 scheduler
->NotifyBeginMainFrameStarted();
1831 scheduler
->NotifyReadyToCommit();
1832 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1833 EXPECT_TRUE(client
.needs_begin_frames());
1836 EXPECT_FALSE(scheduler
->IsBeginRetroFrameArgsEmpty());
1837 scheduler
->DidLoseOutputSurface();
1838 EXPECT_ACTION("SetNeedsBeginFrames(false)", client
, 0, 2);
1839 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
, 1, 2);
1840 EXPECT_TRUE(scheduler
->IsBeginRetroFrameArgsEmpty());
1842 // Posted BeginRetroFrame is aborted.
1844 client
.task_runner().RunPendingTasks();
1845 EXPECT_NO_ACTION(client
);
1848 TEST(SchedulerTest
, DidLoseOutputSurfaceDuringBeginRetroFrameRunning
) {
1849 FakeSchedulerClient client
;
1850 SchedulerSettings scheduler_settings
;
1851 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1852 scheduler
->SetCanStart();
1853 scheduler
->SetVisible(true);
1854 scheduler
->SetCanDraw(true);
1855 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1857 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1859 scheduler
->SetNeedsCommit();
1860 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1862 // Create a BeginFrame with a long deadline to avoid race conditions.
1863 // This is the first BeginFrame, which will be handled immediately.
1865 BeginFrameArgs args
= CreateBeginFrameArgsForTesting(client
.now_src());
1866 args
.deadline
+= base::TimeDelta::FromHours(1);
1867 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1868 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1869 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1870 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1871 EXPECT_TRUE(client
.needs_begin_frames());
1873 // Queue BeginFrames while we are still handling the previous BeginFrame.
1874 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1875 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1876 args
.frame_time
+= base::TimeDelta::FromSeconds(1);
1877 client
.ExternalBeginFrameSource()->TestOnBeginFrame(args
);
1879 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
1881 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1882 EXPECT_NO_ACTION(client
);
1883 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1884 EXPECT_TRUE(client
.needs_begin_frames());
1886 // NotifyReadyToCommit should trigger the commit.
1888 scheduler
->NotifyBeginMainFrameStarted();
1889 scheduler
->NotifyReadyToCommit();
1890 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1891 EXPECT_TRUE(client
.needs_begin_frames());
1893 // BeginImplFrame should prepare the draw.
1895 client
.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
1896 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1897 EXPECT_ACTION("ScheduledActionAnimate", client
, 1, 2);
1898 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1899 EXPECT_TRUE(client
.needs_begin_frames());
1902 EXPECT_FALSE(scheduler
->IsBeginRetroFrameArgsEmpty());
1903 scheduler
->DidLoseOutputSurface();
1904 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client
);
1905 EXPECT_TRUE(scheduler
->IsBeginRetroFrameArgsEmpty());
1907 // BeginImplFrame deadline should abort drawing.
1909 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1910 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1911 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
1912 EXPECT_FALSE(client
.needs_begin_frames());
1914 // No more BeginRetroFrame because BeginRetroFrame queue is cleared.
1916 client
.task_runner().RunPendingTasks();
1917 EXPECT_NO_ACTION(client
);
1921 StopBeginFrameAfterDidLoseOutputSurfaceWithSyntheticBeginFrameSource
) {
1922 FakeSchedulerClient client
;
1923 SchedulerSettings scheduler_settings
;
1924 scheduler_settings
.begin_frame_scheduling_enabled
= false;
1925 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1926 scheduler
->SetCanStart();
1927 scheduler
->SetVisible(true);
1928 scheduler
->SetCanDraw(true);
1929 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1931 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1933 EXPECT_FALSE(scheduler
->frame_source().NeedsBeginFrames());
1934 scheduler
->SetNeedsCommit();
1935 EXPECT_TRUE(scheduler
->frame_source().NeedsBeginFrames());
1938 client
.task_runner().RunPendingTasks(); // Run posted Tick.
1939 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1940 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1941 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1942 EXPECT_TRUE(scheduler
->frame_source().NeedsBeginFrames());
1944 // NotifyReadyToCommit should trigger the commit.
1946 scheduler
->NotifyBeginMainFrameStarted();
1947 scheduler
->NotifyReadyToCommit();
1948 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1949 EXPECT_TRUE(scheduler
->frame_source().NeedsBeginFrames());
1952 scheduler
->DidLoseOutputSurface();
1953 EXPECT_NO_ACTION(client
);
1954 EXPECT_FALSE(scheduler
->frame_source().NeedsBeginFrames());
1957 client
.task_runner().RunPendingTasks(); // Run posted deadline.
1958 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1959 EXPECT_FALSE(scheduler
->frame_source().NeedsBeginFrames());
1962 TEST(SchedulerTest
, ScheduledActionActivateAfterBecomingInvisible
) {
1963 FakeSchedulerClient client
;
1964 SchedulerSettings scheduler_settings
;
1965 scheduler_settings
.impl_side_painting
= true;
1966 TestScheduler
* scheduler
= client
.CreateScheduler(scheduler_settings
);
1967 scheduler
->SetCanStart();
1968 scheduler
->SetVisible(true);
1969 scheduler
->SetCanDraw(true);
1971 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
1972 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
1974 // SetNeedsCommit should begin the frame.
1976 scheduler
->SetNeedsCommit();
1977 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client
);
1980 client
.AdvanceFrame();
1981 EXPECT_ACTION("WillBeginImplFrame", client
, 0, 2);
1982 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client
, 1, 2);
1983 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
1986 scheduler
->NotifyBeginMainFrameStarted();
1987 scheduler
->NotifyReadyToCommit();
1988 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
1991 scheduler
->SetVisible(false);
1992 // Sync tree should be forced to activate.
1993 EXPECT_ACTION("SetNeedsBeginFrames(false)", client
, 0, 2);
1994 EXPECT_ACTION("ScheduledActionActivateSyncTree", client
, 1, 2);
1997 TEST(SchedulerTest
, SchedulerPowerMonitoring
) {
1998 FakeSchedulerClient client
;
1999 SchedulerSettings settings
;
2000 settings
.disable_hi_res_timer_tasks_on_battery
= true;
2001 TestScheduler
* scheduler
= client
.CreateScheduler(settings
);
2003 base::TimeTicks before_deadline
, after_deadline
;
2005 scheduler
->SetCanStart();
2006 scheduler
->SetVisible(true);
2007 scheduler
->SetCanDraw(true);
2009 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
2011 scheduler
->SetNeedsCommit();
2012 scheduler
->SetNeedsRedraw();
2015 // On non-battery power
2016 EXPECT_FALSE(client
.PowerMonitor()->IsOnBatteryPower());
2018 client
.AdvanceFrame();
2021 before_deadline
= client
.now_src()->Now();
2022 EXPECT_TRUE(client
.task_runner().RunTasksWhile(
2023 client
.ImplFrameDeadlinePending(true)));
2024 after_deadline
= client
.now_src()->Now();
2026 // We post a non-zero deadline task when not on battery
2027 EXPECT_LT(before_deadline
, after_deadline
);
2029 // Switch to battery power
2030 client
.PowerMonitorSource()->GeneratePowerStateEvent(true);
2031 EXPECT_TRUE(client
.PowerMonitor()->IsOnBatteryPower());
2033 client
.AdvanceFrame();
2034 scheduler
->SetNeedsCommit();
2035 scheduler
->SetNeedsRedraw();
2038 before_deadline
= client
.now_src()->Now();
2039 EXPECT_TRUE(client
.task_runner().RunTasksWhile(
2040 client
.ImplFrameDeadlinePending(true)));
2041 after_deadline
= client
.now_src()->Now();
2043 // We post a zero deadline task when on battery
2044 EXPECT_EQ(before_deadline
, after_deadline
);
2046 // Switch to non-battery power
2047 client
.PowerMonitorSource()->GeneratePowerStateEvent(false);
2048 EXPECT_FALSE(client
.PowerMonitor()->IsOnBatteryPower());
2050 client
.AdvanceFrame();
2051 scheduler
->SetNeedsCommit();
2052 scheduler
->SetNeedsRedraw();
2056 before_deadline
= client
.now_src()->Now();
2057 EXPECT_TRUE(client
.task_runner().RunTasksWhile(
2058 client
.ImplFrameDeadlinePending(true)));
2059 after_deadline
= client
.now_src()->Now();
2063 SimulateWindowsLowResolutionTimerOnBattery_PrioritizeImplLatencyOff
) {
2064 FakeSchedulerClient client
;
2065 SchedulerSettings settings
;
2066 TestScheduler
* scheduler
= client
.CreateScheduler(settings
);
2068 scheduler
->SetCanStart();
2069 scheduler
->SetVisible(true);
2070 scheduler
->SetCanDraw(true);
2072 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
2074 // Set needs commit so that the scheduler tries to wait for the main thread
2075 scheduler
->SetNeedsCommit();
2076 // Set needs redraw so that the scheduler doesn't wait too long
2077 scheduler
->SetNeedsRedraw();
2080 // Switch to battery power
2081 client
.PowerMonitorSource()->GeneratePowerStateEvent(true);
2082 EXPECT_TRUE(client
.PowerMonitor()->IsOnBatteryPower());
2084 client
.AdvanceFrame();
2085 scheduler
->SetNeedsCommit();
2086 scheduler
->SetNeedsRedraw();
2089 // Disable auto-advancing of now_src
2090 client
.task_runner().SetAutoAdvanceNowToPendingTasks(false);
2092 // Deadline task is pending
2093 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
2094 client
.task_runner().RunPendingTasks();
2095 // Deadline task is still pending
2096 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
2098 // Advance now by 15 ms - same as windows low res timer
2099 client
.now_src()->AdvanceNowMicroseconds(15000);
2100 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
2101 client
.task_runner().RunPendingTasks();
2102 // Deadline task finally completes
2103 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());
2107 SimulateWindowsLowResolutionTimerOnBattery_PrioritizeImplLatencyOn
) {
2108 FakeSchedulerClient client
;
2109 SchedulerSettings settings
;
2110 settings
.disable_hi_res_timer_tasks_on_battery
= true;
2111 TestScheduler
* scheduler
= client
.CreateScheduler(settings
);
2113 scheduler
->SetCanStart();
2114 scheduler
->SetVisible(true);
2115 scheduler
->SetCanDraw(true);
2117 InitializeOutputSurfaceAndFirstCommit(scheduler
, &client
);
2119 // Set needs commit so that the scheduler tries to wait for the main thread
2120 scheduler
->SetNeedsCommit();
2121 // Set needs redraw so that the scheduler doesn't wait too long
2122 scheduler
->SetNeedsRedraw();
2125 // Switch to battery power
2126 client
.PowerMonitorSource()->GeneratePowerStateEvent(true);
2127 EXPECT_TRUE(client
.PowerMonitor()->IsOnBatteryPower());
2129 client
.AdvanceFrame();
2130 scheduler
->SetNeedsCommit();
2131 scheduler
->SetNeedsRedraw();
2134 // Disable auto-advancing of now_src
2135 client
.task_runner().SetAutoAdvanceNowToPendingTasks(false);
2137 // Deadline task is pending
2138 EXPECT_TRUE(scheduler
->BeginImplFrameDeadlinePending());
2139 client
.task_runner().RunPendingTasks();
2140 // Deadline task runs immediately
2141 EXPECT_FALSE(scheduler
->BeginImplFrameDeadlinePending());