12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2011 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/scheduler/scheduler.h"
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <string>
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector>
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/debug/trace_event.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/scoped_vector.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/message_loop/message_loop.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/run_loop.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/time/time.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "cc/test/begin_frame_args_test.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "cc/test/ordered_simple_task_runner.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/test/scheduler_test_common.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define EXPECT_ACTION(action, client, action_index, expected_num_actions) \
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  do {                                                                    \
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_EQ(expected_num_actions, client.num_actions_());               \
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (action_index >= 0) {                                              \
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ASSERT_LT(action_index, client.num_actions_()) << scheduler;        \
26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      EXPECT_STREQ(action, client.Action(action_index));                  \
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }                                                                     \
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (int i = expected_num_actions; i < client.num_actions_(); ++i)    \
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ADD_FAILURE() << "Unexpected action: " << client.Action(i)          \
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                    << " with state:\n" << client.StateForAction(i);      \
3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  } while (false)
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define EXPECT_NO_ACTION(client) EXPECT_ACTION("", client, -1, 0)
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define EXPECT_SINGLE_ACTION(action, client) \
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_ACTION(action, client, 0, 1)
3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass FakeSchedulerClient;
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler,
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                           FakeSchedulerClient* client);
45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FakeSchedulerClient : public SchedulerClient {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FakeSchedulerClient()
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      : needs_begin_frame_(false),
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        automatic_swap_ack_(true),
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        swap_contains_incomplete_tile_(false),
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        redraw_will_happen_if_update_visible_tiles_happens_(false),
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        now_src_(TestNowSource::Create()) {
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    Reset();
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Reset() {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    actions_.clear();
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    states_.clear();
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_will_happen_ = true;
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    swap_will_happen_if_draw_happens_ = true;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    num_draws_ = 0;
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    log_anticipated_draw_time_change_ = false;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* CreateScheduler(const SchedulerSettings& settings) {
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scheduler_ = TestScheduler::Create(now_src_, this, settings, 0);
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Fail if we need to run 100 tasks in a row.
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    task_runner().SetRunTaskLimit(100);
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return scheduler_.get();
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // for tests that do.
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void set_log_anticipated_draw_time_change(bool log) {
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    log_anticipated_draw_time_change_ = log;
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool needs_begin_frame() { return needs_begin_frame_; }
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int num_draws() const { return num_draws_; }
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int num_actions_() const { return static_cast<int>(actions_.size()); }
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const char* Action(int i) const { return actions_[i]; }
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string StateForAction(int i) const { return states_[i]->ToString(); }
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::TimeTicks posted_begin_impl_frame_deadline() const {
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return posted_begin_impl_frame_deadline_;
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void AdvanceFrame() {
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool external_begin_frame =
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        scheduler_->settings().begin_frame_scheduling_enabled &&
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        scheduler_->settings().throttle_frame_production;
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (external_begin_frame) {
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scheduler_->BeginFrame(CreateBeginFrameArgsForTesting(now_src_));
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(task_runner().RunTasksWhile(ImplFrameDeadlinePending(false)));
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  OrderedSimpleTaskRunner& task_runner() { return scheduler_->task_runner(); }
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TestNowSource* now_src() { return now_src_.get(); }
102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  int ActionIndex(const char* action) const {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < actions_.size(); i++)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!strcmp(actions_[i], action))
106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        return i;
107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return -1;
108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void SetSwapContainsIncompleteTile(bool contain) {
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    swap_contains_incomplete_tile_ = contain;
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool HasAction(const char* action) const {
115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return ActionIndex(action) >= 0;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetDrawWillHappen(bool draw_will_happen) {
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    draw_will_happen_ = draw_will_happen;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetSwapWillHappenIfDrawHappens(bool swap_will_happen_if_draw_happens) {
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    swap_will_happen_if_draw_happens_ = swap_will_happen_if_draw_happens;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void SetAutomaticSwapAck(bool automatic_swap_ack) {
1250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    automatic_swap_ack_ = automatic_swap_ack;
1260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void SetRedrawWillHappenIfUpdateVisibleTilesHappens(bool redraw) {
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    redraw_will_happen_if_update_visible_tiles_happens_ = redraw;
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // SchedulerClient implementation.
131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void SetNeedsBeginFrame(bool enable) OVERRIDE {
132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    actions_.push_back("SetNeedsBeginFrame");
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    states_.push_back(scheduler_->AsValue());
1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    needs_begin_frame_ = enable;
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  virtual void WillBeginImplFrame(const BeginFrameArgs& args) OVERRIDE {
137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    actions_.push_back("WillBeginImplFrame");
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    states_.push_back(scheduler_->AsValue());
139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void ScheduledActionSendBeginMainFrame() OVERRIDE {
1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    actions_.push_back("ScheduledActionSendBeginMainFrame");
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    states_.push_back(scheduler_->AsValue());
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  virtual void ScheduledActionAnimate() OVERRIDE {
1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    actions_.push_back("ScheduledActionAnimate");
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    states_.push_back(scheduler_->AsValue());
1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual DrawResult ScheduledActionDrawAndSwapIfPossible() OVERRIDE {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    actions_.push_back("ScheduledActionDrawAndSwapIfPossible");
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    states_.push_back(scheduler_->AsValue());
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    num_draws_++;
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    DrawResult result =
153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        draw_will_happen_ ? DRAW_SUCCESS : DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
1540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool swap_will_happen =
1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        draw_will_happen_ && swap_will_happen_if_draw_happens_;
1560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (swap_will_happen) {
1570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      scheduler_->DidSwapBuffers();
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (swap_contains_incomplete_tile_) {
159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        scheduler_->SetSwapUsedIncompleteTile(true);
160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        swap_contains_incomplete_tile_ = false;
161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      } else {
162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        scheduler_->SetSwapUsedIncompleteTile(false);
163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      if (automatic_swap_ack_)
1660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        scheduler_->DidSwapBuffersComplete();
1670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return result;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual DrawResult ScheduledActionDrawAndSwapForced() OVERRIDE {
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    actions_.push_back("ScheduledActionDrawAndSwapForced");
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    states_.push_back(scheduler_->AsValue());
173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return DRAW_SUCCESS;
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ScheduledActionCommit() OVERRIDE {
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    actions_.push_back("ScheduledActionCommit");
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    states_.push_back(scheduler_->AsValue());
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
179ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual void ScheduledActionUpdateVisibleTiles() OVERRIDE {
180ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    actions_.push_back("ScheduledActionUpdateVisibleTiles");
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    states_.push_back(scheduler_->AsValue());
182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (redraw_will_happen_if_update_visible_tiles_happens_)
183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      scheduler_->SetNeedsRedraw();
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void ScheduledActionActivateSyncTree() OVERRIDE {
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    actions_.push_back("ScheduledActionActivateSyncTree");
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    states_.push_back(scheduler_->AsValue());
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    actions_.push_back("ScheduledActionBeginOutputSurfaceCreation");
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    states_.push_back(scheduler_->AsValue());
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
193d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  virtual void ScheduledActionManageTiles() OVERRIDE {
194d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    actions_.push_back("ScheduledActionManageTiles");
1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    states_.push_back(scheduler_->AsValue());
196d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (log_anticipated_draw_time_change_)
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      actions_.push_back("DidAnticipatedDrawTimeChange");
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  virtual base::TimeDelta DrawDurationEstimate() OVERRIDE {
2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return base::TimeDelta();
2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
2048bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual base::TimeDelta BeginMainFrameToCommitDurationEstimate() OVERRIDE {
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return base::TimeDelta();
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual base::TimeDelta CommitToActivateDurationEstimate() OVERRIDE {
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return base::TimeDelta();
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void DidBeginImplFrameDeadline() OVERRIDE {}
21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::Callback<bool(void)> ImplFrameDeadlinePending(bool state) {
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return base::Bind(&FakeSchedulerClient::ImplFrameDeadlinePendingCallback,
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      base::Unretained(this),
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      state);
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool ImplFrameDeadlinePendingCallback(bool state) {
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return scheduler_->BeginImplFrameDeadlinePending() == state;
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool needs_begin_frame_;
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool draw_will_happen_;
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool swap_will_happen_if_draw_happens_;
2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool automatic_swap_ack_;
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int num_draws_;
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool log_anticipated_draw_time_change_;
230cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool swap_contains_incomplete_tile_;
231cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool redraw_will_happen_if_update_visible_tiles_happens_;
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::TimeTicks posted_begin_impl_frame_deadline_;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<const char*> actions_;
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::vector<scoped_refptr<base::debug::ConvertableToTraceFormat> > states_;
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scoped_ptr<TestScheduler> scheduler_;
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_refptr<TestNowSource> now_src_;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler,
240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                           FakeSchedulerClient* client) {
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT0("cc",
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "SchedulerUnitTest::InitializeOutputSurfaceAndFirstCommit");
2435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
244c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scheduler->DidCreateAndInitializeOutputSurface();
245c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scheduler->SetNeedsCommit();
246c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scheduler->NotifyBeginMainFrameStarted();
247c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scheduler->NotifyReadyToCommit();
248cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (scheduler->settings().impl_side_painting)
249cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    scheduler->NotifyReadyToActivate();
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Go through the motions to draw the commit.
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client->AdvanceFrame();
253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Run the posted deadline task.
255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client->task_runner().RunTasksWhile(client->ImplFrameDeadlinePending(true));
257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // We need another BeginImplFrame so Scheduler calls
260a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // SetNeedsBeginFrame(false).
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client->AdvanceFrame();
262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Run the posted deadline task.
264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client->task_runner().RunTasksWhile(client->ImplFrameDeadlinePending(true));
266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
267c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
268c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)TEST(SchedulerTest, InitializeOutputSurfaceDoesNotBeginImplFrame) {
27090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  FakeSchedulerClient client;
27190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  SchedulerSettings default_scheduler_settings;
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
27390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler->SetCanStart();
27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler->SetVisible(true);
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler->SetCanDraw(true);
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  client.Reset();
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scheduler->DidCreateAndInitializeOutputSurface();
280f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
283a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SchedulerTest, RequestCommit) {
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeSchedulerClient client;
28568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SchedulerSettings scheduler_settings;
286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler->SetCanStart();
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetVisible(true);
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetCanDraw(true);
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  client.Reset();
2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetNeedsCommit();
2975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
298a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
29968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
30068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
302a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
303a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
30423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
30668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
30768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // If we don't swap on the deadline, we wait for the next BeginFrame.
309a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
31123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
3125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client.Reset();
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
315a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // NotifyReadyToCommit should trigger the commit.
316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
317a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
318424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
3195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client.Reset();
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // BeginImplFrame should prepare the draw.
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
3245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
3255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
32623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
3275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
32868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
32968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // BeginImplFrame deadline should draw.
331a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
3325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
33323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
3345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client.Reset();
33668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
337a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
3388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // to avoid excessive toggles.
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
340a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
34123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
34268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
34368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
344a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
345a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
3465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
34768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
350a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeSchedulerClient client;
35268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  SchedulerSettings scheduler_settings;
353cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler->SetCanStart();
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetVisible(true);
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetCanDraw(true);
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
359c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  client.Reset();
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
36268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // SetNeedsCommit should begin the frame.
3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetNeedsCommit();
364a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
36568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client.Reset();
3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
368a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
369a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
37023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
37368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
37468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
37568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Now SetNeedsCommit again. Calling here means we need a second commit.
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetNeedsCommit();
37768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(client.num_actions_(), 0);
37868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
38068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Finish the first commit.
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
38323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
38423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client.Reset();
386a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
3875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
3885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
38923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
391d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Because we just swapped, the Scheduler should also request the next
3928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // BeginImplFrame from the OutputSurface.
3935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  client.Reset();
3958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Since another commit is needed, the next BeginImplFrame should initiate
39668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // the second commit.
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
398a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
399a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
40023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
40168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
40268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
40368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Finishing the commit before the deadline should post a new deadline task
40468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // to trigger the deadline early.
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
406a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
40723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
40823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
40968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
410a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
4115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
4125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
41323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
4145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
415d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  client.Reset();
416d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
4178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // On the next BeginImplFrame, verify we go back to a quiescent state and
4188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // no longer request BeginImplFrames.
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
420a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
4215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
42268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient {
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
4278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void ScheduledActionSendBeginMainFrame() OVERRIDE {}
428cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual DrawResult ScheduledActionDrawAndSwapIfPossible()
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      OVERRIDE {
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Only SetNeedsRedraw the first time this is called
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!num_draws_)
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scheduler_->SetNeedsRedraw();
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual DrawResult ScheduledActionDrawAndSwapForced() OVERRIDE {
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
438cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return DRAW_SUCCESS;
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ScheduledActionCommit() OVERRIDE {}
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {}
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {}
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests for two different situations:
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1. the scheduler dropping SetNeedsRedraw requests that happen inside
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//    a ScheduledActionDrawAndSwap
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 2. the scheduler drawing twice inside a single tick
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(SchedulerTest, RequestRedrawInsideDraw) {
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulerClientThatsetNeedsDrawInsideDraw client;
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulerSettings default_scheduler_settings;
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler->SetCanStart();
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetVisible(true);
4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetCanDraw(true);
457c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
458424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  client.Reset();
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetNeedsRedraw();
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
4625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, client.num_draws());
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
466a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
4695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
472a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, client.num_draws());
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
4755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
476d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
4778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
4788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // swap.
4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
480a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
481d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(2, client.num_draws());
482d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
4835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that requesting redraw inside a failed draw doesn't lose the request.
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(SchedulerTest, RequestRedrawInsideFailedDraw) {
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulerClientThatsetNeedsDrawInsideDraw client;
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulerSettings default_scheduler_settings;
490cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler->SetCanStart();
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetVisible(true);
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetCanDraw(true);
494c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
495424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  client.Reset();
496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client.SetDrawWillHappen(false);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetNeedsRedraw();
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
5015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, client.num_draws());
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fail the draw.
5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
506a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We have a commit pending and the draw failed, and we didn't lose the redraw
5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // request.
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->CommitPending());
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
5135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fail the draw again.
5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
517a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, client.num_draws());
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->CommitPending());
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
5215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Draw successfully.
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client.SetDrawWillHappen(true);
5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
526a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, client.num_draws());
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->CommitPending());
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
5305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
533424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)class SchedulerClientThatSetNeedsCommitInsideDraw : public FakeSchedulerClient {
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
535424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SchedulerClientThatSetNeedsCommitInsideDraw()
536424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      : set_needs_commit_on_next_draw_(false) {}
537424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
5388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  virtual void ScheduledActionSendBeginMainFrame() OVERRIDE {}
539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual DrawResult ScheduledActionDrawAndSwapIfPossible()
54058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      OVERRIDE {
5412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Only SetNeedsCommit the first time this is called
542424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    if (set_needs_commit_on_next_draw_) {
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scheduler_->SetNeedsCommit();
544424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      set_needs_commit_on_next_draw_ = false;
545424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual DrawResult ScheduledActionDrawAndSwapForced() OVERRIDE {
5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return DRAW_SUCCESS;
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ScheduledActionCommit() OVERRIDE {}
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {}
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {}
557424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
558424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_ = true; }
559424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
560424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) private:
561424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool set_needs_commit_on_next_draw_;
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests for the scheduler infinite-looping on SetNeedsCommit requests that
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// happen inside a ScheduledActionDrawAndSwap
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(SchedulerTest, RequestCommitInsideDraw) {
567424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SchedulerClientThatSetNeedsCommitInsideDraw client;
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulerSettings default_scheduler_settings;
569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler->SetCanStart();
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetVisible(true);
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetCanDraw(true);
573c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
574424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  client.Reset();
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetNeedsRedraw();
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, client.num_draws());
5805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  client.SetNeedsCommitOnNextDraw();
5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
58468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.SetNeedsCommitOnNextDraw();
585a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->CommitPending());
5885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
589a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
590a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
593a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
59468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  EXPECT_EQ(2, client.num_draws());
59568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
5977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_FALSE(scheduler->CommitPending());
5985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
599d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
6008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
6018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // swap.
6021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
603a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
604d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(2, client.num_draws());
605d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
606d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(scheduler->CommitPending());
6075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that when a draw fails then the pending commit should not be dropped.
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(SchedulerTest, RequestCommitInsideFailedDraw) {
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulerClientThatsetNeedsDrawInsideDraw client;
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulerSettings default_scheduler_settings;
614cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler->SetCanStart();
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetVisible(true);
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetCanDraw(true);
618c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
619424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  client.Reset();
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client.SetDrawWillHappen(false);
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetNeedsRedraw();
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
6255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, client.num_draws());
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fail the draw.
6291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
630a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We have a commit pending and the draw failed, and we didn't lose the commit
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // request.
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->CommitPending());
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
6375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fail the draw again.
6401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
641a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
642a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, client.num_draws());
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->CommitPending());
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
6465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Draw successfully.
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client.SetDrawWillHappen(true);
6501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
651a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(3, client.num_draws());
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->CommitPending());
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
6555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
65890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST(SchedulerTest, NoSwapWhenDrawFails) {
659424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  SchedulerClientThatSetNeedsCommitInsideDraw client;
6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SchedulerSettings default_scheduler_settings;
661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scheduler->SetCanStart();
6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetVisible(true);
6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetCanDraw(true);
665c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
666424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  client.Reset();
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetNeedsRedraw();
6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
6705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0, client.num_draws());
6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Draw successfully, this starts a new frame.
674424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  client.SetNeedsCommitOnNextDraw();
6751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
676a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scheduler->SetNeedsRedraw();
6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
6815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Fail to draw, this should not start a frame.
6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  client.SetDrawWillHappen(false);
685424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  client.SetNeedsCommitOnNextDraw();
6861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
687a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(2, client.num_draws());
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
691d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class SchedulerClientNeedsManageTilesInDraw : public FakeSchedulerClient {
692d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
693cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual DrawResult ScheduledActionDrawAndSwapIfPossible()
694d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      OVERRIDE {
695d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    scheduler_->SetNeedsManageTiles();
696d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
697d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
698d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
699d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
700d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Test manage tiles is independant of draws.
701d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)TEST(SchedulerTest, ManageTiles) {
702d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  SchedulerClientNeedsManageTilesInDraw client;
703d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  SchedulerSettings default_scheduler_settings;
704cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
705d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scheduler->SetCanStart();
706d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scheduler->SetVisible(true);
707d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scheduler->SetCanDraw(true);
708c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
709d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
710d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Request both draw and manage tiles. ManageTiles shouldn't
7118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // be trigged until BeginImplFrame.
712d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  client.Reset();
713d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scheduler->SetNeedsManageTiles();
714d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scheduler->SetNeedsRedraw();
715d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
716d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(scheduler->ManageTilesPending());
7175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
718d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(0, client.num_draws());
719d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles"));
720d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
72168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // We have no immediate actions to perform, so the BeginImplFrame should post
72368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // the deadline task.
72468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
7251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
7265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
7275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
72823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
72968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
73068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // On the deadline, he actions should have occured in the right order.
73168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
732a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
733d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
734d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
735d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
736d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_LT(client.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
737d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            client.ActionIndex("ScheduledActionManageTiles"));
738d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
739d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(scheduler->ManageTilesPending());
74023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
741d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
742d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Request a draw. We don't need a ManageTiles yet.
743d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  client.Reset();
744d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scheduler->SetNeedsRedraw();
745d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(scheduler->RedrawPending());
746d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(scheduler->ManageTilesPending());
7475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
748d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(0, client.num_draws());
749d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
7508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // We have no immediate actions to perform, so the BeginImplFrame should post
75168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // the deadline task.
75268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
7531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
7545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
7555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
75623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
75768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
758d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Draw. The draw will trigger SetNeedsManageTiles, and
759d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // then the ManageTiles action will be triggered after the Draw.
760d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Afterwards, neither a draw nor ManageTiles are pending.
76168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
762a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
763d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
764d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
765d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
766d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_LT(client.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
767d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            client.ActionIndex("ScheduledActionManageTiles"));
768d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
769d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(scheduler->ManageTilesPending());
77023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
771d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
7728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // We need a BeginImplFrame where we don't swap to go idle.
773d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  client.Reset();
7741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
775a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
77623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
77768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
778a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
779a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
7805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
78123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
782d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(0, client.num_draws());
783d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
784d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Now trigger a ManageTiles outside of a draw. We will then need
785d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // a begin-frame for the ManageTiles, but we don't need a draw.
786d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  client.Reset();
7875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
788d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scheduler->SetNeedsManageTiles();
7895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
790d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(scheduler->ManageTilesPending());
791d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
792d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
7938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // BeginImplFrame. There will be no draw, only ManageTiles.
79468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
7951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
796a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
79723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
79868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  client.Reset();
799a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
800d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_EQ(0, client.num_draws());
801d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_FALSE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
802d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
80323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
804d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
805d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
806f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Test that ManageTiles only happens once per frame.  If an external caller
8075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// initiates it, then the state machine should not ManageTiles on that frame.
808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST(SchedulerTest, ManageTilesOncePerFrame) {
809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FakeSchedulerClient client;
810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SchedulerSettings default_scheduler_settings;
811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
812f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetCanStart();
813f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetVisible(true);
814f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetCanDraw(true);
815c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
816f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
817f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If DidManageTiles during a frame, then ManageTiles should not occur again.
818f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetNeedsManageTiles();
819f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetNeedsRedraw();
820f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client.Reset();
8211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
8225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
8235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
82423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
825f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
826f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(scheduler->ManageTilesPending());
8275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler->DidManageTiles();  // An explicit ManageTiles.
828f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(scheduler->ManageTilesPending());
829f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
830f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client.Reset();
831a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
832f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
833f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
834f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles"));
835f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
836f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(scheduler->ManageTilesPending());
83723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
838f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
839f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Next frame without DidManageTiles should ManageTiles with draw.
840f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetNeedsManageTiles();
841f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetNeedsRedraw();
842f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client.Reset();
8431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
8445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
8455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
84623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
847f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
848f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client.Reset();
849a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
850f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
851f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
852f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
853f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_LT(client.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
854f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            client.ActionIndex("ScheduledActionManageTiles"));
855f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
856f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(scheduler->ManageTilesPending());
85723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
8585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler->DidManageTiles();  // Corresponds to ScheduledActionManageTiles
8595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If we get another DidManageTiles within the same frame, we should
8615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // not ManageTiles on the next frame.
8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler->DidManageTiles();  // An explicit ManageTiles.
8635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler->SetNeedsManageTiles();
8645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler->SetNeedsRedraw();
8655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  client.Reset();
8661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
8675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
8685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
86923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(scheduler->ManageTilesPending());
8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  client.Reset();
874a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles"));
8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
87923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
8805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If we get another DidManageTiles, we should not ManageTiles on the next
8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // frame. This verifies we don't alternate calling ManageTiles once and twice.
8835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(scheduler->ManageTilesPending());
8845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler->DidManageTiles();  // An explicit ManageTiles.
8855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(scheduler->ManageTilesPending());
8865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler->SetNeedsManageTiles();
8875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler->SetNeedsRedraw();
8885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  client.Reset();
8891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
8905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
8915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
89223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
8935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(scheduler->ManageTilesPending());
8955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
8965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  client.Reset();
897a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
8995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
9005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(client.HasAction("ScheduledActionManageTiles"));
9015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
90223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
9035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Next frame without DidManageTiles should ManageTiles with draw.
9055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler->SetNeedsManageTiles();
9065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler->SetNeedsRedraw();
9075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  client.Reset();
9081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
9095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
9105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
91123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
9125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  client.Reset();
914a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
9155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(1, client.num_draws());
9165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapIfPossible"));
9175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionManageTiles"));
9185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_LT(client.ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
9195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            client.ActionIndex("ScheduledActionManageTiles"));
9205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
9215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_FALSE(scheduler->ManageTilesPending());
92223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
9235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scheduler->DidManageTiles();  // Corresponds to ScheduledActionManageTiles
924f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
925f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
926cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(SchedulerTest, ShouldUpdateVisibleTiles) {
927cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FakeSchedulerClient client;
928cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SchedulerSettings scheduler_settings;
929cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler_settings.impl_side_painting = true;
930cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
931cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanStart();
932cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetVisible(true);
933cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanDraw(true);
934cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
935cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
936cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.SetRedrawWillHappenIfUpdateVisibleTilesHappens(true);
937cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
938cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // SetNeedsCommit should begin the frame.
939cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
940cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetNeedsCommit();
941cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
942cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
9441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
945cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
948cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
950cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
952cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
953cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
954cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
955cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyReadyToActivate();
956116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client);
957cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
958cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
959cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.SetSwapContainsIncompleteTile(true);
960cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted deadline.
961cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
962cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
963cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(scheduler->RedrawPending());
964cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
965cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
9661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
967cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
968cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
969cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
970cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
971cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted deadline.
972cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionUpdateVisibleTiles", client, 0, 3);
973cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 3);
974cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 2, 3);
975cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
976cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
9771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
978cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
979cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
980cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
981cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // No more UpdateVisibleTiles().
982cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
983cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted deadline.
984cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
985cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(client.needs_begin_frame());
986cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
987cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
988a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(SchedulerTest, TriggerBeginFrameDeadlineEarly) {
989a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SchedulerClientNeedsManageTilesInDraw client;
990a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SchedulerSettings default_scheduler_settings;
991cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
992a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->SetCanStart();
993a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->SetVisible(true);
994a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->SetCanDraw(true);
995c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
996a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
997a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  client.Reset();
998a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->SetNeedsRedraw();
9991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
1000a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1001a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The deadline should be zero since there is no work other than drawing
1002a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // pending.
1003a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_EQ(base::TimeTicks(), client.posted_begin_impl_frame_deadline());
1004a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1005a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1006f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class SchedulerClientWithFixedEstimates : public FakeSchedulerClient {
1007f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
1008f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SchedulerClientWithFixedEstimates(
1009f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::TimeDelta draw_duration,
1010f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::TimeDelta begin_main_frame_to_commit_duration,
1011f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::TimeDelta commit_to_activate_duration)
1012f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      : draw_duration_(draw_duration),
1013f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        begin_main_frame_to_commit_duration_(
1014f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            begin_main_frame_to_commit_duration),
1015f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        commit_to_activate_duration_(commit_to_activate_duration) {}
1016f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1017f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual base::TimeDelta DrawDurationEstimate() OVERRIDE {
1018f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return draw_duration_;
1019f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1020f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual base::TimeDelta BeginMainFrameToCommitDurationEstimate() OVERRIDE {
1021f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return begin_main_frame_to_commit_duration_;
1022f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1023f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual base::TimeDelta CommitToActivateDurationEstimate() OVERRIDE {
1024f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return commit_to_activate_duration_;
1025f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1026f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1027f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
1028f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::TimeDelta draw_duration_;
1029f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::TimeDelta begin_main_frame_to_commit_duration_;
1030f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::TimeDelta commit_to_activate_duration_;
1031f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
1032f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1033f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MainFrameInHighLatencyMode(int64 begin_main_frame_to_commit_estimate_in_ms,
1034f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                int64 commit_to_activate_estimate_in_ms,
10351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                bool impl_latency_takes_priority,
1036f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                bool should_send_begin_main_frame) {
1037f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Set up client with specified estimates (draw duration is set to 1).
1038f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SchedulerClientWithFixedEstimates client(
1039f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(1),
1040f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(
1041f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          begin_main_frame_to_commit_estimate_in_ms),
1042f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms));
1043a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SchedulerSettings default_scheduler_settings;
1044cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
1045f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetCanStart();
1046f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetVisible(true);
1047f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetCanDraw(true);
10481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scheduler->SetImplLatencyTakesPriority(impl_latency_takes_priority);
1049c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1050f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1051f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Impl thread hits deadline before commit finishes.
1052f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client.Reset();
1053f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetNeedsCommit();
1054f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(scheduler->MainThreadIsInHighLatencyMode());
10551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
1056f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(scheduler->MainThreadIsInHighLatencyMode());
1057a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
1058f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode());
1059a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
1060a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
1061f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode());
1062f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(client.HasAction("ScheduledActionSendBeginMainFrame"));
1063f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1064f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client.Reset();
1065f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetNeedsCommit();
1066f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode());
10671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
1068f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(scheduler->MainThreadIsInHighLatencyMode());
1069a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
1070f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(scheduler->MainThreadIsInHighLatencyMode(),
1071f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            should_send_begin_main_frame);
1072f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(client.HasAction("ScheduledActionSendBeginMainFrame"),
1073f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            should_send_begin_main_frame);
1074f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1075f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1076f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST(SchedulerTest,
1077f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) {
1078f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Set up client so that estimates indicate that we can commit and activate
1079f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // before the deadline (~8ms by default).
1080a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MainFrameInHighLatencyMode(1, 1, false, false);
1081f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1082f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1083f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) {
1084f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Set up client so that estimates indicate that the commit cannot finish
1085f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // before the deadline (~8ms by default).
1086a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MainFrameInHighLatencyMode(10, 1, false, true);
1087f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1088f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1089f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) {
1090f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Set up client so that estimates indicate that the activate cannot finish
1091f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // before the deadline (~8ms by default).
1092a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MainFrameInHighLatencyMode(1, 10, false, true);
1093a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1094a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
10951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) {
1096a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Set up client so that estimates indicate that we can commit and activate
10971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // before the deadline (~8ms by default), but also enable impl latency takes
1098a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // priority mode.
1099a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  MainFrameInHighLatencyMode(1, 1, true, true);
1100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST(SchedulerTest, PollForCommitCompletion) {
1103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Since we are simulating a long commit, set up a client with draw duration
1104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // estimates that prevent skipping main frames to get to low latency mode.
1105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SchedulerClientWithFixedEstimates client(
1106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(1),
1107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(32),
1108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(32));
1109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  client.set_log_anticipated_draw_time_change(true);
1110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SchedulerSettings default_scheduler_settings;
1111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
1112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetCanDraw(true);
1114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetCanStart();
1115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetVisible(true);
1116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->DidCreateAndInitializeOutputSurface();
1117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetNeedsCommit();
1119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(scheduler->CommitPending());
1120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
1121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
1122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetNeedsRedraw();
1123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
11241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BeginFrameArgs frame_args = CreateBeginFrameArgsForTesting(client.now_src());
1125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  frame_args.interval = base::TimeDelta::FromMilliseconds(1000);
1126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scheduler->BeginFrame(frame_args);
1127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
1130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
11320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->DidSwapBuffers();
11330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->DidSwapBuffersComplete();
11340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // At this point, we've drawn a frame. Start another commit, but hold off on
1136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // the NotifyReadyToCommit for now.
1137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(scheduler->CommitPending());
1138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scheduler->SetNeedsCommit();
1139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scheduler->BeginFrame(frame_args);
1140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(scheduler->CommitPending());
1141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
11420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Draw and swap the frame, but don't ack the swap to simulate the Browser
11430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // blocking on the renderer.
11440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
11450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
11460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
11470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->DidSwapBuffers();
11480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Spin the event loop a few times and make sure we get more
1150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // DidAnticipateDrawTimeChange calls every time.
1151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int actions_so_far = client.num_actions_();
1152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Does three iterations to make sure that the timer is properly repeating.
1154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  for (int i = 0; i < 3; ++i) {
1155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
11561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              client.task_runner().DelayToNextTaskTime().InMicroseconds())
11575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        << scheduler->AsValue()->ToString();
1158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    client.task_runner().RunPendingTasks();
1159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    EXPECT_GT(client.num_actions_(), actions_so_far);
1160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    EXPECT_STREQ(client.Action(client.num_actions_() - 1),
1161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 "DidAnticipatedDrawTimeChange");
1162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    actions_so_far = client.num_actions_();
1163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
1164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Do the same thing after BeginMainFrame starts but still before activation.
1166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scheduler->NotifyBeginMainFrameStarted();
1167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (int i = 0; i < 3; ++i) {
1168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
11691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              client.task_runner().DelayToNextTaskTime().InMicroseconds())
11705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        << scheduler->AsValue()->ToString();
1171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    client.task_runner().RunPendingTasks();
1172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_GT(client.num_actions_(), actions_so_far);
1173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_STREQ(client.Action(client.num_actions_() - 1),
1174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 "DidAnticipatedDrawTimeChange");
1175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    actions_so_far = client.num_actions_();
1176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
1177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
11795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(SchedulerTest, BeginRetroFrame) {
1180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  FakeSchedulerClient client;
1181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SchedulerSettings scheduler_settings;
1182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
1183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scheduler->SetCanStart();
1184a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scheduler->SetVisible(true);
1185a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scheduler->SetCanDraw(true);
1186a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1189a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.Reset();
1190a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scheduler->SetNeedsCommit();
11915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
1192a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
1193a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.Reset();
1194a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Create a BeginFrame with a long deadline to avoid race conditions.
1196a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // This is the first BeginFrame, which will be handled immediately.
11971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BeginFrameArgs args = CreateBeginFrameArgsForTesting(client.now_src());
1198a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  args.deadline += base::TimeDelta::FromHours(1);
1199a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scheduler->BeginFrame(args);
1200a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1201a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1202a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
12035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
1204a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.Reset();
1205a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1206a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Queue BeginFrames while we are still handling the previous BeginFrame.
1207a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  args.frame_time += base::TimeDelta::FromSeconds(1);
1208a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scheduler->BeginFrame(args);
1209a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  args.frame_time += base::TimeDelta::FromSeconds(1);
1210a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scheduler->BeginFrame(args);
1211a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
12125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // If we don't swap on the deadline, we wait for the next BeginImplFrame.
1213a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
1214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
1215a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
12165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
1217a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.Reset();
1218a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1219a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // NotifyReadyToCommit should trigger the commit.
1220a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scheduler->NotifyBeginMainFrameStarted();
1221a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  scheduler->NotifyReadyToCommit();
1222a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
12235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
1224a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.Reset();
1225a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1226a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // BeginImplFrame should prepare the draw.
1227a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted BeginRetroFrame.
12285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
12295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
1230a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
12315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
1232a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.Reset();
1233a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1234a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // BeginImplFrame deadline should draw.
1235a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
12365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
1237a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
12385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
1239a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.Reset();
1240a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1241a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
1242a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // to avoid excessive toggles.
1243a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted BeginRetroFrame.
1244a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
1245a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1246a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.Reset();
1247a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
1248a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
1249a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
12505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
1251a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  client.Reset();
1252a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
1253a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
12540529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochTEST(SchedulerTest, BeginRetroFrame_SwapThrottled) {
12550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  FakeSchedulerClient client;
12560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SchedulerSettings scheduler_settings;
1257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
12580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->SetCanStart();
12590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->SetVisible(true);
12600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->SetCanDraw(true);
12610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
12620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
12630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // To test swap ack throttling, this test disables automatic swap acks.
12640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->SetMaxSwapsPending(1);
12650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.SetAutomaticSwapAck(false);
12660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
12670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
12680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.Reset();
12690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->SetNeedsCommit();
12705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
12710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
12720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.Reset();
12730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
12740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Create a BeginFrame with a long deadline to avoid race conditions.
12750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // This is the first BeginFrame, which will be handled immediately.
12761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BeginFrameArgs args = CreateBeginFrameArgsForTesting(client.now_src());
12770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  args.deadline += base::TimeDelta::FromHours(1);
12780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->BeginFrame(args);
12790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
12800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
12810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
12825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
12830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.Reset();
12840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
12850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Queue BeginFrame while we are still handling the previous BeginFrame.
12860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
12870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  args.frame_time += base::TimeDelta::FromSeconds(1);
12880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->BeginFrame(args);
1289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
12900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
12910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.Reset();
12920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
12930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // NotifyReadyToCommit should trigger the pending commit and draw.
12940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->NotifyBeginMainFrameStarted();
12950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->NotifyReadyToCommit();
12960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
12975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
12980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.Reset();
12990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Swapping will put us into a swap throttled state.
13010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted deadline.
13025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
13035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
13040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
13055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
13060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.Reset();
13070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // While swap throttled, BeginRetroFrames should trigger BeginImplFrames
13090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // but not a BeginMainFrame or draw.
13100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->SetNeedsCommit();
13110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.task_runner().RunPendingTasks();  // Run posted BeginRetroFrame.
13120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_ACTION("WillBeginImplFrame", client, 0, 1);
13130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
13145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
13150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.Reset();
13160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Queue BeginFrame while we are still handling the previous BeginFrame.
13180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  args.frame_time += base::TimeDelta::FromSeconds(1);
13190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->BeginFrame(args);
1320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
13210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
13225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
13230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.Reset();
13240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Take us out of a swap throttled state.
13260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->DidSwapBuffersComplete();
13270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 0, 1);
13280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
13295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
13300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.Reset();
13310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
13320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // BeginImplFrame deadline should draw.
13330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scheduler->SetNeedsRedraw();
13341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
13351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(client.task_runner().RunTasksWhile(
13361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      client.ImplFrameDeadlinePending(true)));
13371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
13385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
13395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
13405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
13415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(client.needs_begin_frame());
13425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
13435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
13445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
13455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid BeginFramesNotFromClient(bool begin_frame_scheduling_enabled,
13465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                              bool throttle_frame_production) {
13475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  FakeSchedulerClient client;
13485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SchedulerSettings scheduler_settings;
13495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler_settings.begin_frame_scheduling_enabled =
13505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      begin_frame_scheduling_enabled;
13515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler_settings.throttle_frame_production = throttle_frame_production;
1352cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
13535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->SetCanStart();
13545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->SetVisible(true);
13555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->SetCanDraw(true);
13565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
13575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
13585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // SetNeedsCommit should begin the frame on the next BeginImplFrame
13595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // without calling SetNeedsBeginFrame.
13605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
13615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->SetNeedsCommit();
13625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
1363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
13645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
13655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
13665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // When the client-driven BeginFrame are disabled, the scheduler posts it's
13675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // own BeginFrame tasks.
13685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.task_runner().RunPendingTasks();  // Run posted BeginFrame.
13695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
13705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
13715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
13725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
13735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
13745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
13755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // If we don't swap on the deadline, we wait for the next BeginFrame.
13765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.task_runner().RunPendingTasks();  // Run posted deadline.
1377f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
13785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
13795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
13805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
13815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
13825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // NotifyReadyToCommit should trigger the commit.
13835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->NotifyBeginMainFrameStarted();
13845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->NotifyReadyToCommit();
13855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
13865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
13875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
13885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
13895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // BeginImplFrame should prepare the draw.
13905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.task_runner().RunPendingTasks();  // Run posted BeginFrame.
13915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
13925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
13935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
13945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
13955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
13965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
13975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // BeginImplFrame deadline should draw.
13981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.task_runner().RunTasksWhile(client.ImplFrameDeadlinePending(true));
13995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
14000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
14015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
14020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  client.Reset();
14035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
14055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // to avoid excessive toggles.
14065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.task_runner().RunPendingTasks();  // Run posted BeginFrame.
14075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
14085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
14095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
14105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Make sure SetNeedsBeginFrame isn't called on the client
14125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // when the BeginFrame is no longer needed.
14135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.task_runner().RunPendingTasks();  // Run posted deadline.
1414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
14155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
14165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
14175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
14185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(SchedulerTest, SyntheticBeginFrames) {
14205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool begin_frame_scheduling_enabled = false;
14215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool throttle_frame_production = true;
14225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  BeginFramesNotFromClient(begin_frame_scheduling_enabled,
14235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           throttle_frame_production);
14245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
14255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(SchedulerTest, VSyncThrottlingDisabled) {
14275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool begin_frame_scheduling_enabled = true;
14285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool throttle_frame_production = false;
14295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  BeginFramesNotFromClient(begin_frame_scheduling_enabled,
14305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           throttle_frame_production);
14315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
14325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(SchedulerTest, SyntheticBeginFrames_And_VSyncThrottlingDisabled) {
14345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool begin_frame_scheduling_enabled = false;
14355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool throttle_frame_production = false;
14365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  BeginFramesNotFromClient(begin_frame_scheduling_enabled,
14375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           throttle_frame_production);
14385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
14395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid BeginFramesNotFromClient_SwapThrottled(bool begin_frame_scheduling_enabled,
14415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                            bool throttle_frame_production) {
14425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  FakeSchedulerClient client;
14435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SchedulerSettings scheduler_settings;
14445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler_settings.begin_frame_scheduling_enabled =
14455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      begin_frame_scheduling_enabled;
14465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler_settings.throttle_frame_production = throttle_frame_production;
1447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
14485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->SetCanStart();
14495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->SetVisible(true);
14505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->SetCanDraw(true);
14515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
14525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // To test swap ack throttling, this test disables automatic swap acks.
14545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->SetMaxSwapsPending(1);
14555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.SetAutomaticSwapAck(false);
14565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
14585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
14595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->SetNeedsCommit();
14605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
1461f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
14625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
14635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Trigger the first BeginImplFrame and BeginMainFrame
14655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.task_runner().RunPendingTasks();  // Run posted BeginFrame.
14665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
14675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
14685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
14695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
14705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
14715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // NotifyReadyToCommit should trigger the pending commit and draw.
14735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->NotifyBeginMainFrameStarted();
14745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->NotifyReadyToCommit();
14755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
14765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
14775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
14785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Swapping will put us into a swap throttled state.
14805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.task_runner().RunPendingTasks();  // Run posted deadline.
14815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
14825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
14835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
14845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
14855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
14865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // While swap throttled, BeginFrames should trigger BeginImplFrames,
14885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // but not a BeginMainFrame or draw.
14895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->SetNeedsCommit();
14905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.task_runner().RunPendingTasks();  // Run posted BeginFrame.
14915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("WillBeginImplFrame", client, 0, 1);
14925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
14935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
14945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
14955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // Take us out of a swap throttled state.
14975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->DidSwapBuffersComplete();
14985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 0, 1);
14995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
15005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
15015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
15025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
15035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  // BeginImplFrame deadline should draw.
15045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scheduler->SetNeedsRedraw();
15055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.task_runner().RunPendingTasks();  // Run posted deadline.
15065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
15075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
15085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
15095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  EXPECT_FALSE(client.needs_begin_frame());
15105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client.Reset();
15115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
15125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
15131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(SchedulerTest, SyntheticBeginFrames_SwapThrottled) {
15145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool begin_frame_scheduling_enabled = false;
15155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool throttle_frame_production = true;
15165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  BeginFramesNotFromClient_SwapThrottled(begin_frame_scheduling_enabled,
15175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                         throttle_frame_production);
15185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
15195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
15205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(SchedulerTest, VSyncThrottlingDisabled_SwapThrottled) {
15215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool begin_frame_scheduling_enabled = true;
15225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool throttle_frame_production = false;
15235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  BeginFramesNotFromClient_SwapThrottled(begin_frame_scheduling_enabled,
15245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                         throttle_frame_production);
15255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
15265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
15275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuTEST(SchedulerTest,
15281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     SyntheticBeginFrames_And_VSyncThrottlingDisabled_SwapThrottled) {
15295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool begin_frame_scheduling_enabled = false;
15305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool throttle_frame_production = false;
15315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  BeginFramesNotFromClient_SwapThrottled(begin_frame_scheduling_enabled,
15325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                         throttle_frame_production);
15330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
15340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(SchedulerTest, DidLoseOutputSurfaceAfterOutputSurfaceIsInitialized) {
1536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FakeSchedulerClient client;
1537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SchedulerSettings scheduler_settings;
1538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
1539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanStart();
1540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetVisible(true);
1541cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanDraw(true);
1542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
1544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1545cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->DidCreateAndInitializeOutputSurface();
1546f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
1547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1548cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->DidLoseOutputSurface();
1549cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
1550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1552cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(SchedulerTest, DidLoseOutputSurfaceAfterBeginFrameStarted) {
1553cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FakeSchedulerClient client;
1554cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SchedulerSettings scheduler_settings;
1555cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
1556cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanStart();
1557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetVisible(true);
1558cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanDraw(true);
1559cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1560cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
1561cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1562cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // SetNeedsCommit should begin the frame.
1563cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetNeedsCommit();
1565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
1566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1567cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
15681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
1569cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1572cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1573cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1574cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->DidLoseOutputSurface();
1575cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Do nothing when impl frame is in deadine pending state.
1576f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
1577cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1578cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1579cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
1580cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
1581cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionCommit", client, 0, 1);
1582cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted deadline.
1585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
1586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1588cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(
1589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    bool impl_side_painting) {
1590cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FakeSchedulerClient client;
1591cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SchedulerSettings scheduler_settings;
1592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler_settings.impl_side_painting = impl_side_painting;
1593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
1594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanStart();
1595cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetVisible(true);
1596cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanDraw(true);
1597cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1598cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
1599cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1600cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1601cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // SetNeedsCommit should begin the frame.
1602cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1603cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetNeedsCommit();
1604cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
1605cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1606cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
16071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
1608cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1609cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1610cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1611cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1612cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1613cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->DidLoseOutputSurface();
1614cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Do nothing when impl frame is in deadine pending state.
1615f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
1616cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1617cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
16181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Run posted deadline.
16191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
16201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.task_runner().RunTasksWhile(client.ImplFrameDeadlinePending(true));
1621cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // OnBeginImplFrameDeadline didn't schedule any actions because main frame is
1622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // not yet completed.
1623f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
16241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1625cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // BeginImplFrame is not started.
16271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.task_runner().RunUntilTime(client.now_src()->Now() +
16281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                    base::TimeDelta::FromMilliseconds(10));
1629f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
1630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1633cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
1634cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
1635cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (impl_side_painting) {
1636cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_ACTION("ScheduledActionCommit", client, 0, 3);
1637116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_ACTION("ScheduledActionActivateSyncTree", client, 1, 3);
1638cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client, 2, 3);
1639cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
1640cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_ACTION("ScheduledActionCommit", client, 0, 2);
1641cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client, 1, 2);
1642cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1643cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1644cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1645cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(SchedulerTest, DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency) {
1646cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool impl_side_painting = false;
1647cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting);
1648cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1649cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1650cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(SchedulerTest,
1651cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)     DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatencyWithImplPaint) {
1652cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool impl_side_painting = true;
1653cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting);
1654cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1655cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1656cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting) {
1657cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FakeSchedulerClient client;
1658cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SchedulerSettings scheduler_settings;
1659cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler_settings.impl_side_painting = impl_side_painting;
1660cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
1661cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanStart();
1662cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetVisible(true);
1663cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanDraw(true);
1664cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1665cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
1666cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1667cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1668cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // SetNeedsCommit should begin the frame.
1669cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1670cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetNeedsCommit();
1671cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
1672cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1673cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
16741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
1675cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1680cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
1681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
1682cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1683cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1684cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1685cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->DidLoseOutputSurface();
1686cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (impl_side_painting) {
1687116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Sync tree should be forced to activate.
1688116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client);
1689cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  } else {
1690cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Do nothing when impl frame is in deadine pending state.
1691f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    EXPECT_NO_ACTION(client);
1692cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1693cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1694cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1695cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted deadline.
1696cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
1697cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1698cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1699cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(SchedulerTest, DidLoseOutputSurfaceAfterReadyToCommit) {
1700cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DidLoseOutputSurfaceAfterReadyToCommit(false);
1701cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1702cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1703cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(SchedulerTest, DidLoseOutputSurfaceAfterReadyToCommitWithImplPainting) {
1704cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DidLoseOutputSurfaceAfterReadyToCommit(true);
1705cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1706cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1707cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(SchedulerTest, DidLoseOutputSurfaceAfterSetNeedsManageTiles) {
1708cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FakeSchedulerClient client;
1709cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SchedulerSettings scheduler_settings;
1710cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
1711cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanStart();
1712cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetVisible(true);
1713cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanDraw(true);
1714cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1715cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1716cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1717cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetNeedsManageTiles();
1718cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetNeedsRedraw();
1719cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
1720cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1721cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1722cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
17231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  client.AdvanceFrame();
1724cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1725cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
1726cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1727cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1729cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->DidLoseOutputSurface();
1730f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
1731cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1732cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1733cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted deadline.
1734cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionManageTiles", client, 0, 2);
1735cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client, 1, 2);
1736cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1737cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1738cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(SchedulerTest, DidLoseOutputSurfaceAfterBeginRetroFramePosted) {
1739cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FakeSchedulerClient client;
1740cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SchedulerSettings scheduler_settings;
1741cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
1742cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanStart();
1743cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetVisible(true);
1744cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanDraw(true);
1745cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1746cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1747cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1748cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1749cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetNeedsCommit();
1750cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1751cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
1752cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1753cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create a BeginFrame with a long deadline to avoid race conditions.
1754cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This is the first BeginFrame, which will be handled immediately.
1755cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
17561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BeginFrameArgs args = CreateBeginFrameArgsForTesting(client.now_src());
1757cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  args.deadline += base::TimeDelta::FromHours(1);
1758cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->BeginFrame(args);
1759cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1760cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1761cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1762cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1763cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1764cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Queue BeginFrames while we are still handling the previous BeginFrame.
1765cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  args.frame_time += base::TimeDelta::FromSeconds(1);
1766cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->BeginFrame(args);
1767cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  args.frame_time += base::TimeDelta::FromSeconds(1);
1768cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->BeginFrame(args);
1769cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1770cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If we don't swap on the deadline, we wait for the next BeginImplFrame.
1771cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1772cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted deadline.
1773f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
1774cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1775cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1776cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1777cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // NotifyReadyToCommit should trigger the commit.
1778cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1779cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
1780cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
1781cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1782cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1783cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1784cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1785cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(scheduler->IsBeginRetroFrameArgsEmpty());
1786cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->DidLoseOutputSurface();
1787cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
1788cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1789cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->IsBeginRetroFrameArgsEmpty());
1790cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1791cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Posted BeginRetroFrame is aborted.
1792cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1793cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();
1794f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
1795cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1796cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1797cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TEST(SchedulerTest, DidLoseOutputSurfaceDuringBeginRetroFrameRunning) {
1798cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  FakeSchedulerClient client;
1799cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SchedulerSettings scheduler_settings;
1800cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
1801cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanStart();
1802cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetVisible(true);
1803cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetCanDraw(true);
1804cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
1805cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1806cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
1807cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1808cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->SetNeedsCommit();
1809cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1810cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
1811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1812cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Create a BeginFrame with a long deadline to avoid race conditions.
1813cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This is the first BeginFrame, which will be handled immediately.
1814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
18151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  BeginFrameArgs args = CreateBeginFrameArgsForTesting(client.now_src());
1816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  args.deadline += base::TimeDelta::FromHours(1);
1817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->BeginFrame(args);
1818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
1820cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1823cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Queue BeginFrames while we are still handling the previous BeginFrame.
1824cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  args.frame_time += base::TimeDelta::FromSeconds(1);
1825cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->BeginFrame(args);
1826cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  args.frame_time += base::TimeDelta::FromSeconds(1);
1827cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->BeginFrame(args);
1828cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1829cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If we don't swap on the deadline, we wait for the next BeginImplFrame.
1830cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1831cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted deadline.
1832f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
1833cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1834cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1835cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1836cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // NotifyReadyToCommit should trigger the commit.
1837cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1838cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
1839cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->NotifyReadyToCommit();
1840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1841cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1842cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1843cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // BeginImplFrame should prepare the draw.
1844cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1845cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted BeginRetroFrame.
1846cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
1847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
1848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
1849cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1851cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1852cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(scheduler->IsBeginRetroFrameArgsEmpty());
1853cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  scheduler->DidLoseOutputSurface();
1854f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
1855cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(scheduler->IsBeginRetroFrameArgsEmpty());
1856cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1857cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // BeginImplFrame deadline should abort drawing.
1858cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1859cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted deadline.
1860cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
1861cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
1862cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXPECT_TRUE(client.needs_begin_frame());
1863cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1864cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // No more BeginRetroFrame because BeginRetroFrame queue is cleared.
1865cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.Reset();
1866cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  client.task_runner().RunPendingTasks();
1867f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  EXPECT_NO_ACTION(client);
1868cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1869cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
18701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(SchedulerTest,
18711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     StopBeginFrameAfterDidLoseOutputSurfaceWithSyntheticBeginFrameSource) {
187246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  FakeSchedulerClient client;
187346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  SchedulerSettings scheduler_settings;
187446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scheduler_settings.begin_frame_scheduling_enabled = false;
187546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
187646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scheduler->SetCanStart();
187746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scheduler->SetVisible(true);
187846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scheduler->SetCanDraw(true);
187946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
188046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
188146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
188246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  client.Reset();
188346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(scheduler->IsSyntheticBeginFrameSourceActive());
188446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scheduler->SetNeedsCommit();
188546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(scheduler->IsSyntheticBeginFrameSourceActive());
188646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
188746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  client.Reset();
188846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted Tick.
188946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
189046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
189146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
189246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(scheduler->IsSyntheticBeginFrameSourceActive());
189346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
189446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // NotifyReadyToCommit should trigger the commit.
189546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  client.Reset();
189646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scheduler->NotifyBeginMainFrameStarted();
189746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scheduler->NotifyReadyToCommit();
189846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
189946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_TRUE(scheduler->IsSyntheticBeginFrameSourceActive());
190046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
190146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  client.Reset();
190246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  scheduler->DidLoseOutputSurface();
190346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_EQ(0, client.num_actions_());
190446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(scheduler->IsSyntheticBeginFrameSourceActive());
190546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
190646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  client.Reset();
190746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  client.task_runner().RunPendingTasks();  // Run posted deadline.
190846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
190946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_FALSE(scheduler->IsSyntheticBeginFrameSourceActive());
191046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
191146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
19121675a649fd7a8b3cb80ffddae2dc181f122353c5Ben MurdochTEST(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {
19131675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  FakeSchedulerClient client;
19141675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  SchedulerSettings scheduler_settings;
19151675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  scheduler_settings.impl_side_painting = true;
19161675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  TestScheduler* scheduler = client.CreateScheduler(scheduler_settings);
19171675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  scheduler->SetCanStart();
19181675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  scheduler->SetVisible(true);
19191675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  scheduler->SetCanDraw(true);
19201675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
19211675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
19221675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
19231675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
19241675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  // SetNeedsCommit should begin the frame.
19251675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  client.Reset();
19261675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  scheduler->SetNeedsCommit();
19271675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  EXPECT_SINGLE_ACTION("SetNeedsBeginFrame", client);
19281675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
19291675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  client.Reset();
19301675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  client.AdvanceFrame();
19311675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
19321675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client, 1, 2);
19331675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
19341675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
19351675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  client.Reset();
19361675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  scheduler->NotifyBeginMainFrameStarted();
19371675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  scheduler->NotifyReadyToCommit();
19381675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
19391675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
19401675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  client.Reset();
19411675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  scheduler->SetVisible(false);
19421675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  // Sync tree should be forced to activate.
19431675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch  EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client);
19441675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch}
19451675a649fd7a8b3cb80ffddae2dc181f122353c5Ben Murdoch
19462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
19472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1948