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 #include "cc/scheduler/scheduler_state_machine.h"
      6 
      7 #include "base/debug/trace_event.h"
      8 #include "base/format_macros.h"
      9 #include "base/logging.h"
     10 #include "base/strings/stringprintf.h"
     11 #include "base/values.h"
     12 #include "ui/gfx/frame_time.h"
     13 
     14 namespace cc {
     15 
     16 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
     17     : settings_(settings),
     18       output_surface_state_(OUTPUT_SURFACE_LOST),
     19       begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE),
     20       commit_state_(COMMIT_STATE_IDLE),
     21       texture_state_(LAYER_TEXTURE_STATE_UNLOCKED),
     22       forced_redraw_state_(FORCED_REDRAW_STATE_IDLE),
     23       readback_state_(READBACK_STATE_IDLE),
     24       commit_count_(0),
     25       current_frame_number_(0),
     26       last_frame_number_swap_performed_(-1),
     27       last_frame_number_begin_main_frame_sent_(-1),
     28       last_frame_number_update_visible_tiles_was_called_(-1),
     29       last_frame_number_manage_tiles_called_(-1),
     30       consecutive_failed_draws_(0),
     31       needs_redraw_(false),
     32       needs_manage_tiles_(false),
     33       swap_used_incomplete_tile_(false),
     34       needs_commit_(false),
     35       main_thread_needs_layer_textures_(false),
     36       inside_poll_for_anticipated_draw_triggers_(false),
     37       visible_(false),
     38       can_start_(false),
     39       can_draw_(false),
     40       has_pending_tree_(false),
     41       pending_tree_is_ready_for_activation_(false),
     42       active_tree_needs_first_draw_(false),
     43       draw_if_possible_failed_(false),
     44       did_create_and_initialize_first_output_surface_(false),
     45       smoothness_takes_priority_(false),
     46       skip_begin_main_frame_to_reduce_latency_(false) {}
     47 
     48 const char* SchedulerStateMachine::OutputSurfaceStateToString(
     49     OutputSurfaceState state) {
     50   switch (state) {
     51     case OUTPUT_SURFACE_ACTIVE:
     52       return "OUTPUT_SURFACE_ACTIVE";
     53     case OUTPUT_SURFACE_LOST:
     54       return "OUTPUT_SURFACE_LOST";
     55     case OUTPUT_SURFACE_CREATING:
     56       return "OUTPUT_SURFACE_CREATING";
     57     case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
     58       return "OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT";
     59     case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
     60       return "OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION";
     61   }
     62   NOTREACHED();
     63   return "???";
     64 }
     65 
     66 const char* SchedulerStateMachine::BeginImplFrameStateToString(
     67     BeginImplFrameState state) {
     68   switch (state) {
     69     case BEGIN_IMPL_FRAME_STATE_IDLE:
     70       return "BEGIN_IMPL_FRAME_STATE_IDLE";
     71     case BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING:
     72       return "BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING";
     73     case BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME:
     74       return "BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME";
     75     case BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE:
     76       return "BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE";
     77   }
     78   NOTREACHED();
     79   return "???";
     80 }
     81 
     82 const char* SchedulerStateMachine::CommitStateToString(CommitState state) {
     83   switch (state) {
     84     case COMMIT_STATE_IDLE:
     85       return "COMMIT_STATE_IDLE";
     86     case COMMIT_STATE_FRAME_IN_PROGRESS:
     87       return "COMMIT_STATE_FRAME_IN_PROGRESS";
     88     case COMMIT_STATE_READY_TO_COMMIT:
     89       return "COMMIT_STATE_READY_TO_COMMIT";
     90     case COMMIT_STATE_WAITING_FOR_FIRST_DRAW:
     91       return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW";
     92   }
     93   NOTREACHED();
     94   return "???";
     95 }
     96 
     97 const char* SchedulerStateMachine::TextureStateToString(TextureState state) {
     98   switch (state) {
     99     case LAYER_TEXTURE_STATE_UNLOCKED:
    100       return "LAYER_TEXTURE_STATE_UNLOCKED";
    101     case LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD:
    102       return "LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD";
    103     case LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD:
    104       return "LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD";
    105   }
    106   NOTREACHED();
    107   return "???";
    108 }
    109 
    110 const char* SchedulerStateMachine::SynchronousReadbackStateToString(
    111     SynchronousReadbackState state) {
    112   switch (state) {
    113     case READBACK_STATE_IDLE:
    114       return "READBACK_STATE_IDLE";
    115     case READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME:
    116       return "READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME";
    117     case READBACK_STATE_WAITING_FOR_COMMIT:
    118       return "READBACK_STATE_WAITING_FOR_COMMIT";
    119     case READBACK_STATE_WAITING_FOR_ACTIVATION:
    120       return "READBACK_STATE_WAITING_FOR_ACTIVATION";
    121     case READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK:
    122       return "READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK";
    123     case READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT:
    124       return "READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT";
    125     case READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION:
    126       return "READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION";
    127   }
    128   NOTREACHED();
    129   return "???";
    130 }
    131 
    132 const char* SchedulerStateMachine::ForcedRedrawOnTimeoutStateToString(
    133     ForcedRedrawOnTimeoutState state) {
    134   switch (state) {
    135     case FORCED_REDRAW_STATE_IDLE:
    136       return "FORCED_REDRAW_STATE_IDLE";
    137     case FORCED_REDRAW_STATE_WAITING_FOR_COMMIT:
    138       return "FORCED_REDRAW_STATE_WAITING_FOR_COMMIT";
    139     case FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION:
    140       return "FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION";
    141     case FORCED_REDRAW_STATE_WAITING_FOR_DRAW:
    142       return "FORCED_REDRAW_STATE_WAITING_FOR_DRAW";
    143   }
    144   NOTREACHED();
    145   return "???";
    146 }
    147 
    148 const char* SchedulerStateMachine::ActionToString(Action action) {
    149   switch (action) {
    150     case ACTION_NONE:
    151       return "ACTION_NONE";
    152     case ACTION_SEND_BEGIN_MAIN_FRAME:
    153       return "ACTION_SEND_BEGIN_MAIN_FRAME";
    154     case ACTION_COMMIT:
    155       return "ACTION_COMMIT";
    156     case ACTION_UPDATE_VISIBLE_TILES:
    157       return "ACTION_UPDATE_VISIBLE_TILES";
    158     case ACTION_ACTIVATE_PENDING_TREE:
    159       return "ACTION_ACTIVATE_PENDING_TREE";
    160     case ACTION_DRAW_AND_SWAP_IF_POSSIBLE:
    161       return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE";
    162     case ACTION_DRAW_AND_SWAP_FORCED:
    163       return "ACTION_DRAW_AND_SWAP_FORCED";
    164     case ACTION_DRAW_AND_SWAP_ABORT:
    165       return "ACTION_DRAW_AND_SWAP_ABORT";
    166     case ACTION_DRAW_AND_READBACK:
    167       return "ACTION_DRAW_AND_READBACK";
    168     case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
    169       return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION";
    170     case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
    171       return "ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD";
    172     case ACTION_MANAGE_TILES:
    173       return "ACTION_MANAGE_TILES";
    174   }
    175   NOTREACHED();
    176   return "???";
    177 }
    178 
    179 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const  {
    180   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
    181 
    182   scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue);
    183   major_state->SetString("next_action", ActionToString(NextAction()));
    184   major_state->SetString("begin_impl_frame_state",
    185                          BeginImplFrameStateToString(begin_impl_frame_state_));
    186   major_state->SetString("commit_state", CommitStateToString(commit_state_));
    187   major_state->SetString("texture_state_",
    188                          TextureStateToString(texture_state_));
    189   major_state->SetString("output_surface_state_",
    190                          OutputSurfaceStateToString(output_surface_state_));
    191   major_state->SetString(
    192       "forced_redraw_state",
    193       ForcedRedrawOnTimeoutStateToString(forced_redraw_state_));
    194   major_state->SetString("readback_state",
    195                          SynchronousReadbackStateToString(readback_state_));
    196   state->Set("major_state", major_state.release());
    197 
    198   scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue);
    199   base::TimeTicks now = gfx::FrameTime::Now();
    200   timestamps_state->SetDouble(
    201       "0_interval",
    202       last_begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L);
    203   timestamps_state->SetDouble(
    204       "1_now_to_deadline",
    205       (last_begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L);
    206   timestamps_state->SetDouble(
    207       "2_frame_time_to_now",
    208       (now - last_begin_impl_frame_args_.frame_time).InMicroseconds() /
    209           1000.0L);
    210   timestamps_state->SetDouble(
    211       "3_frame_time_to_deadline",
    212       (last_begin_impl_frame_args_.deadline -
    213               last_begin_impl_frame_args_.frame_time).InMicroseconds() /
    214           1000.0L);
    215   timestamps_state->SetDouble(
    216       "4_now", (now - base::TimeTicks()).InMicroseconds() / 1000.0L);
    217   timestamps_state->SetDouble(
    218       "5_frame_time",
    219       (last_begin_impl_frame_args_.frame_time - base::TimeTicks())
    220               .InMicroseconds() /
    221           1000.0L);
    222   timestamps_state->SetDouble(
    223       "6_deadline",
    224       (last_begin_impl_frame_args_.deadline - base::TimeTicks())
    225               .InMicroseconds() /
    226           1000.0L);
    227   state->Set("major_timestamps_in_ms", timestamps_state.release());
    228 
    229   scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue);
    230   minor_state->SetInteger("commit_count", commit_count_);
    231   minor_state->SetInteger("current_frame_number", current_frame_number_);
    232 
    233   minor_state->SetInteger("last_frame_number_swap_performed",
    234                           last_frame_number_swap_performed_);
    235   minor_state->SetInteger(
    236       "last_frame_number_begin_main_frame_sent",
    237       last_frame_number_begin_main_frame_sent_);
    238   minor_state->SetInteger(
    239       "last_frame_number_update_visible_tiles_was_called",
    240       last_frame_number_update_visible_tiles_was_called_);
    241 
    242   minor_state->SetInteger("consecutive_failed_draws",
    243                           consecutive_failed_draws_);
    244   minor_state->SetBoolean("needs_redraw", needs_redraw_);
    245   minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_);
    246   minor_state->SetBoolean("swap_used_incomplete_tile",
    247                           swap_used_incomplete_tile_);
    248   minor_state->SetBoolean("needs_commit", needs_commit_);
    249   minor_state->SetBoolean("main_thread_needs_layer_textures",
    250                           main_thread_needs_layer_textures_);
    251   minor_state->SetBoolean("visible", visible_);
    252   minor_state->SetBoolean("can_start", can_start_);
    253   minor_state->SetBoolean("can_draw", can_draw_);
    254   minor_state->SetBoolean("has_pending_tree", has_pending_tree_);
    255   minor_state->SetBoolean("pending_tree_is_ready_for_activation",
    256                           pending_tree_is_ready_for_activation_);
    257   minor_state->SetBoolean("active_tree_needs_first_draw",
    258                           active_tree_needs_first_draw_);
    259   minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_);
    260   minor_state->SetBoolean("did_create_and_initialize_first_output_surface",
    261                           did_create_and_initialize_first_output_surface_);
    262   minor_state->SetBoolean("smoothness_takes_priority",
    263                           smoothness_takes_priority_);
    264   minor_state->SetBoolean("main_thread_is_in_high_latency_mode",
    265                           MainThreadIsInHighLatencyMode());
    266   minor_state->SetBoolean("skip_begin_main_frame_to_reduce_latency",
    267                           skip_begin_main_frame_to_reduce_latency_);
    268   state->Set("minor_state", minor_state.release());
    269 
    270   return state.PassAs<base::Value>();
    271 }
    272 
    273 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const {
    274   return current_frame_number_ ==
    275          last_frame_number_begin_main_frame_sent_;
    276 }
    277 
    278 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const {
    279   return current_frame_number_ ==
    280          last_frame_number_update_visible_tiles_was_called_;
    281 }
    282 
    283 bool SchedulerStateMachine::HasSwappedThisFrame() const {
    284   return current_frame_number_ == last_frame_number_swap_performed_;
    285 }
    286 
    287 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
    288   // These are all the cases where we normally cannot or do not want to draw
    289   // but, if needs_redraw_ is true and we do not draw to make forward progress,
    290   // we might deadlock with the main thread.
    291   // This should be a superset of PendingActivationsShouldBeForced() since
    292   // activation of the pending tree is blocked by drawing of the active tree and
    293   // the main thread might be blocked on activation of the most recent commit.
    294   if (PendingActivationsShouldBeForced())
    295     return true;
    296 
    297   // Additional states where we should abort draws.
    298   // Note: We don't force activation in these cases because doing so would
    299   // result in checkerboarding on resize, becoming visible, etc.
    300   if (!can_draw_)
    301     return true;
    302   if (!visible_)
    303     return true;
    304   return false;
    305 }
    306 
    307 bool SchedulerStateMachine::PendingActivationsShouldBeForced() const {
    308   // These are all the cases where, if we do not force activations to make
    309   // forward progress, we might deadlock with the main thread.
    310 
    311   // The impl thread cannot lock layer textures unless the pending
    312   // tree can be activated to unblock the commit.
    313   if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD)
    314     return true;
    315 
    316   // There is no output surface to trigger our activations.
    317   if (output_surface_state_ == OUTPUT_SURFACE_LOST)
    318     return true;
    319 
    320   return false;
    321 }
    322 
    323 bool SchedulerStateMachine::ShouldBeginOutputSurfaceCreation() const {
    324   // Don't try to initialize too early.
    325   if (!can_start_)
    326     return false;
    327 
    328   // We only want to start output surface initialization after the
    329   // previous commit is complete.
    330   if (commit_state_ != COMMIT_STATE_IDLE)
    331     return false;
    332 
    333   // We want to clear the pipline of any pending draws and activations
    334   // before starting output surface initialization. This allows us to avoid
    335   // weird corner cases where we abort draws or force activation while we
    336   // are initializing the output surface and can potentially have a pending
    337   // readback.
    338   if (active_tree_needs_first_draw_ || has_pending_tree_)
    339     return false;
    340 
    341   // We need to create the output surface if we don't have one and we haven't
    342   // started creating one yet.
    343   return output_surface_state_ == OUTPUT_SURFACE_LOST;
    344 }
    345 
    346 bool SchedulerStateMachine::ShouldDraw() const {
    347   // After a readback, make sure not to draw again until we've replaced the
    348   // readback commit with a real one.
    349   if (readback_state_ == READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT ||
    350       readback_state_ == READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION)
    351     return false;
    352 
    353   // Draw immediately for readbacks to unblock the main thread quickly.
    354   if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) {
    355     DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
    356     return true;
    357   }
    358 
    359   // If we need to abort draws, we should do so ASAP since the draw could
    360   // be blocking other important actions (like output surface initialization),
    361   // from occuring. If we are waiting for the first draw, then perfom the
    362   // aborted draw to keep things moving. If we are not waiting for the first
    363   // draw however, we don't want to abort for no reason.
    364   if (PendingDrawsShouldBeAborted())
    365     return active_tree_needs_first_draw_;
    366 
    367   // After this line, we only want to swap once per frame.
    368   if (HasSwappedThisFrame())
    369     return false;
    370 
    371   // Except for the cases above, do not draw outside of the BeginImplFrame
    372   // deadline.
    373   if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
    374     return false;
    375 
    376   // Only handle forced redraws due to timeouts on the regular deadline.
    377   if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) {
    378     DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
    379     return true;
    380   }
    381 
    382   return needs_redraw_;
    383 }
    384 
    385 bool SchedulerStateMachine::ShouldAcquireLayerTexturesForMainThread() const {
    386   if (!main_thread_needs_layer_textures_)
    387     return false;
    388   if (texture_state_ == LAYER_TEXTURE_STATE_UNLOCKED)
    389     return true;
    390   DCHECK_EQ(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD);
    391   return false;
    392 }
    393 
    394 bool SchedulerStateMachine::ShouldActivatePendingTree() const {
    395   // There is nothing to activate.
    396   if (!has_pending_tree_)
    397     return false;
    398 
    399   // We should not activate a second tree before drawing the first one.
    400   // Even if we need to force activation of the pending tree, we should abort
    401   // drawing the active tree first.
    402   if (active_tree_needs_first_draw_)
    403     return false;
    404 
    405   // If we want to force activation, do so ASAP.
    406   if (PendingActivationsShouldBeForced())
    407     return true;
    408 
    409   // At this point, only activate if we are ready to activate.
    410   return pending_tree_is_ready_for_activation_;
    411 }
    412 
    413 bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const {
    414   if (!settings_.impl_side_painting)
    415     return false;
    416   if (HasUpdatedVisibleTilesThisFrame())
    417     return false;
    418 
    419   // There's no reason to check for tiles if we don't have an output surface.
    420   if (!HasInitializedOutputSurface())
    421     return false;
    422 
    423   // We should not check for visible tiles until we've entered the deadline so
    424   // we check as late as possible and give the tiles more time to initialize.
    425   if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
    426     return false;
    427 
    428   // If the last swap drew with checkerboard or missing tiles, we should
    429   // poll for any new visible tiles so we can be notified to draw again
    430   // when there are.
    431   if (swap_used_incomplete_tile_)
    432     return true;
    433 
    434   return false;
    435 }
    436 
    437 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
    438   if (!needs_commit_)
    439     return false;
    440 
    441   // Only send BeginMainFrame when there isn't another commit pending already.
    442   if (commit_state_ != COMMIT_STATE_IDLE)
    443     return false;
    444 
    445   // We can't accept a commit if we have a pending tree.
    446   if (has_pending_tree_)
    447     return false;
    448 
    449   // We want to handle readback commits immediately to unblock the main thread.
    450   // Note: This BeginMainFrame will correspond to the replacement commit that
    451   // comes after the readback commit itself, so we only send the BeginMainFrame
    452   // if a commit isn't already pending behind the readback.
    453   if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME)
    454     return !CommitPending();
    455 
    456   // We do not need commits if we are not visible, unless there's a
    457   // request for a readback.
    458   if (!visible_)
    459     return false;
    460 
    461   // We want to start the first commit after we get a new output surface ASAP.
    462   if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT)
    463     return true;
    464 
    465   // With deadline scheduling enabled, we should not send BeginMainFrame while
    466   // we are in BEGIN_IMPL_FRAME_STATE_IDLE, since we might have new user input
    467   // coming in soon.
    468   // However, if we are not expecting a BeginImplFrame to take us out of idle,
    469   // we should not early out here to avoid blocking commits forever.
    470   // This only works well when deadline scheduling is enabled because there is
    471   // an interval over which to accept the commit and draw. Without deadline
    472   // scheduling, delaying the commit could prevent us from having something
    473   // to draw on the next BeginImplFrame.
    474   // TODO(brianderson): Allow sending BeginMainFrame while idle when the main
    475   // thread isn't consuming user input.
    476   if (settings_.deadline_scheduling_enabled &&
    477       begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE &&
    478       BeginImplFrameNeeded())
    479     return false;
    480 
    481   // We need a new commit for the forced redraw. This honors the
    482   // single commit per interval because the result will be swapped to screen.
    483   if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
    484     return true;
    485 
    486   // After this point, we only start a commit once per frame.
    487   if (HasSentBeginMainFrameThisFrame())
    488     return false;
    489 
    490   // We shouldn't normally accept commits if there isn't an OutputSurface.
    491   if (!HasInitializedOutputSurface())
    492     return false;
    493 
    494   if (skip_begin_main_frame_to_reduce_latency_)
    495     return false;
    496 
    497   return true;
    498 }
    499 
    500 bool SchedulerStateMachine::ShouldCommit() const {
    501   return commit_state_ == COMMIT_STATE_READY_TO_COMMIT;
    502 }
    503 
    504 bool SchedulerStateMachine::IsCommitStateWaiting() const {
    505   return commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS;
    506 }
    507 
    508 bool SchedulerStateMachine::ShouldManageTiles() const {
    509   // ManageTiles only really needs to be called immediately after commit
    510   // and then periodically after that.  Limiting to once per frame prevents
    511   // post-commit and post-draw ManageTiles on the same frame.
    512   if (last_frame_number_manage_tiles_called_ == current_frame_number_)
    513     return false;
    514 
    515   // Limiting to once per-frame is not enough, since we only want to
    516   // manage tiles _after_ draws. Polling for draw triggers and
    517   // begin-frame are mutually exclusive, so we limit to these two cases.
    518   if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
    519       !inside_poll_for_anticipated_draw_triggers_)
    520     return false;
    521   return needs_manage_tiles_;
    522 }
    523 
    524 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
    525   if (ShouldAcquireLayerTexturesForMainThread())
    526     return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD;
    527   if (ShouldUpdateVisibleTiles())
    528     return ACTION_UPDATE_VISIBLE_TILES;
    529   if (ShouldActivatePendingTree())
    530     return ACTION_ACTIVATE_PENDING_TREE;
    531   if (ShouldCommit())
    532     return ACTION_COMMIT;
    533   if (ShouldDraw()) {
    534     if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK)
    535       return ACTION_DRAW_AND_READBACK;
    536     else if (PendingDrawsShouldBeAborted())
    537       return ACTION_DRAW_AND_SWAP_ABORT;
    538     else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
    539       return ACTION_DRAW_AND_SWAP_FORCED;
    540     else
    541       return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
    542   }
    543   if (ShouldManageTiles())
    544     return ACTION_MANAGE_TILES;
    545   if (ShouldSendBeginMainFrame())
    546     return ACTION_SEND_BEGIN_MAIN_FRAME;
    547   if (ShouldBeginOutputSurfaceCreation())
    548     return ACTION_BEGIN_OUTPUT_SURFACE_CREATION;
    549   return ACTION_NONE;
    550 }
    551 
    552 void SchedulerStateMachine::CheckInvariants() {
    553   // We should never try to perform a draw for readback and forced draw due to
    554   // timeout simultaneously.
    555   DCHECK(!(forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW &&
    556            readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK));
    557 }
    558 
    559 void SchedulerStateMachine::UpdateState(Action action) {
    560   switch (action) {
    561     case ACTION_NONE:
    562       return;
    563 
    564     case ACTION_UPDATE_VISIBLE_TILES:
    565       last_frame_number_update_visible_tiles_was_called_ =
    566           current_frame_number_;
    567       return;
    568 
    569     case ACTION_ACTIVATE_PENDING_TREE:
    570       UpdateStateOnActivation();
    571       return;
    572 
    573     case ACTION_SEND_BEGIN_MAIN_FRAME:
    574       DCHECK(!has_pending_tree_);
    575       DCHECK(visible_ ||
    576              readback_state_ == READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME);
    577       commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS;
    578       needs_commit_ = false;
    579       if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME)
    580         readback_state_ = READBACK_STATE_WAITING_FOR_COMMIT;
    581       last_frame_number_begin_main_frame_sent_ =
    582           current_frame_number_;
    583       return;
    584 
    585     case ACTION_COMMIT: {
    586       bool commit_was_aborted = false;
    587       UpdateStateOnCommit(commit_was_aborted);
    588       return;
    589     }
    590 
    591     case ACTION_DRAW_AND_SWAP_FORCED:
    592     case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: {
    593       bool did_swap = true;
    594       UpdateStateOnDraw(did_swap);
    595       return;
    596     }
    597 
    598     case ACTION_DRAW_AND_SWAP_ABORT:
    599     case ACTION_DRAW_AND_READBACK: {
    600       bool did_swap = false;
    601       UpdateStateOnDraw(did_swap);
    602       return;
    603     }
    604 
    605     case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
    606       DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST);
    607       output_surface_state_ = OUTPUT_SURFACE_CREATING;
    608 
    609       // The following DCHECKs make sure we are in the proper quiescent state.
    610       // The pipeline should be flushed entirely before we start output
    611       // surface creation to avoid complicated corner cases.
    612       DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE);
    613       DCHECK(!has_pending_tree_);
    614       DCHECK(!active_tree_needs_first_draw_);
    615       return;
    616 
    617     case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
    618       texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD;
    619       main_thread_needs_layer_textures_ = false;
    620       return;
    621 
    622     case ACTION_MANAGE_TILES:
    623       UpdateStateOnManageTiles();
    624       return;
    625   }
    626 }
    627 
    628 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) {
    629   commit_count_++;
    630 
    631   // If we are impl-side-painting but the commit was aborted, then we behave
    632   // mostly as if we are not impl-side-painting since there is no pending tree.
    633   has_pending_tree_ = settings_.impl_side_painting && !commit_was_aborted;
    634 
    635   // Update state related to readbacks.
    636   if (readback_state_ == READBACK_STATE_WAITING_FOR_COMMIT) {
    637     // Update the state if this is the readback commit.
    638     readback_state_ = has_pending_tree_
    639                           ? READBACK_STATE_WAITING_FOR_ACTIVATION
    640                           : READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK;
    641   } else if (readback_state_ == READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT) {
    642     // Update the state if this is the commit replacing the readback commit.
    643     readback_state_ = has_pending_tree_
    644                           ? READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION
    645                           : READBACK_STATE_IDLE;
    646   } else {
    647     DCHECK(readback_state_ == READBACK_STATE_IDLE);
    648   }
    649 
    650   // Readbacks can interrupt output surface initialization and forced draws,
    651   // so we do not want to advance those states if we are in the middle of a
    652   // readback. Note: It is possible for the readback's replacement commit to
    653   // be the output surface's first commit and/or the forced redraw's commit.
    654   if (readback_state_ == READBACK_STATE_IDLE ||
    655       readback_state_ == READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION) {
    656     // Update state related to forced draws.
    657     if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) {
    658       forced_redraw_state_ = has_pending_tree_
    659                                  ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
    660                                  : FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
    661     }
    662 
    663     // Update the output surface state.
    664     DCHECK_NE(output_surface_state_,
    665               OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
    666     if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) {
    667       if (has_pending_tree_) {
    668         output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION;
    669       } else {
    670         output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
    671         needs_redraw_ = true;
    672       }
    673     }
    674   }
    675 
    676   // Update the commit state. We expect and wait for a draw if the commit
    677   // was not aborted or if we are in a readback or forced draw.
    678   if (!commit_was_aborted) {
    679     DCHECK(commit_state_ == COMMIT_STATE_READY_TO_COMMIT);
    680     commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
    681   } else if (readback_state_ != READBACK_STATE_IDLE ||
    682              forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE) {
    683     commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
    684   } else {
    685     commit_state_ = COMMIT_STATE_IDLE;
    686   }
    687 
    688   // Update state if we have a new active tree to draw, or if the active tree
    689   // was unchanged but we need to do a readback or forced draw.
    690   if (!has_pending_tree_ &&
    691       (!commit_was_aborted ||
    692        readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK ||
    693        forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) {
    694     needs_redraw_ = true;
    695     active_tree_needs_first_draw_ = true;
    696   }
    697 
    698   // This post-commit work is common to both completed and aborted commits.
    699   pending_tree_is_ready_for_activation_ = false;
    700 
    701   if (draw_if_possible_failed_)
    702     last_frame_number_swap_performed_ = -1;
    703 
    704   // If we are planing to draw with the new commit, lock the layer textures for
    705   // use on the impl thread. Otherwise, leave them unlocked.
    706   if (has_pending_tree_ || needs_redraw_)
    707     texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD;
    708   else
    709     texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED;
    710 }
    711 
    712 void SchedulerStateMachine::UpdateStateOnActivation() {
    713   // Update output surface state.
    714   if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
    715     output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
    716 
    717   // Update readback state
    718   if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION)
    719     forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
    720 
    721   // Update forced redraw state
    722   if (readback_state_ == READBACK_STATE_WAITING_FOR_ACTIVATION)
    723     readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK;
    724   else if (readback_state_ == READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION)
    725     readback_state_ = READBACK_STATE_IDLE;
    726 
    727   has_pending_tree_ = false;
    728   pending_tree_is_ready_for_activation_ = false;
    729   active_tree_needs_first_draw_ = true;
    730   needs_redraw_ = true;
    731 }
    732 
    733 void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) {
    734   DCHECK(readback_state_ != READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT &&
    735          readback_state_ != READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION)
    736       << *AsValue();
    737 
    738   if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) {
    739     // The draw correspons to a readback commit.
    740     DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
    741     // We are blocking commits from the main thread until after this draw, so
    742     // we should not have a pending tree.
    743     DCHECK(!has_pending_tree_);
    744     // We transition to COMMIT_STATE_FRAME_IN_PROGRESS because there is a
    745     // pending BeginMainFrame behind the readback request.
    746     commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS;
    747     readback_state_ = READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT;
    748   } else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) {
    749     DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
    750     commit_state_ = COMMIT_STATE_IDLE;
    751     forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
    752   } else if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW &&
    753              !has_pending_tree_) {
    754     commit_state_ = COMMIT_STATE_IDLE;
    755   }
    756 
    757   if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD)
    758     texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED;
    759 
    760   needs_redraw_ = false;
    761   draw_if_possible_failed_ = false;
    762   active_tree_needs_first_draw_ = false;
    763 
    764   if (did_swap)
    765     last_frame_number_swap_performed_ = current_frame_number_;
    766 }
    767 
    768 void SchedulerStateMachine::UpdateStateOnManageTiles() {
    769   needs_manage_tiles_ = false;
    770 }
    771 
    772 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() {
    773   DCHECK(!main_thread_needs_layer_textures_);
    774   DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD);
    775   main_thread_needs_layer_textures_ = true;
    776 }
    777 
    778 void SchedulerStateMachine::SetSkipBeginMainFrameToReduceLatency(bool skip) {
    779   skip_begin_main_frame_to_reduce_latency_ = skip;
    780 }
    781 
    782 bool SchedulerStateMachine::BeginImplFrameNeeded() const {
    783   // Proactive BeginImplFrames are bad for the synchronous compositor because we
    784   // have to draw when we get the BeginImplFrame and could end up drawing many
    785   // duplicate frames if our new frame isn't ready in time.
    786   // To poll for state with the synchronous compositor without having to draw,
    787   // we rely on ShouldPollForAnticipatedDrawTriggers instead.
    788   if (!SupportsProactiveBeginImplFrame())
    789     return BeginImplFrameNeededToDraw();
    790 
    791   return BeginImplFrameNeededToDraw() ||
    792          ProactiveBeginImplFrameWanted();
    793 }
    794 
    795 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
    796   // ShouldPollForAnticipatedDrawTriggers is what we use in place of
    797   // ProactiveBeginImplFrameWanted when we are using the synchronous
    798   // compositor.
    799   if (!SupportsProactiveBeginImplFrame()) {
    800     return !BeginImplFrameNeededToDraw() &&
    801            ProactiveBeginImplFrameWanted();
    802   }
    803 
    804   // Non synchronous compositors should rely on
    805   // ProactiveBeginImplFrameWanted to poll for state instead.
    806   return false;
    807 }
    808 
    809 bool SchedulerStateMachine::SupportsProactiveBeginImplFrame() const {
    810   // Both the synchronous compositor and disabled vsync settings
    811   // make it undesirable to proactively request BeginImplFrames.
    812   // If this is true, the scheduler should poll.
    813   return !settings_.using_synchronous_renderer_compositor &&
    814          settings_.throttle_frame_production;
    815 }
    816 
    817 // These are the cases where we definitely (or almost definitely) have a
    818 // new frame to draw and can draw.
    819 bool SchedulerStateMachine::BeginImplFrameNeededToDraw() const {
    820   // The output surface is the provider of BeginImplFrames, so we are not going
    821   // to get them even if we ask for them.
    822   if (!HasInitializedOutputSurface())
    823     return false;
    824 
    825   // If we can't draw, don't tick until we are notified that we can draw again.
    826   if (!can_draw_)
    827     return false;
    828 
    829   // The forced draw respects our normal draw scheduling, so we need to
    830   // request a BeginImplFrame for it.
    831   if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
    832     return true;
    833 
    834   // There's no need to produce frames if we are not visible.
    835   if (!visible_)
    836     return false;
    837 
    838   // We need to draw a more complete frame than we did the last BeginImplFrame,
    839   // so request another BeginImplFrame in anticipation that we will have
    840   // additional visible tiles.
    841   if (swap_used_incomplete_tile_)
    842     return true;
    843 
    844   return needs_redraw_;
    845 }
    846 
    847 // These are cases where we are very likely to draw soon, but might not
    848 // actually have a new frame to draw when we receive the next BeginImplFrame.
    849 // Proactively requesting the BeginImplFrame helps hide the round trip latency
    850 // of the SetNeedsBeginImplFrame request that has to go to the Browser.
    851 bool SchedulerStateMachine::ProactiveBeginImplFrameWanted() const {
    852   // The output surface is the provider of BeginImplFrames,
    853   // so we are not going to get them even if we ask for them.
    854   if (!HasInitializedOutputSurface())
    855     return false;
    856 
    857   // Do not be proactive when invisible.
    858   if (!visible_)
    859     return false;
    860 
    861   // We should proactively request a BeginImplFrame if a commit is pending
    862   // because we will want to draw if the commit completes quickly.
    863   if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE)
    864     return true;
    865 
    866   // If the pending tree activates quickly, we'll want a BeginImplFrame soon
    867   // to draw the new active tree.
    868   if (has_pending_tree_)
    869     return true;
    870 
    871   // Changing priorities may allow us to activate (given the new priorities),
    872   // which may result in a new frame.
    873   if (needs_manage_tiles_)
    874     return true;
    875 
    876   // If we just swapped, it's likely that we are going to produce another
    877   // frame soon. This helps avoid negative glitches in our
    878   // SetNeedsBeginImplFrame requests, which may propagate to the BeginImplFrame
    879   // provider and get sampled at an inopportune time, delaying the next
    880   // BeginImplFrame.
    881   if (last_frame_number_swap_performed_ == current_frame_number_)
    882     return true;
    883 
    884   return false;
    885 }
    886 
    887 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) {
    888   current_frame_number_++;
    889   last_begin_impl_frame_args_ = args;
    890   DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) << *AsValue();
    891   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING;
    892 }
    893 
    894 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() {
    895   DCHECK_EQ(begin_impl_frame_state_,
    896             BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING)
    897       << *AsValue();
    898   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
    899 }
    900 
    901 void SchedulerStateMachine::OnBeginImplFrameDeadline() {
    902   DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
    903       << *AsValue();
    904   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
    905 }
    906 
    907 void SchedulerStateMachine::OnBeginImplFrameIdle() {
    908   DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
    909       << *AsValue();
    910   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE;
    911 }
    912 
    913 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineEarly() const {
    914   // TODO(brianderson): This should take into account multiple commit sources.
    915 
    916   // If we are in the middle of the readback, we won't swap, so there is
    917   // no reason to trigger the deadline early.
    918   if (readback_state_ != READBACK_STATE_IDLE)
    919     return false;
    920 
    921   if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
    922     return false;
    923 
    924   if (active_tree_needs_first_draw_)
    925     return true;
    926 
    927   if (!needs_redraw_)
    928     return false;
    929 
    930   // This is used to prioritize impl-thread draws when the main thread isn't
    931   // producing anything, e.g., after an aborted commit. We also check that we
    932   // don't have a pending tree -- otherwise we should give it a chance to
    933   // activate.
    934   // TODO(skyostil): Revisit this when we have more accurate deadline estimates.
    935   if (commit_state_ == COMMIT_STATE_IDLE && !has_pending_tree_)
    936     return true;
    937 
    938   // Prioritize impl-thread draws in smoothness mode.
    939   if (smoothness_takes_priority_)
    940     return true;
    941 
    942   return false;
    943 }
    944 
    945 bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const {
    946   // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main
    947   // thread is in a low latency mode.
    948   if (last_frame_number_begin_main_frame_sent_ == current_frame_number_ &&
    949       (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING ||
    950        begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME))
    951     return false;
    952 
    953   // If there's a commit in progress it must either be from the previous frame
    954   // or it started after the impl thread's deadline. In either case the main
    955   // thread is in high latency mode.
    956   if (commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS ||
    957       commit_state_ == COMMIT_STATE_READY_TO_COMMIT)
    958     return true;
    959 
    960   // Similarly, if there's a pending tree the main thread is in high latency
    961   // mode, because either
    962   //   it's from the previous frame
    963   // or
    964   //   we're currently drawing the active tree and the pending tree will thus
    965   //   only be drawn in the next frame.
    966   if (has_pending_tree_)
    967     return true;
    968 
    969   if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) {
    970     // Even if there's a new active tree to draw at the deadline or we've just
    971     // drawn it, it may have been triggered by a previous BeginImplFrame, in
    972     // which case the main thread is in a high latency mode.
    973     return (active_tree_needs_first_draw_ ||
    974             last_frame_number_swap_performed_ == current_frame_number_) &&
    975            last_frame_number_begin_main_frame_sent_ != current_frame_number_;
    976   }
    977 
    978   // If the active tree needs its first draw in any other state, we know the
    979   // main thread is in a high latency mode.
    980   return active_tree_needs_first_draw_;
    981 }
    982 
    983 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() {
    984   current_frame_number_++;
    985   inside_poll_for_anticipated_draw_triggers_ = true;
    986 }
    987 
    988 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() {
    989   inside_poll_for_anticipated_draw_triggers_ = false;
    990 }
    991 
    992 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
    993 
    994 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }
    995 
    996 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
    997 
    998 void SchedulerStateMachine::SetNeedsManageTiles() {
    999   if (!needs_manage_tiles_) {
   1000     TRACE_EVENT0("cc",
   1001                  "SchedulerStateMachine::SetNeedsManageTiles");
   1002     needs_manage_tiles_ = true;
   1003   }
   1004 }
   1005 
   1006 void SchedulerStateMachine::SetSwapUsedIncompleteTile(
   1007     bool used_incomplete_tile) {
   1008   swap_used_incomplete_tile_ = used_incomplete_tile;
   1009 }
   1010 
   1011 void SchedulerStateMachine::SetSmoothnessTakesPriority(
   1012     bool smoothness_takes_priority) {
   1013   smoothness_takes_priority_ = smoothness_takes_priority;
   1014 }
   1015 
   1016 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) {
   1017   draw_if_possible_failed_ = !success;
   1018   if (draw_if_possible_failed_) {
   1019     needs_redraw_ = true;
   1020 
   1021     // If we're already in the middle of a redraw, we don't need to
   1022     // restart it.
   1023     if (forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE)
   1024       return;
   1025 
   1026     needs_commit_ = true;
   1027     consecutive_failed_draws_++;
   1028     if (settings_.timeout_and_draw_when_animation_checkerboards &&
   1029         consecutive_failed_draws_ >=
   1030             settings_.maximum_number_of_failed_draws_before_draw_is_forced_) {
   1031       consecutive_failed_draws_ = 0;
   1032       // We need to force a draw, but it doesn't make sense to do this until
   1033       // we've committed and have new textures.
   1034       forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
   1035     }
   1036   } else {
   1037     consecutive_failed_draws_ = 0;
   1038     forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
   1039   }
   1040 }
   1041 
   1042 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; }
   1043 
   1044 void SchedulerStateMachine::SetNeedsForcedCommitForReadback() {
   1045   // If this is called in READBACK_STATE_IDLE, this is a "first" readback
   1046   // request.
   1047   // If this is called in READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT, this
   1048   // is a back-to-back readback request that started before the replacement
   1049   // commit had a chance to land.
   1050   DCHECK(readback_state_ == READBACK_STATE_IDLE ||
   1051          readback_state_ == READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT);
   1052 
   1053   // If there is already a commit in progress when we get the readback request
   1054   // (we are in COMMIT_STATE_FRAME_IN_PROGRESS), then we don't need to send a
   1055   // BeginMainFrame for the replacement commit, since there's already a
   1056   // BeginMainFrame behind the readback request. In that case, we can skip
   1057   // READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME and go directly to
   1058   // READBACK_STATE_WAITING_FOR_COMMIT
   1059   if (commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS)
   1060     readback_state_ = READBACK_STATE_WAITING_FOR_COMMIT;
   1061   else
   1062     readback_state_ = READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME;
   1063 }
   1064 
   1065 void SchedulerStateMachine::FinishCommit() {
   1066   DCHECK(commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS) << *AsValue();
   1067   commit_state_ = COMMIT_STATE_READY_TO_COMMIT;
   1068 }
   1069 
   1070 void SchedulerStateMachine::BeginMainFrameAborted(bool did_handle) {
   1071   DCHECK_EQ(commit_state_, COMMIT_STATE_FRAME_IN_PROGRESS);
   1072   if (did_handle) {
   1073     bool commit_was_aborted = true;
   1074     UpdateStateOnCommit(commit_was_aborted);
   1075   } else {
   1076     DCHECK_NE(readback_state_, READBACK_STATE_WAITING_FOR_COMMIT);
   1077     commit_state_ = COMMIT_STATE_IDLE;
   1078     SetNeedsCommit();
   1079   }
   1080 }
   1081 
   1082 void SchedulerStateMachine::DidManageTiles() {
   1083   needs_manage_tiles_ = false;
   1084   last_frame_number_manage_tiles_called_ = current_frame_number_;
   1085 }
   1086 
   1087 void SchedulerStateMachine::DidLoseOutputSurface() {
   1088   if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
   1089       output_surface_state_ == OUTPUT_SURFACE_CREATING)
   1090     return;
   1091   output_surface_state_ = OUTPUT_SURFACE_LOST;
   1092   needs_redraw_ = false;
   1093   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE;
   1094 }
   1095 
   1096 void SchedulerStateMachine::NotifyReadyToActivate() {
   1097   if (has_pending_tree_)
   1098     pending_tree_is_ready_for_activation_ = true;
   1099 }
   1100 
   1101 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
   1102   DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING);
   1103   output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT;
   1104 
   1105   if (did_create_and_initialize_first_output_surface_) {
   1106     // TODO(boliu): See if we can remove this when impl-side painting is always
   1107     // on. Does anything on the main thread need to update after recreate?
   1108     needs_commit_ = true;
   1109   }
   1110   did_create_and_initialize_first_output_surface_ = true;
   1111 }
   1112 
   1113 bool SchedulerStateMachine::HasInitializedOutputSurface() const {
   1114   switch (output_surface_state_) {
   1115     case OUTPUT_SURFACE_LOST:
   1116     case OUTPUT_SURFACE_CREATING:
   1117       return false;
   1118 
   1119     case OUTPUT_SURFACE_ACTIVE:
   1120     case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
   1121     case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
   1122       return true;
   1123   }
   1124   NOTREACHED();
   1125   return false;
   1126 }
   1127 
   1128 }  // namespace cc
   1129