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 16 namespace 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. 29 class 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 // PollForAnticipatedDrawTriggers is used by the synchronous compositor to 88 // avoid requesting BeginImplFrames when we won't actually draw but still 89 // need to advance our state at vsync intervals. 90 void PollForAnticipatedDrawTriggers(); 91 92 // Indicates whether the LayerTreeHostImpl is visible. 93 void SetVisible(bool visible); 94 95 // Indicates that a redraw is required, either due to the impl tree changing 96 // or the screen being damaged and simply needing redisplay. 97 void SetNeedsRedraw(); 98 99 // As SetNeedsRedraw(), but ensures the draw will definitely happen even if 100 // we are not visible. 101 void SetNeedsForcedRedraw(); 102 103 // Indicates that a redraw is required because we are currently rendering 104 // with a low resolution or checkerboarded tile. 105 void DidSwapUseIncompleteTile(); 106 107 // Indicates whether ACTION_DRAW_IF_POSSIBLE drew to the screen or not. 108 void DidDrawIfPossibleCompleted(bool success); 109 110 // Indicates that a new commit flow needs to be performed, either to pull 111 // updates from the main thread to the impl, or to push deltas from the impl 112 // thread to main. 113 void SetNeedsCommit(); 114 115 // As SetNeedsCommit(), but ensures the begin frame will be sent to the main 116 // thread even if we are not visible. After this call we expect to go through 117 // the forced commit flow and then return to waiting for a non-forced 118 // begin frame to finish. 119 void SetNeedsForcedCommit(); 120 121 // Call this only in response to receiving an 122 // ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD from NextAction. 123 // Indicates that all painting is complete. 124 void FinishCommit(); 125 126 // Call this only in response to receiving an 127 // ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD from NextAction if the client 128 // rejects the begin frame message. If did_handle is false, then 129 // another commit will be retried soon. 130 void BeginFrameAbortedByMainThread(bool did_handle); 131 132 // Request exclusive access to the textures that back single buffered 133 // layers on behalf of the main thread. Upon acquisition, 134 // ACTION_DRAW_IF_POSSIBLE will not draw until the main thread releases the 135 // textures to the impl thread by committing the layers. 136 void SetMainThreadNeedsLayerTextures(); 137 138 // Set that we can create the first OutputSurface and start the scheduler. 139 void SetCanStart() { can_start_ = true; } 140 141 // Indicates whether drawing would, at this time, make sense. 142 // CanDraw can be used to supress flashes or checkerboarding 143 // when such behavior would be undesirable. 144 void SetCanDraw(bool can); 145 146 // Indicates whether or not there is a pending tree. This influences 147 // whether or not we can succesfully commit at this time. If the 148 // last commit is still being processed (but not blocking), it may not 149 // be possible to take another commit yet. This overrides force commit, 150 // as a commit is already still in flight. 151 void SetHasPendingTree(bool has_pending_tree); 152 bool has_pending_tree() const { return has_pending_tree_; } 153 154 void DidLoseOutputSurface(); 155 void DidCreateAndInitializeOutputSurface(); 156 bool HasInitializedOutputSurface() const; 157 158 // Exposed for testing purposes. 159 void SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(int num_draws); 160 161 // False if drawing is not being prevented, true if drawing won't happen 162 // for some reason, such as not being visible. 163 bool DrawSuspendedUntilCommit() const; 164 165 std::string ToString(); 166 167 protected: 168 bool ShouldDrawForced() const; 169 bool ScheduledToDraw() const; 170 bool ShouldDraw() const; 171 bool ShouldAttemptTreeActivation() const; 172 bool ShouldAcquireLayerTexturesForMainThread() const; 173 bool ShouldUpdateVisibleTiles() const; 174 bool HasDrawnThisFrame() const; 175 bool HasAttemptedTreeActivationThisFrame() const; 176 bool HasUpdatedVisibleTilesThisFrame() const; 177 void SetPostCommitFlags(); 178 179 const SchedulerSettings settings_; 180 181 CommitState commit_state_; 182 int commit_count_; 183 184 int current_frame_number_; 185 int last_frame_number_where_begin_frame_sent_to_main_thread_; 186 int last_frame_number_where_draw_was_called_; 187 int last_frame_number_where_tree_activation_attempted_; 188 int last_frame_number_where_update_visible_tiles_was_called_; 189 int consecutive_failed_draws_; 190 int maximum_number_of_failed_draws_before_draw_is_forced_; 191 bool needs_redraw_; 192 bool swap_used_incomplete_tile_; 193 bool needs_forced_redraw_; 194 bool needs_forced_redraw_after_next_commit_; 195 bool needs_redraw_after_next_commit_; 196 bool needs_commit_; 197 bool needs_forced_commit_; 198 bool expect_immediate_begin_frame_for_main_thread_; 199 bool main_thread_needs_layer_textures_; 200 bool inside_begin_frame_; 201 BeginFrameArgs last_begin_frame_args_; 202 bool visible_; 203 bool can_start_; 204 bool can_draw_; 205 bool has_pending_tree_; 206 bool draw_if_possible_failed_; 207 TextureState texture_state_; 208 OutputSurfaceState output_surface_state_; 209 bool did_create_and_initialize_first_output_surface_; 210 211 private: 212 DISALLOW_COPY_AND_ASSIGN(SchedulerStateMachine); 213 }; 214 215 } // namespace cc 216 217 #endif // CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_ 218