Home | History | Annotate | Download | only in scheduler
      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