| Index: cc/scheduler/scheduler_state_machine.cc
|
| diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
|
| index e73508ce1ab1fb198c9b69ff0e65609a3e637e8e..5011ef862dd0d50b14046dc414b4aaba2fdbd0fa 100644
|
| --- a/cc/scheduler/scheduler_state_machine.cc
|
| +++ b/cc/scheduler/scheduler_state_machine.cc
|
| @@ -42,9 +42,10 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
|
| last_frame_number_begin_main_frame_sent_(-1),
|
| last_frame_number_invalidate_compositor_frame_sink_performed_(-1),
|
| draw_funnel_(false),
|
| - send_begin_main_frame_funnel_(true),
|
| + did_send_begin_main_frame_for_current_frame_(true),
|
| invalidate_compositor_frame_sink_funnel_(false),
|
| impl_side_invalidation_funnel_(false),
|
| + did_do_idle_work_(false),
|
| prepare_tiles_funnel_(0),
|
| consecutive_checkerboard_animations_(0),
|
| pending_submit_frames_(0),
|
| @@ -194,6 +195,8 @@ const char* SchedulerStateMachine::ActionToString(Action action) {
|
| return "ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK";
|
| case ACTION_PERFORM_IMPL_SIDE_INVALIDATION:
|
| return "ACTION_PERFORM_IMPL_SIDE_INVALIDATION";
|
| + case ACTION_DO_SHORT_IDLE_WORK:
|
| + return "ACTION_DO_SHORT_IDLE_WORK";
|
| }
|
| NOTREACHED();
|
| return "???";
|
| @@ -244,8 +247,9 @@ void SchedulerStateMachine::AsValueInto(
|
| "last_begin_frame_sequence_number_compositor_frame_was_fresh",
|
| last_begin_frame_sequence_number_compositor_frame_was_fresh_);
|
| state->SetBoolean("funnel: draw_funnel", draw_funnel_);
|
| - state->SetBoolean("funnel: send_begin_main_frame_funnel",
|
| - send_begin_main_frame_funnel_);
|
| + state->SetBoolean("funnel: did_send_begin_main_frame",
|
| + did_send_begin_main_frame_for_current_frame_);
|
| + state->SetBoolean("funnel: did_do_idle_work", did_do_idle_work_);
|
| state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_);
|
| state->SetBoolean("funnel: invalidate_compositor_frame_sink_funnel",
|
| invalidate_compositor_frame_sink_funnel_);
|
| @@ -428,6 +432,33 @@ bool SchedulerStateMachine::ShouldActivatePendingTree() const {
|
| return pending_tree_is_ready_for_activation_;
|
| }
|
|
|
| +bool SchedulerStateMachine::ShouldDoShortIdleWork() const {
|
| + // BeginMainFrame already triggers idle work, so we don't need to schedule
|
| + // extra idle work here.
|
| + if (needs_begin_main_frame_ || did_send_begin_main_frame_for_current_frame_)
|
| + return false;
|
| +
|
| + // Only schedule extra idle work when we're visible.
|
| + if (!visible_)
|
| + return false;
|
| +
|
| + // There are no BeginImplFrames while BeginFrameSource is paused,
|
| + // so should also stop scheduling extra idle work.
|
| + if (begin_frame_source_paused_)
|
| + return false;
|
| +
|
| + // Do not do idle work too many times in a single frame or before
|
| + // the first BeginFrame.
|
| + if (did_do_idle_work_)
|
| + return false;
|
| +
|
| + // If a BeginMainFrame is in progress, don't do any extra idle work.
|
| + if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE)
|
| + return false;
|
| +
|
| + return true;
|
| +}
|
| +
|
| bool SchedulerStateMachine::CouldSendBeginMainFrame() const {
|
| if (!needs_begin_main_frame_)
|
| return false;
|
| @@ -454,7 +485,7 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
|
|
|
| // Do not send begin main frame too many times in a single frame or before
|
| // the first BeginFrame.
|
| - if (send_begin_main_frame_funnel_)
|
| + if (did_send_begin_main_frame_for_current_frame_)
|
| return false;
|
|
|
| // Only send BeginMainFrame when there isn't another commit pending already.
|
| @@ -598,6 +629,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
|
| return ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK;
|
| if (ShouldBeginCompositorFrameSinkCreation())
|
| return ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION;
|
| + if (ShouldDoShortIdleWork())
|
| + return ACTION_DO_SHORT_IDLE_WORK;
|
| return ACTION_NONE;
|
| }
|
|
|
| @@ -683,15 +716,22 @@ void SchedulerStateMachine::WillSendBeginMainFrame() {
|
| DCHECK(!has_pending_tree_ || settings_.main_frame_before_activation_enabled);
|
| DCHECK(visible_);
|
| DCHECK(!begin_frame_source_paused_);
|
| - DCHECK(!send_begin_main_frame_funnel_);
|
| + DCHECK(!did_send_begin_main_frame_for_current_frame_);
|
| begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_SENT;
|
| needs_begin_main_frame_ = false;
|
| - send_begin_main_frame_funnel_ = true;
|
| + did_send_begin_main_frame_for_current_frame_ = true;
|
| last_frame_number_begin_main_frame_sent_ = current_frame_number_;
|
| last_begin_frame_sequence_number_begin_main_frame_sent_ =
|
| begin_frame_sequence_number_;
|
| }
|
|
|
| +void SchedulerStateMachine::WillDoShortIdleWork() {
|
| + DCHECK(visible_);
|
| + DCHECK(!begin_frame_source_paused_);
|
| + DCHECK(!did_do_idle_work_);
|
| + did_do_idle_work_ = true;
|
| +}
|
| +
|
| void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) {
|
| bool can_have_pending_tree =
|
| commit_has_no_updates &&
|
| @@ -1047,7 +1087,8 @@ void SchedulerStateMachine::OnBeginImplFrame(uint32_t source_id,
|
| needs_one_begin_impl_frame_ = false;
|
|
|
| // Clear funnels for any actions we perform during the frame.
|
| - send_begin_main_frame_funnel_ = false;
|
| + did_do_idle_work_ = false;
|
| + did_send_begin_main_frame_for_current_frame_ = false;
|
| invalidate_compositor_frame_sink_funnel_ = false;
|
| impl_side_invalidation_funnel_ = false;
|
|
|
| @@ -1085,7 +1126,7 @@ void SchedulerStateMachine::OnBeginImplFrameIdle() {
|
| // If we're entering a state where we won't get BeginFrames set all the
|
| // funnels so that we don't perform any actions that we shouldn't.
|
| if (!BeginFrameNeeded())
|
| - send_begin_main_frame_funnel_ = true;
|
| + did_send_begin_main_frame_for_current_frame_ = true;
|
|
|
| // Synchronous compositor finishes BeginFrames before triggering their
|
| // deadline. Therefore, we update sequence numbers when becoming idle, before
|
|
|