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

Unified Diff: cc/scheduler/scheduler.cc

Issue 2828873006: Revert of Revert "cc: Make scheduler run incoming frame after previous deadline." (Closed)
Patch Set: Created 3 years, 8 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
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/scheduler/scheduler.cc
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index 40294b8a3a6a9d6ce77b5a8c25e7a1bf0897c68e..682944e2de0c5ca471dfde833de0237d4753841f 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -44,10 +44,6 @@
TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue());
DCHECK(client_);
DCHECK(!state_machine_.BeginFrameNeeded());
-
- begin_impl_frame_deadline_closure_ = base::Bind(
- &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
-
ProcessScheduledActions();
}
@@ -225,19 +221,53 @@
bool needs_begin_frames = state_machine_.BeginFrameNeeded();
if (needs_begin_frames && !observing_begin_frame_source_) {
- observing_begin_frame_source_ = true;
- if (begin_frame_source_)
- begin_frame_source_->AddObserver(this);
- devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, true);
+ StartObservingBeginFrameSource();
} else if (!needs_begin_frames && observing_begin_frame_source_) {
- observing_begin_frame_source_ = false;
- if (begin_frame_source_)
- begin_frame_source_->RemoveObserver(this);
- missed_begin_frame_task_.Cancel();
- BeginImplFrameNotExpectedSoon();
- devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
- false);
- }
+ StopObservingBeginFrameSource();
+ }
+
+ if (missed_begin_frame_args_.IsValid()) {
+ DCHECK(observing_begin_frame_source_);
+ DCHECK(missed_begin_frame_task_.IsCancelled());
+ missed_begin_frame_task_.Reset(base::Bind(&Scheduler::BeginImplFrameMissed,
+ weak_factory_.GetWeakPtr(),
+ missed_begin_frame_args_));
+ missed_begin_frame_args_ = BeginFrameArgs();
+ task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback());
+ }
+}
+
+void Scheduler::StartObservingBeginFrameSource() {
+ observing_begin_frame_source_ = true;
+
+ if (begin_frame_source_)
+ begin_frame_source_->AddObserver(this);
+
+ devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, true);
+}
+
+void Scheduler::StopObservingBeginFrameSource() {
+ observing_begin_frame_source_ = false;
+
+ if (begin_frame_source_)
+ begin_frame_source_->RemoveObserver(this);
+
+ missed_begin_frame_task_.Cancel();
+
+ if (missed_begin_frame_args_.IsValid()) {
+ // We need to confirm the ignored BeginFrame, since we don't have updates.
+ // To persist the confirmation for future BeginFrameAcks, we let the state
+ // machine know about the BeginFrame.
+ state_machine_.OnBeginFrameDroppedNotObserving(
+ missed_begin_frame_args_.source_id,
+ missed_begin_frame_args_.sequence_number);
+ SendBeginFrameAck(missed_begin_frame_args_, kBeginFrameSkipped);
+ missed_begin_frame_args_ = BeginFrameArgs();
+ }
+
+ BeginImplFrameNotExpectedSoon();
+
+ devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, false);
}
void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) {
@@ -276,14 +306,20 @@
return true;
}
- if (inside_process_scheduled_actions_) {
- // The BFS can send a missed begin frame inside AddObserver. We can't handle
- // a begin frame inside ProcessScheduledActions so post a task.
- DCHECK_EQ(args.type, BeginFrameArgs::MISSED);
- DCHECK(missed_begin_frame_task_.IsCancelled());
- missed_begin_frame_task_.Reset(base::Bind(
- &Scheduler::BeginImplFrameWithDeadline, base::Unretained(this), args));
- task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback());
+ // Cancel any pending missed begin frame task because we're either handling
+ // this begin frame immediately or saving it as a missed frame for which we
+ // will post a new task.
+ missed_begin_frame_task_.Cancel();
+
+ // Save args if we're inside ProcessScheduledActions or the middle of a frame.
+ // At the end of ProcessScheduledActions and at the end of the current frame,
+ // we will post a task to handle the missed begin frame.
+ bool inside_begin_frame =
+ state_machine_.begin_impl_frame_state() ==
+ SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
+ if (inside_process_scheduled_actions_ || inside_begin_frame) {
+ missed_begin_frame_args_ = args;
+ missed_begin_frame_args_.type = BeginFrameArgs::MISSED;
return true;
}
@@ -311,55 +347,39 @@
state_machine_.SetResourcelessSoftwareDraw(false);
}
+void Scheduler::BeginImplFrameMissed(const BeginFrameArgs& args) {
+ // The storage for the args is owned by the task so copy them before canceling
+ // the task.
+ BeginFrameArgs copy_args = args;
+ missed_begin_frame_task_.Cancel();
+ BeginImplFrameWithDeadline(copy_args);
+}
+
void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
- // The storage for |args| is owned by the missed begin frame task. Therefore
- // save |args| before cancelling the task either here or in the deadline.
- BeginFrameArgs adjusted_args = args;
- // Cancel the missed begin frame task in case the BFS sends a begin frame
- // before the missed frame task runs.
- missed_begin_frame_task_.Cancel();
-
- base::TimeTicks now = Now();
-
- // Discard missed begin frames if they are too late.
- if (adjusted_args.type == BeginFrameArgs::MISSED &&
- now > adjusted_args.deadline) {
- skipped_last_frame_missed_exceeded_deadline_ = true;
- SendBeginFrameAck(adjusted_args, kBeginFrameSkipped);
- return;
- }
-
- skipped_last_frame_missed_exceeded_deadline_ = false;
-
- // Run the previous deadline if any.
- if (state_machine_.begin_impl_frame_state() ==
- SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) {
- OnBeginImplFrameDeadline();
- // We may not need begin frames any longer.
- if (!observing_begin_frame_source_) {
- // We need to confirm the ignored BeginFrame, since we don't have updates.
- // To persist the confirmation for future BeginFrameAcks, we let the state
- // machine know about the BeginFrame.
- state_machine_.OnBeginFrameDroppedNotObserving(args.source_id,
- args.sequence_number);
- SendBeginFrameAck(adjusted_args, kBeginFrameSkipped);
- return;
- }
- }
+ DCHECK(!inside_process_scheduled_actions_);
DCHECK_EQ(state_machine_.begin_impl_frame_state(),
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
+
+ base::TimeTicks now = Now();
+
+ // Discard missed begin frames if they are too late.
+ if (args.type == BeginFrameArgs::MISSED && now > args.deadline) {
+ skipped_last_frame_missed_exceeded_deadline_ = true;
+ SendBeginFrameAck(args, kBeginFrameSkipped);
+ return;
+ }
+
+ skipped_last_frame_missed_exceeded_deadline_ = false;
bool main_thread_is_in_high_latency_mode =
state_machine_.main_thread_missed_last_deadline();
TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args",
- adjusted_args.AsValue(), "main_thread_missed_last_deadline",
+ args.AsValue(), "main_thread_missed_last_deadline",
main_thread_is_in_high_latency_mode);
TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
"MainThreadLatency", main_thread_is_in_high_latency_mode);
- DCHECK_EQ(state_machine_.begin_impl_frame_state(),
- SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
-
+ BeginFrameArgs adjusted_args = args;
adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate();
adjusted_args.deadline -= kDeadlineFudgeFactor;
@@ -428,10 +448,14 @@
void Scheduler::FinishImplFrame() {
state_machine_.OnBeginImplFrameIdle();
+
+ // Call this before ProcessScheduledActions because we might send an ack for
+ // missed begin frame there.
+ SendBeginFrameAck(begin_impl_frame_tracker_.Current(), kBeginFrameFinished);
+
ProcessScheduledActions();
client_->DidFinishImplFrame();
- SendBeginFrameAck(begin_main_frame_args_, kBeginFrameFinished);
begin_impl_frame_tracker_.Finish();
}
@@ -482,8 +506,8 @@
// The synchronous compositor does not post a deadline task.
DCHECK(!settings_.using_synchronous_renderer_compositor);
- begin_impl_frame_deadline_task_.Cancel();
- begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_);
+ begin_impl_frame_deadline_task_.Reset(base::Bind(
+ &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()));
begin_impl_frame_deadline_mode_ =
state_machine_.CurrentBeginImplFrameDeadlineMode();
@@ -686,8 +710,6 @@
}
void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const {
- base::TimeTicks now = Now();
-
state->BeginDictionary("state_machine");
state_machine_.AsValueInto(state);
state->EndDictionary();
@@ -720,11 +742,11 @@
(deadline_scheduled_at_ - Now()).InMillisecondsF());
state->BeginDictionary("begin_impl_frame_tracker");
- begin_impl_frame_tracker_.AsValueInto(now, state);
+ begin_impl_frame_tracker_.AsValueInto(state);
state->EndDictionary();
- state->BeginDictionary("begin_impl_frame_args");
- begin_impl_frame_tracker_.AsValueInto(now, state);
+ state->BeginDictionary("missed_begin_frame_args");
+ missed_begin_frame_args_.AsValueInto(state);
state->EndDictionary();
state->BeginDictionary("begin_frame_observer_state");
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698