Change DtmfSenderHandler to handle events on the signaling thread.
[chromium-blink-merge.git] / cc / scheduler / scheduler_unittest.cc
blob7da62676c6c4a4aeb19f5a1a5c1451bc6e5c8010
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"
6 #include <string>
7 #include <vector>
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) \
24 do { \
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)); \
29 } \
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); \
33 } while (false)
35 #define EXPECT_NO_ACTION(client) EXPECT_ACTION("", client, -1, 0)
37 #define EXPECT_SINGLE_ACTION(action, client) \
38 EXPECT_ACTION(action, client, 0, 1)
40 namespace cc {
41 namespace {
43 class FakeSchedulerClient;
45 void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler,
46 FakeSchedulerClient* client);
48 class FakeSchedulerClient : public SchedulerClient {
49 public:
50 struct FakeBeginFrameSourceForFakeSchedulerClient
51 : public FakeBeginFrameSource {
52 FakeSchedulerClient* client_;
54 explicit FakeBeginFrameSourceForFakeSchedulerClient(
55 FakeSchedulerClient* client)
56 : client_(client) {}
58 void OnNeedsBeginFramesChange(bool needs_begin_frames) override {
59 if (needs_begin_frames) {
60 client_->actions_.push_back("SetNeedsBeginFrames(true)");
61 } else {
62 client_->actions_.push_back("SetNeedsBeginFrames(false)");
64 client_->states_.push_back(client_->scheduler_->AsValue());
68 class FakePowerMonitorSource : public base::PowerMonitorSource {
69 public:
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_; }
79 private:
80 bool on_battery_power_impl_;
83 FakeSchedulerClient()
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_)),
93 scheduler_(nullptr) {
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);
98 Reset();
101 void Reset() {
102 actions_.clear();
103 states_.clear();
104 draw_will_happen_ = true;
105 swap_will_happen_if_draw_happens_ = true;
106 num_draws_ = 0;
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_);
113 DCHECK(scheduler_);
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))
168 return i;
169 return -1;
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());
208 num_draws_++;
209 DrawResult result =
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;
218 } else {
219 scheduler_->SetSwapUsedIncompleteTile(false);
222 if (automatic_swap_ack_)
223 scheduler_->DidSwapBuffersComplete();
225 return result;
227 DrawResult ScheduledActionDrawAndSwapForced() override {
228 actions_.push_back("ScheduledActionDrawAndSwapForced");
229 states_.push_back(scheduler_->AsValue());
230 return DRAW_SUCCESS;
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),
271 state);
274 protected:
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_;
282 int num_draws_;
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) {
299 TRACE_EVENT0("cc",
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());
320 SCOPED_TRACE(
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);
343 client.Reset();
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.
360 client.Reset();
361 scheduler->SetNeedsCommit();
362 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client);
363 client.Reset();
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());
370 client.Reset();
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());
377 client.Reset();
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());
384 client.Reset();
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());
392 client.Reset();
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());
399 client.Reset();
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());
406 client.Reset();
408 client.task_runner().RunPendingTasks(); // Run posted deadline.
409 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client);
410 client.Reset();
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);
423 client.Reset();
425 // SetNeedsCommit should begin the frame.
426 scheduler->SetNeedsCommit();
427 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client);
429 client.Reset();
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());
436 client.Reset();
438 // Now SetNeedsCommit again. Calling here means we need a second commit.
439 scheduler->SetNeedsCommit();
440 EXPECT_EQ(client.num_actions_(), 0);
441 client.Reset();
443 // Finish the first commit.
444 scheduler->NotifyBeginMainFrameStarted();
445 scheduler->NotifyReadyToCommit();
446 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
447 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
448 client.Reset();
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());
457 client.Reset();
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());
464 client.Reset();
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());
472 client.Reset();
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());
478 client.Reset();
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());
485 client.Reset();
488 class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient {
489 public:
490 void ScheduledActionSendBeginMainFrame() override {}
491 DrawResult ScheduledActionDrawAndSwapIfPossible() override {
492 // Only SetNeedsRedraw the first time this is called
493 if (!num_draws_)
494 scheduler_->SetNeedsRedraw();
495 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
498 DrawResult ScheduledActionDrawAndSwapForced() override {
499 NOTREACHED();
500 return DRAW_SUCCESS;
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);
520 client.Reset();
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
540 // swap.
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);
557 client.Reset();
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());
566 // Fail the draw.
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
572 // request.
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 {
596 public:
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 {
611 NOTREACHED();
612 return DRAW_SUCCESS;
615 void ScheduledActionCommit() override {}
616 void ScheduledActionBeginOutputSurfaceCreation() override {}
617 void DidAnticipatedDrawTimeChange(base::TimeTicks) override {}
619 void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_ = true; }
621 private:
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);
635 client.Reset();
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
662 // swap.
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);
680 client.Reset();
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());
689 // Fail the draw.
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
695 // request.
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);
727 client.Reset();
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 {
753 public:
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.
772 client.Reset();
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.
784 client.Reset();
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.
791 client.Reset();
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.
803 client.Reset();
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.
812 client.Reset();
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.
821 client.Reset();
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.
833 client.Reset();
834 client.AdvanceFrame();
835 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
836 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
837 client.Reset();
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.
845 client.Reset();
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.
853 client.Reset();
854 client.AdvanceFrame();
855 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
856 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
857 client.Reset();
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();
879 client.Reset();
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());
889 client.Reset();
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();
901 client.Reset();
902 client.AdvanceFrame();
903 EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
904 EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
905 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
907 client.Reset();
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();
924 client.Reset();
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());
932 client.Reset();
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();
947 client.Reset();
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());
955 client.Reset();
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();
966 client.Reset();
967 client.AdvanceFrame();
968 EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
969 EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
970 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
972 client.Reset();
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.
998 client.Reset();
999 scheduler->SetNeedsCommit();
1000 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client);
1002 client.Reset();
1003 client.AdvanceFrame();
1004 EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1005 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1006 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1008 client.Reset();
1009 scheduler->NotifyBeginMainFrameStarted();
1010 scheduler->NotifyReadyToCommit();
1011 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1013 client.Reset();
1014 scheduler->NotifyReadyToActivate();
1015 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client);
1017 client.Reset();
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());
1024 client.Reset();
1025 client.AdvanceFrame();
1026 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
1027 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1029 client.Reset();
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);
1035 client.Reset();
1036 client.AdvanceFrame();
1037 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
1038 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1040 // No more UpdateVisibleTiles().
1041 client.Reset();
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);
1055 client.Reset();
1056 scheduler->SetNeedsRedraw();
1057 client.AdvanceFrame();
1059 // The deadline should be zero since there is no work other than drawing
1060 // pending.
1061 EXPECT_EQ(base::TimeTicks(), client.posted_begin_impl_frame_deadline());
1064 class SchedulerClientWithFixedEstimates : public FakeSchedulerClient {
1065 public:
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_;
1083 private:
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.
1108 client.Reset();
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"));
1120 client.Reset();
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);
1132 TEST(SchedulerTest,
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
1154 // priority mode.
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.
1245 client.Reset();
1246 scheduler->SetNeedsCommit();
1247 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client);
1248 client.Reset();
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());
1259 client.Reset();
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());
1272 client.Reset();
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());
1279 client.Reset();
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());
1287 client.Reset();
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());
1294 client.Reset();
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());
1301 client.Reset();
1303 client.task_runner().RunPendingTasks(); // Run posted deadline.
1304 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client);
1305 client.Reset();
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.
1322 client.Reset();
1323 scheduler->SetNeedsCommit();
1324 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client);
1325 client.Reset();
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());
1336 client.Reset();
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());
1344 client.Reset();
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());
1351 client.Reset();
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());
1359 client.Reset();
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());
1368 client.Reset();
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());
1376 client.Reset();
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());
1383 client.Reset();
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());
1395 client.Reset();
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.
1413 client.Reset();
1414 scheduler->SetNeedsCommit();
1415 EXPECT_FALSE(client.needs_begin_frames());
1416 EXPECT_NO_ACTION(client);
1417 client.Reset();
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());
1426 client.Reset();
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());
1433 client.Reset();
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());
1440 client.Reset();
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());
1448 client.Reset();
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());
1455 client.Reset();
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());
1462 client.Reset();
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());
1469 client.Reset();
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.
1511 client.Reset();
1512 scheduler->SetNeedsCommit();
1513 EXPECT_FALSE(client.needs_begin_frames());
1514 EXPECT_NO_ACTION(client);
1515 client.Reset();
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());
1523 client.Reset();
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());
1530 client.Reset();
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());
1538 client.Reset();
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());
1547 client.Reset();
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());
1554 client.Reset();
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());
1563 client.Reset();
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);
1580 TEST(SchedulerTest,
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);
1597 client.Reset();
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.
1616 client.Reset();
1617 scheduler->SetNeedsCommit();
1618 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client);
1620 client.Reset();
1621 client.AdvanceFrame();
1622 EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1623 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1624 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1626 client.Reset();
1627 scheduler->DidLoseOutputSurface();
1628 // Do nothing when impl frame is in deadine pending state.
1629 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client);
1631 client.Reset();
1632 scheduler->NotifyBeginMainFrameStarted();
1633 scheduler->NotifyReadyToCommit();
1634 EXPECT_ACTION("ScheduledActionCommit", client, 0, 1);
1636 client.Reset();
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.
1655 client.Reset();
1656 scheduler->SetNeedsCommit();
1657 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client);
1659 client.Reset();
1660 client.AdvanceFrame();
1661 EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1662 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1663 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1665 client.Reset();
1666 scheduler->DidLoseOutputSurface();
1667 // Do nothing when impl frame is in deadine pending state.
1668 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client);
1670 client.Reset();
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());
1685 client.Reset();
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);
1692 } else {
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);
1703 TEST(SchedulerTest,
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.
1722 client.Reset();
1723 scheduler->SetNeedsCommit();
1724 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client);
1726 client.Reset();
1727 client.AdvanceFrame();
1728 EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1729 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1730 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1732 client.Reset();
1733 scheduler->NotifyBeginMainFrameStarted();
1734 scheduler->NotifyReadyToCommit();
1735 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1737 client.Reset();
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);
1743 } else {
1744 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client);
1747 client.Reset();
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);
1769 client.Reset();
1770 scheduler->SetNeedsManageTiles();
1771 scheduler->SetNeedsRedraw();
1772 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client);
1774 client.Reset();
1775 client.AdvanceFrame();
1776 EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1777 EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
1778 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1780 client.Reset();
1781 scheduler->DidLoseOutputSurface();
1782 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(false)", client);
1784 client.Reset();
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.
1800 client.Reset();
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.
1806 client.Reset();
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.
1822 client.Reset();
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.
1829 client.Reset();
1830 scheduler->NotifyBeginMainFrameStarted();
1831 scheduler->NotifyReadyToCommit();
1832 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1833 EXPECT_TRUE(client.needs_begin_frames());
1835 client.Reset();
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.
1843 client.Reset();
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.
1858 client.Reset();
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.
1864 client.Reset();
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.
1880 client.Reset();
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.
1887 client.Reset();
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.
1894 client.Reset();
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());
1901 client.Reset();
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.
1908 client.Reset();
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.
1915 client.Reset();
1916 client.task_runner().RunPendingTasks();
1917 EXPECT_NO_ACTION(client);
1920 TEST(SchedulerTest,
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.
1932 client.Reset();
1933 EXPECT_FALSE(scheduler->frame_source().NeedsBeginFrames());
1934 scheduler->SetNeedsCommit();
1935 EXPECT_TRUE(scheduler->frame_source().NeedsBeginFrames());
1937 client.Reset();
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.
1945 client.Reset();
1946 scheduler->NotifyBeginMainFrameStarted();
1947 scheduler->NotifyReadyToCommit();
1948 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1949 EXPECT_TRUE(scheduler->frame_source().NeedsBeginFrames());
1951 client.Reset();
1952 scheduler->DidLoseOutputSurface();
1953 EXPECT_NO_ACTION(client);
1954 EXPECT_FALSE(scheduler->frame_source().NeedsBeginFrames());
1956 client.Reset();
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.
1975 client.Reset();
1976 scheduler->SetNeedsCommit();
1977 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client);
1979 client.Reset();
1980 client.AdvanceFrame();
1981 EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1982 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1983 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1985 client.Reset();
1986 scheduler->NotifyBeginMainFrameStarted();
1987 scheduler->NotifyReadyToCommit();
1988 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1990 client.Reset();
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();
2013 client.Reset();
2015 // On non-battery power
2016 EXPECT_FALSE(client.PowerMonitor()->IsOnBatteryPower());
2018 client.AdvanceFrame();
2019 client.Reset();
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();
2036 client.Reset();
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();
2053 client.Reset();
2055 // Same as before
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();
2062 TEST(SchedulerTest,
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();
2078 client.Reset();
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();
2087 client.Reset();
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());
2106 TEST(SchedulerTest,
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();
2123 client.Reset();
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();
2132 client.Reset();
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());
2144 } // namespace
2145 } // namespace cc