Chromium Code Reviews| Index: cc/scheduler/scheduler.cc |
| diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc |
| index 225745111a2c00faa483c564b343f9c53e03e401..2f07941350abf3d8cf6a837bb7f477a5d1bac66c 100644 |
| --- a/cc/scheduler/scheduler.cc |
| +++ b/cc/scheduler/scheduler.cc |
| @@ -218,8 +218,9 @@ void Scheduler::DidSwapBuffersComplete() { |
| ProcessScheduledActions(); |
| } |
| -void Scheduler::SetImplLatencyTakesPriority(bool impl_latency_takes_priority) { |
| - state_machine_.SetImplLatencyTakesPriority(impl_latency_takes_priority); |
| +void Scheduler::SetSmoothnessMode(TreePriority tree_priority, |
|
brianderson
2015/11/17 23:01:45
Note: I ended up keeping this a single function so
Sami
2015/11/18 19:46:04
Ok, the enums do make the call sites easier to rea
|
| + ScrollHandlerState scroll_handler_state) { |
| + state_machine_.SetSmoothnessMode(tree_priority, scroll_handler_state); |
| ProcessScheduledActions(); |
| } |
| @@ -317,7 +318,6 @@ bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { |
| // TODO(brianderson): Adjust deadline in the DisplayScheduler. |
| BeginFrameArgs adjusted_args(args); |
| adjusted_args.deadline -= EstimatedParentDrawTime(); |
| - adjusted_args.on_critical_path = !ImplLatencyTakesPriority(); |
| // Deliver BeginFrames to children. |
| // TODO(brianderson): Move this responsibility to the DisplayScheduler. |
| @@ -474,11 +474,44 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { |
| adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); |
| adjusted_args.deadline -= kDeadlineFudgeFactor; |
| - if (ShouldRecoverMainLatency(adjusted_args)) { |
| + base::TimeDelta bmf_start_to_activate = |
| + compositor_timing_history_ |
| + ->BeginMainFrameStartToCommitDurationEstimate() + |
| + compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + |
| + compositor_timing_history_->ActivateDurationEstimate(); |
| + |
| + base::TimeDelta bmf_to_activate_estimate_if_critical = |
| + bmf_start_to_activate + |
| + compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate(); |
| + |
| + bool can_activate_before_deadline_if_critical = |
| + CanBeginMainFrameAndActivateBeforeDeadline( |
| + adjusted_args, bmf_to_activate_estimate_if_critical); |
| + state_machine_.SetCriticalBeginMainFrameToActivateIsFast( |
| + can_activate_before_deadline_if_critical); |
| + |
| + // Update the BeginMainFrame args now that we know whether the main |
| + // thread will be on the critical path or not. |
| + begin_main_frame_args_ = adjusted_args; |
| + begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); |
| + |
| + bool can_activate_before_deadline = can_activate_before_deadline_if_critical; |
| + if (!begin_main_frame_args_.on_critical_path) { |
| + base::TimeDelta bmf_to_activate_estimate = |
| + bmf_start_to_activate + |
| + compositor_timing_history_ |
| + ->BeginMainFrameQueueDurationNotCriticalEstimate(); |
| + |
| + can_activate_before_deadline = CanBeginMainFrameAndActivateBeforeDeadline( |
| + adjusted_args, bmf_to_activate_estimate); |
| + } |
| + |
| + if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { |
| TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", |
| TRACE_EVENT_SCOPE_THREAD); |
| state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
| - } else if (ShouldRecoverImplLatency(adjusted_args)) { |
| + } else if (ShouldRecoverImplLatency(adjusted_args, |
| + can_activate_before_deadline)) { |
| TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", |
| TRACE_EVENT_SCOPE_THREAD); |
| frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); |
| @@ -495,6 +528,13 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { |
| void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { |
| TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
| args.AsValue()); |
| + |
| + // The main thread currently can't commit before we draw with the |
| + // synchronous compositor, so never consider the BeginMainFrame fast. |
| + state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); |
| + begin_main_frame_args_ = args; |
| + begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); |
| + |
| BeginImplFrame(args); |
| FinishImplFrame(); |
| } |
| @@ -518,7 +558,6 @@ void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
| DCHECK(state_machine_.HasInitializedOutputSurface()); |
| begin_impl_frame_tracker_.Start(args); |
| - begin_main_frame_args_ = args; |
| state_machine_.OnBeginImplFrame(); |
| devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); |
| client_->WillBeginImplFrame(begin_impl_frame_tracker_.Current()); |
| @@ -790,7 +829,9 @@ void Scheduler::UpdateCompositorTimingHistoryRecordingEnabled() { |
| state_machine_.HasInitializedOutputSurface() && state_machine_.visible()); |
| } |
| -bool Scheduler::ShouldRecoverMainLatency(const BeginFrameArgs& args) const { |
| +bool Scheduler::ShouldRecoverMainLatency( |
| + const BeginFrameArgs& args, |
| + bool can_activate_before_deadline) const { |
| DCHECK(!settings_.using_synchronous_renderer_compositor); |
| if (!state_machine_.main_thread_missed_last_deadline()) |
| @@ -798,13 +839,15 @@ bool Scheduler::ShouldRecoverMainLatency(const BeginFrameArgs& args) const { |
| // When prioritizing impl thread latency, we currently put the |
| // main thread in a high latency mode. Don't try to fight it. |
| - if (state_machine_.impl_latency_takes_priority()) |
| + if (state_machine_.ImplLatencyTakesPriority()) |
| return false; |
| - return CanCommitAndActivateBeforeDeadline(args); |
| + return can_activate_before_deadline; |
| } |
| -bool Scheduler::ShouldRecoverImplLatency(const BeginFrameArgs& args) const { |
| +bool Scheduler::ShouldRecoverImplLatency( |
| + const BeginFrameArgs& args, |
| + bool can_activate_before_deadline) const { |
| DCHECK(!settings_.using_synchronous_renderer_compositor); |
| // Disable impl thread latency recovery when using the unthrottled |
| @@ -824,7 +867,7 @@ bool Scheduler::ShouldRecoverImplLatency(const BeginFrameArgs& args) const { |
| // When prioritizing impl thread latency, the deadline doesn't wait |
| // for the main thread. |
| - if (state_machine_.impl_latency_takes_priority()) |
| + if (state_machine_.ImplLatencyTakesPriority()) |
| return can_draw_before_deadline; |
| // If we only have impl-side updates, the deadline doesn't wait for |
| @@ -836,18 +879,16 @@ bool Scheduler::ShouldRecoverImplLatency(const BeginFrameArgs& args) const { |
| // to the impl thread. In this case, only try to also recover impl thread |
| // latency if both the main and impl threads can run serially before the |
| // deadline. |
| - return CanCommitAndActivateBeforeDeadline(args); |
| + return can_activate_before_deadline; |
| } |
| -bool Scheduler::CanCommitAndActivateBeforeDeadline( |
| - const BeginFrameArgs& args) const { |
| +bool Scheduler::CanBeginMainFrameAndActivateBeforeDeadline( |
| + const BeginFrameArgs& args, |
| + base::TimeDelta bmf_to_activate_estimate) const { |
| // Check if the main thread computation and commit can be finished before the |
| // impl thread's deadline. |
| base::TimeTicks estimated_draw_time = |
| - args.frame_time + |
| - compositor_timing_history_->BeginMainFrameToCommitDurationEstimate() + |
| - compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + |
| - compositor_timing_history_->ActivateDurationEstimate(); |
| + args.frame_time + bmf_to_activate_estimate; |
| return estimated_draw_time < args.deadline; |
| } |