diff options
author | dominikg@chromium.org <dominikg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-08 00:51:45 +0000 |
---|---|---|
committer | dominikg@chromium.org <dominikg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-08 00:51:45 +0000 |
commit | 56ec73072f135e7e77788f5a09e43e807faa9882 (patch) | |
tree | 3eba8d6d7ab158e2bdafe65616d8d28c3e2018cf /cc/scheduler/scheduler_state_machine.cc | |
parent | 6ee97bc958ab1e45df101763dbd7afd2c7cb6526 (diff) | |
download | chromium_src-56ec73072f135e7e77788f5a09e43e807faa9882.zip chromium_src-56ec73072f135e7e77788f5a09e43e807faa9882.tar.gz chromium_src-56ec73072f135e7e77788f5a09e43e807faa9882.tar.bz2 |
Scheduler: Switch from high to low latency mode if possible.
Detect if the renderer's impl thread is one frame behind the main thread (i.e. the main thread is in a high
latency mode). If, based on our estimates, the main thread can produce a new tree
before the impl thread's deadline, skip a BeginMainFrame to let the impl thread
catch up and operate in low latency mode from then on.
This feature is currently disabled by default.
BUG=309648
Review URL: https://codereview.chromium.org/54913003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@233734 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/scheduler/scheduler_state_machine.cc')
-rw-r--r-- | cc/scheduler/scheduler_state_machine.cc | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc index 4d9e5e9..e6c8275 100644 --- a/cc/scheduler/scheduler_state_machine.cc +++ b/cc/scheduler/scheduler_state_machine.cc @@ -42,7 +42,8 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) active_tree_needs_first_draw_(false), draw_if_possible_failed_(false), did_create_and_initialize_first_output_surface_(false), - smoothness_takes_priority_(false) {} + smoothness_takes_priority_(false), + skip_begin_main_frame_to_reduce_latency_(false) {} const char* SchedulerStateMachine::OutputSurfaceStateToString( OutputSurfaceState state) { @@ -260,6 +261,10 @@ scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { did_create_and_initialize_first_output_surface_); minor_state->SetBoolean("smoothness_takes_priority", smoothness_takes_priority_); + minor_state->SetBoolean("main_thread_is_in_high_latency_mode", + MainThreadIsInHighLatencyMode()); + minor_state->SetBoolean("skip_begin_main_frame_to_reduce_latency", + skip_begin_main_frame_to_reduce_latency_); state->Set("minor_state", minor_state.release()); return state.PassAs<base::Value>(); @@ -486,6 +491,9 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { if (!HasInitializedOutputSurface()) return false; + if (skip_begin_main_frame_to_reduce_latency_) + return false; + return true; } @@ -763,6 +771,10 @@ void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { main_thread_needs_layer_textures_ = true; } +void SchedulerStateMachine::SetSkipBeginMainFrameToReduceLatency(bool skip) { + skip_begin_main_frame_to_reduce_latency_ = skip; +} + bool SchedulerStateMachine::BeginImplFrameNeeded() const { // Proactive BeginImplFrames are bad for the synchronous compositor because we // have to draw when we get the BeginImplFrame and could end up drawing many @@ -926,6 +938,44 @@ bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineEarly() const { return false; } +bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const { + // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main + // thread is in a low latency mode. + if (last_frame_number_begin_main_frame_sent_ == current_frame_number_ && + (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING || + begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)) + return false; + + // If there's a commit in progress it must either be from the previous frame + // or it started after the impl thread's deadline. In either case the main + // thread is in high latency mode. + if (commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS || + commit_state_ == COMMIT_STATE_READY_TO_COMMIT) + return true; + + // Similarly, if there's a pending tree the main thread is in high latency + // mode, because either + // it's from the previous frame + // or + // we're currently drawing the active tree and the pending tree will thus + // only be drawn in the next frame. + if (has_pending_tree_) + return true; + + if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) { + // Even if there's a new active tree to draw at the deadline or we've just + // drawn it, it may have been triggered by a previous BeginImplFrame, in + // which case the main thread is in a high latency mode. + return (active_tree_needs_first_draw_ || + last_frame_number_swap_performed_ == current_frame_number_) && + last_frame_number_begin_main_frame_sent_ != current_frame_number_; + } + + // If the active tree needs its first draw in any other state, we know the + // main thread is in a high latency mode. + return active_tree_needs_first_draw_; +} + void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { current_frame_number_++; inside_poll_for_anticipated_draw_triggers_ = true; |