Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: cc/scheduler/scheduler_state_machine.cc

Issue 2753843003: Create a new action triggered when a BeginMainFrame is not expected before vsync (Closed)
Patch Set: fix funnel initial state Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« cc/scheduler/scheduler.cc ('K') | « cc/scheduler/scheduler_state_machine.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..a22b3ddf5ac2a490276623435663caf6500fb2f8 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -45,6 +45,7 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
send_begin_main_frame_funnel_(true),
invalidate_compositor_frame_sink_funnel_(false),
impl_side_invalidation_funnel_(false),
+ do_idle_work_funnel_(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_IDLE_WORK:
+ return "ACTION_DO_IDLE_WORK";
}
NOTREACHED();
return "???";
@@ -246,6 +249,7 @@ void SchedulerStateMachine::AsValueInto(
state->SetBoolean("funnel: draw_funnel", draw_funnel_);
state->SetBoolean("funnel: send_begin_main_frame_funnel",
send_begin_main_frame_funnel_);
+ state->SetBoolean("funnel: do_idle_work_funnel", do_idle_work_funnel_);
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,98 @@ bool SchedulerStateMachine::ShouldActivatePendingTree() const {
return pending_tree_is_ready_for_activation_;
}
+bool SchedulerStateMachine::CouldDoIdleWork() const {
+ if (needs_begin_main_frame_)
Sami 2017/03/20 16:58:49 // BeginMainFrame already triggers idle work, so w
Dan Elphick 2017/03/21 15:56:25 Done.
+ return false;
+
+ // We can not perform commits if we are not visible.
Sami 2017/03/20 16:58:49 // Only do FooIdle work when we're visible.
Dan Elphick 2017/03/21 15:56:25 Done.
+ if (!visible_)
+ return false;
+
+ // There are no BeginImplFrames while BeginFrameSource is paused,
+ // so should also stop BeginMainFrames.
Sami 2017/03/20 16:58:49 ...stop FooIdle work
Dan Elphick 2017/03/21 15:56:25 Done.
+ if (begin_frame_source_paused_)
+ return false;
+
+ // Do not make a new commits when it is deferred.
+ if (defer_commits_)
Sami 2017/03/20 16:58:49 This one we can drop.
Dan Elphick 2017/03/21 15:56:25 Done.
+ return false;
+
+ return true;
+}
+
+bool SchedulerStateMachine::ShouldDoIdleWork() const {
+ if (!CouldDoIdleWork())
+ return false;
+
+ // Do not do idle work too many times in a single frame or before
+ // the first BeginFrame.
+ if (do_idle_work_funnel_)
+ return false;
+
+ // Only send BeginMainFrame when there isn't another commit pending already.
+ // Other parts of the state machine indirectly defer the BeginMainFrame
+ // by transitioning to WAITING commit states rather than going
+ // immediately to IDLE.
+ if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE)
Sami 2017/03/20 16:58:49 // If a BeginMainFrame is in progress, don't do an
Dan Elphick 2017/03/21 15:56:25 Done.
+ return false;
+
+ // MFBA is disabled and we are waiting for previous activation.
+ if (!settings_.main_frame_before_activation_enabled && has_pending_tree_)
Sami 2017/03/20 16:58:49 Drop this.
Dan Elphick 2017/03/21 15:56:25 Done.
+ return false;
+
+ // We are waiting for previous frame to be drawn, submitted and acked.
+ if (settings_.commit_to_active_tree &&
Sami 2017/03/20 16:58:49 Drop this.
+ (active_tree_needs_first_draw_ || IsDrawThrottled())) {
+ return false;
+ }
+
+ // Don't send BeginMainFrame early if we are prioritizing the active tree
+ // because of ImplLatencyTakesPriority.
+ if (ImplLatencyTakesPriority() &&
Sami 2017/03/20 16:58:49 Drop this.
+ (has_pending_tree_ || active_tree_needs_first_draw_)) {
+ return false;
+ }
+
+ // We should not send BeginMainFrame while we are in the idle state since we
+ // might have new user input arriving soon. It's okay to send BeginMainFrame
+ // for the synchronous compositor because the main thread is always high
+ // latency in that case.
+ // TODO(brianderson): Allow sending BeginMainFrame while idle when the main
+ // thread isn't consuming user input for non-synchronous compositor.
+ if (!settings_.using_synchronous_renderer_compositor &&
Sami 2017/03/20 16:58:49 Drop this.
+ begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE) {
+ return false;
+ }
+
+ // We need a new commit for the forced redraw. This honors the
+ // single commit per interval because the result will be swapped to screen.
+ if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
Sami 2017/03/20 16:58:49 Drop this.
+ return true;
+
+ // We shouldn't normally accept commits if there isn't an CompositorFrameSink.
+ if (!HasInitializedCompositorFrameSink())
Sami 2017/03/20 16:58:49 Drop this.
+ return false;
+
+ if (!settings_.main_frame_while_submit_frame_throttled_enabled) {
Sami 2017/03/20 16:58:49 Drop this.
+ // Throttle the BeginMainFrames on CompositorFrameAck unless we just
+ // submitted a frame to potentially improve impl-thread latency over
+ // main-thread throughput.
+ // TODO(brianderson): Remove this restriction to improve throughput or
+ // make it conditional on ImplLatencyTakesPriority.
+ bool just_submitted_in_deadline =
+ begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
+ did_submit_in_last_frame_;
+ if (IsDrawThrottled() && !just_submitted_in_deadline)
+ return false;
+ }
+
+ if (skip_next_begin_main_frame_to_reduce_latency_)
Sami 2017/03/20 16:58:49 Drop this.
+ return false;
+
+ return true;
+}
+
bool SchedulerStateMachine::CouldSendBeginMainFrame() const {
if (!needs_begin_main_frame_)
return false;
@@ -594,6 +690,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
return ACTION_PREPARE_TILES;
if (ShouldSendBeginMainFrame())
return ACTION_SEND_BEGIN_MAIN_FRAME;
+ if (ShouldDoIdleWork())
Sami 2017/03/20 16:58:49 Let's move this to the end.
+ return ACTION_DO_IDLE_WORK;
if (ShouldInvalidateCompositorFrameSink())
return ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK;
if (ShouldBeginCompositorFrameSinkCreation())
@@ -692,6 +790,14 @@ void SchedulerStateMachine::WillSendBeginMainFrame() {
begin_frame_sequence_number_;
}
+void SchedulerStateMachine::WillDoIdleWork() {
+ DCHECK(!has_pending_tree_ || settings_.main_frame_before_activation_enabled);
Sami 2017/03/20 16:58:49 Drop this.
+ DCHECK(visible_);
+ DCHECK(!begin_frame_source_paused_);
+ DCHECK(!do_idle_work_funnel_);
+ do_idle_work_funnel_ = true;
+}
+
void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) {
bool can_have_pending_tree =
commit_has_no_updates &&
@@ -1047,6 +1153,7 @@ void SchedulerStateMachine::OnBeginImplFrame(uint32_t source_id,
needs_one_begin_impl_frame_ = false;
// Clear funnels for any actions we perform during the frame.
+ do_idle_work_funnel_ = false;
send_begin_main_frame_funnel_ = false;
invalidate_compositor_frame_sink_funnel_ = false;
impl_side_invalidation_funnel_ = false;
« cc/scheduler/scheduler.cc ('K') | « cc/scheduler/scheduler_state_machine.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698