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