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