| Index: cc/scheduler/scheduler.cc
|
| diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
|
| index 535d1056bd382eb5d31c23b736787b2cb7db7672..8d407decd4da8df7371460700f0291ae4f0e19cf 100644
|
| --- a/cc/scheduler/scheduler.cc
|
| +++ b/cc/scheduler/scheduler.cc
|
| @@ -78,6 +78,7 @@ Scheduler::Scheduler(
|
| task_runner_(task_runner),
|
| begin_impl_frame_deadline_mode_(
|
| SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE),
|
| + begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE),
|
| state_machine_(scheduler_settings),
|
| inside_process_scheduled_actions_(false),
|
| inside_action_(SchedulerStateMachine::ACTION_NONE),
|
| @@ -274,18 +275,19 @@ void Scheduler::NotifyBeginMainFrameStarted() {
|
|
|
| base::TimeTicks Scheduler::AnticipatedDrawTime() const {
|
| if (!frame_source_->NeedsBeginFrames() ||
|
| - begin_impl_frame_args_.interval <= base::TimeDelta())
|
| + begin_impl_frame_tracker_.DangerousMethodHasFinished())
|
| return base::TimeTicks();
|
|
|
| base::TimeTicks now = Now();
|
| - base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time,
|
| - begin_impl_frame_args_.deadline);
|
| - int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval);
|
| - return timebase + (begin_impl_frame_args_.interval * intervals);
|
| + BeginFrameArgs args = begin_impl_frame_tracker_.Current();
|
| + base::TimeTicks timebase = std::max(args.frame_time, args.deadline);
|
| + int64 intervals =
|
| + 1 + ((now - timebase) / begin_impl_frame_tracker_.Interval());
|
| + return timebase + (begin_impl_frame_tracker_.Interval() * intervals);
|
| }
|
|
|
| base::TimeTicks Scheduler::LastBeginImplFrameTime() {
|
| - return begin_impl_frame_args_.frame_time;
|
| + return begin_impl_frame_tracker_.Current().frame_time;
|
| }
|
|
|
| void Scheduler::SetupNextBeginFrameIfNeeded() {
|
| @@ -319,13 +321,13 @@ void Scheduler::SetupPollingMechanisms() {
|
| if (IsBeginMainFrameSentOrStarted() &&
|
| !settings_.using_synchronous_renderer_compositor) {
|
| if (advance_commit_state_task_.IsCancelled() &&
|
| - begin_impl_frame_args_.IsValid()) {
|
| + begin_impl_frame_tracker_.DangerousMethodCurrentOrLast().IsValid()) {
|
| // Since we'd rather get a BeginImplFrame by the normal mechanism, we
|
| // set the interval to twice the interval from the previous frame.
|
| advance_commit_state_task_.Reset(advance_commit_state_closure_);
|
| task_runner_->PostDelayedTask(FROM_HERE,
|
| advance_commit_state_task_.callback(),
|
| - begin_impl_frame_args_.interval * 2);
|
| + begin_impl_frame_tracker_.Interval() * 2);
|
| }
|
| } else {
|
| advance_commit_state_task_.Cancel();
|
| @@ -339,6 +341,11 @@ void Scheduler::SetupPollingMechanisms() {
|
| bool Scheduler::OnBeginFrameMixInDelegate(const BeginFrameArgs& args) {
|
| TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue());
|
|
|
| + // Trace this begin frame time through the Chrome stack
|
| + TRACE_EVENT_FLOW_BEGIN0(
|
| + TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs",
|
| + args.frame_time.ToInternalValue());
|
| +
|
| // TODO(brianderson): Adjust deadline in the DisplayScheduler.
|
| BeginFrameArgs adjusted_args(args);
|
| adjusted_args.deadline -= EstimatedParentDrawTime();
|
| @@ -494,8 +501,8 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
|
|
|
| advance_commit_state_task_.Cancel();
|
|
|
| - begin_impl_frame_args_ = args;
|
| - begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate();
|
| + BeginFrameArgs adjusted_args = args;
|
| + adjusted_args.deadline -= client_->DrawDurationEstimate();
|
|
|
| if (!state_machine_.impl_latency_takes_priority() &&
|
| main_thread_is_in_high_latency_mode &&
|
| @@ -503,7 +510,7 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
|
| state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
|
| }
|
|
|
| - BeginImplFrame();
|
| + BeginImplFrame(adjusted_args);
|
|
|
| // The deadline will be scheduled in ProcessScheduledActions.
|
| state_machine_.OnBeginImplFrameDeadlinePending();
|
| @@ -513,8 +520,7 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
|
| void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) {
|
| TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args",
|
| args.AsValue());
|
| - begin_impl_frame_args_ = args;
|
| - BeginImplFrame();
|
| + BeginImplFrame(args);
|
| FinishImplFrame();
|
| }
|
|
|
| @@ -524,21 +530,23 @@ void Scheduler::FinishImplFrame() {
|
|
|
| client_->DidFinishImplFrame();
|
| frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
|
| + begin_impl_frame_tracker_.Finish();
|
| }
|
|
|
| // BeginImplFrame starts a compositor frame that will wait up until a deadline
|
| // for a BeginMainFrame+activation to complete before it times out and draws
|
| // any asynchronous animation and scroll/pinch updates.
|
| -void Scheduler::BeginImplFrame() {
|
| +void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
|
| DCHECK_EQ(state_machine_.begin_impl_frame_state(),
|
| SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
|
| DCHECK(!BeginImplFrameDeadlinePending());
|
| DCHECK(state_machine_.HasInitializedOutputSurface());
|
| DCHECK(advance_commit_state_task_.IsCancelled());
|
|
|
| + begin_impl_frame_tracker_.Start(args);
|
| state_machine_.OnBeginImplFrame();
|
| devtools_instrumentation::DidBeginFrame(layer_tree_host_id_);
|
| - client_->WillBeginImplFrame(begin_impl_frame_args_);
|
| + client_->WillBeginImplFrame(begin_impl_frame_tracker_.Current());
|
|
|
| ProcessScheduledActions();
|
| }
|
| @@ -565,14 +573,14 @@ void Scheduler::ScheduleBeginImplFrameDeadline() {
|
| break;
|
| case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR:
|
| // We are animating on the impl thread but we can wait for some time.
|
| - deadline = begin_impl_frame_args_.deadline;
|
| + deadline = begin_impl_frame_tracker_.Current().deadline;
|
| break;
|
| case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE:
|
| // We are blocked for one reason or another and we should wait.
|
| // TODO(brianderson): Handle long deadlines (that are past the next
|
| // frame's frame time) properly instead of using this hack.
|
| - deadline =
|
| - begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval;
|
| + deadline = begin_impl_frame_tracker_.Current().frame_time +
|
| + begin_impl_frame_tracker_.Current().interval;
|
| break;
|
| case SchedulerStateMachine::
|
| BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW:
|
| @@ -768,26 +776,8 @@ void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const {
|
| state->SetBoolean("advance_commit_state_task_",
|
| !advance_commit_state_task_.IsCancelled());
|
| state->BeginDictionary("begin_impl_frame_args");
|
| - begin_impl_frame_args_.AsValueInto(state);
|
| + begin_impl_frame_tracker_.AsValueInto(Now(), state);
|
| state->EndDictionary();
|
| -
|
| - base::TimeTicks now = Now();
|
| - base::TimeTicks frame_time = begin_impl_frame_args_.frame_time;
|
| - base::TimeTicks deadline = begin_impl_frame_args_.deadline;
|
| - base::TimeDelta interval = begin_impl_frame_args_.interval;
|
| - state->BeginDictionary("major_timestamps_in_ms");
|
| - state->SetDouble("0_interval", interval.InMillisecondsF());
|
| - state->SetDouble("1_now_to_deadline", (deadline - now).InMillisecondsF());
|
| - state->SetDouble("2_frame_time_to_now", (now - frame_time).InMillisecondsF());
|
| - state->SetDouble("3_frame_time_to_deadline",
|
| - (deadline - frame_time).InMillisecondsF());
|
| - state->SetDouble("4_now", (now - base::TimeTicks()).InMillisecondsF());
|
| - state->SetDouble("5_frame_time",
|
| - (frame_time - base::TimeTicks()).InMillisecondsF());
|
| - state->SetDouble("6_deadline",
|
| - (deadline - base::TimeTicks()).InMillisecondsF());
|
| - state->EndDictionary();
|
| -
|
| state->EndDictionary();
|
|
|
| state->BeginDictionary("client_state");
|
| @@ -803,22 +793,22 @@ void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const {
|
| }
|
|
|
| bool Scheduler::CanCommitAndActivateBeforeDeadline() const {
|
| + BeginFrameArgs args =
|
| + begin_impl_frame_tracker_.DangerousMethodCurrentOrLast();
|
| +
|
| // Check if the main thread computation and commit can be finished before the
|
| // impl thread's deadline.
|
| base::TimeTicks estimated_draw_time =
|
| - begin_impl_frame_args_.frame_time +
|
| - client_->BeginMainFrameToCommitDurationEstimate() +
|
| + args.frame_time + 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());
|
| + TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
|
| + "CanCommitAndActivateBeforeDeadline",
|
| + "time_left_after_drawing_ms",
|
| + (args.deadline - estimated_draw_time).InMillisecondsF(), "state",
|
| + AsValue());
|
|
|
| - return estimated_draw_time < begin_impl_frame_args_.deadline;
|
| + return estimated_draw_time < args.deadline;
|
| }
|
|
|
| bool Scheduler::IsBeginMainFrameSentOrStarted() const {
|
|
|