| Index: cc/scheduler/scheduler.cc
|
| diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
|
| index 15b13d0391c87f6985340305c859ef7b99ef9be8..b24430f2aa6e12e7f7784f7423f2904f7523125d 100644
|
| --- a/cc/scheduler/scheduler.cc
|
| +++ b/cc/scheduler/scheduler.cc
|
| @@ -20,16 +20,7 @@ namespace cc {
|
|
|
| BeginFrameSource* SchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource(
|
| Scheduler* scheduler) {
|
| - if (!scheduler->settings_.throttle_frame_production) {
|
| - TRACE_EVENT1("cc",
|
| - "Scheduler::Scheduler()",
|
| - "PrimaryFrameSource",
|
| - "BackToBackBeginFrameSource");
|
| - DCHECK(!scheduler->primary_frame_source_internal_);
|
| - scheduler->primary_frame_source_internal_ =
|
| - BackToBackBeginFrameSource::Create(scheduler->task_runner_.get());
|
| - return scheduler->primary_frame_source_internal_.get();
|
| - } else if (scheduler->settings_.use_external_begin_frame_source) {
|
| + if (scheduler->settings_.use_external_begin_frame_source) {
|
| TRACE_EVENT1("cc",
|
| "Scheduler::Scheduler()",
|
| "PrimaryFrameSource",
|
| @@ -71,6 +62,17 @@ SchedulerFrameSourcesConstructor::ConstructBackgroundFrameSource(
|
| return scheduler->background_frame_source_internal_.get();
|
| }
|
|
|
| +BeginFrameSource*
|
| +SchedulerFrameSourcesConstructor::ConstructUnthrottledFrameSource(
|
| + Scheduler* scheduler) {
|
| + TRACE_EVENT1("cc", "Scheduler::Scheduler()", "UnthrottledFrameSource",
|
| + "BackToBackBeginFrameSource");
|
| + DCHECK(!scheduler->unthrottled_frame_source_internal_);
|
| + scheduler->unthrottled_frame_source_internal_ =
|
| + BackToBackBeginFrameSource::Create(scheduler->task_runner_.get());
|
| + return scheduler->unthrottled_frame_source_internal_.get();
|
| +}
|
| +
|
| Scheduler::Scheduler(
|
| SchedulerClient* client,
|
| const SchedulerSettings& scheduler_settings,
|
| @@ -85,12 +87,12 @@ Scheduler::Scheduler(
|
| primary_frame_source_internal_(external_begin_frame_source.Pass()),
|
| background_frame_source_internal_(),
|
| vsync_observer_(NULL),
|
| + throttle_frame_production_(scheduler_settings.throttle_frame_production),
|
| settings_(scheduler_settings),
|
| client_(client),
|
| layer_tree_host_id_(layer_tree_host_id),
|
| task_runner_(task_runner),
|
| power_monitor_(power_monitor),
|
| - begin_retro_frame_posted_(false),
|
| state_machine_(scheduler_settings),
|
| inside_process_scheduled_actions_(false),
|
| inside_action_(SchedulerStateMachine::ACTION_NONE),
|
| @@ -125,6 +127,11 @@ Scheduler::Scheduler(
|
| frame_sources_constructor->ConstructBackgroundFrameSource(this);
|
| frame_source_->AddSource(background_frame_source_);
|
|
|
| + // Unthrottled frame source
|
| + unthrottled_frame_source_ =
|
| + frame_sources_constructor->ConstructUnthrottledFrameSource(this);
|
| + frame_source_->AddSource(unthrottled_frame_source_);
|
| +
|
| SetupPowerMonitoring();
|
| }
|
|
|
| @@ -184,16 +191,24 @@ void Scheduler::SetCanStart() {
|
| ProcessScheduledActions();
|
| }
|
|
|
| -void Scheduler::SetVisible(bool visible) {
|
| - state_machine_.SetVisible(visible);
|
| - if (visible) {
|
| - frame_source_->SetActiveSource(primary_frame_source_);
|
| +void Scheduler::UpdateActiveFrameSource() {
|
| + if (state_machine_.visible()) {
|
| + if (throttle_frame_production_) {
|
| + frame_source_->SetActiveSource(primary_frame_source_);
|
| + } else {
|
| + frame_source_->SetActiveSource(unthrottled_frame_source_);
|
| + }
|
| } else {
|
| frame_source_->SetActiveSource(background_frame_source_);
|
| }
|
| ProcessScheduledActions();
|
| }
|
|
|
| +void Scheduler::SetVisible(bool visible) {
|
| + state_machine_.SetVisible(visible);
|
| + UpdateActiveFrameSource();
|
| +}
|
| +
|
| void Scheduler::SetCanDraw(bool can_draw) {
|
| state_machine_.SetCanDraw(can_draw);
|
| ProcessScheduledActions();
|
| @@ -209,6 +224,11 @@ void Scheduler::NotifyReadyToDraw() {
|
| // crbugs 352894, 383157, 421923.
|
| }
|
|
|
| +void Scheduler::SetThrottleFrameProduction(bool throttle) {
|
| + throttle_frame_production_ = throttle;
|
| + UpdateActiveFrameSource();
|
| +}
|
| +
|
| void Scheduler::SetNeedsCommit() {
|
| state_machine_.SetNeedsCommit();
|
| ProcessScheduledActions();
|
| @@ -273,10 +293,9 @@ void Scheduler::DidPrepareTiles() {
|
|
|
| void Scheduler::DidLoseOutputSurface() {
|
| TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
|
| - state_machine_.DidLoseOutputSurface();
|
| - if (frame_source_->NeedsBeginFrames())
|
| - frame_source_->SetNeedsBeginFrames(false);
|
| begin_retro_frame_args_.clear();
|
| + begin_retro_frame_task_.Cancel();
|
| + state_machine_.DidLoseOutputSurface();
|
| ProcessScheduledActions();
|
| }
|
|
|
| @@ -313,41 +332,29 @@ void Scheduler::SetupNextBeginFrameIfNeeded() {
|
| if (!task_runner_.get())
|
| return;
|
|
|
| - bool needs_begin_frame = state_machine_.BeginFrameNeeded();
|
| -
|
| - bool at_end_of_deadline =
|
| - (state_machine_.begin_impl_frame_state() ==
|
| - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
|
| -
|
| - bool should_call_set_needs_begin_frame =
|
| - // Always request the BeginFrame immediately if it wasn't needed before.
|
| - (needs_begin_frame && !frame_source_->NeedsBeginFrames()) ||
|
| - // Only stop requesting BeginFrames after a deadline.
|
| - (!needs_begin_frame && frame_source_->NeedsBeginFrames() &&
|
| - at_end_of_deadline);
|
| -
|
| - if (should_call_set_needs_begin_frame) {
|
| - frame_source_->SetNeedsBeginFrames(needs_begin_frame);
|
| + if (state_machine_.ShouldSetNeedsBeginFrames(
|
| + frame_source_->NeedsBeginFrames())) {
|
| + frame_source_->SetNeedsBeginFrames(state_machine_.BeginFrameNeeded());
|
| }
|
|
|
| - if (at_end_of_deadline) {
|
| + if (state_machine_.begin_impl_frame_state() ==
|
| + SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) {
|
| frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
|
| }
|
|
|
| PostBeginRetroFrameIfNeeded();
|
| - SetupPollingMechanisms(needs_begin_frame);
|
| + SetupPollingMechanisms();
|
| }
|
|
|
| // We may need to poll when we can't rely on BeginFrame to advance certain
|
| // state or to avoid deadlock.
|
| -void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) {
|
| +void Scheduler::SetupPollingMechanisms() {
|
| bool needs_advance_commit_state_timer = false;
|
| // Setup PollForAnticipatedDrawTriggers if we need to monitor state but
|
| // aren't expecting any more BeginFrames. This should only be needed by
|
| // the synchronous compositor when BeginFrameNeeded is false.
|
| if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
|
| DCHECK(!state_machine_.SupportsProactiveBeginFrame());
|
| - DCHECK(!needs_begin_frame);
|
| if (poll_for_draw_triggers_task_.IsCancelled()) {
|
| poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_);
|
| base::TimeDelta delay = begin_impl_frame_args_.IsValid()
|
| @@ -427,7 +434,8 @@ bool Scheduler::OnBeginFrameMixInDelegate(const BeginFrameArgs& args) {
|
| should_defer_begin_frame = false;
|
| } else {
|
| should_defer_begin_frame =
|
| - !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ ||
|
| + !begin_retro_frame_args_.empty() ||
|
| + !begin_retro_frame_task_.IsCancelled() ||
|
| !frame_source_->NeedsBeginFrames() ||
|
| (state_machine_.begin_impl_frame_state() !=
|
| SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
|
| @@ -455,15 +463,12 @@ void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) {
|
| void Scheduler::BeginRetroFrame() {
|
| TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame");
|
| DCHECK(!settings_.using_synchronous_renderer_compositor);
|
| - DCHECK(begin_retro_frame_posted_);
|
| + DCHECK(!begin_retro_frame_args_.empty());
|
| + DCHECK(!begin_retro_frame_task_.IsCancelled());
|
| DCHECK_EQ(state_machine_.begin_impl_frame_state(),
|
| SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
|
| - begin_retro_frame_posted_ = false;
|
|
|
| - // If there aren't any retroactive BeginFrames, then we've lost the
|
| - // OutputSurface and should abort.
|
| - if (begin_retro_frame_args_.empty())
|
| - return;
|
| + begin_retro_frame_task_.Cancel();
|
|
|
| // Discard expired BeginRetroFrames
|
| // Today, we should always end up with at most one un-expired BeginRetroFrame
|
| @@ -510,7 +515,7 @@ void Scheduler::PostBeginRetroFrameIfNeeded() {
|
| if (!frame_source_->NeedsBeginFrames())
|
| return;
|
|
|
| - if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_)
|
| + if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled())
|
| return;
|
|
|
| // begin_retro_frame_args_ should always be empty for the
|
| @@ -521,8 +526,9 @@ void Scheduler::PostBeginRetroFrameIfNeeded() {
|
| SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
|
| return;
|
|
|
| - begin_retro_frame_posted_ = true;
|
| - task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_);
|
| + begin_retro_frame_task_.Reset(begin_retro_frame_closure_);
|
| +
|
| + task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback());
|
| }
|
|
|
| // BeginImplFrame starts a compositor frame that will wait up until a deadline
|
| @@ -757,8 +763,9 @@ void Scheduler::AsValueInto(base::debug::TracedValue* state) const {
|
| estimated_parent_draw_time_.InMillisecondsF());
|
| state->SetBoolean("last_set_needs_begin_frame_",
|
| frame_source_->NeedsBeginFrames());
|
| - state->SetBoolean("begin_retro_frame_posted_", begin_retro_frame_posted_);
|
| state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size());
|
| + state->SetBoolean("begin_retro_frame_task_",
|
| + !begin_retro_frame_task_.IsCancelled());
|
| state->SetBoolean("begin_impl_frame_deadline_task_",
|
| !begin_impl_frame_deadline_task_.IsCancelled());
|
| state->SetBoolean("poll_for_draw_triggers_task_",
|
|
|