Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / cc / scheduler / scheduler_unittest.cc
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 #include "cc/scheduler/scheduler.h"
5
6 #include <string>
7 #include <vector>
8
9 #include "base/logging.h"
10 #include "base/memory/scoped_vector.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/test/test_simple_task_runner.h"
14 #include "base/time/time.h"
15 #include "cc/test/scheduler_test_common.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \
20   EXPECT_EQ(expected_num_actions, client.num_actions_());                 \
21   ASSERT_LT(action_index, client.num_actions_());                         \
22   do {                                                                    \
23     EXPECT_STREQ(action, client.Action(action_index));                    \
24     for (int i = expected_num_actions; i < client.num_actions_(); ++i)    \
25       ADD_FAILURE() << "Unexpected action: " << client.Action(i) <<       \
26           " with state:\n" << client.StateForAction(action_index);        \
27   } while (false)
28
29 #define EXPECT_SINGLE_ACTION(action, client) \
30   EXPECT_ACTION(action, client, 0, 1)
31
32 namespace cc {
33 namespace {
34
35 class FakeSchedulerClient;
36
37 void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler,
38                                            FakeSchedulerClient* client);
39
40 class FakeSchedulerClient : public SchedulerClient {
41  public:
42   FakeSchedulerClient() : needs_begin_frame_(false), automatic_swap_ack_(true) {
43     Reset();
44   }
45
46   void Reset() {
47     actions_.clear();
48     states_.clear();
49     draw_will_happen_ = true;
50     swap_will_happen_if_draw_happens_ = true;
51     num_draws_ = 0;
52     log_anticipated_draw_time_change_ = false;
53   }
54
55   Scheduler* CreateScheduler(const SchedulerSettings& settings) {
56     task_runner_ = new base::TestSimpleTaskRunner;
57     scheduler_ = Scheduler::Create(this, settings, 0, task_runner_);
58     return scheduler_.get();
59   }
60
61   // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it
62   // for tests that do.
63   void set_log_anticipated_draw_time_change(bool log) {
64     log_anticipated_draw_time_change_ = log;
65   }
66   bool needs_begin_frame() { return needs_begin_frame_; }
67   int num_draws() const { return num_draws_; }
68   int num_actions_() const { return static_cast<int>(actions_.size()); }
69   const char* Action(int i) const { return actions_[i]; }
70   base::Value& StateForAction(int i) const { return *states_[i]; }
71   base::TimeTicks posted_begin_impl_frame_deadline() const {
72     return posted_begin_impl_frame_deadline_;
73   }
74
75   base::TestSimpleTaskRunner& task_runner() { return *task_runner_; }
76
77   int ActionIndex(const char* action) const {
78     for (size_t i = 0; i < actions_.size(); i++)
79       if (!strcmp(actions_[i], action))
80         return i;
81     return -1;
82   }
83
84   bool HasAction(const char* action) const {
85     return ActionIndex(action) >= 0;
86   }
87
88   void SetDrawWillHappen(bool draw_will_happen) {
89     draw_will_happen_ = draw_will_happen;
90   }
91   void SetSwapWillHappenIfDrawHappens(bool swap_will_happen_if_draw_happens) {
92     swap_will_happen_if_draw_happens_ = swap_will_happen_if_draw_happens;
93   }
94   void SetAutomaticSwapAck(bool automatic_swap_ack) {
95     automatic_swap_ack_ = automatic_swap_ack;
96   }
97
98   // SchedulerClient implementation.
99   virtual void SetNeedsBeginFrame(bool enable) OVERRIDE {
100     actions_.push_back("SetNeedsBeginFrame");
101     states_.push_back(scheduler_->StateAsValue().release());
102     needs_begin_frame_ = enable;
103   }
104   virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE {
105     actions_.push_back("WillBeginImplFrame");
106     states_.push_back(scheduler_->StateAsValue().release());
107   }
108   virtual void ScheduledActionSendBeginMainFrame() OVERRIDE {
109     actions_.push_back("ScheduledActionSendBeginMainFrame");
110     states_.push_back(scheduler_->StateAsValue().release());
111   }
112   virtual void ScheduledActionAnimate() OVERRIDE {
113     actions_.push_back("ScheduledActionAnimate");
114     states_.push_back(scheduler_->StateAsValue().release());
115   }
116   virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible()
117       OVERRIDE {
118     actions_.push_back("ScheduledActionDrawAndSwapIfPossible");
119     states_.push_back(scheduler_->StateAsValue().release());
120     num_draws_++;
121     bool did_readback = false;
122     DrawSwapReadbackResult::DrawResult result =
123         draw_will_happen_
124             ? DrawSwapReadbackResult::DRAW_SUCCESS
125             : DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
126     bool swap_will_happen =
127         draw_will_happen_ && swap_will_happen_if_draw_happens_;
128     if (swap_will_happen) {
129       scheduler_->DidSwapBuffers();
130       if (automatic_swap_ack_)
131         scheduler_->DidSwapBuffersComplete();
132     }
133     return DrawSwapReadbackResult(
134         result,
135         draw_will_happen_ && swap_will_happen_if_draw_happens_,
136         did_readback);
137   }
138   virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE {
139     actions_.push_back("ScheduledActionDrawAndSwapForced");
140     states_.push_back(scheduler_->StateAsValue().release());
141     bool did_request_swap = swap_will_happen_if_draw_happens_;
142     bool did_readback = false;
143     return DrawSwapReadbackResult(
144         DrawSwapReadbackResult::DRAW_SUCCESS, did_request_swap, did_readback);
145   }
146   virtual DrawSwapReadbackResult ScheduledActionDrawAndReadback() OVERRIDE {
147     actions_.push_back("ScheduledActionDrawAndReadback");
148     states_.push_back(scheduler_->StateAsValue().release());
149     bool did_request_swap = false;
150     bool did_readback = true;
151     return DrawSwapReadbackResult(
152         DrawSwapReadbackResult::DRAW_SUCCESS, did_request_swap, did_readback);
153   }
154   virtual void ScheduledActionCommit() OVERRIDE {
155     actions_.push_back("ScheduledActionCommit");
156     states_.push_back(scheduler_->StateAsValue().release());
157   }
158   virtual void ScheduledActionUpdateVisibleTiles() OVERRIDE {
159     actions_.push_back("ScheduledActionUpdateVisibleTiles");
160     states_.push_back(scheduler_->StateAsValue().release());
161   }
162   virtual void ScheduledActionActivatePendingTree() OVERRIDE {
163     actions_.push_back("ScheduledActionActivatePendingTree");
164     states_.push_back(scheduler_->StateAsValue().release());
165   }
166   virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {
167     actions_.push_back("ScheduledActionBeginOutputSurfaceCreation");
168     states_.push_back(scheduler_->StateAsValue().release());
169   }
170   virtual void ScheduledActionManageTiles() OVERRIDE {
171     actions_.push_back("ScheduledActionManageTiles");
172     states_.push_back(scheduler_->StateAsValue().release());
173   }
174   virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {
175     if (log_anticipated_draw_time_change_)
176       actions_.push_back("DidAnticipatedDrawTimeChange");
177   }
178   virtual base::TimeDelta DrawDurationEstimate() OVERRIDE {
179     return base::TimeDelta();
180   }
181   virtual base::TimeDelta BeginMainFrameToCommitDurationEstimate() OVERRIDE {
182     return base::TimeDelta();
183   }
184   virtual base::TimeDelta CommitToActivateDurationEstimate() OVERRIDE {
185     return base::TimeDelta();
186   }
187
188   virtual void DidBeginImplFrameDeadline() OVERRIDE {}
189
190  protected:
191   bool needs_begin_frame_;
192   bool draw_will_happen_;
193   bool swap_will_happen_if_draw_happens_;
194   bool automatic_swap_ack_;
195   int num_draws_;
196   bool log_anticipated_draw_time_change_;
197   base::TimeTicks posted_begin_impl_frame_deadline_;
198   std::vector<const char*> actions_;
199   ScopedVector<base::Value> states_;
200   scoped_ptr<Scheduler> scheduler_;
201   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
202 };
203
204 void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler,
205                                            FakeSchedulerClient* client) {
206   bool client_initiates_begin_frame =
207       scheduler->settings().begin_frame_scheduling_enabled &&
208       scheduler->settings().throttle_frame_production;
209
210   scheduler->DidCreateAndInitializeOutputSurface();
211   scheduler->SetNeedsCommit();
212   scheduler->NotifyBeginMainFrameStarted();
213   scheduler->NotifyReadyToCommit();
214   // Go through the motions to draw the commit.
215   if (client_initiates_begin_frame)
216     scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
217   else
218     client->task_runner().RunPendingTasks();  // Run posted BeginFrame.
219
220   // Run the posted deadline task.
221   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
222   client->task_runner().RunPendingTasks();
223   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
224
225   // We need another BeginImplFrame so Scheduler calls
226   // SetNeedsBeginFrame(false).
227   if (client_initiates_begin_frame)
228     scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
229   else
230     client->task_runner().RunPendingTasks();  // Run posted BeginFrame.
231
232   // Run the posted deadline task.
233   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
234   client->task_runner().RunPendingTasks();
235   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
236 }
237
238 TEST(SchedulerTest, InitializeOutputSurfaceDoesNotBeginImplFrame) {
239   FakeSchedulerClient client;
240   SchedulerSettings default_scheduler_settings;
241   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
242   scheduler->SetCanStart();
243   scheduler->SetVisible(true);
244   scheduler->SetCanDraw(true);
245
246   EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
247   client.Reset();
248   scheduler->DidCreateAndInitializeOutputSurface();
249   EXPECT_EQ(0, client.num_actions_());
250 }
251
252 TEST(SchedulerTest, RequestCommit) {
253   FakeSchedulerClient client;
254   SchedulerSettings scheduler_settings;
255   Scheduler* scheduler = client.CreateScheduler(scheduler_settings);
256   scheduler->SetCanStart();
257   scheduler->SetVisible(true);
258   scheduler->SetCanDraw(true);
259
260   EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
261   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
262
263   // SetNeedsCommit should begin the frame on the next BeginImplFrame.
264   client.Reset();
265   scheduler->SetNeedsCommit();
266   EXPECT_TRUE(client.needs_begin_frame());
267   EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
268   client.Reset();
269
270   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
271   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
272   EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
273   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
274   EXPECT_TRUE(client.needs_begin_frame());
275   client.Reset();
276
277   // If we don't swap on the deadline, we wait for the next BeginFrame.
278   client.task_runner().RunPendingTasks();  // Run posted deadline.
279   EXPECT_EQ(0, client.num_actions_());
280   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
281   EXPECT_TRUE(client.needs_begin_frame());
282   client.Reset();
283
284   // NotifyReadyToCommit should trigger the commit.
285   scheduler->NotifyBeginMainFrameStarted();
286   scheduler->NotifyReadyToCommit();
287   EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
288   EXPECT_TRUE(client.needs_begin_frame());
289   client.Reset();
290
291   // BeginImplFrame should prepare the draw.
292   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
293   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
294   EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
295   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
296   EXPECT_TRUE(client.needs_begin_frame());
297   client.Reset();
298
299   // BeginImplFrame deadline should draw.
300   client.task_runner().RunPendingTasks();  // Run posted deadline.
301   EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
302   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
303   EXPECT_TRUE(client.needs_begin_frame());
304   client.Reset();
305
306   // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
307   // to avoid excessive toggles.
308   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
309   EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
310   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
311   client.Reset();
312
313   client.task_runner().RunPendingTasks();  // Run posted deadline.
314   EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
315   EXPECT_FALSE(client.needs_begin_frame());
316   client.Reset();
317 }
318
319 TEST(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
320   FakeSchedulerClient client;
321   SchedulerSettings scheduler_settings;
322   Scheduler* scheduler = client.CreateScheduler(scheduler_settings);
323   scheduler->SetCanStart();
324   scheduler->SetVisible(true);
325   scheduler->SetCanDraw(true);
326
327   EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
328   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
329   client.Reset();
330
331   // SetNeedsCommit should begin the frame.
332   scheduler->SetNeedsCommit();
333   EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
334
335   client.Reset();
336   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
337   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
338   EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
339   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
340
341   EXPECT_TRUE(client.needs_begin_frame());
342   client.Reset();
343
344   // Now SetNeedsCommit again. Calling here means we need a second commit.
345   scheduler->SetNeedsCommit();
346   EXPECT_EQ(client.num_actions_(), 0);
347   client.Reset();
348
349   // Finish the first commit.
350   scheduler->NotifyBeginMainFrameStarted();
351   scheduler->NotifyReadyToCommit();
352   EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
353   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
354   client.Reset();
355   client.task_runner().RunPendingTasks();  // Run posted deadline.
356   EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
357   EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
358   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
359
360   // Because we just swapped, the Scheduler should also request the next
361   // BeginImplFrame from the OutputSurface.
362   EXPECT_TRUE(client.needs_begin_frame());
363   client.Reset();
364   // Since another commit is needed, the next BeginImplFrame should initiate
365   // the second commit.
366   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
367   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
368   EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
369   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
370   client.Reset();
371
372   // Finishing the commit before the deadline should post a new deadline task
373   // to trigger the deadline early.
374   scheduler->NotifyBeginMainFrameStarted();
375   scheduler->NotifyReadyToCommit();
376   EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
377   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
378   client.Reset();
379   client.task_runner().RunPendingTasks();  // Run posted deadline.
380   EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
381   EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
382   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
383   EXPECT_TRUE(client.needs_begin_frame());
384   client.Reset();
385
386   // On the next BeginImplFrame, verify we go back to a quiescent state and
387   // no longer request BeginImplFrames.
388   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
389   client.task_runner().RunPendingTasks();  // Run posted deadline.
390   EXPECT_FALSE(client.needs_begin_frame());
391   client.Reset();
392 }
393
394 class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient {
395  public:
396   virtual void ScheduledActionSendBeginMainFrame() OVERRIDE {}
397   virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible()
398       OVERRIDE {
399     // Only SetNeedsRedraw the first time this is called
400     if (!num_draws_)
401       scheduler_->SetNeedsRedraw();
402     return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
403   }
404
405   virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE {
406     NOTREACHED();
407     bool did_request_swap = true;
408     bool did_readback = false;
409     return DrawSwapReadbackResult(
410         DrawSwapReadbackResult::DRAW_SUCCESS, did_request_swap, did_readback);
411   }
412
413   virtual void ScheduledActionCommit() OVERRIDE {}
414   virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {}
415   virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {}
416 };
417
418 // Tests for two different situations:
419 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside
420 //    a ScheduledActionDrawAndSwap
421 // 2. the scheduler drawing twice inside a single tick
422 TEST(SchedulerTest, RequestRedrawInsideDraw) {
423   SchedulerClientThatsetNeedsDrawInsideDraw client;
424   SchedulerSettings default_scheduler_settings;
425   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
426   scheduler->SetCanStart();
427   scheduler->SetVisible(true);
428   scheduler->SetCanDraw(true);
429   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
430   client.Reset();
431
432   scheduler->SetNeedsRedraw();
433   EXPECT_TRUE(scheduler->RedrawPending());
434   EXPECT_TRUE(client.needs_begin_frame());
435   EXPECT_EQ(0, client.num_draws());
436
437   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
438   client.task_runner().RunPendingTasks();  // Run posted deadline.
439   EXPECT_EQ(1, client.num_draws());
440   EXPECT_TRUE(scheduler->RedrawPending());
441   EXPECT_TRUE(client.needs_begin_frame());
442
443   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
444   client.task_runner().RunPendingTasks();  // Run posted deadline.
445   EXPECT_EQ(2, client.num_draws());
446   EXPECT_FALSE(scheduler->RedrawPending());
447   EXPECT_TRUE(client.needs_begin_frame());
448
449   // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
450   // swap.
451   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
452   client.task_runner().RunPendingTasks();  // Run posted deadline.
453   EXPECT_EQ(2, client.num_draws());
454   EXPECT_FALSE(scheduler->RedrawPending());
455   EXPECT_FALSE(client.needs_begin_frame());
456 }
457
458 // Test that requesting redraw inside a failed draw doesn't lose the request.
459 TEST(SchedulerTest, RequestRedrawInsideFailedDraw) {
460   SchedulerClientThatsetNeedsDrawInsideDraw client;
461   SchedulerSettings default_scheduler_settings;
462   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
463   scheduler->SetCanStart();
464   scheduler->SetVisible(true);
465   scheduler->SetCanDraw(true);
466   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
467   client.Reset();
468
469   client.SetDrawWillHappen(false);
470
471   scheduler->SetNeedsRedraw();
472   EXPECT_TRUE(scheduler->RedrawPending());
473   EXPECT_TRUE(client.needs_begin_frame());
474   EXPECT_EQ(0, client.num_draws());
475
476   // Fail the draw.
477   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
478   client.task_runner().RunPendingTasks();  // Run posted deadline.
479   EXPECT_EQ(1, client.num_draws());
480
481   // We have a commit pending and the draw failed, and we didn't lose the redraw
482   // request.
483   EXPECT_TRUE(scheduler->CommitPending());
484   EXPECT_TRUE(scheduler->RedrawPending());
485   EXPECT_TRUE(client.needs_begin_frame());
486
487   // Fail the draw again.
488   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
489   client.task_runner().RunPendingTasks();  // Run posted deadline.
490   EXPECT_EQ(2, client.num_draws());
491   EXPECT_TRUE(scheduler->CommitPending());
492   EXPECT_TRUE(scheduler->RedrawPending());
493   EXPECT_TRUE(client.needs_begin_frame());
494
495   // Draw successfully.
496   client.SetDrawWillHappen(true);
497   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
498   client.task_runner().RunPendingTasks();  // Run posted deadline.
499   EXPECT_EQ(3, client.num_draws());
500   EXPECT_TRUE(scheduler->CommitPending());
501   EXPECT_FALSE(scheduler->RedrawPending());
502   EXPECT_TRUE(client.needs_begin_frame());
503 }
504
505 class SchedulerClientThatSetNeedsCommitInsideDraw : public FakeSchedulerClient {
506  public:
507   SchedulerClientThatSetNeedsCommitInsideDraw()
508       : set_needs_commit_on_next_draw_(false) {}
509
510   virtual void ScheduledActionSendBeginMainFrame() OVERRIDE {}
511   virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible()
512       OVERRIDE {
513     // Only SetNeedsCommit the first time this is called
514     if (set_needs_commit_on_next_draw_) {
515       scheduler_->SetNeedsCommit();
516       set_needs_commit_on_next_draw_ = false;
517     }
518     return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
519   }
520
521   virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE {
522     NOTREACHED();
523     bool did_request_swap = false;
524     bool did_readback = false;
525     return DrawSwapReadbackResult(
526         DrawSwapReadbackResult::DRAW_SUCCESS, did_request_swap, did_readback);
527   }
528
529   virtual void ScheduledActionCommit() OVERRIDE {}
530   virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {}
531   virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {}
532
533   void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_ = true; }
534
535  private:
536   bool set_needs_commit_on_next_draw_;
537 };
538
539 // Tests for the scheduler infinite-looping on SetNeedsCommit requests that
540 // happen inside a ScheduledActionDrawAndSwap
541 TEST(SchedulerTest, RequestCommitInsideDraw) {
542   SchedulerClientThatSetNeedsCommitInsideDraw client;
543   SchedulerSettings default_scheduler_settings;
544   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
545   scheduler->SetCanStart();
546   scheduler->SetVisible(true);
547   scheduler->SetCanDraw(true);
548   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
549   client.Reset();
550
551   EXPECT_FALSE(client.needs_begin_frame());
552   scheduler->SetNeedsRedraw();
553   EXPECT_TRUE(scheduler->RedrawPending());
554   EXPECT_EQ(0, client.num_draws());
555   EXPECT_TRUE(client.needs_begin_frame());
556
557   client.SetNeedsCommitOnNextDraw();
558   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
559   client.SetNeedsCommitOnNextDraw();
560   client.task_runner().RunPendingTasks();  // Run posted deadline.
561   EXPECT_EQ(1, client.num_draws());
562   EXPECT_TRUE(scheduler->CommitPending());
563   EXPECT_TRUE(client.needs_begin_frame());
564   scheduler->NotifyBeginMainFrameStarted();
565   scheduler->NotifyReadyToCommit();
566
567   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
568   client.task_runner().RunPendingTasks();  // Run posted deadline.
569   EXPECT_EQ(2, client.num_draws());
570
571   EXPECT_FALSE(scheduler->RedrawPending());
572   EXPECT_FALSE(scheduler->CommitPending());
573   EXPECT_TRUE(client.needs_begin_frame());
574
575   // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
576   // swap.
577   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
578   client.task_runner().RunPendingTasks();  // Run posted deadline.
579   EXPECT_EQ(2, client.num_draws());
580   EXPECT_FALSE(scheduler->RedrawPending());
581   EXPECT_FALSE(scheduler->CommitPending());
582   EXPECT_FALSE(client.needs_begin_frame());
583 }
584
585 // Tests that when a draw fails then the pending commit should not be dropped.
586 TEST(SchedulerTest, RequestCommitInsideFailedDraw) {
587   SchedulerClientThatsetNeedsDrawInsideDraw client;
588   SchedulerSettings default_scheduler_settings;
589   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
590   scheduler->SetCanStart();
591   scheduler->SetVisible(true);
592   scheduler->SetCanDraw(true);
593   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
594   client.Reset();
595
596   client.SetDrawWillHappen(false);
597
598   scheduler->SetNeedsRedraw();
599   EXPECT_TRUE(scheduler->RedrawPending());
600   EXPECT_TRUE(client.needs_begin_frame());
601   EXPECT_EQ(0, client.num_draws());
602
603   // Fail the draw.
604   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
605   client.task_runner().RunPendingTasks();  // Run posted deadline.
606   EXPECT_EQ(1, client.num_draws());
607
608   // We have a commit pending and the draw failed, and we didn't lose the commit
609   // request.
610   EXPECT_TRUE(scheduler->CommitPending());
611   EXPECT_TRUE(scheduler->RedrawPending());
612   EXPECT_TRUE(client.needs_begin_frame());
613
614   // Fail the draw again.
615   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
616
617   client.task_runner().RunPendingTasks();  // Run posted deadline.
618   EXPECT_EQ(2, client.num_draws());
619   EXPECT_TRUE(scheduler->CommitPending());
620   EXPECT_TRUE(scheduler->RedrawPending());
621   EXPECT_TRUE(client.needs_begin_frame());
622
623   // Draw successfully.
624   client.SetDrawWillHappen(true);
625   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
626   client.task_runner().RunPendingTasks();  // Run posted deadline.
627   EXPECT_EQ(3, client.num_draws());
628   EXPECT_TRUE(scheduler->CommitPending());
629   EXPECT_FALSE(scheduler->RedrawPending());
630   EXPECT_TRUE(client.needs_begin_frame());
631 }
632
633 TEST(SchedulerTest, NoSwapWhenDrawFails) {
634   SchedulerClientThatSetNeedsCommitInsideDraw client;
635   SchedulerSettings default_scheduler_settings;
636   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
637   scheduler->SetCanStart();
638   scheduler->SetVisible(true);
639   scheduler->SetCanDraw(true);
640   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
641   client.Reset();
642
643   scheduler->SetNeedsRedraw();
644   EXPECT_TRUE(scheduler->RedrawPending());
645   EXPECT_TRUE(client.needs_begin_frame());
646   EXPECT_EQ(0, client.num_draws());
647
648   // Draw successfully, this starts a new frame.
649   client.SetNeedsCommitOnNextDraw();
650   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
651   client.task_runner().RunPendingTasks();  // Run posted deadline.
652   EXPECT_EQ(1, client.num_draws());
653
654   scheduler->SetNeedsRedraw();
655   EXPECT_TRUE(scheduler->RedrawPending());
656   EXPECT_TRUE(client.needs_begin_frame());
657
658   // Fail to draw, this should not start a frame.
659   client.SetDrawWillHappen(false);
660   client.SetNeedsCommitOnNextDraw();
661   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
662   client.task_runner().RunPendingTasks();  // Run posted deadline.
663   EXPECT_EQ(2, client.num_draws());
664 }
665
666 TEST(SchedulerTest, NoSwapWhenSwapFailsDuringForcedCommit) {
667   FakeSchedulerClient client;
668   SchedulerSettings default_scheduler_settings;
669   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
670
671   // Tell the client that it will fail to swap.
672   client.SetDrawWillHappen(true);
673   client.SetSwapWillHappenIfDrawHappens(false);
674
675   // Get the compositor to do a ScheduledActionDrawAndReadback.
676   scheduler->SetCanDraw(true);
677   scheduler->SetNeedsRedraw();
678   scheduler->SetNeedsForcedCommitForReadback();
679   scheduler->NotifyBeginMainFrameStarted();
680   scheduler->NotifyReadyToCommit();
681   EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback"));
682 }
683
684 TEST(SchedulerTest, BackToBackReadbackAllowed) {
685   // Some clients call readbacks twice in a row before the replacement
686   // commit comes in.  Make sure it is allowed.
687   FakeSchedulerClient client;
688   SchedulerSettings default_scheduler_settings;
689   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
690
691   // Get the compositor to do 2 ScheduledActionDrawAndReadbacks before
692   // the replacement commit comes in.
693   scheduler->SetCanDraw(true);
694   scheduler->SetNeedsRedraw();
695   scheduler->SetNeedsForcedCommitForReadback();
696   scheduler->NotifyBeginMainFrameStarted();
697   scheduler->NotifyReadyToCommit();
698   EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback"));
699
700   client.Reset();
701   scheduler->SetNeedsForcedCommitForReadback();
702   scheduler->NotifyBeginMainFrameStarted();
703   scheduler->NotifyReadyToCommit();
704   EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback"));
705
706   // The replacement commit comes in after 2 readbacks.
707   client.Reset();
708   scheduler->NotifyBeginMainFrameStarted();
709   scheduler->NotifyReadyToCommit();
710 }
711
712
713 class SchedulerClientNeedsManageTilesInDraw : public FakeSchedulerClient {
714  public:
715   virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible()
716       OVERRIDE {
717     scheduler_->SetNeedsManageTiles();
718     return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
719   }
720 };
721
722 // Test manage tiles is independant of draws.
723 TEST(SchedulerTest, ManageTiles) {
724   SchedulerClientNeedsManageTilesInDraw client;
725   SchedulerSettings default_scheduler_settings;
726   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
727   scheduler->SetCanStart();
728   scheduler->SetVisible(true);
729   scheduler->SetCanDraw(true);
730   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
731
732   // Request both draw and manage tiles. ManageTiles shouldn't
733   // be trigged until BeginImplFrame.
734   client.Reset();
735   scheduler->SetNeedsManageTiles();
736   scheduler->SetNeedsRedraw();
737   EXPECT_TRUE(scheduler->RedrawPending());
738   EXPECT_TRUE(scheduler->ManageTilesPending());
739   EXPECT_TRUE(client.needs_begin_frame());
740   EXPECT_EQ(0, client.num_draws());
741   EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles"));
742   EXPECT_FALSE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
743
744   // We have no immediate actions to perform, so the BeginImplFrame should post
745   // the deadline task.
746   client.Reset();
747   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
748   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
749   EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
750   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
751
752   // On the deadline, he actions should have occured in the right order.
753   client.Reset();
754   client.task_runner().RunPendingTasks();  // Run posted deadline.
755   EXPECT_EQ(1, client.num_draws());
756   EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
757   EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
758   EXPECT_LT(client.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
759             client.ActionIndex("ScheduledActionManageTiles"));
760   EXPECT_FALSE(scheduler->RedrawPending());
761   EXPECT_FALSE(scheduler->ManageTilesPending());
762   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
763
764   // Request a draw. We don't need a ManageTiles yet.
765   client.Reset();
766   scheduler->SetNeedsRedraw();
767   EXPECT_TRUE(scheduler->RedrawPending());
768   EXPECT_FALSE(scheduler->ManageTilesPending());
769   EXPECT_TRUE(client.needs_begin_frame());
770   EXPECT_EQ(0, client.num_draws());
771
772   // We have no immediate actions to perform, so the BeginImplFrame should post
773   // the deadline task.
774   client.Reset();
775   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
776   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
777   EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
778   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
779
780   // Draw. The draw will trigger SetNeedsManageTiles, and
781   // then the ManageTiles action will be triggered after the Draw.
782   // Afterwards, neither a draw nor ManageTiles are pending.
783   client.Reset();
784   client.task_runner().RunPendingTasks();  // Run posted deadline.
785   EXPECT_EQ(1, client.num_draws());
786   EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
787   EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
788   EXPECT_LT(client.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
789             client.ActionIndex("ScheduledActionManageTiles"));
790   EXPECT_FALSE(scheduler->RedrawPending());
791   EXPECT_FALSE(scheduler->ManageTilesPending());
792   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
793
794   // We need a BeginImplFrame where we don't swap to go idle.
795   client.Reset();
796   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
797   EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
798   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
799   client.Reset();
800   client.task_runner().RunPendingTasks();  // Run posted deadline.
801   EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
802   EXPECT_FALSE(client.needs_begin_frame());
803   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
804   EXPECT_EQ(0, client.num_draws());
805
806   // Now trigger a ManageTiles outside of a draw. We will then need
807   // a begin-frame for the ManageTiles, but we don't need a draw.
808   client.Reset();
809   EXPECT_FALSE(client.needs_begin_frame());
810   scheduler->SetNeedsManageTiles();
811   EXPECT_TRUE(client.needs_begin_frame());
812   EXPECT_TRUE(scheduler->ManageTilesPending());
813   EXPECT_FALSE(scheduler->RedrawPending());
814
815   // BeginImplFrame. There will be no draw, only ManageTiles.
816   client.Reset();
817   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
818   EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
819   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
820   client.Reset();
821   client.task_runner().RunPendingTasks();  // Run posted deadline.
822   EXPECT_EQ(0, client.num_draws());
823   EXPECT_FALSE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
824   EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
825   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
826 }
827
828 // Test that ManageTiles only happens once per frame.  If an external caller
829 // initiates it, then the state machine should not ManageTiles on that frame.
830 TEST(SchedulerTest, ManageTilesOncePerFrame) {
831   FakeSchedulerClient client;
832   SchedulerSettings default_scheduler_settings;
833   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
834   scheduler->SetCanStart();
835   scheduler->SetVisible(true);
836   scheduler->SetCanDraw(true);
837   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
838
839   // If DidManageTiles during a frame, then ManageTiles should not occur again.
840   scheduler->SetNeedsManageTiles();
841   scheduler->SetNeedsRedraw();
842   client.Reset();
843   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
844   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
845   EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
846   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
847
848   EXPECT_TRUE(scheduler->ManageTilesPending());
849   scheduler->DidManageTiles();  // An explicit ManageTiles.
850   EXPECT_FALSE(scheduler->ManageTilesPending());
851
852   client.Reset();
853   client.task_runner().RunPendingTasks();  // Run posted deadline.
854   EXPECT_EQ(1, client.num_draws());
855   EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
856   EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles"));
857   EXPECT_FALSE(scheduler->RedrawPending());
858   EXPECT_FALSE(scheduler->ManageTilesPending());
859   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
860
861   // Next frame without DidManageTiles should ManageTiles with draw.
862   scheduler->SetNeedsManageTiles();
863   scheduler->SetNeedsRedraw();
864   client.Reset();
865   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
866   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
867   EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
868   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
869
870   client.Reset();
871   client.task_runner().RunPendingTasks();  // Run posted deadline.
872   EXPECT_EQ(1, client.num_draws());
873   EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
874   EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
875   EXPECT_LT(client.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
876             client.ActionIndex("ScheduledActionManageTiles"));
877   EXPECT_FALSE(scheduler->RedrawPending());
878   EXPECT_FALSE(scheduler->ManageTilesPending());
879   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
880   scheduler->DidManageTiles();  // Corresponds to ScheduledActionManageTiles
881
882   // If we get another DidManageTiles within the same frame, we should
883   // not ManageTiles on the next frame.
884   scheduler->DidManageTiles();  // An explicit ManageTiles.
885   scheduler->SetNeedsManageTiles();
886   scheduler->SetNeedsRedraw();
887   client.Reset();
888   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
889   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
890   EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
891   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
892
893   EXPECT_TRUE(scheduler->ManageTilesPending());
894
895   client.Reset();
896   client.task_runner().RunPendingTasks();  // Run posted deadline.
897   EXPECT_EQ(1, client.num_draws());
898   EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
899   EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles"));
900   EXPECT_FALSE(scheduler->RedrawPending());
901   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
902
903   // If we get another DidManageTiles, we should not ManageTiles on the next
904   // frame. This verifies we don't alternate calling ManageTiles once and twice.
905   EXPECT_TRUE(scheduler->ManageTilesPending());
906   scheduler->DidManageTiles();  // An explicit ManageTiles.
907   EXPECT_FALSE(scheduler->ManageTilesPending());
908   scheduler->SetNeedsManageTiles();
909   scheduler->SetNeedsRedraw();
910   client.Reset();
911   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
912   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
913   EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
914   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
915
916   EXPECT_TRUE(scheduler->ManageTilesPending());
917
918   client.Reset();
919   client.task_runner().RunPendingTasks();  // Run posted deadline.
920   EXPECT_EQ(1, client.num_draws());
921   EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
922   EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles"));
923   EXPECT_FALSE(scheduler->RedrawPending());
924   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
925
926   // Next frame without DidManageTiles should ManageTiles with draw.
927   scheduler->SetNeedsManageTiles();
928   scheduler->SetNeedsRedraw();
929   client.Reset();
930   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
931   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
932   EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
933   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
934
935   client.Reset();
936   client.task_runner().RunPendingTasks();  // Run posted deadline.
937   EXPECT_EQ(1, client.num_draws());
938   EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
939   EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
940   EXPECT_LT(client.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
941             client.ActionIndex("ScheduledActionManageTiles"));
942   EXPECT_FALSE(scheduler->RedrawPending());
943   EXPECT_FALSE(scheduler->ManageTilesPending());
944   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
945   scheduler->DidManageTiles();  // Corresponds to ScheduledActionManageTiles
946 }
947
948 TEST(SchedulerTest, TriggerBeginFrameDeadlineEarly) {
949   SchedulerClientNeedsManageTilesInDraw client;
950   SchedulerSettings default_scheduler_settings;
951   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
952   scheduler->SetCanStart();
953   scheduler->SetVisible(true);
954   scheduler->SetCanDraw(true);
955   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
956
957   client.Reset();
958   scheduler->SetNeedsRedraw();
959   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
960
961   // The deadline should be zero since there is no work other than drawing
962   // pending.
963   EXPECT_EQ(base::TimeTicks(), client.posted_begin_impl_frame_deadline());
964 }
965
966 class SchedulerClientWithFixedEstimates : public FakeSchedulerClient {
967  public:
968   SchedulerClientWithFixedEstimates(
969       base::TimeDelta draw_duration,
970       base::TimeDelta begin_main_frame_to_commit_duration,
971       base::TimeDelta commit_to_activate_duration)
972       : draw_duration_(draw_duration),
973         begin_main_frame_to_commit_duration_(
974             begin_main_frame_to_commit_duration),
975         commit_to_activate_duration_(commit_to_activate_duration) {}
976
977   virtual base::TimeDelta DrawDurationEstimate() OVERRIDE {
978     return draw_duration_;
979   }
980   virtual base::TimeDelta BeginMainFrameToCommitDurationEstimate() OVERRIDE {
981     return begin_main_frame_to_commit_duration_;
982   }
983   virtual base::TimeDelta CommitToActivateDurationEstimate() OVERRIDE {
984     return commit_to_activate_duration_;
985   }
986
987  private:
988     base::TimeDelta draw_duration_;
989     base::TimeDelta begin_main_frame_to_commit_duration_;
990     base::TimeDelta commit_to_activate_duration_;
991 };
992
993 void MainFrameInHighLatencyMode(int64 begin_main_frame_to_commit_estimate_in_ms,
994                                 int64 commit_to_activate_estimate_in_ms,
995                                 bool smoothness_takes_priority,
996                                 bool should_send_begin_main_frame) {
997   // Set up client with specified estimates (draw duration is set to 1).
998   SchedulerClientWithFixedEstimates client(
999       base::TimeDelta::FromMilliseconds(1),
1000       base::TimeDelta::FromMilliseconds(
1001           begin_main_frame_to_commit_estimate_in_ms),
1002       base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms));
1003   SchedulerSettings default_scheduler_settings;
1004   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
1005   scheduler->SetCanStart();
1006   scheduler->SetVisible(true);
1007   scheduler->SetCanDraw(true);
1008   scheduler->SetSmoothnessTakesPriority(smoothness_takes_priority);
1009   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1010
1011   // Impl thread hits deadline before commit finishes.
1012   client.Reset();
1013   scheduler->SetNeedsCommit();
1014   EXPECT_FALSE(scheduler->MainThreadIsInHighLatencyMode());
1015   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
1016   EXPECT_FALSE(scheduler->MainThreadIsInHighLatencyMode());
1017   client.task_runner().RunPendingTasks();  // Run posted deadline.
1018   EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode());
1019   scheduler->NotifyBeginMainFrameStarted();
1020   scheduler->NotifyReadyToCommit();
1021   EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode());
1022   EXPECT_TRUE(client.HasAction("ScheduledActionSendBeginMainFrame"));
1023
1024   client.Reset();
1025   scheduler->SetNeedsCommit();
1026   EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode());
1027   scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
1028   EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode());
1029   client.task_runner().RunPendingTasks();  // Run posted deadline.
1030   EXPECT_EQ(scheduler->MainThreadIsInHighLatencyMode(),
1031             should_send_begin_main_frame);
1032   EXPECT_EQ(client.HasAction("ScheduledActionSendBeginMainFrame"),
1033             should_send_begin_main_frame);
1034 }
1035
1036 TEST(SchedulerTest,
1037     SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) {
1038   // Set up client so that estimates indicate that we can commit and activate
1039   // before the deadline (~8ms by default).
1040   MainFrameInHighLatencyMode(1, 1, false, false);
1041 }
1042
1043 TEST(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) {
1044   // Set up client so that estimates indicate that the commit cannot finish
1045   // before the deadline (~8ms by default).
1046   MainFrameInHighLatencyMode(10, 1, false, true);
1047 }
1048
1049 TEST(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) {
1050   // Set up client so that estimates indicate that the activate cannot finish
1051   // before the deadline (~8ms by default).
1052   MainFrameInHighLatencyMode(1, 10, false, true);
1053 }
1054
1055 TEST(SchedulerTest, NotSkipMainFrameInPreferSmoothnessMode) {
1056   // Set up client so that estimates indicate that we can commit and activate
1057   // before the deadline (~8ms by default), but also enable smoothness takes
1058   // priority mode.
1059   MainFrameInHighLatencyMode(1, 1, true, true);
1060 }
1061
1062 TEST(SchedulerTest, PollForCommitCompletion) {
1063   // Since we are simulating a long commit, set up a client with draw duration
1064   // estimates that prevent skipping main frames to get to low latency mode.
1065   SchedulerClientWithFixedEstimates client(
1066       base::TimeDelta::FromMilliseconds(1),
1067       base::TimeDelta::FromMilliseconds(32),
1068       base::TimeDelta::FromMilliseconds(32));
1069   client.set_log_anticipated_draw_time_change(true);
1070   SchedulerSettings default_scheduler_settings;
1071   Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
1072
1073   scheduler->SetCanDraw(true);
1074   scheduler->SetCanStart();
1075   scheduler->SetVisible(true);
1076   scheduler->DidCreateAndInitializeOutputSurface();
1077
1078   scheduler->SetNeedsCommit();
1079   EXPECT_TRUE(scheduler->CommitPending());
1080   scheduler->NotifyBeginMainFrameStarted();
1081   scheduler->NotifyReadyToCommit();
1082   scheduler->SetNeedsRedraw();
1083
1084   BeginFrameArgs frame_args = BeginFrameArgs::CreateForTesting();
1085   frame_args.interval = base::TimeDelta::FromMilliseconds(1000);
1086   scheduler->BeginFrame(frame_args);
1087
1088   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1089   client.task_runner().RunPendingTasks();  // Run posted deadline.
1090   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1091
1092   scheduler->DidSwapBuffers();
1093   scheduler->DidSwapBuffersComplete();
1094
1095   // At this point, we've drawn a frame. Start another commit, but hold off on
1096   // the NotifyReadyToCommit for now.
1097   EXPECT_FALSE(scheduler->CommitPending());
1098   scheduler->SetNeedsCommit();
1099   scheduler->BeginFrame(frame_args);
1100   EXPECT_TRUE(scheduler->CommitPending());
1101
1102   // Draw and swap the frame, but don't ack the swap to simulate the Browser
1103   // blocking on the renderer.
1104   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1105   client.task_runner().RunPendingTasks();  // Run posted deadline.
1106   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1107   scheduler->DidSwapBuffers();
1108
1109   // Spin the event loop a few times and make sure we get more
1110   // DidAnticipateDrawTimeChange calls every time.
1111   int actions_so_far = client.num_actions_();
1112
1113   // Does three iterations to make sure that the timer is properly repeating.
1114   for (int i = 0; i < 3; ++i) {
1115     EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
1116               client.task_runner().NextPendingTaskDelay().InMicroseconds())
1117         << *scheduler->StateAsValue();
1118     client.task_runner().RunPendingTasks();
1119     EXPECT_GT(client.num_actions_(), actions_so_far);
1120     EXPECT_STREQ(client.Action(client.num_actions_() - 1),
1121                  "DidAnticipatedDrawTimeChange");
1122     actions_so_far = client.num_actions_();
1123   }
1124
1125   // Do the same thing after BeginMainFrame starts but still before activation.
1126   scheduler->NotifyBeginMainFrameStarted();
1127   for (int i = 0; i < 3; ++i) {
1128     EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
1129               client.task_runner().NextPendingTaskDelay().InMicroseconds())
1130         << *scheduler->StateAsValue();
1131     client.task_runner().RunPendingTasks();
1132     EXPECT_GT(client.num_actions_(), actions_so_far);
1133     EXPECT_STREQ(client.Action(client.num_actions_() - 1),
1134                  "DidAnticipatedDrawTimeChange");
1135     actions_so_far = client.num_actions_();
1136   }
1137 }
1138
1139 TEST(SchedulerTest, BeginRetroFrame) {
1140   FakeSchedulerClient client;
1141   SchedulerSettings scheduler_settings;
1142   Scheduler* scheduler = client.CreateScheduler(scheduler_settings);
1143   scheduler->SetCanStart();
1144   scheduler->SetVisible(true);
1145   scheduler->SetCanDraw(true);
1146   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1147
1148   // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1149   client.Reset();
1150   scheduler->SetNeedsCommit();
1151   EXPECT_TRUE(client.needs_begin_frame());
1152   EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
1153   client.Reset();
1154
1155   // Create a BeginFrame with a long deadline to avoid race conditions.
1156   // This is the first BeginFrame, which will be handled immediately.
1157   BeginFrameArgs args = BeginFrameArgs::CreateForTesting();
1158   args.deadline += base::TimeDelta::FromHours(1);
1159   scheduler->BeginFrame(args);
1160   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1161   EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1162   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1163   EXPECT_TRUE(client.needs_begin_frame());
1164   client.Reset();
1165
1166   // Queue BeginFrames while we are still handling the previous BeginFrame.
1167   args.frame_time += base::TimeDelta::FromSeconds(1);
1168   scheduler->BeginFrame(args);
1169   args.frame_time += base::TimeDelta::FromSeconds(1);
1170   scheduler->BeginFrame(args);
1171
1172   // If we don't swap on the deadline, we wait for the next BeginImplFrame.
1173   client.task_runner().RunPendingTasks();  // Run posted deadline.
1174   EXPECT_EQ(0, client.num_actions_());
1175   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1176   EXPECT_TRUE(client.needs_begin_frame());
1177   client.Reset();
1178
1179   // NotifyReadyToCommit should trigger the commit.
1180   scheduler->NotifyBeginMainFrameStarted();
1181   scheduler->NotifyReadyToCommit();
1182   EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1183   EXPECT_TRUE(client.needs_begin_frame());
1184   client.Reset();
1185
1186   // BeginImplFrame should prepare the draw.
1187   client.task_runner().RunPendingTasks();  // Run posted BeginRetroFrame.
1188   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1189   EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
1190   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1191   EXPECT_TRUE(client.needs_begin_frame());
1192   client.Reset();
1193
1194   // BeginImplFrame deadline should draw.
1195   client.task_runner().RunPendingTasks();  // Run posted deadline.
1196   EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
1197   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1198   EXPECT_TRUE(client.needs_begin_frame());
1199   client.Reset();
1200
1201   // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
1202   // to avoid excessive toggles.
1203   client.task_runner().RunPendingTasks();  // Run posted BeginRetroFrame.
1204   EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
1205   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1206   client.Reset();
1207
1208   client.task_runner().RunPendingTasks();  // Run posted deadline.
1209   EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
1210   EXPECT_FALSE(client.needs_begin_frame());
1211   client.Reset();
1212 }
1213
1214 TEST(SchedulerTest, BeginRetroFrame_SwapThrottled) {
1215   FakeSchedulerClient client;
1216   SchedulerSettings scheduler_settings;
1217   Scheduler* scheduler = client.CreateScheduler(scheduler_settings);
1218   scheduler->SetCanStart();
1219   scheduler->SetVisible(true);
1220   scheduler->SetCanDraw(true);
1221   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1222
1223   // To test swap ack throttling, this test disables automatic swap acks.
1224   scheduler->SetMaxSwapsPending(1);
1225   client.SetAutomaticSwapAck(false);
1226
1227   // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1228   client.Reset();
1229   scheduler->SetNeedsCommit();
1230   EXPECT_TRUE(client.needs_begin_frame());
1231   EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
1232   client.Reset();
1233
1234   // Create a BeginFrame with a long deadline to avoid race conditions.
1235   // This is the first BeginFrame, which will be handled immediately.
1236   BeginFrameArgs args = BeginFrameArgs::CreateForTesting();
1237   args.deadline += base::TimeDelta::FromHours(1);
1238   scheduler->BeginFrame(args);
1239   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1240   EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1241   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1242   EXPECT_TRUE(client.needs_begin_frame());
1243   client.Reset();
1244
1245   // Queue BeginFrame while we are still handling the previous BeginFrame.
1246   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1247   args.frame_time += base::TimeDelta::FromSeconds(1);
1248   scheduler->BeginFrame(args);
1249   EXPECT_EQ(0, client.num_actions_());
1250   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1251   client.Reset();
1252
1253   // NotifyReadyToCommit should trigger the pending commit and draw.
1254   scheduler->NotifyBeginMainFrameStarted();
1255   scheduler->NotifyReadyToCommit();
1256   EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1257   EXPECT_TRUE(client.needs_begin_frame());
1258   client.Reset();
1259
1260   // Swapping will put us into a swap throttled state.
1261   client.task_runner().RunPendingTasks();  // Run posted deadline.
1262   EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
1263   EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
1264   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1265   EXPECT_TRUE(client.needs_begin_frame());
1266   client.Reset();
1267
1268   // While swap throttled, BeginRetroFrames should trigger BeginImplFrames
1269   // but not a BeginMainFrame or draw.
1270   scheduler->SetNeedsCommit();
1271   client.task_runner().RunPendingTasks();  // Run posted BeginRetroFrame.
1272   EXPECT_ACTION("WillBeginImplFrame", client, 0, 1);
1273   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1274   EXPECT_TRUE(client.needs_begin_frame());
1275   client.Reset();
1276
1277   // Queue BeginFrame while we are still handling the previous BeginFrame.
1278   args.frame_time += base::TimeDelta::FromSeconds(1);
1279   scheduler->BeginFrame(args);
1280   EXPECT_EQ(0, client.num_actions_());
1281   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1282   EXPECT_TRUE(client.needs_begin_frame());
1283   client.Reset();
1284
1285   // Take us out of a swap throttled state.
1286   scheduler->DidSwapBuffersComplete();
1287   EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 0, 1);
1288   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1289   EXPECT_TRUE(client.needs_begin_frame());
1290   client.Reset();
1291
1292   // BeginImplFrame deadline should draw.
1293   scheduler->SetNeedsRedraw();
1294   client.task_runner().RunPendingTasks();  // Run posted deadline.
1295   EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
1296   EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
1297   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1298   EXPECT_TRUE(client.needs_begin_frame());
1299   client.Reset();
1300 }
1301
1302 void BeginFramesNotFromClient(bool begin_frame_scheduling_enabled,
1303                               bool throttle_frame_production) {
1304   FakeSchedulerClient client;
1305   SchedulerSettings scheduler_settings;
1306   scheduler_settings.begin_frame_scheduling_enabled =
1307       begin_frame_scheduling_enabled;
1308   scheduler_settings.throttle_frame_production = throttle_frame_production;
1309   Scheduler* scheduler = client.CreateScheduler(scheduler_settings);
1310   scheduler->SetCanStart();
1311   scheduler->SetVisible(true);
1312   scheduler->SetCanDraw(true);
1313   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1314
1315   // SetNeedsCommit should begin the frame on the next BeginImplFrame
1316   // without calling SetNeedsBeginFrame.
1317   client.Reset();
1318   scheduler->SetNeedsCommit();
1319   EXPECT_FALSE(client.needs_begin_frame());
1320   EXPECT_EQ(0, client.num_actions_());
1321   client.Reset();
1322
1323   // When the client-driven BeginFrame are disabled, the scheduler posts it's
1324   // own BeginFrame tasks.
1325   client.task_runner().RunPendingTasks();  // Run posted BeginFrame.
1326   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1327   EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1328   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1329   EXPECT_FALSE(client.needs_begin_frame());
1330   client.Reset();
1331
1332   // If we don't swap on the deadline, we wait for the next BeginFrame.
1333   client.task_runner().RunPendingTasks();  // Run posted deadline.
1334   EXPECT_EQ(0, client.num_actions_());
1335   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1336   EXPECT_FALSE(client.needs_begin_frame());
1337   client.Reset();
1338
1339   // NotifyReadyToCommit should trigger the commit.
1340   scheduler->NotifyBeginMainFrameStarted();
1341   scheduler->NotifyReadyToCommit();
1342   EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1343   EXPECT_FALSE(client.needs_begin_frame());
1344   client.Reset();
1345
1346   // BeginImplFrame should prepare the draw.
1347   client.task_runner().RunPendingTasks();  // Run posted BeginFrame.
1348   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1349   EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
1350   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1351   EXPECT_FALSE(client.needs_begin_frame());
1352   client.Reset();
1353
1354   // BeginImplFrame deadline should draw.
1355   client.task_runner().RunPendingTasks();  // Run posted deadline.
1356   EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
1357   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1358   EXPECT_FALSE(client.needs_begin_frame());
1359   client.Reset();
1360
1361   // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
1362   // to avoid excessive toggles.
1363   client.task_runner().RunPendingTasks();  // Run posted BeginFrame.
1364   EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
1365   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1366   client.Reset();
1367
1368   // Make sure SetNeedsBeginFrame isn't called on the client
1369   // when the BeginFrame is no longer needed.
1370   client.task_runner().RunPendingTasks();  // Run posted deadline.
1371   EXPECT_EQ(0, client.num_actions_());
1372   EXPECT_FALSE(client.needs_begin_frame());
1373   client.Reset();
1374 }
1375
1376 TEST(SchedulerTest, SyntheticBeginFrames) {
1377   bool begin_frame_scheduling_enabled = false;
1378   bool throttle_frame_production = true;
1379   BeginFramesNotFromClient(begin_frame_scheduling_enabled,
1380                            throttle_frame_production);
1381 }
1382
1383 TEST(SchedulerTest, VSyncThrottlingDisabled) {
1384   bool begin_frame_scheduling_enabled = true;
1385   bool throttle_frame_production = false;
1386   BeginFramesNotFromClient(begin_frame_scheduling_enabled,
1387                            throttle_frame_production);
1388 }
1389
1390 TEST(SchedulerTest, SyntheticBeginFrames_And_VSyncThrottlingDisabled) {
1391   bool begin_frame_scheduling_enabled = false;
1392   bool throttle_frame_production = false;
1393   BeginFramesNotFromClient(begin_frame_scheduling_enabled,
1394                            throttle_frame_production);
1395 }
1396
1397 void BeginFramesNotFromClient_SwapThrottled(bool begin_frame_scheduling_enabled,
1398                                             bool throttle_frame_production) {
1399   FakeSchedulerClient client;
1400   SchedulerSettings scheduler_settings;
1401   scheduler_settings.begin_frame_scheduling_enabled =
1402       begin_frame_scheduling_enabled;
1403   scheduler_settings.throttle_frame_production = throttle_frame_production;
1404   Scheduler* scheduler = client.CreateScheduler(scheduler_settings);
1405   scheduler->SetCanStart();
1406   scheduler->SetVisible(true);
1407   scheduler->SetCanDraw(true);
1408   InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1409
1410   // To test swap ack throttling, this test disables automatic swap acks.
1411   scheduler->SetMaxSwapsPending(1);
1412   client.SetAutomaticSwapAck(false);
1413
1414   // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1415   client.Reset();
1416   scheduler->SetNeedsCommit();
1417   EXPECT_FALSE(client.needs_begin_frame());
1418   EXPECT_EQ(0, client.num_actions_());
1419   client.Reset();
1420
1421   // Trigger the first BeginImplFrame and BeginMainFrame
1422   client.task_runner().RunPendingTasks();  // Run posted BeginFrame.
1423   EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1424   EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1425   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1426   EXPECT_FALSE(client.needs_begin_frame());
1427   client.Reset();
1428
1429   // NotifyReadyToCommit should trigger the pending commit and draw.
1430   scheduler->NotifyBeginMainFrameStarted();
1431   scheduler->NotifyReadyToCommit();
1432   EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1433   EXPECT_FALSE(client.needs_begin_frame());
1434   client.Reset();
1435
1436   // Swapping will put us into a swap throttled state.
1437   client.task_runner().RunPendingTasks();  // Run posted deadline.
1438   EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
1439   EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
1440   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1441   EXPECT_FALSE(client.needs_begin_frame());
1442   client.Reset();
1443
1444   // While swap throttled, BeginFrames should trigger BeginImplFrames,
1445   // but not a BeginMainFrame or draw.
1446   scheduler->SetNeedsCommit();
1447   client.task_runner().RunPendingTasks();  // Run posted BeginFrame.
1448   EXPECT_ACTION("WillBeginImplFrame", client, 0, 1);
1449   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1450   EXPECT_FALSE(client.needs_begin_frame());
1451   client.Reset();
1452
1453   // Take us out of a swap throttled state.
1454   scheduler->DidSwapBuffersComplete();
1455   EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 0, 1);
1456   EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1457   EXPECT_FALSE(client.needs_begin_frame());
1458   client.Reset();
1459
1460   // BeginImplFrame deadline should draw.
1461   scheduler->SetNeedsRedraw();
1462   client.task_runner().RunPendingTasks();  // Run posted deadline.
1463   EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
1464   EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
1465   EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1466   EXPECT_FALSE(client.needs_begin_frame());
1467   client.Reset();
1468 }
1469
1470 TEST(SchedulerTest, SyntheticBeginFrames_SwapThrottled) {
1471   bool begin_frame_scheduling_enabled = false;
1472   bool throttle_frame_production = true;
1473   BeginFramesNotFromClient_SwapThrottled(begin_frame_scheduling_enabled,
1474                                          throttle_frame_production);
1475 }
1476
1477 TEST(SchedulerTest, VSyncThrottlingDisabled_SwapThrottled) {
1478   bool begin_frame_scheduling_enabled = true;
1479   bool throttle_frame_production = false;
1480   BeginFramesNotFromClient_SwapThrottled(begin_frame_scheduling_enabled,
1481                                          throttle_frame_production);
1482 }
1483
1484 TEST(SchedulerTest,
1485      SyntheticBeginFrames_And_VSyncThrottlingDisabled_SwapThrottled) {
1486   bool begin_frame_scheduling_enabled = false;
1487   bool throttle_frame_production = false;
1488   BeginFramesNotFromClient_SwapThrottled(begin_frame_scheduling_enabled,
1489                                          throttle_frame_production);
1490 }
1491
1492 }  // namespace
1493 }  // namespace cc