Chromium Code Reviews| Index: cc/scheduler/scheduler.cc |
| diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc |
| index 2a03a34225e55b6da9cb03b1d162e82389836789..5a12af316d227a681b11198cbb37debc223a4cda 100644 |
| --- a/cc/scheduler/scheduler.cc |
| +++ b/cc/scheduler/scheduler.cc |
| @@ -129,8 +129,18 @@ base::TimeTicks Scheduler::Now() const { |
| return now; |
| } |
| +void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) { |
| + authoritative_vsync_interval_ = interval; |
| + if (vsync_observer_) |
| + vsync_observer_->OnUpdateVSyncParameters(last_vsync_timebase_, interval); |
| +} |
| + |
| void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, |
| base::TimeDelta interval) { |
| + TRACE_EVENT2("cc", "Scheduler::CommitVSyncParameters", "timebase", |
| + (timebase - base::TimeTicks()).InSecondsF(), "interval", |
| + interval.InSecondsF()); |
| + |
| if (authoritative_vsync_interval_ != base::TimeDelta()) { |
| interval = authoritative_vsync_interval_; |
| } else if (interval == base::TimeDelta()) { |
| @@ -387,12 +397,6 @@ void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { |
| ProcessScheduledActions(); |
| } |
| -void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) { |
| - authoritative_vsync_interval_ = interval; |
| - if (vsync_observer_) |
| - vsync_observer_->OnUpdateVSyncParameters(last_vsync_timebase_, interval); |
| -} |
| - |
| void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { |
| state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); |
| ProcessScheduledActions(); |
| @@ -498,10 +502,15 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { |
| begin_impl_frame_args_ = args; |
| begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); |
| - if (!state_machine_.impl_latency_takes_priority() && |
| - main_thread_is_in_high_latency_mode && |
| - CanCommitAndActivateBeforeDeadline()) { |
| + if (ShouldRecoverMainLatency()) { |
| + TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", |
| + TRACE_EVENT_SCOPE_THREAD); |
| state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
| + } else if (ShouldRecoverImplLatency()) { |
|
sunnyps
2015/05/22 21:15:04
Does it make sense to prioritize skipping impl fra
brianderson
2015/06/30 22:03:52
I prioritize skipping the main frame first for two
|
| + TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", |
| + TRACE_EVENT_SCOPE_THREAD); |
| + ProcessScheduledActions(); |
| + return; |
|
sunnyps
2015/05/22 21:15:05
FinishImplFrame should be called here, right?
brianderson
2015/05/23 00:53:56
Ah! I am missing a call to frame_source_->DidFinis
|
| } |
| BeginImplFrame(); |
| @@ -516,6 +525,7 @@ void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { |
| args.AsValue()); |
| begin_impl_frame_args_ = args; |
| BeginImplFrame(); |
| + |
| FinishImplFrame(); |
| } |
| @@ -553,7 +563,6 @@ void Scheduler::ScheduleBeginImplFrameDeadline() { |
| begin_impl_frame_deadline_mode_ = |
| state_machine_.CurrentBeginImplFrameDeadlineMode(); |
| - |
| base::TimeTicks deadline; |
| switch (begin_impl_frame_deadline_mode_) { |
| case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE: |
| @@ -771,6 +780,9 @@ void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const { |
| state->BeginDictionary("begin_impl_frame_args"); |
| begin_impl_frame_args_.AsValueInto(state); |
| state->EndDictionary(); |
| + state->SetString("begin_impl_frame_deadline_mode_", |
| + SchedulerStateMachine::BeginImplFrameDeadlineModeToString( |
| + begin_impl_frame_deadline_mode_)); |
| base::TimeTicks now = Now(); |
| base::TimeTicks frame_time = begin_impl_frame_args_.frame_time; |
| @@ -803,6 +815,43 @@ void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const { |
| state->EndDictionary(); |
| } |
| +bool Scheduler::ShouldRecoverMainLatency() const { |
| + if (!state_machine_.MainThreadIsInHighLatencyMode()) |
| + return false; |
| + |
| + if (state_machine_.impl_latency_takes_priority()) |
| + return false; |
| + |
| + return CanCommitAndActivateBeforeDeadline(); |
| +} |
| + |
| +bool Scheduler::ShouldRecoverImplLatency() const { |
| + if (!state_machine_.ImplThreadIsLikelyInHighLatencyMode()) |
| + return false; |
| + |
| + bool frame_time_is_before_deadline = |
| + begin_impl_frame_args_.frame_time < begin_impl_frame_args_.deadline; |
| + |
| + SchedulerStateMachine::BeginImplFrameDeadlineMode |
| + next_begin_impl_frame_deadline_mode = |
| + state_machine_.CurrentBeginImplFrameDeadlineMode(); |
| + switch (next_begin_impl_frame_deadline_mode) { |
| + case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE: |
| + return false; |
| + case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE: |
| + return frame_time_is_before_deadline; |
| + case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR: |
| + return frame_time_is_before_deadline; |
| + case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: |
| + return CanCommitAndActivateBeforeDeadline(); |
| + case SchedulerStateMachine:: |
| + BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW: |
| + return false; |
| + } |
| + NOTREACHED(); |
| + return false; |
| +} |
| + |
| bool Scheduler::CanCommitAndActivateBeforeDeadline() const { |
| // Check if the main thread computation and commit can be finished before the |
| // impl thread's deadline. |
| @@ -811,14 +860,6 @@ bool Scheduler::CanCommitAndActivateBeforeDeadline() const { |
| client_->BeginMainFrameToCommitDurationEstimate() + |
| client_->CommitToActivateDurationEstimate(); |
| - TRACE_EVENT2( |
| - TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
| - "CanCommitAndActivateBeforeDeadline", |
| - "time_left_after_drawing_ms", |
| - (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(), |
| - "state", |
| - AsValue()); |
| - |
| return estimated_draw_time < begin_impl_frame_args_.deadline; |
| } |