scheduler_state_machine.h revision 558790d6acca3451cf3a6b497803a5f07d0bec58
1// Copyright 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_
6#define CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/time/time.h"
12#include "cc/base/cc_export.h"
13#include "cc/output/begin_frame_args.h"
14#include "cc/scheduler/scheduler_settings.h"
15
16namespace cc {
17
18// The SchedulerStateMachine decides how to coordinate main thread activites
19// like painting/running javascript with rendering and input activities on the
20// impl thread.
21//
22// The state machine tracks internal state but is also influenced by external
23// state.  Internal state includes things like whether a frame has been
24// requested, while external state includes things like the current time being
25// near to the vblank time.
26//
27// The scheduler seperates "what to do next" from the updating of its internal
28// state to make testing cleaner.
29class CC_EXPORT SchedulerStateMachine {
30 public:
31  // settings must be valid for the lifetime of this class.
32  explicit SchedulerStateMachine(const SchedulerSettings& settings);
33
34  enum CommitState {
35    COMMIT_STATE_IDLE,
36    COMMIT_STATE_FRAME_IN_PROGRESS,
37    COMMIT_STATE_READY_TO_COMMIT,
38    COMMIT_STATE_WAITING_FOR_FIRST_DRAW,
39    COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW,
40  };
41
42  enum TextureState {
43    LAYER_TEXTURE_STATE_UNLOCKED,
44    LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD,
45    LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD,
46  };
47
48  enum OutputSurfaceState {
49    OUTPUT_SURFACE_ACTIVE,
50    OUTPUT_SURFACE_LOST,
51    OUTPUT_SURFACE_CREATING,
52  };
53
54  bool CommitPending() const {
55    return commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS ||
56           commit_state_ == COMMIT_STATE_READY_TO_COMMIT;
57  }
58
59  bool RedrawPending() const { return needs_redraw_; }
60
61  enum Action {
62    ACTION_NONE,
63    ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD,
64    ACTION_COMMIT,
65    ACTION_UPDATE_VISIBLE_TILES,
66    ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED,
67    ACTION_DRAW_IF_POSSIBLE,
68    ACTION_DRAW_FORCED,
69    ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
70    ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD,
71  };
72  Action NextAction() const;
73  void UpdateState(Action action);
74
75  // Indicates whether the main thread needs a begin frame callback in order to
76  // make progress.
77  bool BeginFrameNeededToDrawByImplThread() const;
78  bool ProactiveBeginFrameWantedByImplThread() const;
79
80  // Indicates that the system has entered and left a BeginFrame callback.
81  // The scheduler will not draw more than once in a given BeginFrame
82  // callback nor send more than one BeginFrame message.
83  void DidEnterBeginFrame(const BeginFrameArgs& args);
84  void DidLeaveBeginFrame();
85  bool inside_begin_frame() const { return inside_begin_frame_; }
86
87  // Indicates whether the LayerTreeHostImpl is visible.
88  void SetVisible(bool visible);
89
90  // Indicates that a redraw is required, either due to the impl tree changing
91  // or the screen being damaged and simply needing redisplay.
92  void SetNeedsRedraw();
93
94  // As SetNeedsRedraw(), but ensures the draw will definitely happen even if
95  // we are not visible.
96  void SetNeedsForcedRedraw();
97
98  // Indicates that a redraw is required because we are currently rendering
99  // with a low resolution or checkerboarded tile.
100  void DidSwapUseIncompleteTile();
101
102  // Indicates whether ACTION_DRAW_IF_POSSIBLE drew to the screen or not.
103  void DidDrawIfPossibleCompleted(bool success);
104
105  // Indicates that a new commit flow needs to be performed, either to pull
106  // updates from the main thread to the impl, or to push deltas from the impl
107  // thread to main.
108  void SetNeedsCommit();
109
110  // As SetNeedsCommit(), but ensures the begin frame will be sent to the main
111  // thread even if we are not visible.  After this call we expect to go through
112  // the forced commit flow and then return to waiting for a non-forced
113  // begin frame to finish.
114  void SetNeedsForcedCommit();
115
116  // Call this only in response to receiving an
117  // ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD from NextAction.
118  // Indicates that all painting is complete.
119  void FinishCommit();
120
121  // Call this only in response to receiving an
122  // ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD from NextAction if the client
123  // rejects the begin frame message.  If did_handle is false, then
124  // another commit will be retried soon.
125  void BeginFrameAbortedByMainThread(bool did_handle);
126
127  // Request exclusive access to the textures that back single buffered
128  // layers on behalf of the main thread. Upon acquisition,
129  // ACTION_DRAW_IF_POSSIBLE will not draw until the main thread releases the
130  // textures to the impl thread by committing the layers.
131  void SetMainThreadNeedsLayerTextures();
132
133  // Set that we can create the first OutputSurface and start the scheduler.
134  void SetCanStart() { can_start_ = true; }
135
136  // Indicates whether drawing would, at this time, make sense.
137  // CanDraw can be used to supress flashes or checkerboarding
138  // when such behavior would be undesirable.
139  void SetCanDraw(bool can);
140
141  // Indicates whether or not there is a pending tree.  This influences
142  // whether or not we can succesfully commit at this time.  If the
143  // last commit is still being processed (but not blocking), it may not
144  // be possible to take another commit yet.  This overrides force commit,
145  // as a commit is already still in flight.
146  void SetHasPendingTree(bool has_pending_tree);
147  bool has_pending_tree() const { return has_pending_tree_; }
148
149  void DidLoseOutputSurface();
150  void DidCreateAndInitializeOutputSurface();
151  bool HasInitializedOutputSurface() const;
152
153  // Exposed for testing purposes.
154  void SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(int num_draws);
155
156  // False if drawing is not being prevented, true if drawing won't happen
157  // for some reason, such as not being visible.
158  bool DrawSuspendedUntilCommit() const;
159
160  std::string ToString();
161
162 protected:
163  bool ShouldDrawForced() const;
164  bool ScheduledToDraw() const;
165  bool ShouldDraw() const;
166  bool ShouldAttemptTreeActivation() const;
167  bool ShouldAcquireLayerTexturesForMainThread() const;
168  bool ShouldUpdateVisibleTiles() const;
169  bool HasDrawnThisFrame() const;
170  bool HasAttemptedTreeActivationThisFrame() const;
171  bool HasUpdatedVisibleTilesThisFrame() const;
172  void SetPostCommitFlags();
173
174  const SchedulerSettings settings_;
175
176  CommitState commit_state_;
177  int commit_count_;
178
179  int current_frame_number_;
180  int last_frame_number_where_begin_frame_sent_to_main_thread_;
181  int last_frame_number_where_draw_was_called_;
182  int last_frame_number_where_tree_activation_attempted_;
183  int last_frame_number_where_update_visible_tiles_was_called_;
184  int consecutive_failed_draws_;
185  int maximum_number_of_failed_draws_before_draw_is_forced_;
186  bool needs_redraw_;
187  bool swap_used_incomplete_tile_;
188  bool needs_forced_redraw_;
189  bool needs_forced_redraw_after_next_commit_;
190  bool needs_redraw_after_next_commit_;
191  bool needs_commit_;
192  bool needs_forced_commit_;
193  bool expect_immediate_begin_frame_for_main_thread_;
194  bool main_thread_needs_layer_textures_;
195  bool inside_begin_frame_;
196  BeginFrameArgs last_begin_frame_args_;
197  bool visible_;
198  bool can_start_;
199  bool can_draw_;
200  bool has_pending_tree_;
201  bool draw_if_possible_failed_;
202  TextureState texture_state_;
203  OutputSurfaceState output_surface_state_;
204  bool did_create_and_initialize_first_output_surface_;
205
206 private:
207  DISALLOW_COPY_AND_ASSIGN(SchedulerStateMachine);
208};
209
210}  // namespace cc
211
212#endif  // CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_
213