Upstream version 7.36.149.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 SynchronousReadbackState {
72     READBACK_STATE_IDLE,
73     READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME,
74     READBACK_STATE_WAITING_FOR_COMMIT,
75     READBACK_STATE_WAITING_FOR_ACTIVATION,
76     READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK,
77     READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT,
78     READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION,
79   };
80   static const char* SynchronousReadbackStateToString(
81       SynchronousReadbackState state);
82
83   enum ForcedRedrawOnTimeoutState {
84     FORCED_REDRAW_STATE_IDLE,
85     FORCED_REDRAW_STATE_WAITING_FOR_COMMIT,
86     FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION,
87     FORCED_REDRAW_STATE_WAITING_FOR_DRAW,
88   };
89   static const char* ForcedRedrawOnTimeoutStateToString(
90       ForcedRedrawOnTimeoutState state);
91
92   bool CommitPending() const {
93     return commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
94            commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED ||
95            commit_state_ == COMMIT_STATE_READY_TO_COMMIT;
96   }
97   CommitState commit_state() const { return commit_state_; }
98
99   bool RedrawPending() const { return needs_redraw_; }
100   bool ManageTilesPending() const { return needs_manage_tiles_; }
101
102   enum Action {
103     ACTION_NONE,
104     ACTION_ANIMATE,
105     ACTION_SEND_BEGIN_MAIN_FRAME,
106     ACTION_COMMIT,
107     ACTION_UPDATE_VISIBLE_TILES,
108     ACTION_ACTIVATE_PENDING_TREE,
109     ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
110     ACTION_DRAW_AND_SWAP_FORCED,
111     ACTION_DRAW_AND_SWAP_ABORT,
112     ACTION_DRAW_AND_READBACK,
113     ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
114     ACTION_MANAGE_TILES,
115   };
116   static const char* ActionToString(Action action);
117
118   scoped_ptr<base::Value> AsValue() const;
119
120   Action NextAction() const;
121   void UpdateState(Action action);
122
123   void CheckInvariants();
124
125   // Indicates whether the impl thread needs a BeginImplFrame callback in order
126   // to make progress.
127   bool BeginFrameNeeded() const;
128
129   // Indicates that we need to independently poll for new state and actions
130   // because we can't expect a BeginImplFrame. This is mostly used to avoid
131   // drawing repeat frames with the synchronous compositor without dropping
132   // necessary actions on the floor.
133   bool ShouldPollForAnticipatedDrawTriggers() const;
134
135   // Indicates that the system has entered and left a BeginImplFrame callback.
136   // The scheduler will not draw more than once in a given BeginImplFrame
137   // callback nor send more than one BeginMainFrame message.
138   void OnBeginImplFrame(const BeginFrameArgs& args);
139   void OnBeginImplFrameDeadlinePending();
140   void OnBeginImplFrameDeadline();
141   void OnBeginImplFrameIdle();
142   bool ShouldTriggerBeginImplFrameDeadlineEarly() const;
143   BeginImplFrameState begin_impl_frame_state() const {
144     return begin_impl_frame_state_;
145   }
146
147   // If the main thread didn't manage to produce a new frame in time for the
148   // impl thread to draw, it is in a high latency mode.
149   bool MainThreadIsInHighLatencyMode() const;
150
151   // PollForAnticipatedDrawTriggers is used by the synchronous compositor to
152   // avoid requesting BeginImplFrames when we won't actually draw but still
153   // need to advance our state at vsync intervals.
154   void DidEnterPollForAnticipatedDrawTriggers();
155   void DidLeavePollForAnticipatedDrawTriggers();
156   bool inside_poll_for_anticipated_draw_triggers() const {
157     return inside_poll_for_anticipated_draw_triggers_;
158   }
159
160   // Indicates whether the LayerTreeHostImpl is visible.
161   void SetVisible(bool visible);
162
163   // Indicates that a redraw is required, either due to the impl tree changing
164   // or the screen being damaged and simply needing redisplay.
165   void SetNeedsRedraw();
166   bool needs_redraw() const { return needs_redraw_; }
167
168   void SetNeedsAnimate();
169   bool needs_animate() const { return needs_animate_; }
170
171   // Indicates that manage-tiles is required. This guarantees another
172   // ManageTiles will occur shortly (even if no redraw is required).
173   void SetNeedsManageTiles();
174
175   // Sets how many swaps can be pending to the OutputSurface.
176   void SetMaxSwapsPending(int max);
177
178   // If the scheduler attempted to draw and swap, this provides feedback
179   // regarding whether or not the swap actually occured. We might skip the
180   // swap when there is not damage, for example.
181   void DidSwapBuffers();
182
183   // Indicates whether a redraw is required because we are currently rendering
184   // with a low resolution or checkerboarded tile.
185   void SetSwapUsedIncompleteTile(bool used_incomplete_tile);
186
187   // Notification from the OutputSurface that a swap has been consumed.
188   void DidSwapBuffersComplete();
189
190   // Indicates whether to prioritize animation smoothness over new content
191   // activation.
192   void SetSmoothnessTakesPriority(bool smoothness_takes_priority);
193   bool smoothness_takes_priority() const { return smoothness_takes_priority_; }
194
195   // Indicates whether ACTION_DRAW_AND_SWAP_IF_POSSIBLE drew to the screen.
196   void DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DrawResult result);
197
198   // Indicates that a new commit flow needs to be performed, either to pull
199   // updates from the main thread to the impl, or to push deltas from the impl
200   // thread to main.
201   void SetNeedsCommit();
202
203   // As SetNeedsCommit(), but ensures the BeginMainFrame will be sent even
204   // if we are not visible.  After this call we expect to go through
205   // the forced commit flow and then return to waiting for a non-forced
206   // BeginMainFrame to finish.
207   void SetNeedsForcedCommitForReadback();
208
209   // Call this only in response to receiving an ACTION_SEND_BEGIN_MAIN_FRAME
210   // from NextAction.
211   // Indicates that all painting is complete.
212   void NotifyReadyToCommit();
213
214   // Call this only in response to receiving an ACTION_SEND_BEGIN_MAIN_FRAME
215   // from NextAction if the client rejects the BeginMainFrame message.
216   // If did_handle is false, then another commit will be retried soon.
217   void BeginMainFrameAborted(bool did_handle);
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 SupportsProactiveBeginFrame() const;
249
250   void SetContinuousPainting(bool continuous_painting) {
251     continuous_painting_ = continuous_painting;
252   }
253
254  protected:
255   bool BeginFrameNeededToAnimateOrDraw() const;
256   bool ProactiveBeginFrameWanted() const;
257
258   // True if we need to force activations to make forward progress.
259   bool PendingActivationsShouldBeForced() const;
260
261   bool ShouldAnimate() const;
262   bool ShouldBeginOutputSurfaceCreation() const;
263   bool ShouldDrawForced() const;
264   bool ShouldDraw() const;
265   bool ShouldActivatePendingTree() const;
266   bool ShouldUpdateVisibleTiles() const;
267   bool ShouldSendBeginMainFrame() const;
268   bool ShouldCommit() const;
269   bool ShouldManageTiles() const;
270
271   void AdvanceCurrentFrameNumber();
272   bool HasSentBeginMainFrameThisFrame() const;
273   bool HasUpdatedVisibleTilesThisFrame() const;
274   bool HasSwappedThisFrame() const;
275
276   void UpdateStateOnCommit(bool commit_was_aborted);
277   void UpdateStateOnActivation();
278   void UpdateStateOnDraw(bool did_request_swap);
279   void UpdateStateOnManageTiles();
280
281   const SchedulerSettings settings_;
282
283   OutputSurfaceState output_surface_state_;
284   BeginImplFrameState begin_impl_frame_state_;
285   CommitState commit_state_;
286   ForcedRedrawOnTimeoutState forced_redraw_state_;
287   SynchronousReadbackState readback_state_;
288
289   BeginFrameArgs begin_impl_frame_args_;
290
291   int commit_count_;
292   int current_frame_number_;
293   int last_frame_number_animate_performed_;
294   int last_frame_number_swap_performed_;
295   int last_frame_number_begin_main_frame_sent_;
296   int last_frame_number_update_visible_tiles_was_called_;
297
298   // manage_tiles_funnel_ is "filled" each time ManageTiles is called
299   // and "drained" on each BeginImplFrame. If the funnel gets too full,
300   // we start throttling ACTION_MANAGE_TILES such that we average one
301   // ManageTile per BeginImplFrame.
302   int manage_tiles_funnel_;
303   int consecutive_checkerboard_animations_;
304   int max_pending_swaps_;
305   int pending_swaps_;
306   bool needs_redraw_;
307   bool needs_animate_;
308   bool needs_manage_tiles_;
309   bool swap_used_incomplete_tile_;
310   bool needs_commit_;
311   bool inside_poll_for_anticipated_draw_triggers_;
312   bool visible_;
313   bool can_start_;
314   bool can_draw_;
315   bool has_pending_tree_;
316   bool pending_tree_is_ready_for_activation_;
317   bool active_tree_needs_first_draw_;
318   bool did_create_and_initialize_first_output_surface_;
319   bool smoothness_takes_priority_;
320   bool skip_next_begin_main_frame_to_reduce_latency_;
321   bool skip_begin_main_frame_to_reduce_latency_;
322   bool continuous_painting_;
323   bool needs_back_to_back_readback_;
324
325  private:
326   DISALLOW_COPY_AND_ASSIGN(SchedulerStateMachine);
327 };
328
329 }  // namespace cc
330
331 #endif  // CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_