Give names to all utility processes.
[chromium-blink-merge.git] / cc / scheduler / scheduler_unittest.cc
blob52f7c4633b336f752804ee6f70ed98a6f8274725
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/scheduler/scheduler.h"
7 #include <string>
8 #include <vector>
10 #include "base/logging.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/run_loop.h"
14 #include "base/time/time.h"
15 #include "base/trace_event/trace_event.h"
16 #include "cc/test/begin_frame_args_test.h"
17 #include "cc/test/ordered_simple_task_runner.h"
18 #include "cc/test/scheduler_test_common.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \
23 do { \
24 EXPECT_EQ(expected_num_actions, client->num_actions_()); \
25 if (action_index >= 0) { \
26 ASSERT_LT(action_index, client->num_actions_()) << scheduler_.get(); \
27 EXPECT_STREQ(action, client->Action(action_index)); \
28 } \
29 for (int i = expected_num_actions; i < client->num_actions_(); ++i) \
30 ADD_FAILURE() << "Unexpected action: " << client->Action(i) \
31 << " with state:\n" << client->StateForAction(i); \
32 } while (false)
34 #define EXPECT_NO_ACTION(client) EXPECT_ACTION("", client, -1, 0)
36 #define EXPECT_SINGLE_ACTION(action, client) \
37 EXPECT_ACTION(action, client, 0, 1)
39 #define EXPECT_SCOPED(statements) \
40 { \
41 SCOPED_TRACE(""); \
42 statements; \
45 namespace cc {
46 namespace {
48 class FakeSchedulerClient : public SchedulerClient {
49 public:
50 FakeSchedulerClient()
51 : automatic_swap_ack_(true),
52 begin_frame_is_sent_to_children_(false),
53 scheduler_(nullptr) {
54 Reset();
57 void Reset() {
58 actions_.clear();
59 states_.clear();
60 draw_will_happen_ = true;
61 swap_will_happen_if_draw_happens_ = true;
62 num_draws_ = 0;
63 log_anticipated_draw_time_change_ = false;
64 begin_frame_is_sent_to_children_ = false;
67 void set_scheduler(TestScheduler* scheduler) { scheduler_ = scheduler; }
69 // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it
70 // for tests that do.
71 void set_log_anticipated_draw_time_change(bool log) {
72 log_anticipated_draw_time_change_ = log;
74 bool needs_begin_frames() {
75 return scheduler_->frame_source().NeedsBeginFrames();
77 int num_draws() const { return num_draws_; }
78 int num_actions_() const { return static_cast<int>(actions_.size()); }
79 const char* Action(int i) const { return actions_[i]; }
80 std::string StateForAction(int i) const { return states_[i]->ToString(); }
81 base::TimeTicks posted_begin_impl_frame_deadline() const {
82 return posted_begin_impl_frame_deadline_;
85 int ActionIndex(const char* action) const {
86 for (size_t i = 0; i < actions_.size(); i++)
87 if (!strcmp(actions_[i], action))
88 return i;
89 return -1;
92 bool HasAction(const char* action) const {
93 return ActionIndex(action) >= 0;
96 void SetDrawWillHappen(bool draw_will_happen) {
97 draw_will_happen_ = draw_will_happen;
99 void SetSwapWillHappenIfDrawHappens(bool swap_will_happen_if_draw_happens) {
100 swap_will_happen_if_draw_happens_ = swap_will_happen_if_draw_happens;
102 void SetAutomaticSwapAck(bool automatic_swap_ack) {
103 automatic_swap_ack_ = automatic_swap_ack;
105 // SchedulerClient implementation.
106 void WillBeginImplFrame(const BeginFrameArgs& args) override {
107 PushAction("WillBeginImplFrame");
109 void ScheduledActionSendBeginMainFrame() override {
110 PushAction("ScheduledActionSendBeginMainFrame");
112 void ScheduledActionAnimate() override {
113 PushAction("ScheduledActionAnimate");
115 DrawResult ScheduledActionDrawAndSwapIfPossible() override {
116 PushAction("ScheduledActionDrawAndSwapIfPossible");
117 num_draws_++;
118 DrawResult result =
119 draw_will_happen_ ? DRAW_SUCCESS : DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
120 bool swap_will_happen =
121 draw_will_happen_ && swap_will_happen_if_draw_happens_;
122 if (swap_will_happen) {
123 scheduler_->DidSwapBuffers();
125 if (automatic_swap_ack_)
126 scheduler_->DidSwapBuffersComplete();
128 return result;
130 DrawResult ScheduledActionDrawAndSwapForced() override {
131 PushAction("ScheduledActionDrawAndSwapForced");
132 return DRAW_SUCCESS;
134 void ScheduledActionCommit() override { PushAction("ScheduledActionCommit"); }
135 void ScheduledActionActivateSyncTree() override {
136 PushAction("ScheduledActionActivateSyncTree");
138 void ScheduledActionBeginOutputSurfaceCreation() override {
139 PushAction("ScheduledActionBeginOutputSurfaceCreation");
141 void ScheduledActionPrepareTiles() override {
142 PushAction("ScheduledActionPrepareTiles");
144 void ScheduledActionInvalidateOutputSurface() override {
145 actions_.push_back("ScheduledActionInvalidateOutputSurface");
146 states_.push_back(scheduler_->AsValue());
148 void DidAnticipatedDrawTimeChange(base::TimeTicks) override {
149 if (log_anticipated_draw_time_change_)
150 PushAction("DidAnticipatedDrawTimeChange");
152 base::TimeDelta DrawDurationEstimate() override { return base::TimeDelta(); }
153 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override {
154 return base::TimeDelta();
156 base::TimeDelta CommitToActivateDurationEstimate() override {
157 return base::TimeDelta();
160 void DidBeginImplFrameDeadline() override {}
162 void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
163 begin_frame_is_sent_to_children_ = true;
166 void SendBeginMainFrameNotExpectedSoon() override {
167 PushAction("SendBeginMainFrameNotExpectedSoon");
170 base::Callback<bool(void)> ImplFrameDeadlinePending(bool state) {
171 return base::Bind(&FakeSchedulerClient::ImplFrameDeadlinePendingCallback,
172 base::Unretained(this),
173 state);
176 bool begin_frame_is_sent_to_children() const {
177 return begin_frame_is_sent_to_children_;
180 void PushAction(const char* description) {
181 actions_.push_back(description);
182 states_.push_back(scheduler_->AsValue());
185 protected:
186 bool ImplFrameDeadlinePendingCallback(bool state) {
187 return scheduler_->BeginImplFrameDeadlinePending() == state;
190 bool draw_will_happen_;
191 bool swap_will_happen_if_draw_happens_;
192 bool automatic_swap_ack_;
193 int num_draws_;
194 bool log_anticipated_draw_time_change_;
195 bool begin_frame_is_sent_to_children_;
196 base::TimeTicks posted_begin_impl_frame_deadline_;
197 std::vector<const char*> actions_;
198 std::vector<scoped_refptr<base::trace_event::ConvertableToTraceFormat>>
199 states_;
200 TestScheduler* scheduler_;
203 class FakeExternalBeginFrameSource : public BeginFrameSourceMixIn {
204 public:
205 explicit FakeExternalBeginFrameSource(FakeSchedulerClient* client)
206 : client_(client) {}
207 ~FakeExternalBeginFrameSource() override {}
209 void OnNeedsBeginFramesChange(bool needs_begin_frames) override {
210 if (needs_begin_frames) {
211 client_->PushAction("SetNeedsBeginFrames(true)");
212 } else {
213 client_->PushAction("SetNeedsBeginFrames(false)");
217 void TestOnBeginFrame(const BeginFrameArgs& args) {
218 return CallOnBeginFrame(args);
221 private:
222 FakeSchedulerClient* client_;
225 class SchedulerTest : public testing::Test {
226 public:
227 SchedulerTest()
228 : now_src_(TestNowSource::Create()),
229 task_runner_(new OrderedSimpleTaskRunner(now_src_, true)),
230 fake_external_begin_frame_source_(nullptr) {
231 // A bunch of tests require Now() to be > BeginFrameArgs::DefaultInterval()
232 now_src_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
233 // Fail if we need to run 100 tasks in a row.
234 task_runner_->SetRunTaskLimit(100);
237 ~SchedulerTest() override {}
239 protected:
240 TestScheduler* CreateScheduler() {
241 scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source;
242 if (scheduler_settings_.use_external_begin_frame_source) {
243 fake_external_begin_frame_source.reset(
244 new FakeExternalBeginFrameSource(client_.get()));
245 fake_external_begin_frame_source_ =
246 fake_external_begin_frame_source.get();
248 scheduler_ = TestScheduler::Create(now_src_, client_.get(),
249 scheduler_settings_, 0, task_runner_,
250 fake_external_begin_frame_source.Pass());
251 DCHECK(scheduler_);
252 client_->set_scheduler(scheduler_.get());
253 return scheduler_.get();
256 void CreateSchedulerAndInitSurface() {
257 CreateScheduler();
258 EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit());
261 void SetUpScheduler(bool initSurface) {
262 SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient), initSurface);
265 void SetUpScheduler(scoped_ptr<FakeSchedulerClient> client,
266 bool initSurface) {
267 client_ = client.Pass();
268 if (initSurface)
269 CreateSchedulerAndInitSurface();
270 else
271 CreateScheduler();
274 OrderedSimpleTaskRunner& task_runner() { return *task_runner_; }
275 TestNowSource* now_src() { return now_src_.get(); }
277 // As this function contains EXPECT macros, to allow debugging it should be
278 // called inside EXPECT_SCOPED like so;
279 // EXPECT_SCOPED(client.InitializeOutputSurfaceAndFirstCommit(scheduler));
280 void InitializeOutputSurfaceAndFirstCommit() {
281 TRACE_EVENT0("cc",
282 "SchedulerUnitTest::InitializeOutputSurfaceAndFirstCommit");
283 DCHECK(scheduler_);
285 // Check the client doesn't have any actions queued when calling this
286 // function.
287 EXPECT_NO_ACTION(client_);
288 EXPECT_FALSE(client_->needs_begin_frames());
290 // Start the initial output surface creation.
291 EXPECT_FALSE(scheduler_->CanStart());
292 scheduler_->SetCanStart();
293 scheduler_->SetVisible(true);
294 scheduler_->SetCanDraw(true);
295 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_);
297 client_->Reset();
299 // We don't see anything happening until the first impl frame.
300 scheduler_->DidCreateAndInitializeOutputSurface();
301 scheduler_->SetNeedsCommit();
302 EXPECT_TRUE(client_->needs_begin_frames());
303 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
304 client_->Reset();
307 SCOPED_TRACE("Do first frame to commit after initialize.");
308 AdvanceFrame();
310 scheduler_->NotifyBeginMainFrameStarted();
311 scheduler_->NotifyReadyToCommitThenActivateIfNeeded();
313 EXPECT_FALSE(scheduler_->CommitPending());
315 if (scheduler_settings_.using_synchronous_renderer_compositor) {
316 scheduler_->SetNeedsRedraw();
317 scheduler_->OnDrawForOutputSurface();
318 } else {
319 // Run the posted deadline task.
320 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
321 task_runner_->RunTasksWhile(client_->ImplFrameDeadlinePending(true));
324 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
327 client_->Reset();
330 SCOPED_TRACE(
331 "Run second frame so Scheduler calls SetNeedsBeginFrame(false).");
332 AdvanceFrame();
334 if (!scheduler_settings_.using_synchronous_renderer_compositor) {
335 // Run the posted deadline task.
336 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
337 task_runner_->RunTasksWhile(client_->ImplFrameDeadlinePending(true));
340 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
343 EXPECT_FALSE(client_->needs_begin_frames());
344 client_->Reset();
347 // As this function contains EXPECT macros, to allow debugging it should be
348 // called inside EXPECT_SCOPED like so;
349 // EXPECT_SCOPED(client.AdvanceFrame());
350 void AdvanceFrame() {
351 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
352 "FakeSchedulerClient::AdvanceFrame");
353 // Consume any previous deadline first, if no deadline is currently
354 // pending, ImplFrameDeadlinePending will return false straight away and we
355 // will run no tasks.
356 task_runner_->RunTasksWhile(client_->ImplFrameDeadlinePending(true));
357 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
359 // Send the next BeginFrame message if using an external source, otherwise
360 // it will be already in the task queue.
361 if (scheduler_->settings().use_external_begin_frame_source &&
362 scheduler_->FrameProductionThrottled()) {
363 SendNextBeginFrame();
366 if (!scheduler_->settings().using_synchronous_renderer_compositor) {
367 // Then run tasks until new deadline is scheduled.
368 EXPECT_TRUE(task_runner_->RunTasksWhile(
369 client_->ImplFrameDeadlinePending(false)));
370 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
374 void SendNextBeginFrame() {
375 DCHECK(scheduler_->settings().use_external_begin_frame_source);
376 // Creep the time forward so that any BeginFrameArgs is not equal to the
377 // last one otherwise we violate the BeginFrameSource contract.
378 now_src_->AdvanceNow(BeginFrameArgs::DefaultInterval());
379 fake_external_begin_frame_source_->TestOnBeginFrame(
380 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()));
383 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const {
384 return fake_external_begin_frame_source_;
387 void MainFrameInHighLatencyMode(
388 int64 begin_main_frame_to_commit_estimate_in_ms,
389 int64 commit_to_activate_estimate_in_ms,
390 bool impl_latency_takes_priority,
391 bool should_send_begin_main_frame);
392 void BeginFramesNotFromClient(bool use_external_begin_frame_source,
393 bool throttle_frame_production);
394 void BeginFramesNotFromClient_SwapThrottled(
395 bool use_external_begin_frame_source,
396 bool throttle_frame_production);
397 void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(
398 bool impl_side_painting);
399 void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting);
401 scoped_refptr<TestNowSource> now_src_;
402 scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
403 FakeExternalBeginFrameSource* fake_external_begin_frame_source_;
404 SchedulerSettings scheduler_settings_;
405 scoped_ptr<FakeSchedulerClient> client_;
406 scoped_ptr<TestScheduler> scheduler_;
409 TEST_F(SchedulerTest, InitializeOutputSurfaceDoesNotBeginImplFrame) {
410 scheduler_settings_.use_external_begin_frame_source = true;
411 SetUpScheduler(false);
412 scheduler_->SetCanStart();
413 scheduler_->SetVisible(true);
414 scheduler_->SetCanDraw(true);
416 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_);
417 client_->Reset();
418 scheduler_->DidCreateAndInitializeOutputSurface();
419 EXPECT_NO_ACTION(client_);
422 TEST_F(SchedulerTest, SendBeginFramesToChildren) {
423 scheduler_settings_.use_external_begin_frame_source = true;
424 SetUpScheduler(true);
426 EXPECT_FALSE(client_->begin_frame_is_sent_to_children());
427 scheduler_->SetNeedsCommit();
428 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
429 EXPECT_TRUE(client_->needs_begin_frames());
431 scheduler_->SetChildrenNeedBeginFrames(true);
433 client_->Reset();
434 EXPECT_SCOPED(AdvanceFrame());
435 EXPECT_TRUE(client_->begin_frame_is_sent_to_children());
436 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
437 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
438 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
439 EXPECT_TRUE(client_->needs_begin_frames());
442 TEST_F(SchedulerTest, SendBeginFramesToChildrenWithoutCommit) {
443 scheduler_settings_.use_external_begin_frame_source = true;
444 SetUpScheduler(true);
446 EXPECT_FALSE(client_->needs_begin_frames());
447 scheduler_->SetChildrenNeedBeginFrames(true);
448 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
449 EXPECT_TRUE(client_->needs_begin_frames());
451 client_->Reset();
452 EXPECT_SCOPED(AdvanceFrame());
453 EXPECT_TRUE(client_->begin_frame_is_sent_to_children());
456 TEST_F(SchedulerTest, RequestCommit) {
457 scheduler_settings_.use_external_begin_frame_source = true;
458 SetUpScheduler(true);
460 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
461 scheduler_->SetNeedsCommit();
462 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
463 client_->Reset();
465 EXPECT_SCOPED(AdvanceFrame());
466 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
467 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
468 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
469 EXPECT_TRUE(client_->needs_begin_frames());
470 client_->Reset();
472 // If we don't swap on the deadline, we wait for the next BeginFrame.
473 task_runner().RunPendingTasks(); // Run posted deadline.
474 EXPECT_NO_ACTION(client_);
475 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
476 EXPECT_TRUE(client_->needs_begin_frames());
477 client_->Reset();
479 // NotifyReadyToCommit should trigger the commit.
480 scheduler_->NotifyBeginMainFrameStarted();
481 scheduler_->NotifyReadyToCommit();
482 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
483 EXPECT_TRUE(client_->needs_begin_frames());
484 client_->Reset();
486 // BeginImplFrame should prepare the draw.
487 EXPECT_SCOPED(AdvanceFrame());
488 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
489 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
490 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
491 EXPECT_TRUE(client_->needs_begin_frames());
492 client_->Reset();
494 // BeginImplFrame deadline should draw.
495 task_runner().RunPendingTasks(); // Run posted deadline.
496 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
497 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
498 EXPECT_TRUE(client_->needs_begin_frames());
499 client_->Reset();
501 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
502 // to avoid excessive toggles.
503 EXPECT_SCOPED(AdvanceFrame());
504 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
505 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
506 client_->Reset();
508 task_runner().RunPendingTasks(); // Run posted deadline.
509 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
510 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
511 client_->Reset();
514 TEST_F(SchedulerTest, RequestCommitAfterSetDeferCommit) {
515 scheduler_settings_.use_external_begin_frame_source = true;
516 SetUpScheduler(true);
518 scheduler_->SetDeferCommits(true);
520 scheduler_->SetNeedsCommit();
521 EXPECT_NO_ACTION(client_);
523 client_->Reset();
524 task_runner().RunPendingTasks();
525 // There are no pending tasks or actions.
526 EXPECT_NO_ACTION(client_);
527 EXPECT_FALSE(client_->needs_begin_frames());
529 client_->Reset();
530 scheduler_->SetDeferCommits(false);
531 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
533 // Start new BeginMainFrame after defer commit is off.
534 client_->Reset();
535 EXPECT_SCOPED(AdvanceFrame());
536 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
537 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
538 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
541 TEST_F(SchedulerTest, DeferCommitWithRedraw) {
542 scheduler_settings_.use_external_begin_frame_source = true;
543 SetUpScheduler(true);
545 scheduler_->SetDeferCommits(true);
547 scheduler_->SetNeedsCommit();
548 EXPECT_NO_ACTION(client_);
550 // The SetNeedsRedraw will override the SetDeferCommits(true), to allow a
551 // begin frame to be needed.
552 client_->Reset();
553 scheduler_->SetNeedsRedraw();
554 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
556 client_->Reset();
557 AdvanceFrame();
558 // BeginMainFrame is not sent during the defer commit is on.
559 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
560 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
562 client_->Reset();
563 task_runner().RunPendingTasks(); // Run posted deadline.
564 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
565 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
566 EXPECT_TRUE(client_->needs_begin_frames());
568 client_->Reset();
569 AdvanceFrame();
570 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
573 TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
574 scheduler_settings_.use_external_begin_frame_source = true;
575 SetUpScheduler(true);
577 // SetNeedsCommit should begin the frame.
578 scheduler_->SetNeedsCommit();
579 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
581 client_->Reset();
582 EXPECT_SCOPED(AdvanceFrame());
583 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
584 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
585 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
587 EXPECT_TRUE(client_->needs_begin_frames());
588 client_->Reset();
590 // Now SetNeedsCommit again. Calling here means we need a second commit.
591 scheduler_->SetNeedsCommit();
592 EXPECT_EQ(client_->num_actions_(), 0);
593 client_->Reset();
595 // Finish the first commit.
596 scheduler_->NotifyBeginMainFrameStarted();
597 scheduler_->NotifyReadyToCommit();
598 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
599 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
600 client_->Reset();
601 task_runner().RunPendingTasks(); // Run posted deadline.
602 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
603 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
604 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
606 // Because we just swapped, the Scheduler should also request the next
607 // BeginImplFrame from the OutputSurface.
608 EXPECT_TRUE(client_->needs_begin_frames());
609 client_->Reset();
610 // Since another commit is needed, the next BeginImplFrame should initiate
611 // the second commit.
612 EXPECT_SCOPED(AdvanceFrame());
613 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
614 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
615 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
616 client_->Reset();
618 // Finishing the commit before the deadline should post a new deadline task
619 // to trigger the deadline early.
620 scheduler_->NotifyBeginMainFrameStarted();
621 scheduler_->NotifyReadyToCommit();
622 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
623 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
624 client_->Reset();
625 task_runner().RunPendingTasks(); // Run posted deadline.
626 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
627 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
628 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
629 EXPECT_TRUE(client_->needs_begin_frames());
630 client_->Reset();
632 // On the next BeginImplFrame, verify we go back to a quiescent state and
633 // no longer request BeginImplFrames.
634 EXPECT_SCOPED(AdvanceFrame());
635 task_runner().RunPendingTasks(); // Run posted deadline.
636 EXPECT_FALSE(client_->needs_begin_frames());
637 client_->Reset();
640 class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient {
641 public:
642 SchedulerClientThatsetNeedsDrawInsideDraw()
643 : FakeSchedulerClient(), request_redraws_(false) {}
645 void ScheduledActionSendBeginMainFrame() override {}
647 void SetRequestRedrawsInsideDraw(bool enable) { request_redraws_ = enable; }
649 DrawResult ScheduledActionDrawAndSwapIfPossible() override {
650 // Only SetNeedsRedraw the first time this is called
651 if (request_redraws_) {
652 scheduler_->SetNeedsRedraw();
654 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
657 DrawResult ScheduledActionDrawAndSwapForced() override {
658 NOTREACHED();
659 return DRAW_SUCCESS;
662 void ScheduledActionCommit() override {}
663 void DidAnticipatedDrawTimeChange(base::TimeTicks) override {}
665 private:
666 bool request_redraws_;
669 // Tests for two different situations:
670 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside
671 // a ScheduledActionDrawAndSwap
672 // 2. the scheduler drawing twice inside a single tick
673 TEST_F(SchedulerTest, RequestRedrawInsideDraw) {
674 SchedulerClientThatsetNeedsDrawInsideDraw* client =
675 new SchedulerClientThatsetNeedsDrawInsideDraw;
676 scheduler_settings_.use_external_begin_frame_source = true;
677 SetUpScheduler(make_scoped_ptr(client).Pass(), true);
678 client->SetRequestRedrawsInsideDraw(true);
680 scheduler_->SetNeedsRedraw();
681 EXPECT_TRUE(scheduler_->RedrawPending());
682 EXPECT_TRUE(client->needs_begin_frames());
683 EXPECT_EQ(0, client->num_draws());
685 EXPECT_SCOPED(AdvanceFrame());
686 task_runner().RunPendingTasks(); // Run posted deadline.
687 EXPECT_EQ(1, client->num_draws());
688 EXPECT_TRUE(scheduler_->RedrawPending());
689 EXPECT_TRUE(client->needs_begin_frames());
691 client->SetRequestRedrawsInsideDraw(false);
693 EXPECT_SCOPED(AdvanceFrame());
694 task_runner().RunPendingTasks(); // Run posted deadline.
695 EXPECT_EQ(2, client_->num_draws());
696 EXPECT_FALSE(scheduler_->RedrawPending());
697 EXPECT_TRUE(client->needs_begin_frames());
699 // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
700 // swap.
701 EXPECT_SCOPED(AdvanceFrame());
702 task_runner().RunPendingTasks(); // Run posted deadline.
703 EXPECT_EQ(2, client->num_draws());
704 EXPECT_FALSE(scheduler_->RedrawPending());
705 EXPECT_FALSE(client->needs_begin_frames());
708 // Test that requesting redraw inside a failed draw doesn't lose the request.
709 TEST_F(SchedulerTest, RequestRedrawInsideFailedDraw) {
710 SchedulerClientThatsetNeedsDrawInsideDraw* client =
711 new SchedulerClientThatsetNeedsDrawInsideDraw;
712 scheduler_settings_.use_external_begin_frame_source = true;
713 SetUpScheduler(make_scoped_ptr(client).Pass(), true);
715 client->SetRequestRedrawsInsideDraw(true);
716 client->SetDrawWillHappen(false);
718 scheduler_->SetNeedsRedraw();
719 EXPECT_TRUE(scheduler_->RedrawPending());
720 EXPECT_TRUE(client->needs_begin_frames());
721 EXPECT_EQ(0, client->num_draws());
723 // Fail the draw.
724 EXPECT_SCOPED(AdvanceFrame());
725 task_runner().RunPendingTasks(); // Run posted deadline.
726 EXPECT_EQ(1, client->num_draws());
728 // We have a commit pending and the draw failed, and we didn't lose the redraw
729 // request.
730 EXPECT_TRUE(scheduler_->CommitPending());
731 EXPECT_TRUE(scheduler_->RedrawPending());
732 EXPECT_TRUE(client->needs_begin_frames());
734 client->SetRequestRedrawsInsideDraw(false);
736 // Fail the draw again.
737 EXPECT_SCOPED(AdvanceFrame());
738 task_runner().RunPendingTasks(); // Run posted deadline.
739 EXPECT_EQ(2, client->num_draws());
740 EXPECT_TRUE(scheduler_->CommitPending());
741 EXPECT_TRUE(scheduler_->RedrawPending());
742 EXPECT_TRUE(client->needs_begin_frames());
744 // Draw successfully.
745 client->SetDrawWillHappen(true);
746 EXPECT_SCOPED(AdvanceFrame());
747 task_runner().RunPendingTasks(); // Run posted deadline.
748 EXPECT_EQ(3, client->num_draws());
749 EXPECT_TRUE(scheduler_->CommitPending());
750 EXPECT_FALSE(scheduler_->RedrawPending());
751 EXPECT_TRUE(client->needs_begin_frames());
754 class SchedulerClientThatSetNeedsCommitInsideDraw : public FakeSchedulerClient {
755 public:
756 SchedulerClientThatSetNeedsCommitInsideDraw()
757 : set_needs_commit_on_next_draw_(false) {}
759 void ScheduledActionSendBeginMainFrame() override {}
760 DrawResult ScheduledActionDrawAndSwapIfPossible() override {
761 // Only SetNeedsCommit the first time this is called
762 if (set_needs_commit_on_next_draw_) {
763 scheduler_->SetNeedsCommit();
764 set_needs_commit_on_next_draw_ = false;
766 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
769 DrawResult ScheduledActionDrawAndSwapForced() override {
770 NOTREACHED();
771 return DRAW_SUCCESS;
774 void ScheduledActionCommit() override {}
775 void DidAnticipatedDrawTimeChange(base::TimeTicks) override {}
777 void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_ = true; }
779 private:
780 bool set_needs_commit_on_next_draw_;
783 // Tests for the scheduler infinite-looping on SetNeedsCommit requests that
784 // happen inside a ScheduledActionDrawAndSwap
785 TEST_F(SchedulerTest, RequestCommitInsideDraw) {
786 SchedulerClientThatSetNeedsCommitInsideDraw* client =
787 new SchedulerClientThatSetNeedsCommitInsideDraw;
789 scheduler_settings_.use_external_begin_frame_source = true;
790 SetUpScheduler(make_scoped_ptr(client).Pass(), true);
792 EXPECT_FALSE(client->needs_begin_frames());
793 scheduler_->SetNeedsRedraw();
794 EXPECT_TRUE(scheduler_->RedrawPending());
795 EXPECT_EQ(0, client->num_draws());
796 EXPECT_TRUE(client->needs_begin_frames());
798 client->SetNeedsCommitOnNextDraw();
799 EXPECT_SCOPED(AdvanceFrame());
800 client->SetNeedsCommitOnNextDraw();
801 task_runner().RunPendingTasks(); // Run posted deadline.
802 EXPECT_EQ(1, client->num_draws());
803 EXPECT_TRUE(scheduler_->CommitPending());
804 EXPECT_TRUE(client->needs_begin_frames());
805 scheduler_->NotifyBeginMainFrameStarted();
806 scheduler_->NotifyReadyToCommit();
808 EXPECT_SCOPED(AdvanceFrame());
809 task_runner().RunPendingTasks(); // Run posted deadline.
810 EXPECT_EQ(2, client->num_draws());
812 EXPECT_FALSE(scheduler_->RedrawPending());
813 EXPECT_FALSE(scheduler_->CommitPending());
814 EXPECT_TRUE(client->needs_begin_frames());
816 // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
817 // swap.
818 EXPECT_SCOPED(AdvanceFrame());
819 task_runner().RunPendingTasks(); // Run posted deadline.
820 EXPECT_EQ(2, client->num_draws());
821 EXPECT_FALSE(scheduler_->RedrawPending());
822 EXPECT_FALSE(scheduler_->CommitPending());
823 EXPECT_FALSE(client->needs_begin_frames());
826 // Tests that when a draw fails then the pending commit should not be dropped.
827 TEST_F(SchedulerTest, RequestCommitInsideFailedDraw) {
828 SchedulerClientThatsetNeedsDrawInsideDraw* client =
829 new SchedulerClientThatsetNeedsDrawInsideDraw;
830 scheduler_settings_.use_external_begin_frame_source = true;
831 SetUpScheduler(make_scoped_ptr(client).Pass(), true);
833 client->SetDrawWillHappen(false);
835 scheduler_->SetNeedsRedraw();
836 EXPECT_TRUE(scheduler_->RedrawPending());
837 EXPECT_TRUE(client->needs_begin_frames());
838 EXPECT_EQ(0, client->num_draws());
840 // Fail the draw.
841 EXPECT_SCOPED(AdvanceFrame());
842 task_runner().RunPendingTasks(); // Run posted deadline.
843 EXPECT_EQ(1, client->num_draws());
845 // We have a commit pending and the draw failed, and we didn't lose the commit
846 // request.
847 EXPECT_TRUE(scheduler_->CommitPending());
848 EXPECT_TRUE(scheduler_->RedrawPending());
849 EXPECT_TRUE(client->needs_begin_frames());
851 // Fail the draw again.
852 EXPECT_SCOPED(AdvanceFrame());
854 task_runner().RunPendingTasks(); // Run posted deadline.
855 EXPECT_EQ(2, client->num_draws());
856 EXPECT_TRUE(scheduler_->CommitPending());
857 EXPECT_TRUE(scheduler_->RedrawPending());
858 EXPECT_TRUE(client->needs_begin_frames());
860 // Draw successfully.
861 client->SetDrawWillHappen(true);
862 EXPECT_SCOPED(AdvanceFrame());
863 task_runner().RunPendingTasks(); // Run posted deadline.
864 EXPECT_EQ(3, client->num_draws());
865 EXPECT_TRUE(scheduler_->CommitPending());
866 EXPECT_FALSE(scheduler_->RedrawPending());
867 EXPECT_TRUE(client->needs_begin_frames());
870 TEST_F(SchedulerTest, NoSwapWhenDrawFails) {
871 SchedulerClientThatSetNeedsCommitInsideDraw* client =
872 new SchedulerClientThatSetNeedsCommitInsideDraw;
873 scheduler_settings_.use_external_begin_frame_source = true;
874 SetUpScheduler(make_scoped_ptr(client).Pass(), true);
876 scheduler_->SetNeedsRedraw();
877 EXPECT_TRUE(scheduler_->RedrawPending());
878 EXPECT_TRUE(client->needs_begin_frames());
879 EXPECT_EQ(0, client->num_draws());
881 // Draw successfully, this starts a new frame.
882 client->SetNeedsCommitOnNextDraw();
883 EXPECT_SCOPED(AdvanceFrame());
884 task_runner().RunPendingTasks(); // Run posted deadline.
885 EXPECT_EQ(1, client->num_draws());
887 scheduler_->SetNeedsRedraw();
888 EXPECT_TRUE(scheduler_->RedrawPending());
889 EXPECT_TRUE(client->needs_begin_frames());
891 // Fail to draw, this should not start a frame.
892 client->SetDrawWillHappen(false);
893 client->SetNeedsCommitOnNextDraw();
894 EXPECT_SCOPED(AdvanceFrame());
895 task_runner().RunPendingTasks(); // Run posted deadline.
896 EXPECT_EQ(2, client->num_draws());
899 class SchedulerClientNeedsPrepareTilesInDraw : public FakeSchedulerClient {
900 public:
901 DrawResult ScheduledActionDrawAndSwapIfPossible() override {
902 scheduler_->SetNeedsPrepareTiles();
903 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
907 // Test prepare tiles is independant of draws.
908 TEST_F(SchedulerTest, PrepareTiles) {
909 SchedulerClientNeedsPrepareTilesInDraw* client =
910 new SchedulerClientNeedsPrepareTilesInDraw;
911 scheduler_settings_.use_external_begin_frame_source = true;
912 SetUpScheduler(make_scoped_ptr(client).Pass(), true);
914 // Request both draw and prepare tiles. PrepareTiles shouldn't
915 // be trigged until BeginImplFrame.
916 client->Reset();
917 scheduler_->SetNeedsPrepareTiles();
918 scheduler_->SetNeedsRedraw();
919 EXPECT_TRUE(scheduler_->RedrawPending());
920 EXPECT_TRUE(scheduler_->PrepareTilesPending());
921 EXPECT_TRUE(client->needs_begin_frames());
922 EXPECT_EQ(0, client->num_draws());
923 EXPECT_FALSE(client->HasAction("ScheduledActionPrepareTiles"));
924 EXPECT_FALSE(client->HasAction("ScheduledActionDrawAndSwapIfPossible"));
926 // We have no immediate actions to perform, so the BeginImplFrame should post
927 // the deadline task.
928 client->Reset();
929 EXPECT_SCOPED(AdvanceFrame());
930 EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
931 EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
932 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
934 // On the deadline, he actions should have occured in the right order.
935 client->Reset();
936 task_runner().RunPendingTasks(); // Run posted deadline.
937 EXPECT_EQ(1, client->num_draws());
938 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible"));
939 EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles"));
940 EXPECT_LT(client->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
941 client->ActionIndex("ScheduledActionPrepareTiles"));
942 EXPECT_FALSE(scheduler_->RedrawPending());
943 EXPECT_FALSE(scheduler_->PrepareTilesPending());
944 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
946 // Request a draw. We don't need a PrepareTiles yet.
947 client->Reset();
948 scheduler_->SetNeedsRedraw();
949 EXPECT_TRUE(scheduler_->RedrawPending());
950 EXPECT_FALSE(scheduler_->PrepareTilesPending());
951 EXPECT_TRUE(client->needs_begin_frames());
952 EXPECT_EQ(0, client->num_draws());
954 // We have no immediate actions to perform, so the BeginImplFrame should post
955 // the deadline task.
956 client->Reset();
957 EXPECT_SCOPED(AdvanceFrame());
958 EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
959 EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
960 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
962 // Draw. The draw will trigger SetNeedsPrepareTiles, and
963 // then the PrepareTiles action will be triggered after the Draw.
964 // Afterwards, neither a draw nor PrepareTiles are pending.
965 client->Reset();
966 task_runner().RunPendingTasks(); // Run posted deadline.
967 EXPECT_EQ(1, client->num_draws());
968 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible"));
969 EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles"));
970 EXPECT_LT(client->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
971 client->ActionIndex("ScheduledActionPrepareTiles"));
972 EXPECT_FALSE(scheduler_->RedrawPending());
973 EXPECT_FALSE(scheduler_->PrepareTilesPending());
974 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
976 // We need a BeginImplFrame where we don't swap to go idle.
977 client->Reset();
978 EXPECT_SCOPED(AdvanceFrame());
979 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
980 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
981 client->Reset();
982 task_runner().RunPendingTasks(); // Run posted deadline.
983 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
984 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
985 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
986 EXPECT_EQ(0, client->num_draws());
988 // Now trigger a PrepareTiles outside of a draw. We will then need
989 // a begin-frame for the PrepareTiles, but we don't need a draw.
990 client->Reset();
991 EXPECT_FALSE(client->needs_begin_frames());
992 scheduler_->SetNeedsPrepareTiles();
993 EXPECT_TRUE(client->needs_begin_frames());
994 EXPECT_TRUE(scheduler_->PrepareTilesPending());
995 EXPECT_FALSE(scheduler_->RedrawPending());
997 // BeginImplFrame. There will be no draw, only PrepareTiles.
998 client->Reset();
999 EXPECT_SCOPED(AdvanceFrame());
1000 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
1001 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1002 client->Reset();
1003 task_runner().RunPendingTasks(); // Run posted deadline.
1004 EXPECT_EQ(0, client->num_draws());
1005 EXPECT_FALSE(client->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1006 EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles"));
1007 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1010 // Test that PrepareTiles only happens once per frame. If an external caller
1011 // initiates it, then the state machine should not PrepareTiles on that frame.
1012 TEST_F(SchedulerTest, PrepareTilesOncePerFrame) {
1013 scheduler_settings_.use_external_begin_frame_source = true;
1014 SetUpScheduler(true);
1016 // If DidPrepareTiles during a frame, then PrepareTiles should not occur
1017 // again.
1018 scheduler_->SetNeedsPrepareTiles();
1019 scheduler_->SetNeedsRedraw();
1020 client_->Reset();
1021 EXPECT_SCOPED(AdvanceFrame());
1022 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1023 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1024 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1026 EXPECT_TRUE(scheduler_->PrepareTilesPending());
1027 scheduler_->DidPrepareTiles(); // An explicit PrepareTiles.
1028 EXPECT_FALSE(scheduler_->PrepareTilesPending());
1030 client_->Reset();
1031 task_runner().RunPendingTasks(); // Run posted deadline.
1032 EXPECT_EQ(1, client_->num_draws());
1033 EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1034 EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles"));
1035 EXPECT_FALSE(scheduler_->RedrawPending());
1036 EXPECT_FALSE(scheduler_->PrepareTilesPending());
1037 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1039 // Next frame without DidPrepareTiles should PrepareTiles with draw.
1040 scheduler_->SetNeedsPrepareTiles();
1041 scheduler_->SetNeedsRedraw();
1042 client_->Reset();
1043 EXPECT_SCOPED(AdvanceFrame());
1044 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1045 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1046 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1048 client_->Reset();
1049 task_runner().RunPendingTasks(); // Run posted deadline.
1050 EXPECT_EQ(1, client_->num_draws());
1051 EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1052 EXPECT_TRUE(client_->HasAction("ScheduledActionPrepareTiles"));
1053 EXPECT_LT(client_->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
1054 client_->ActionIndex("ScheduledActionPrepareTiles"));
1055 EXPECT_FALSE(scheduler_->RedrawPending());
1056 EXPECT_FALSE(scheduler_->PrepareTilesPending());
1057 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1058 scheduler_->DidPrepareTiles(); // Corresponds to ScheduledActionPrepareTiles
1060 // If we get another DidPrepareTiles within the same frame, we should
1061 // not PrepareTiles on the next frame.
1062 scheduler_->DidPrepareTiles(); // An explicit PrepareTiles.
1063 scheduler_->SetNeedsPrepareTiles();
1064 scheduler_->SetNeedsRedraw();
1065 client_->Reset();
1066 EXPECT_SCOPED(AdvanceFrame());
1067 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1068 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1069 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1071 EXPECT_TRUE(scheduler_->PrepareTilesPending());
1073 client_->Reset();
1074 task_runner().RunPendingTasks(); // Run posted deadline.
1075 EXPECT_EQ(1, client_->num_draws());
1076 EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1077 EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles"));
1078 EXPECT_FALSE(scheduler_->RedrawPending());
1079 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1081 // If we get another DidPrepareTiles, we should not PrepareTiles on the next
1082 // frame. This verifies we don't alternate calling PrepareTiles once and
1083 // twice.
1084 EXPECT_TRUE(scheduler_->PrepareTilesPending());
1085 scheduler_->DidPrepareTiles(); // An explicit PrepareTiles.
1086 EXPECT_FALSE(scheduler_->PrepareTilesPending());
1087 scheduler_->SetNeedsPrepareTiles();
1088 scheduler_->SetNeedsRedraw();
1089 client_->Reset();
1090 EXPECT_SCOPED(AdvanceFrame());
1091 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1092 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1093 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1095 EXPECT_TRUE(scheduler_->PrepareTilesPending());
1097 client_->Reset();
1098 task_runner().RunPendingTasks(); // Run posted deadline.
1099 EXPECT_EQ(1, client_->num_draws());
1100 EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1101 EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles"));
1102 EXPECT_FALSE(scheduler_->RedrawPending());
1103 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1105 // Next frame without DidPrepareTiles should PrepareTiles with draw.
1106 scheduler_->SetNeedsPrepareTiles();
1107 scheduler_->SetNeedsRedraw();
1108 client_->Reset();
1109 EXPECT_SCOPED(AdvanceFrame());
1110 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1111 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1112 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1114 client_->Reset();
1115 task_runner().RunPendingTasks(); // Run posted deadline.
1116 EXPECT_EQ(1, client_->num_draws());
1117 EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1118 EXPECT_TRUE(client_->HasAction("ScheduledActionPrepareTiles"));
1119 EXPECT_LT(client_->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
1120 client_->ActionIndex("ScheduledActionPrepareTiles"));
1121 EXPECT_FALSE(scheduler_->RedrawPending());
1122 EXPECT_FALSE(scheduler_->PrepareTilesPending());
1123 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1124 scheduler_->DidPrepareTiles(); // Corresponds to ScheduledActionPrepareTiles
1127 TEST_F(SchedulerTest, TriggerBeginFrameDeadlineEarly) {
1128 SchedulerClientNeedsPrepareTilesInDraw* client =
1129 new SchedulerClientNeedsPrepareTilesInDraw;
1130 scheduler_settings_.use_external_begin_frame_source = true;
1131 SetUpScheduler(make_scoped_ptr(client).Pass(), true);
1133 scheduler_->SetNeedsRedraw();
1134 EXPECT_SCOPED(AdvanceFrame());
1136 // The deadline should be zero since there is no work other than drawing
1137 // pending.
1138 EXPECT_EQ(base::TimeTicks(), client->posted_begin_impl_frame_deadline());
1141 TEST_F(SchedulerTest, WaitForReadyToDrawDoNotPostDeadline) {
1142 SchedulerClientNeedsPrepareTilesInDraw* client =
1143 new SchedulerClientNeedsPrepareTilesInDraw;
1144 scheduler_settings_.use_external_begin_frame_source = true;
1145 scheduler_settings_.impl_side_painting = true;
1146 SetUpScheduler(make_scoped_ptr(client).Pass(), true);
1148 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1149 scheduler_->SetNeedsCommit();
1150 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
1151 client_->Reset();
1153 // Begin new frame.
1154 EXPECT_SCOPED(AdvanceFrame());
1155 scheduler_->NotifyBeginMainFrameStarted();
1156 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1157 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1159 client_->Reset();
1160 scheduler_->NotifyReadyToCommit();
1161 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
1163 client_->Reset();
1164 scheduler_->NotifyReadyToActivate();
1165 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
1167 // Set scheduler to wait for ready to draw. Schedule won't post deadline in
1168 // the mode.
1169 scheduler_->SetWaitForReadyToDraw();
1170 client_->Reset();
1171 task_runner().RunPendingTasks(); // Try to run posted deadline.
1172 // There is no posted deadline.
1173 EXPECT_NO_ACTION(client_);
1175 // Scheduler received ready to draw signal, and posted deadline.
1176 scheduler_->NotifyReadyToDraw();
1177 client_->Reset();
1178 task_runner().RunPendingTasks(); // Run posted deadline.
1179 EXPECT_EQ(1, client_->num_draws());
1180 EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1183 TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostOutputSurface) {
1184 SchedulerClientNeedsPrepareTilesInDraw* client =
1185 new SchedulerClientNeedsPrepareTilesInDraw;
1186 scheduler_settings_.use_external_begin_frame_source = true;
1187 scheduler_settings_.impl_side_painting = true;
1188 SetUpScheduler(make_scoped_ptr(client).Pass(), true);
1190 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1191 scheduler_->SetNeedsCommit();
1192 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
1193 client_->Reset();
1195 // Begin new frame.
1196 EXPECT_SCOPED(AdvanceFrame());
1197 scheduler_->NotifyBeginMainFrameStarted();
1198 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1199 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1201 client_->Reset();
1202 scheduler_->NotifyReadyToCommit();
1203 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
1205 client_->Reset();
1206 scheduler_->NotifyReadyToActivate();
1207 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
1209 // Set scheduler to wait for ready to draw. Schedule won't post deadline in
1210 // the mode.
1211 scheduler_->SetWaitForReadyToDraw();
1212 client_->Reset();
1213 task_runner().RunPendingTasks(); // Try to run posted deadline.
1214 // There is no posted deadline.
1215 EXPECT_NO_ACTION(client_);
1217 // Scheduler loses output surface, and stops waiting for ready to draw signal.
1218 client_->Reset();
1219 scheduler_->DidLoseOutputSurface();
1220 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1221 task_runner().RunPendingTasks(); // Run posted deadline.
1222 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
1223 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
1224 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
1227 class SchedulerClientWithFixedEstimates : public FakeSchedulerClient {
1228 public:
1229 SchedulerClientWithFixedEstimates(
1230 base::TimeDelta draw_duration,
1231 base::TimeDelta begin_main_frame_to_commit_duration,
1232 base::TimeDelta commit_to_activate_duration)
1233 : draw_duration_(draw_duration),
1234 begin_main_frame_to_commit_duration_(
1235 begin_main_frame_to_commit_duration),
1236 commit_to_activate_duration_(commit_to_activate_duration) {}
1238 base::TimeDelta DrawDurationEstimate() override { return draw_duration_; }
1239 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override {
1240 return begin_main_frame_to_commit_duration_;
1242 base::TimeDelta CommitToActivateDurationEstimate() override {
1243 return commit_to_activate_duration_;
1246 private:
1247 base::TimeDelta draw_duration_;
1248 base::TimeDelta begin_main_frame_to_commit_duration_;
1249 base::TimeDelta commit_to_activate_duration_;
1252 void SchedulerTest::MainFrameInHighLatencyMode(
1253 int64 begin_main_frame_to_commit_estimate_in_ms,
1254 int64 commit_to_activate_estimate_in_ms,
1255 bool impl_latency_takes_priority,
1256 bool should_send_begin_main_frame) {
1257 // Set up client with specified estimates (draw duration is set to 1).
1258 SchedulerClientWithFixedEstimates* client =
1259 new SchedulerClientWithFixedEstimates(
1260 base::TimeDelta::FromMilliseconds(1),
1261 base::TimeDelta::FromMilliseconds(
1262 begin_main_frame_to_commit_estimate_in_ms),
1263 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms));
1265 scheduler_settings_.use_external_begin_frame_source = true;
1266 SetUpScheduler(make_scoped_ptr(client).Pass(), true);
1268 scheduler_->SetImplLatencyTakesPriority(impl_latency_takes_priority);
1270 // Impl thread hits deadline before commit finishes.
1271 scheduler_->SetNeedsCommit();
1272 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1273 EXPECT_SCOPED(AdvanceFrame());
1274 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1275 task_runner().RunPendingTasks(); // Run posted deadline.
1276 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1277 scheduler_->NotifyBeginMainFrameStarted();
1278 scheduler_->NotifyReadyToCommit();
1279 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1280 EXPECT_TRUE(client->HasAction("ScheduledActionSendBeginMainFrame"));
1282 client->Reset();
1283 scheduler_->SetNeedsCommit();
1284 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1285 EXPECT_SCOPED(AdvanceFrame());
1286 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1287 task_runner().RunPendingTasks(); // Run posted deadline.
1288 EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(),
1289 should_send_begin_main_frame);
1290 EXPECT_EQ(client->HasAction("ScheduledActionSendBeginMainFrame"),
1291 should_send_begin_main_frame);
1294 TEST_F(SchedulerTest,
1295 SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) {
1296 // Set up client so that estimates indicate that we can commit and activate
1297 // before the deadline (~8ms by default).
1298 MainFrameInHighLatencyMode(1, 1, false, false);
1301 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) {
1302 // Set up client so that estimates indicate that the commit cannot finish
1303 // before the deadline (~8ms by default).
1304 MainFrameInHighLatencyMode(10, 1, false, true);
1307 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) {
1308 // Set up client so that estimates indicate that the activate cannot finish
1309 // before the deadline (~8ms by default).
1310 MainFrameInHighLatencyMode(1, 10, false, true);
1313 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) {
1314 // Set up client so that estimates indicate that we can commit and activate
1315 // before the deadline (~8ms by default), but also enable impl latency takes
1316 // priority mode.
1317 MainFrameInHighLatencyMode(1, 1, true, true);
1320 TEST_F(SchedulerTest, PollForCommitCompletion) {
1321 // Since we are simulating a long commit, set up a client with draw duration
1322 // estimates that prevent skipping main frames to get to low latency mode.
1323 SchedulerClientWithFixedEstimates* client =
1324 new SchedulerClientWithFixedEstimates(
1325 base::TimeDelta::FromMilliseconds(1),
1326 base::TimeDelta::FromMilliseconds(32),
1327 base::TimeDelta::FromMilliseconds(32));
1328 scheduler_settings_.use_external_begin_frame_source = true;
1329 SetUpScheduler(make_scoped_ptr(client).Pass(), true);
1331 client->set_log_anticipated_draw_time_change(true);
1333 BeginFrameArgs frame_args =
1334 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
1335 frame_args.interval = base::TimeDelta::FromMilliseconds(1000);
1337 // At this point, we've drawn a frame. Start another commit, but hold off on
1338 // the NotifyReadyToCommit for now.
1339 EXPECT_FALSE(scheduler_->CommitPending());
1340 scheduler_->SetNeedsCommit();
1341 fake_external_begin_frame_source()->TestOnBeginFrame(frame_args);
1342 EXPECT_TRUE(scheduler_->CommitPending());
1344 // Draw and swap the frame, but don't ack the swap to simulate the Browser
1345 // blocking on the renderer.
1346 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1347 task_runner().RunPendingTasks(); // Run posted deadline.
1348 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1349 scheduler_->DidSwapBuffers();
1351 // Spin the event loop a few times and make sure we get more
1352 // DidAnticipateDrawTimeChange calls every time.
1353 int actions_so_far = client->num_actions_();
1355 // Does three iterations to make sure that the timer is properly repeating.
1356 for (int i = 0; i < 3; ++i) {
1357 EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
1358 task_runner().DelayToNextTaskTime().InMicroseconds())
1359 << scheduler_->AsValue()->ToString();
1360 task_runner().RunPendingTasks();
1361 EXPECT_GT(client->num_actions_(), actions_so_far);
1362 EXPECT_STREQ(client->Action(client->num_actions_() - 1),
1363 "DidAnticipatedDrawTimeChange");
1364 actions_so_far = client->num_actions_();
1367 // Do the same thing after BeginMainFrame starts but still before activation.
1368 scheduler_->NotifyBeginMainFrameStarted();
1369 for (int i = 0; i < 3; ++i) {
1370 EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
1371 task_runner().DelayToNextTaskTime().InMicroseconds())
1372 << scheduler_->AsValue()->ToString();
1373 task_runner().RunPendingTasks();
1374 EXPECT_GT(client->num_actions_(), actions_so_far);
1375 EXPECT_STREQ(client->Action(client->num_actions_() - 1),
1376 "DidAnticipatedDrawTimeChange");
1377 actions_so_far = client->num_actions_();
1381 TEST_F(SchedulerTest, BeginRetroFrame) {
1382 scheduler_settings_.use_external_begin_frame_source = true;
1383 SetUpScheduler(true);
1385 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1386 scheduler_->SetNeedsCommit();
1387 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
1388 client_->Reset();
1390 // Create a BeginFrame with a long deadline to avoid race conditions.
1391 // This is the first BeginFrame, which will be handled immediately.
1392 BeginFrameArgs args =
1393 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
1394 args.deadline += base::TimeDelta::FromHours(1);
1395 fake_external_begin_frame_source()->TestOnBeginFrame(args);
1396 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1397 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1398 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1399 EXPECT_TRUE(client_->needs_begin_frames());
1400 client_->Reset();
1402 // Queue BeginFrames while we are still handling the previous BeginFrame.
1403 args.frame_time += base::TimeDelta::FromSeconds(1);
1404 fake_external_begin_frame_source()->TestOnBeginFrame(args);
1405 args.frame_time += base::TimeDelta::FromSeconds(1);
1406 fake_external_begin_frame_source()->TestOnBeginFrame(args);
1408 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
1409 task_runner().RunPendingTasks(); // Run posted deadline.
1410 EXPECT_NO_ACTION(client_);
1411 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1412 EXPECT_TRUE(client_->needs_begin_frames());
1413 client_->Reset();
1415 // NotifyReadyToCommit should trigger the commit.
1416 scheduler_->NotifyBeginMainFrameStarted();
1417 scheduler_->NotifyReadyToCommit();
1418 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
1419 EXPECT_TRUE(client_->needs_begin_frames());
1420 client_->Reset();
1422 // BeginImplFrame should prepare the draw.
1423 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
1424 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1425 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1426 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1427 EXPECT_TRUE(client_->needs_begin_frames());
1428 client_->Reset();
1430 // BeginImplFrame deadline should draw.
1431 task_runner().RunPendingTasks(); // Run posted deadline.
1432 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
1433 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1434 EXPECT_TRUE(client_->needs_begin_frames());
1435 client_->Reset();
1437 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
1438 // to avoid excessive toggles.
1439 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
1440 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
1441 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1442 client_->Reset();
1444 task_runner().RunPendingTasks(); // Run posted deadline.
1445 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
1446 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
1447 client_->Reset();
1450 TEST_F(SchedulerTest, BeginRetroFrame_SwapThrottled) {
1451 scheduler_settings_.use_external_begin_frame_source = true;
1452 SetUpScheduler(true);
1454 scheduler_->SetEstimatedParentDrawTime(base::TimeDelta::FromMicroseconds(1));
1456 // To test swap ack throttling, this test disables automatic swap acks.
1457 scheduler_->SetMaxSwapsPending(1);
1458 client_->SetAutomaticSwapAck(false);
1460 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1461 client_->Reset();
1462 scheduler_->SetNeedsCommit();
1463 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
1464 client_->Reset();
1466 EXPECT_SCOPED(AdvanceFrame());
1467 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1468 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1469 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1470 EXPECT_TRUE(client_->needs_begin_frames());
1471 client_->Reset();
1473 // Queue BeginFrame while we are still handling the previous BeginFrame.
1474 SendNextBeginFrame();
1475 EXPECT_NO_ACTION(client_);
1476 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1477 EXPECT_TRUE(client_->needs_begin_frames());
1478 client_->Reset();
1480 // NotifyReadyToCommit should trigger the pending commit and draw.
1481 scheduler_->NotifyBeginMainFrameStarted();
1482 scheduler_->NotifyReadyToCommit();
1483 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
1484 EXPECT_TRUE(client_->needs_begin_frames());
1485 client_->Reset();
1487 // Swapping will put us into a swap throttled state.
1488 // Run posted deadline.
1489 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1490 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
1491 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
1492 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1493 EXPECT_TRUE(client_->needs_begin_frames());
1494 client_->Reset();
1496 // While swap throttled, BeginRetroFrames should trigger BeginImplFrames
1497 // but not a BeginMainFrame or draw.
1498 scheduler_->SetNeedsCommit();
1499 scheduler_->SetNeedsRedraw();
1500 // Run posted BeginRetroFrame.
1501 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false));
1502 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1503 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1504 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1505 EXPECT_TRUE(client_->needs_begin_frames());
1506 client_->Reset();
1508 // Let time pass sufficiently beyond the regular deadline but not beyond the
1509 // late deadline.
1510 now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() -
1511 base::TimeDelta::FromMicroseconds(1));
1512 task_runner().RunUntilTime(now_src()->Now());
1513 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1515 // Take us out of a swap throttled state.
1516 scheduler_->DidSwapBuffersComplete();
1517 EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_);
1518 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1519 EXPECT_TRUE(client_->needs_begin_frames());
1520 client_->Reset();
1522 // Verify that the deadline was rescheduled.
1523 task_runner().RunUntilTime(now_src()->Now());
1524 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
1525 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1526 EXPECT_TRUE(client_->needs_begin_frames());
1527 client_->Reset();
1530 TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) {
1531 scheduler_settings_.use_external_begin_frame_source = true;
1532 SetUpScheduler(true);
1534 scheduler_->SetNeedsCommit();
1535 EXPECT_TRUE(client_->needs_begin_frames());
1536 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
1538 client_->Reset();
1539 EXPECT_SCOPED(AdvanceFrame());
1540 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1541 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1542 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1544 client_->Reset();
1545 scheduler_->NotifyBeginMainFrameStarted();
1547 client_->Reset();
1548 SendNextBeginFrame();
1549 // This BeginFrame is queued up as a retro frame.
1550 EXPECT_NO_ACTION(client_);
1551 // The previous deadline is still pending.
1552 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1554 client_->Reset();
1555 // This commit should schedule the (previous) deadline to trigger immediately.
1556 scheduler_->NotifyReadyToCommit();
1557 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
1559 client_->Reset();
1560 // The deadline task should trigger causing a draw.
1561 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1562 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1563 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
1564 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
1566 // Keep animating.
1567 client_->Reset();
1568 scheduler_->SetNeedsAnimate();
1569 scheduler_->SetNeedsRedraw();
1570 EXPECT_NO_ACTION(client_);
1572 // Let's advance sufficiently past the next frame's deadline.
1573 now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() -
1574 BeginFrameArgs::DefaultEstimatedParentDrawTime() +
1575 base::TimeDelta::FromMicroseconds(1));
1577 // The retro frame hasn't expired yet.
1578 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false));
1579 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1580 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1581 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1583 // This is an immediate deadline case.
1584 client_->Reset();
1585 task_runner().RunPendingTasks();
1586 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1587 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
1590 TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) {
1591 scheduler_settings_.use_external_begin_frame_source = true;
1592 SetUpScheduler(true);
1594 scheduler_->SetNeedsCommit();
1595 EXPECT_TRUE(client_->needs_begin_frames());
1596 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
1598 client_->Reset();
1599 EXPECT_SCOPED(AdvanceFrame());
1600 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1601 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1602 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1604 client_->Reset();
1605 scheduler_->NotifyBeginMainFrameStarted();
1607 client_->Reset();
1608 SendNextBeginFrame();
1609 // This BeginFrame is queued up as a retro frame.
1610 EXPECT_NO_ACTION(client_);
1611 // The previous deadline is still pending.
1612 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1614 client_->Reset();
1615 // This commit should schedule the (previous) deadline to trigger immediately.
1616 scheduler_->NotifyReadyToCommit();
1617 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
1619 client_->Reset();
1620 // The deadline task should trigger causing a draw.
1621 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1622 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1623 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
1624 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
1626 // Keep animating.
1627 client_->Reset();
1628 scheduler_->SetNeedsAnimate();
1629 scheduler_->SetNeedsRedraw();
1630 EXPECT_NO_ACTION(client_);
1632 // Let's advance sufficiently past the next frame's deadline.
1633 now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() +
1634 base::TimeDelta::FromMicroseconds(1));
1636 // The retro frame should've expired.
1637 EXPECT_NO_ACTION(client_);
1640 void SchedulerTest::BeginFramesNotFromClient(
1641 bool use_external_begin_frame_source,
1642 bool throttle_frame_production) {
1643 scheduler_settings_.use_external_begin_frame_source =
1644 use_external_begin_frame_source;
1645 scheduler_settings_.throttle_frame_production = throttle_frame_production;
1646 SetUpScheduler(true);
1648 // SetNeedsCommit should begin the frame on the next BeginImplFrame
1649 // without calling SetNeedsBeginFrame.
1650 scheduler_->SetNeedsCommit();
1651 EXPECT_NO_ACTION(client_);
1652 client_->Reset();
1654 // When the client-driven BeginFrame are disabled, the scheduler posts it's
1655 // own BeginFrame tasks.
1656 task_runner().RunPendingTasks(); // Run posted BeginFrame.
1657 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1658 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1659 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1660 client_->Reset();
1662 // If we don't swap on the deadline, we wait for the next BeginFrame.
1663 task_runner().RunPendingTasks(); // Run posted deadline.
1664 EXPECT_NO_ACTION(client_);
1665 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1666 client_->Reset();
1668 // NotifyReadyToCommit should trigger the commit.
1669 scheduler_->NotifyBeginMainFrameStarted();
1670 scheduler_->NotifyReadyToCommit();
1671 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
1672 client_->Reset();
1674 // BeginImplFrame should prepare the draw.
1675 task_runner().RunPendingTasks(); // Run posted BeginFrame.
1676 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1677 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1678 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1679 client_->Reset();
1681 // BeginImplFrame deadline should draw.
1682 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1683 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
1684 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1685 client_->Reset();
1687 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
1688 // to avoid excessive toggles.
1689 task_runner().RunPendingTasks(); // Run posted BeginFrame.
1690 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
1691 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1692 client_->Reset();
1694 // Make sure SetNeedsBeginFrame isn't called on the client
1695 // when the BeginFrame is no longer needed.
1696 task_runner().RunPendingTasks(); // Run posted deadline.
1697 EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_);
1698 client_->Reset();
1701 TEST_F(SchedulerTest, SyntheticBeginFrames) {
1702 bool use_external_begin_frame_source = false;
1703 bool throttle_frame_production = true;
1704 BeginFramesNotFromClient(use_external_begin_frame_source,
1705 throttle_frame_production);
1708 TEST_F(SchedulerTest, VSyncThrottlingDisabled) {
1709 bool use_external_begin_frame_source = true;
1710 bool throttle_frame_production = false;
1711 BeginFramesNotFromClient(use_external_begin_frame_source,
1712 throttle_frame_production);
1715 TEST_F(SchedulerTest, SyntheticBeginFrames_And_VSyncThrottlingDisabled) {
1716 bool use_external_begin_frame_source = false;
1717 bool throttle_frame_production = false;
1718 BeginFramesNotFromClient(use_external_begin_frame_source,
1719 throttle_frame_production);
1722 void SchedulerTest::BeginFramesNotFromClient_SwapThrottled(
1723 bool use_external_begin_frame_source,
1724 bool throttle_frame_production) {
1725 scheduler_settings_.use_external_begin_frame_source =
1726 use_external_begin_frame_source;
1727 scheduler_settings_.throttle_frame_production = throttle_frame_production;
1728 SetUpScheduler(true);
1730 scheduler_->SetEstimatedParentDrawTime(base::TimeDelta::FromMicroseconds(1));
1732 // To test swap ack throttling, this test disables automatic swap acks.
1733 scheduler_->SetMaxSwapsPending(1);
1734 client_->SetAutomaticSwapAck(false);
1736 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1737 client_->Reset();
1738 scheduler_->SetNeedsCommit();
1739 EXPECT_NO_ACTION(client_);
1740 client_->Reset();
1742 // Trigger the first BeginImplFrame and BeginMainFrame
1743 EXPECT_SCOPED(AdvanceFrame());
1744 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1745 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1746 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1747 client_->Reset();
1749 // NotifyReadyToCommit should trigger the pending commit and draw.
1750 scheduler_->NotifyBeginMainFrameStarted();
1751 scheduler_->NotifyReadyToCommit();
1752 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
1753 client_->Reset();
1755 // Swapping will put us into a swap throttled state.
1756 // Run posted deadline.
1757 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1758 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
1759 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
1760 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1761 client_->Reset();
1763 // While swap throttled, BeginFrames should trigger BeginImplFrames,
1764 // but not a BeginMainFrame or draw.
1765 scheduler_->SetNeedsCommit();
1766 scheduler_->SetNeedsRedraw();
1767 EXPECT_SCOPED(AdvanceFrame()); // Run posted BeginFrame.
1768 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1769 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1770 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1771 client_->Reset();
1773 // Let time pass sufficiently beyond the regular deadline but not beyond the
1774 // late deadline.
1775 now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() -
1776 base::TimeDelta::FromMicroseconds(1));
1777 task_runner().RunUntilTime(now_src()->Now());
1778 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1780 // Take us out of a swap throttled state.
1781 scheduler_->DidSwapBuffersComplete();
1782 EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_);
1783 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1784 client_->Reset();
1786 // Verify that the deadline was rescheduled.
1787 // We can't use RunUntilTime(now) here because the next frame is also
1788 // scheduled if throttle_frame_production = false.
1789 base::TimeTicks before_deadline = now_src()->Now();
1790 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1791 base::TimeTicks after_deadline = now_src()->Now();
1792 EXPECT_EQ(after_deadline, before_deadline);
1793 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1794 client_->Reset();
1797 TEST_F(SchedulerTest, SyntheticBeginFrames_SwapThrottled) {
1798 bool use_external_begin_frame_source = false;
1799 bool throttle_frame_production = true;
1800 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source,
1801 throttle_frame_production);
1804 TEST_F(SchedulerTest, VSyncThrottlingDisabled_SwapThrottled) {
1805 bool use_external_begin_frame_source = true;
1806 bool throttle_frame_production = false;
1807 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source,
1808 throttle_frame_production);
1811 TEST_F(SchedulerTest,
1812 SyntheticBeginFrames_And_VSyncThrottlingDisabled_SwapThrottled) {
1813 bool use_external_begin_frame_source = false;
1814 bool throttle_frame_production = false;
1815 BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source,
1816 throttle_frame_production);
1819 TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterOutputSurfaceIsInitialized) {
1820 scheduler_settings_.use_external_begin_frame_source = true;
1821 SetUpScheduler(false);
1823 scheduler_->SetCanStart();
1824 scheduler_->SetVisible(true);
1825 scheduler_->SetCanDraw(true);
1827 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_);
1828 client_->Reset();
1829 scheduler_->DidCreateAndInitializeOutputSurface();
1830 EXPECT_NO_ACTION(client_);
1832 scheduler_->DidLoseOutputSurface();
1833 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_);
1836 TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginFrameStarted) {
1837 scheduler_settings_.use_external_begin_frame_source = true;
1838 SetUpScheduler(true);
1840 // SetNeedsCommit should begin the frame.
1841 scheduler_->SetNeedsCommit();
1842 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
1844 client_->Reset();
1845 EXPECT_SCOPED(AdvanceFrame());
1846 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1847 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1848 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1850 client_->Reset();
1851 scheduler_->DidLoseOutputSurface();
1852 // SetNeedsBeginFrames(false) is not called until the end of the frame.
1853 EXPECT_NO_ACTION(client_);
1855 client_->Reset();
1856 scheduler_->NotifyBeginMainFrameStarted();
1857 scheduler_->NotifyReadyToCommit();
1858 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 1);
1860 client_->Reset();
1861 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1862 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
1863 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
1864 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
1867 void SchedulerTest::DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(
1868 bool impl_side_painting) {
1869 scheduler_settings_.impl_side_painting = impl_side_painting;
1870 scheduler_settings_.use_external_begin_frame_source = true;
1871 SetUpScheduler(true);
1873 // SetNeedsCommit should begin the frame.
1874 scheduler_->SetNeedsCommit();
1875 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
1877 client_->Reset();
1878 EXPECT_SCOPED(AdvanceFrame());
1879 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1880 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1881 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1883 client_->Reset();
1884 scheduler_->DidLoseOutputSurface();
1885 // Do nothing when impl frame is in deadine pending state.
1886 EXPECT_NO_ACTION(client_);
1888 client_->Reset();
1889 // Run posted deadline.
1890 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1891 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1892 // OnBeginImplFrameDeadline didn't schedule output surface creation because
1893 // main frame is not yet completed.
1894 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
1895 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
1896 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1898 // BeginImplFrame is not started.
1899 client_->Reset();
1900 task_runner().RunUntilTime(now_src()->Now() +
1901 base::TimeDelta::FromMilliseconds(10));
1902 EXPECT_NO_ACTION(client_);
1903 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1905 client_->Reset();
1906 scheduler_->NotifyBeginMainFrameStarted();
1907 scheduler_->NotifyReadyToCommit();
1908 if (impl_side_painting) {
1909 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 3);
1910 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 3);
1911 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 2, 3);
1912 } else {
1913 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2);
1914 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 1, 2);
1918 TEST_F(SchedulerTest,
1919 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency) {
1920 bool impl_side_painting = false;
1921 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting);
1924 TEST_F(SchedulerTest,
1925 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatencyWithImplPaint) {
1926 bool impl_side_painting = true;
1927 DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting);
1930 void SchedulerTest::DidLoseOutputSurfaceAfterReadyToCommit(
1931 bool impl_side_painting) {
1932 scheduler_settings_.impl_side_painting = impl_side_painting;
1933 scheduler_settings_.use_external_begin_frame_source = true;
1934 SetUpScheduler(true);
1936 // SetNeedsCommit should begin the frame.
1937 scheduler_->SetNeedsCommit();
1938 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
1940 client_->Reset();
1941 EXPECT_SCOPED(AdvanceFrame());
1942 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1943 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
1944 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1946 client_->Reset();
1947 scheduler_->NotifyBeginMainFrameStarted();
1948 scheduler_->NotifyReadyToCommit();
1949 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
1951 client_->Reset();
1952 scheduler_->DidLoseOutputSurface();
1953 // SetNeedsBeginFrames(false) is not called until the end of the frame.
1954 if (impl_side_painting) {
1955 // Sync tree should be forced to activate.
1956 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
1957 } else {
1958 EXPECT_NO_ACTION(client_);
1961 client_->Reset();
1962 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1963 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
1964 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
1965 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
1968 TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterReadyToCommit) {
1969 DidLoseOutputSurfaceAfterReadyToCommit(false);
1972 TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterReadyToCommitWithImplPainting) {
1973 DidLoseOutputSurfaceAfterReadyToCommit(true);
1976 TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterSetNeedsPrepareTiles) {
1977 scheduler_settings_.use_external_begin_frame_source = true;
1978 SetUpScheduler(true);
1980 scheduler_->SetNeedsPrepareTiles();
1981 scheduler_->SetNeedsRedraw();
1982 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
1984 client_->Reset();
1985 EXPECT_SCOPED(AdvanceFrame());
1986 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1987 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1988 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1990 client_->Reset();
1991 scheduler_->DidLoseOutputSurface();
1992 // SetNeedsBeginFrames(false) is not called until the end of the frame.
1993 EXPECT_NO_ACTION(client_);
1995 client_->Reset();
1996 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1997 EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 4);
1998 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 1, 4);
1999 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 2, 4);
2000 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4);
2003 TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginRetroFramePosted) {
2004 scheduler_settings_.use_external_begin_frame_source = true;
2005 SetUpScheduler(true);
2007 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
2008 scheduler_->SetNeedsCommit();
2009 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
2011 // Create a BeginFrame with a long deadline to avoid race conditions.
2012 // This is the first BeginFrame, which will be handled immediately.
2013 client_->Reset();
2014 BeginFrameArgs args =
2015 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
2016 args.deadline += base::TimeDelta::FromHours(1);
2017 fake_external_begin_frame_source()->TestOnBeginFrame(args);
2018 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2019 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
2020 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2021 EXPECT_TRUE(client_->needs_begin_frames());
2023 // Queue BeginFrames while we are still handling the previous BeginFrame.
2024 args.frame_time += base::TimeDelta::FromSeconds(1);
2025 fake_external_begin_frame_source()->TestOnBeginFrame(args);
2026 args.frame_time += base::TimeDelta::FromSeconds(1);
2027 fake_external_begin_frame_source()->TestOnBeginFrame(args);
2029 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
2030 client_->Reset();
2031 task_runner().RunPendingTasks(); // Run posted deadline.
2032 EXPECT_NO_ACTION(client_);
2033 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2034 EXPECT_TRUE(client_->needs_begin_frames());
2036 // NotifyReadyToCommit should trigger the commit.
2037 client_->Reset();
2038 scheduler_->NotifyBeginMainFrameStarted();
2039 scheduler_->NotifyReadyToCommit();
2040 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
2041 EXPECT_TRUE(client_->needs_begin_frames());
2043 client_->Reset();
2044 EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty());
2045 scheduler_->DidLoseOutputSurface();
2046 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
2047 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
2048 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
2049 EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty());
2051 // Posted BeginRetroFrame is aborted.
2052 client_->Reset();
2053 task_runner().RunPendingTasks();
2054 EXPECT_NO_ACTION(client_);
2057 TEST_F(SchedulerTest, DidLoseOutputSurfaceDuringBeginRetroFrameRunning) {
2058 scheduler_settings_.use_external_begin_frame_source = true;
2059 SetUpScheduler(true);
2061 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
2062 scheduler_->SetNeedsCommit();
2063 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
2065 // Create a BeginFrame with a long deadline to avoid race conditions.
2066 // This is the first BeginFrame, which will be handled immediately.
2067 client_->Reset();
2068 BeginFrameArgs args =
2069 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
2070 args.deadline += base::TimeDelta::FromHours(1);
2071 fake_external_begin_frame_source()->TestOnBeginFrame(args);
2072 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2073 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
2074 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2075 EXPECT_TRUE(client_->needs_begin_frames());
2077 // Queue BeginFrames while we are still handling the previous BeginFrame.
2078 args.frame_time += base::TimeDelta::FromSeconds(1);
2079 fake_external_begin_frame_source()->TestOnBeginFrame(args);
2080 args.frame_time += base::TimeDelta::FromSeconds(1);
2081 fake_external_begin_frame_source()->TestOnBeginFrame(args);
2083 // If we don't swap on the deadline, we wait for the next BeginImplFrame.
2084 client_->Reset();
2085 task_runner().RunPendingTasks(); // Run posted deadline.
2086 EXPECT_NO_ACTION(client_);
2087 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2088 EXPECT_TRUE(client_->needs_begin_frames());
2090 // NotifyReadyToCommit should trigger the commit.
2091 client_->Reset();
2092 scheduler_->NotifyBeginMainFrameStarted();
2093 scheduler_->NotifyReadyToCommit();
2094 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
2095 EXPECT_TRUE(client_->needs_begin_frames());
2097 // BeginImplFrame should prepare the draw.
2098 client_->Reset();
2099 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
2100 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2101 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
2102 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2103 EXPECT_TRUE(client_->needs_begin_frames());
2105 client_->Reset();
2106 EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty());
2107 scheduler_->DidLoseOutputSurface();
2108 EXPECT_NO_ACTION(client_);
2109 EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty());
2111 // BeginImplFrame deadline should abort drawing.
2112 client_->Reset();
2113 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
2114 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
2115 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
2116 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
2117 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2118 EXPECT_FALSE(client_->needs_begin_frames());
2120 // No more BeginRetroFrame because BeginRetroFrame queue is cleared.
2121 client_->Reset();
2122 task_runner().RunPendingTasks();
2123 EXPECT_NO_ACTION(client_);
2126 TEST_F(SchedulerTest, DidLoseOutputSurfaceWithSyntheticBeginFrameSource) {
2127 SetUpScheduler(true);
2129 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
2130 EXPECT_FALSE(scheduler_->frame_source().NeedsBeginFrames());
2131 scheduler_->SetNeedsCommit();
2132 EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
2134 client_->Reset();
2135 AdvanceFrame();
2136 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2137 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
2138 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2139 EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
2141 // NotifyReadyToCommit should trigger the commit.
2142 client_->Reset();
2143 scheduler_->NotifyBeginMainFrameStarted();
2144 scheduler_->NotifyReadyToCommit();
2145 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
2146 EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
2148 client_->Reset();
2149 scheduler_->DidLoseOutputSurface();
2150 // SetNeedsBeginFrames(false) is not called until the end of the frame.
2151 EXPECT_NO_ACTION(client_);
2152 EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
2154 client_->Reset();
2155 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
2156 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 2);
2157 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
2158 EXPECT_FALSE(scheduler_->frame_source().NeedsBeginFrames());
2161 TEST_F(SchedulerTest, DidLoseOutputSurfaceWhenIdle) {
2162 scheduler_settings_.use_external_begin_frame_source = true;
2163 SetUpScheduler(true);
2165 // SetNeedsCommit should begin the frame.
2166 scheduler_->SetNeedsCommit();
2167 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
2169 client_->Reset();
2170 EXPECT_SCOPED(AdvanceFrame());
2171 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2172 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
2173 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2175 client_->Reset();
2176 scheduler_->NotifyBeginMainFrameStarted();
2177 scheduler_->NotifyReadyToCommit();
2178 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
2180 client_->Reset();
2181 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
2182 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
2183 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
2185 // Idle time between BeginFrames.
2186 client_->Reset();
2187 scheduler_->DidLoseOutputSurface();
2188 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
2189 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
2190 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
2193 TEST_F(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {
2194 scheduler_settings_.impl_side_painting = true;
2195 scheduler_settings_.use_external_begin_frame_source = true;
2196 SetUpScheduler(true);
2198 // SetNeedsCommit should begin the frame.
2199 scheduler_->SetNeedsCommit();
2200 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
2202 client_->Reset();
2203 EXPECT_SCOPED(AdvanceFrame());
2204 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2205 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
2206 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2208 client_->Reset();
2209 scheduler_->NotifyBeginMainFrameStarted();
2210 scheduler_->NotifyReadyToCommit();
2211 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
2213 client_->Reset();
2214 scheduler_->SetVisible(false);
2215 // Sync tree should be forced to activate.
2216 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
2217 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2);
2220 // Tests to ensure frame sources can be successfully changed while drawing.
2221 TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottled) {
2222 scheduler_settings_.use_external_begin_frame_source = true;
2223 SetUpScheduler(true);
2225 // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
2226 scheduler_->SetNeedsRedraw();
2227 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
2228 client_->Reset();
2230 EXPECT_SCOPED(AdvanceFrame());
2231 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2232 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
2233 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2234 EXPECT_TRUE(client_->needs_begin_frames());
2235 client_->Reset();
2236 task_runner().RunPendingTasks(); // Run posted deadline.
2237 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
2238 scheduler_->SetNeedsRedraw();
2240 // Switch to an unthrottled frame source.
2241 scheduler_->SetThrottleFrameProduction(false);
2242 client_->Reset();
2244 // Unthrottled frame source will immediately begin a new frame.
2245 task_runner().RunPendingTasks(); // Run posted BeginFrame.
2246 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2247 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
2248 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2249 client_->Reset();
2251 // If we don't swap on the deadline, we wait for the next BeginFrame.
2252 task_runner().RunPendingTasks(); // Run posted deadline.
2253 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
2254 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2255 client_->Reset();
2258 // Tests to ensure frame sources can be successfully changed while a frame
2259 // deadline is pending.
2260 TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottledBeforeDeadline) {
2261 scheduler_settings_.use_external_begin_frame_source = true;
2262 SetUpScheduler(true);
2264 // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
2265 scheduler_->SetNeedsRedraw();
2266 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
2267 client_->Reset();
2269 EXPECT_SCOPED(AdvanceFrame());
2270 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2271 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
2273 // Switch to an unthrottled frame source before the frame deadline is hit.
2274 scheduler_->SetThrottleFrameProduction(false);
2275 client_->Reset();
2277 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2278 EXPECT_TRUE(client_->needs_begin_frames());
2279 client_->Reset();
2281 task_runner().RunPendingTasks(); // Run posted deadline and BeginFrame.
2282 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2);
2283 // Unthrottled frame source will immediately begin a new frame.
2284 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 2);
2285 scheduler_->SetNeedsRedraw();
2286 client_->Reset();
2288 task_runner().RunPendingTasks(); // Run posted deadline.
2289 EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
2290 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
2291 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2292 client_->Reset();
2295 // Tests to ensure that the active frame source can successfully be changed from
2296 // unthrottled to throttled.
2297 TEST_F(SchedulerTest, SwitchFrameSourceToThrottled) {
2298 scheduler_settings_.throttle_frame_production = false;
2299 scheduler_settings_.use_external_begin_frame_source = true;
2300 SetUpScheduler(true);
2302 scheduler_->SetNeedsRedraw();
2303 EXPECT_NO_ACTION(client_);
2304 client_->Reset();
2306 task_runner().RunPendingTasks(); // Run posted BeginFrame.
2307 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2308 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
2309 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2310 client_->Reset();
2312 task_runner().RunPendingTasks(); // Run posted deadline.
2313 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
2314 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2315 client_->Reset();
2317 // Switch to a throttled frame source.
2318 scheduler_->SetThrottleFrameProduction(true);
2319 client_->Reset();
2321 // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
2322 scheduler_->SetNeedsRedraw();
2323 task_runner().RunPendingTasks();
2324 EXPECT_NO_ACTION(client_);
2325 client_->Reset();
2327 EXPECT_SCOPED(AdvanceFrame());
2328 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2329 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
2330 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2331 EXPECT_TRUE(client_->needs_begin_frames());
2332 client_->Reset();
2333 task_runner().RunPendingTasks(); // Run posted deadline.
2334 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
2337 // Tests to ensure that we send a BeginMainFrameNotExpectedSoon when expected.
2338 TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon) {
2339 scheduler_settings_.use_external_begin_frame_source = true;
2340 SetUpScheduler(true);
2342 // SetNeedsCommit should begin the frame on the next BeginImplFrame.
2343 scheduler_->SetNeedsCommit();
2344 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
2345 client_->Reset();
2347 // Trigger a frame draw.
2348 EXPECT_SCOPED(AdvanceFrame());
2349 scheduler_->NotifyBeginMainFrameStarted();
2350 scheduler_->NotifyReadyToCommit();
2351 task_runner().RunPendingTasks();
2352 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 5);
2353 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 5);
2354 EXPECT_ACTION("ScheduledActionCommit", client_, 2, 5);
2355 EXPECT_ACTION("ScheduledActionAnimate", client_, 3, 5);
2356 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 5);
2357 client_->Reset();
2359 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
2360 // and send a SendBeginMainFrameNotExpectedSoon.
2361 EXPECT_SCOPED(AdvanceFrame());
2362 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
2363 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
2364 client_->Reset();
2366 task_runner().RunPendingTasks(); // Run posted deadline.
2367 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
2368 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
2369 client_->Reset();
2372 TEST_F(SchedulerTest, UsingSynchronousCompositor) {
2373 scheduler_settings_.using_synchronous_renderer_compositor = true;
2374 scheduler_settings_.use_external_begin_frame_source = true;
2375 scheduler_settings_.impl_side_painting = true;
2376 SetUpScheduler(true);
2378 // Compositor thread initiated input/animation.
2379 // --------------------------------------------
2380 scheduler_->SetNeedsAnimate();
2381 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
2382 client_->Reset();
2384 // Next vsync.
2385 AdvanceFrame();
2386 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
2387 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
2388 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_, 2, 3);
2389 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2390 client_->Reset();
2392 // Continue with animation.
2393 scheduler_->SetNeedsAnimate();
2394 EXPECT_NO_ACTION(client_);
2396 // Android onDraw.
2397 scheduler_->SetNeedsRedraw();
2398 scheduler_->OnDrawForOutputSurface();
2399 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
2400 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2401 client_->Reset();
2403 // Next vsync.
2404 AdvanceFrame();
2405 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
2406 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
2407 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_, 2, 3);
2408 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2409 client_->Reset();
2411 // Android onDraw.
2412 scheduler_->SetNeedsRedraw();
2413 scheduler_->OnDrawForOutputSurface();
2414 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
2415 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2416 client_->Reset();
2418 // Idle on next vsync.
2419 AdvanceFrame();
2420 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
2421 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
2422 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
2423 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2424 client_->Reset();
2426 // Android onDraw after idle.
2427 // --------------------------
2428 scheduler_->SetNeedsRedraw();
2429 scheduler_->OnDrawForOutputSurface();
2430 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 3);
2431 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
2432 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 3);
2433 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2434 client_->Reset();
2436 // Idle on next vsync.
2437 AdvanceFrame();
2438 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
2439 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
2440 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
2441 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2442 client_->Reset();
2444 // Main thread initiated activity.
2445 // -------------------------------
2446 scheduler_->SetNeedsCommit();
2447 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
2448 client_->Reset();
2450 // Next vsync.
2451 AdvanceFrame();
2452 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2453 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
2454 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2455 client_->Reset();
2457 scheduler_->NotifyBeginMainFrameStarted();
2458 EXPECT_NO_ACTION(client_);
2460 // Next vsync.
2461 AdvanceFrame();
2462 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
2463 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2464 client_->Reset();
2466 scheduler_->NotifyReadyToCommit();
2467 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
2468 client_->Reset();
2470 scheduler_->NotifyReadyToActivate();
2471 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
2472 client_->Reset();
2474 // Next vsync.
2475 AdvanceFrame();
2476 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
2477 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
2478 EXPECT_ACTION("ScheduledActionInvalidateOutputSurface", client_, 2, 3);
2479 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2480 client_->Reset();
2482 // Android onDraw.
2483 scheduler_->SetNeedsRedraw();
2484 scheduler_->OnDrawForOutputSurface();
2485 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
2486 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2487 client_->Reset();
2489 // Idle on next vsync.
2490 AdvanceFrame();
2491 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
2492 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
2493 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
2494 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
2495 client_->Reset();
2498 TEST_F(SchedulerTest, AuthoritativeVSyncInterval) {
2499 SetUpScheduler(true);
2501 base::TimeDelta initial_interval =
2502 scheduler_->begin_impl_frame_args().interval;
2503 base::TimeDelta authoritative_interval =
2504 base::TimeDelta::FromMilliseconds(33);
2506 scheduler_->SetNeedsCommit();
2507 EXPECT_SCOPED(AdvanceFrame());
2509 EXPECT_EQ(initial_interval, scheduler_->begin_impl_frame_args().interval);
2511 scheduler_->NotifyBeginMainFrameStarted();
2512 scheduler_->NotifyReadyToCommit();
2513 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
2515 scheduler_->SetAuthoritativeVSyncInterval(authoritative_interval);
2517 EXPECT_SCOPED(AdvanceFrame());
2519 // At the next BeginFrame, authoritative interval is used instead of previous
2520 // interval.
2521 EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval);
2522 EXPECT_EQ(authoritative_interval,
2523 scheduler_->begin_impl_frame_args().interval);
2526 } // namespace
2527 } // namespace cc