- add sources.
[platform/framework/web/crosswalk.git] / src / cc / scheduler / scheduler_state_machine.h
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/memory/scoped_ptr.h"
12 #include "base/time/time.h"
13 #include "cc/base/cc_export.h"
14 #include "cc/output/begin_frame_args.h"
15 #include "cc/scheduler/scheduler_settings.h"
16
17 namespace base {
18 class Value;
19 }
20
21 namespace cc {
22
23 // The SchedulerStateMachine decides how to coordinate main thread activites
24 // like painting/running javascript with rendering and input activities on the
25 // impl thread.
26 //
27 // The state machine tracks internal state but is also influenced by external
28 // state.  Internal state includes things like whether a frame has been
29 // requested, while external state includes things like the current time being
30 // near to the vblank time.
31 //
32 // The scheduler seperates "what to do next" from the updating of its internal
33 // state to make testing cleaner.
34 class CC_EXPORT SchedulerStateMachine {
35  public:
36   // settings must be valid for the lifetime of this class.
37   explicit SchedulerStateMachine(const SchedulerSettings& settings);
38
39   enum OutputSurfaceState {
40     OUTPUT_SURFACE_ACTIVE,
41     OUTPUT_SURFACE_LOST,
42     OUTPUT_SURFACE_CREATING,
43     OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT,
44     OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION,
45   };
46   static const char* OutputSurfaceStateToString(OutputSurfaceState state);
47
48   // Note: BeginImplFrameState will always cycle through all the states in
49   // order. Whether or not it actually waits or draws, it will at least try to
50   // wait in BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME and try to draw in
51   // BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
52   enum BeginImplFrameState {
53     BEGIN_IMPL_FRAME_STATE_IDLE,
54     BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
55     BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
56     BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
57   };
58   static const char* BeginImplFrameStateToString(BeginImplFrameState state);
59
60   enum CommitState {
61     COMMIT_STATE_IDLE,
62     COMMIT_STATE_FRAME_IN_PROGRESS,
63     COMMIT_STATE_READY_TO_COMMIT,
64     COMMIT_STATE_WAITING_FOR_FIRST_DRAW,
65   };
66   static const char* CommitStateToString(CommitState state);
67
68   enum TextureState {
69     LAYER_TEXTURE_STATE_UNLOCKED,
70     LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD,
71     LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD,
72   };
73   static const char* TextureStateToString(TextureState state);
74
75   enum SynchronousReadbackState {
76     READBACK_STATE_IDLE,
77     READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME,
78     READBACK_STATE_WAITING_FOR_COMMIT,
79     READBACK_STATE_WAITING_FOR_ACTIVATION,
80     READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK,
81     READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT,
82     READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION,
83   };
84   static const char* SynchronousReadbackStateToString(
85       SynchronousReadbackState state);
86
87   enum ForcedRedrawOnTimeoutState {
88     FORCED_REDRAW_STATE_IDLE,
89     FORCED_REDRAW_STATE_WAITING_FOR_COMMIT,
90     FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION,
91     FORCED_REDRAW_STATE_WAITING_FOR_DRAW,
92   };
93   static const char* ForcedRedrawOnTimeoutStateToString(
94       ForcedRedrawOnTimeoutState state);
95
96   bool CommitPending() const {
97     return commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS ||
98            commit_state_ == COMMIT_STATE_READY_TO_COMMIT;
99   }
100
101   bool RedrawPending() const { return needs_redraw_; }
102   bool ManageTilesPending() const { return needs_manage_tiles_; }
103
104   enum Action {
105     ACTION_NONE,
106     ACTION_SEND_BEGIN_MAIN_FRAME,
107     ACTION_COMMIT,
108     ACTION_UPDATE_VISIBLE_TILES,
109     ACTION_ACTIVATE_PENDING_TREE,
110     ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
111     ACTION_DRAW_AND_SWAP_FORCED,
112     ACTION_DRAW_AND_SWAP_ABORT,
113     ACTION_DRAW_AND_READBACK,
114     ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
115     ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD,
116     ACTION_MANAGE_TILES,
117   };
118   static const char* ActionToString(Action action);
119
120   scoped_ptr<base::Value> AsValue() const;
121
122   Action NextAction() const;
123   void UpdateState(Action action);
124
125   void CheckInvariants();
126
127   // Indicates whether the impl thread needs a BeginImplFrame callback in order
128   // to make progress.
129   bool BeginImplFrameNeeded() const;
130
131   // Indicates that we need to independently poll for new state and actions
132   // because we can't expect a BeginImplFrame. This is mostly used to avoid
133   // drawing repeat frames with the synchronous compositor without dropping
134   // necessary actions on the floor.
135   bool ShouldPollForAnticipatedDrawTriggers() const;
136
137   // Indicates that the system has entered and left a BeginImplFrame callback.
138   // The scheduler will not draw more than once in a given BeginImplFrame
139   // callback nor send more than one BeginMainFrame message.
140   void OnBeginImplFrame(const BeginFrameArgs& args);
141   void OnBeginImplFrameDeadlinePending();
142   void OnBeginImplFrameDeadline();
143   void OnBeginImplFrameIdle();
144   bool ShouldTriggerBeginImplFrameDeadlineEarly() const;
145   BeginImplFrameState begin_impl_frame_state() const {
146     return begin_impl_frame_state_;
147   }
148
149   // PollForAnticipatedDrawTriggers is used by the synchronous compositor to
150   // avoid requesting BeginImplFrames when we won't actually draw but still
151   // need to advance our state at vsync intervals.
152   void DidEnterPollForAnticipatedDrawTriggers();
153   void DidLeavePollForAnticipatedDrawTriggers();
154   bool inside_poll_for_anticipated_draw_triggers() const {
155     return inside_poll_for_anticipated_draw_triggers_;
156   }
157
158   // Indicates whether the LayerTreeHostImpl is visible.
159   void SetVisible(bool visible);
160
161   // Indicates that a redraw is required, either due to the impl tree changing
162   // or the screen being damaged and simply needing redisplay.
163   void SetNeedsRedraw();
164   bool needs_redraw() const { return needs_redraw_; }
165
166   // Indicates that manage-tiles is required. This guarantees another
167   // ManageTiles will occur shortly (even if no redraw is required).
168   void SetNeedsManageTiles();
169
170   // Indicates whether a redraw is required because we are currently rendering
171   // with a low resolution or checkerboarded tile.
172   void SetSwapUsedIncompleteTile(bool used_incomplete_tile);
173
174   // Indicates whether to prioritize animation smoothness over new content
175   // activation.
176   void SetSmoothnessTakesPriority(bool smoothness_takes_priority);
177
178   // Indicates whether ACTION_DRAW_AND_SWAP_IF_POSSIBLE drew to the screen.
179   void DidDrawIfPossibleCompleted(bool success);
180
181   // Indicates that a new commit flow needs to be performed, either to pull
182   // updates from the main thread to the impl, or to push deltas from the impl
183   // thread to main.
184   void SetNeedsCommit();
185
186   // As SetNeedsCommit(), but ensures the BeginMainFrame will be sent even
187   // if we are not visible.  After this call we expect to go through
188   // the forced commit flow and then return to waiting for a non-forced
189   // BeginMainFrame to finish.
190   void SetNeedsForcedCommitForReadback();
191
192   // Call this only in response to receiving an ACTION_SEND_BEGIN_MAIN_FRAME
193   // from NextAction.
194   // Indicates that all painting is complete.
195   void FinishCommit();
196
197   // Call this only in response to receiving an ACTION_SEND_BEGIN_MAIN_FRAME
198   // from NextAction if the client rejects the BeginMainFrame message.
199   // If did_handle is false, then another commit will be retried soon.
200   void BeginMainFrameAborted(bool did_handle);
201
202   // Request exclusive access to the textures that back single buffered
203   // layers on behalf of the main thread. Upon acquisition,
204   // ACTION_DRAW_AND_SWAP_IF_POSSIBLE will not draw until the main thread
205   // releases the
206   // textures to the impl thread by committing the layers.
207   void SetMainThreadNeedsLayerTextures();
208
209   // Set that we can create the first OutputSurface and start the scheduler.
210   void SetCanStart() { can_start_ = true; }
211
212   // Indicates whether drawing would, at this time, make sense.
213   // CanDraw can be used to suppress flashes or checkerboarding
214   // when such behavior would be undesirable.
215   void SetCanDraw(bool can);
216
217   // Indicates that the pending tree is ready for activation.
218   void NotifyReadyToActivate();
219
220   bool has_pending_tree() const { return has_pending_tree_; }
221
222   void DidLoseOutputSurface();
223   void DidCreateAndInitializeOutputSurface();
224   bool HasInitializedOutputSurface() const;
225
226   // True if we need to abort draws to make forward progress.
227   bool PendingDrawsShouldBeAborted() const;
228
229   bool SupportsProactiveBeginImplFrame() const;
230
231  protected:
232   bool BeginImplFrameNeededToDraw() const;
233   bool ProactiveBeginImplFrameWanted() const;
234
235   // True if we need to force activations to make forward progress.
236   bool PendingActivationsShouldBeForced() const;
237
238   bool ShouldBeginOutputSurfaceCreation() const;
239   bool ShouldDrawForced() const;
240   bool ShouldDraw() const;
241   bool ShouldActivatePendingTree() const;
242   bool ShouldAcquireLayerTexturesForMainThread() const;
243   bool ShouldUpdateVisibleTiles() const;
244   bool ShouldSendBeginMainFrame() const;
245   bool ShouldCommit() const;
246   bool ShouldManageTiles() const;
247
248   bool HasSentBeginMainFrameThisFrame() const;
249   bool HasScheduledManageTilesThisFrame() const;
250   bool HasUpdatedVisibleTilesThisFrame() const;
251   bool HasSwappedThisFrame() const;
252
253   void UpdateStateOnCommit(bool commit_was_aborted);
254   void UpdateStateOnActivation();
255   void UpdateStateOnDraw(bool did_swap);
256   void UpdateStateOnManageTiles();
257
258   const SchedulerSettings settings_;
259
260   OutputSurfaceState output_surface_state_;
261   BeginImplFrameState begin_impl_frame_state_;
262   CommitState commit_state_;
263   TextureState texture_state_;
264   ForcedRedrawOnTimeoutState forced_redraw_state_;
265   SynchronousReadbackState readback_state_;
266
267   BeginFrameArgs last_begin_impl_frame_args_;
268
269   int commit_count_;
270   int current_frame_number_;
271   int last_frame_number_swap_performed_;
272   int last_frame_number_begin_main_frame_sent_;
273   int last_frame_number_update_visible_tiles_was_called_;
274
275   int consecutive_failed_draws_;
276   bool needs_redraw_;
277   bool needs_manage_tiles_;
278   bool swap_used_incomplete_tile_;
279   bool needs_commit_;
280   bool main_thread_needs_layer_textures_;
281   bool inside_poll_for_anticipated_draw_triggers_;
282   bool visible_;
283   bool can_start_;
284   bool can_draw_;
285   bool has_pending_tree_;
286   bool pending_tree_is_ready_for_activation_;
287   bool active_tree_needs_first_draw_;
288   bool draw_if_possible_failed_;
289   bool did_create_and_initialize_first_output_surface_;
290   bool smoothness_takes_priority_;
291
292  private:
293   DISALLOW_COPY_AND_ASSIGN(SchedulerStateMachine);
294 };
295
296 }  // namespace cc
297
298 #endif  // CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_