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