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)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/cc_export.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "cc/output/begin_frame_args.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "cc/scheduler/draw_result.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/scheduler/scheduler_settings.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace base {
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace debug {
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class ConvertableToTraceForamt;
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class TracedValue;
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class Value;
243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The SchedulerStateMachine decides how to coordinate main thread activites
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// like painting/running javascript with rendering and input activities on the
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// impl thread.
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The state machine tracks internal state but is also influenced by external
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// state.  Internal state includes things like whether a frame has been
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// requested, while external state includes things like the current time being
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// near to the vblank time.
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The scheduler seperates "what to do next" from the updating of its internal
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// state to make testing cleaner.
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CC_EXPORT SchedulerStateMachine {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // settings must be valid for the lifetime of this class.
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit SchedulerStateMachine(const SchedulerSettings& settings);
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  enum OutputSurfaceState {
45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    OUTPUT_SURFACE_ACTIVE,
46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    OUTPUT_SURFACE_LOST,
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    OUTPUT_SURFACE_CREATING,
48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT,
49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION,
50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  };
51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  static const char* OutputSurfaceStateToString(OutputSurfaceState state);
52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Note: BeginImplFrameState will always cycle through all the states in
548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // order. Whether or not it actually waits or draws, it will at least try to
558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // wait in BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME and try to draw in
568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  enum BeginImplFrameState {
588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    BEGIN_IMPL_FRAME_STATE_IDLE,
598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  };
638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  static const char* BeginImplFrameStateToString(BeginImplFrameState state);
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum CommitState {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    COMMIT_STATE_IDLE,
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED,
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    COMMIT_STATE_READY_TO_COMMIT,
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    COMMIT_STATE_WAITING_FOR_ACTIVATION,
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    COMMIT_STATE_WAITING_FOR_FIRST_DRAW,
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static const char* CommitStateToString(CommitState state);
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  enum ForcedRedrawOnTimeoutState {
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FORCED_REDRAW_STATE_IDLE,
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FORCED_REDRAW_STATE_WAITING_FOR_COMMIT,
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION,
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    FORCED_REDRAW_STATE_WAITING_FOR_DRAW,
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  };
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  static const char* ForcedRedrawOnTimeoutStateToString(
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ForcedRedrawOnTimeoutState state);
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool CommitPending() const {
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)           commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED ||
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           commit_state_ == COMMIT_STATE_READY_TO_COMMIT;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CommitState commit_state() const { return commit_state_; }
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool RedrawPending() const { return needs_redraw_; }
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool ManageTilesPending() const { return needs_manage_tiles_; }
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum Action {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ACTION_NONE,
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ACTION_ANIMATE,
978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    ACTION_SEND_BEGIN_MAIN_FRAME,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ACTION_COMMIT,
99ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    ACTION_UPDATE_VISIBLE_TILES,
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ACTION_ACTIVATE_SYNC_TREE,
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ACTION_DRAW_AND_SWAP_FORCED,
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ACTION_DRAW_AND_SWAP_ABORT,
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ACTION_MANAGE_TILES,
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  static const char* ActionToString(Action action);
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<base::debug::ConvertableToTraceFormat> AsValue() const;
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void AsValueInto(base::debug::TracedValue* dict, base::TimeTicks now) const;
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Action NextAction() const;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void UpdateState(Action action);
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Indicates whether the impl thread needs a BeginImplFrame callback in order
1168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // to make progress.
117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  bool BeginFrameNeeded() const;
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Indicates that we need to independently poll for new state and actions
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // because we can't expect a BeginImplFrame. This is mostly used to avoid
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // drawing repeat frames with the synchronous compositor without dropping
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // necessary actions on the floor.
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool ShouldPollForAnticipatedDrawTriggers() const;
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Indicates that the system has entered and left a BeginImplFrame callback.
1268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // The scheduler will not draw more than once in a given BeginImplFrame
1278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // callback nor send more than one BeginMainFrame message.
1288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void OnBeginImplFrame(const BeginFrameArgs& args);
1298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void OnBeginImplFrameDeadlinePending();
1308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void OnBeginImplFrameDeadline();
1318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void OnBeginImplFrameIdle();
1328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  bool ShouldTriggerBeginImplFrameDeadlineEarly() const;
1338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  BeginImplFrameState begin_impl_frame_state() const {
1348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return begin_impl_frame_state_;
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // If the main thread didn't manage to produce a new frame in time for the
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // impl thread to draw, it is in a high latency mode.
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool MainThreadIsInHighLatencyMode() const;
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // PollForAnticipatedDrawTriggers is used by the synchronous compositor to
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // avoid requesting BeginImplFrames when we won't actually draw but still
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // need to advance our state at vsync intervals.
144d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void DidEnterPollForAnticipatedDrawTriggers();
145d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void DidLeavePollForAnticipatedDrawTriggers();
146d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool inside_poll_for_anticipated_draw_triggers() const {
147d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return inside_poll_for_anticipated_draw_triggers_;
148d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  }
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Indicates whether the LayerTreeHostImpl is visible.
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetVisible(bool visible);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Indicates that a redraw is required, either due to the impl tree changing
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // or the screen being damaged and simply needing redisplay.
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetNeedsRedraw();
15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool needs_redraw() const { return needs_redraw_; }
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  void SetNeedsAnimate();
1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool needs_animate() const { return needs_animate_; }
1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
161d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Indicates that manage-tiles is required. This guarantees another
162d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // ManageTiles will occur shortly (even if no redraw is required).
163d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void SetNeedsManageTiles();
164d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Sets how many swaps can be pending to the OutputSurface.
1660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void SetMaxSwapsPending(int max);
1670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // If the scheduler attempted to draw and swap, this provides feedback
1690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // regarding whether or not the swap actually occured. We might skip the
1700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // swap when there is not damage, for example.
1710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void DidSwapBuffers();
1720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Indicates whether a redraw is required because we are currently rendering
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // with a low resolution or checkerboarded tile.
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void SetSwapUsedIncompleteTile(bool used_incomplete_tile);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Notification from the OutputSurface that a swap has been consumed.
1780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void DidSwapBuffersComplete();
1790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Indicates whether to prioritize impl thread latency (i.e., animation
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // smoothness) over new content activation.
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void SetImplLatencyTakesPriority(bool impl_latency_takes_priority);
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool impl_latency_takes_priority() const {
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return impl_latency_takes_priority_;
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Indicates whether ACTION_DRAW_AND_SWAP_IF_POSSIBLE drew to the screen.
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void DidDrawIfPossibleCompleted(DrawResult result);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Indicates that a new commit flow needs to be performed, either to pull
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // updates from the main thread to the impl, or to push deltas from the impl
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // thread to main.
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetNeedsCommit();
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Call this only in response to receiving an ACTION_SEND_BEGIN_MAIN_FRAME
1968bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // from NextAction.
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Indicates that all painting is complete.
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void NotifyReadyToCommit();
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Call this only in response to receiving an ACTION_SEND_BEGIN_MAIN_FRAME
2018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // from NextAction if the client rejects the BeginMainFrame message.
2028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // If did_handle is false, then another commit will be retried soon.
2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  void BeginMainFrameAborted(bool did_handle);
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Set that we can create the first OutputSurface and start the scheduler.
206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetCanStart() { can_start_ = true; }
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void SetSkipNextBeginMainFrameToReduceLatency();
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Indicates whether drawing would, at this time, make sense.
2110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // CanDraw can be used to suppress flashes or checkerboarding
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // when such behavior would be undesirable.
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetCanDraw(bool can);
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Indicates that scheduled BeginMainFrame is started.
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void NotifyBeginMainFrameStarted();
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
218424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Indicates that the pending tree is ready for activation.
219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void NotifyReadyToActivate();
220424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_pending_tree() const { return has_pending_tree_; }
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool active_tree_needs_first_draw() const {
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return active_tree_needs_first_draw_;
224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void DidManageTiles();
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DidLoseOutputSurface();
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void DidCreateAndInitializeOutputSurface();
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool HasInitializedOutputSurface() const;
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // True if we need to abort draws to make forward progress.
2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool PendingDrawsShouldBeAborted() const;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
234a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  bool SupportsProactiveBeginFrame() const;
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  void SetContinuousPainting(bool continuous_painting) {
237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    continuous_painting_ = continuous_painting;
238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  bool CouldSendBeginMainFrame() const;
2416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(zmo): This is temporary for debugging crbug.com/393331.
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // We should remove it afterwards.
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string GetStatesForDebugging() const;
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
2475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool BeginFrameNeededToAnimateOrDraw() const;
248a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  bool ProactiveBeginFrameWanted() const;
24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // True if we need to force activations to make forward progress.
251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool PendingActivationsShouldBeForced() const;
252424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
2535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool ShouldAnimate() const;
254424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ShouldBeginOutputSurfaceCreation() const;
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ShouldDrawForced() const;
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool ShouldDraw() const;
257424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ShouldActivatePendingTree() const;
258ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  bool ShouldUpdateVisibleTiles() const;
2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  bool ShouldSendBeginMainFrame() const;
260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool ShouldCommit() const;
261d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool ShouldManageTiles() const;
2623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void AdvanceCurrentFrameNumber();
2648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  bool HasSentBeginMainFrameThisFrame() const;
26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool HasUpdatedVisibleTilesThisFrame() const;
266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool HasRequestedSwapThisFrame() const;
26768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  bool HasSwappedThisFrame() const;
2683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void UpdateStateOnCommit(bool commit_was_aborted);
270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  void UpdateStateOnActivation();
2710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void UpdateStateOnDraw(bool did_request_swap);
272d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void UpdateStateOnManageTiles();
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const SchedulerSettings settings_;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  OutputSurfaceState output_surface_state_;
2778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  BeginImplFrameState begin_impl_frame_state_;
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommitState commit_state_;
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ForcedRedrawOnTimeoutState forced_redraw_state_;
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
281a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  BeginFrameArgs begin_impl_frame_args_;
28268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  int commit_count_;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int current_frame_number_;
2855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int last_frame_number_animate_performed_;
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int last_frame_number_swap_performed_;
287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int last_frame_number_swap_requested_;
2888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  int last_frame_number_begin_main_frame_sent_;
28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int last_frame_number_update_visible_tiles_was_called_;
29068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // manage_tiles_funnel_ is "filled" each time ManageTiles is called
2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // and "drained" on each BeginImplFrame. If the funnel gets too full,
2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // we start throttling ACTION_MANAGE_TILES such that we average one
2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // ManageTile per BeginImplFrame.
2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int manage_tiles_funnel_;
2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int consecutive_checkerboard_animations_;
2970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int max_pending_swaps_;
2980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  int pending_swaps_;
2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_redraw_;
3005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  bool needs_animate_;
301d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool needs_manage_tiles_;
3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool swap_used_incomplete_tile_;
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_commit_;
304d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  bool inside_poll_for_anticipated_draw_triggers_;
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool visible_;
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool can_start_;
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool can_draw_;
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_pending_tree_;
309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  bool pending_tree_is_ready_for_activation_;
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  bool active_tree_needs_first_draw_;
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool did_create_and_initialize_first_output_surface_;
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool impl_latency_takes_priority_;
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  bool skip_next_begin_main_frame_to_reduce_latency_;
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool skip_begin_main_frame_to_reduce_latency_;
315c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool continuous_painting_;
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SchedulerStateMachine);
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_
324