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