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

Side by Side Diff: cc/scheduler/scheduler.cc

Issue 554973002: Disable scheduler deadline task on battery power in Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: After rebase Created 6 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/scheduler/scheduler.h" 5 #include "cc/scheduler/scheduler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include "base/auto_reset.h" 8 #include "base/auto_reset.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/debug/trace_event_argument.h" 10 #include "base/debug/trace_event_argument.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/power_monitor/power_monitor.h"
12 #include "base/single_thread_task_runner.h" 13 #include "base/single_thread_task_runner.h"
13 #include "cc/debug/devtools_instrumentation.h" 14 #include "cc/debug/devtools_instrumentation.h"
14 #include "cc/debug/traced_value.h" 15 #include "cc/debug/traced_value.h"
15 #include "cc/scheduler/delay_based_time_source.h" 16 #include "cc/scheduler/delay_based_time_source.h"
16 #include "ui/gfx/frame_time.h" 17 #include "ui/gfx/frame_time.h"
17 18
18 namespace cc { 19 namespace cc {
19 20
20 Scheduler::SyntheticBeginFrameSource::SyntheticBeginFrameSource( 21 Scheduler::SyntheticBeginFrameSource::SyntheticBeginFrameSource(
21 Scheduler* scheduler, 22 Scheduler* scheduler,
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); 107 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
107 begin_unthrottled_frame_closure_ = 108 begin_unthrottled_frame_closure_ =
108 base::Bind(&Scheduler::BeginUnthrottledFrame, weak_factory_.GetWeakPtr()); 109 base::Bind(&Scheduler::BeginUnthrottledFrame, weak_factory_.GetWeakPtr());
109 begin_impl_frame_deadline_closure_ = base::Bind( 110 begin_impl_frame_deadline_closure_ = base::Bind(
110 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 111 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
111 poll_for_draw_triggers_closure_ = base::Bind( 112 poll_for_draw_triggers_closure_ = base::Bind(
112 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); 113 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
113 advance_commit_state_closure_ = base::Bind( 114 advance_commit_state_closure_ = base::Bind(
114 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); 115 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
115 116
117 if (settings_.high_latency_mode_on_battery) {
118 SetupPowerMonitoring();
119 }
120
116 if (!settings_.begin_frame_scheduling_enabled) { 121 if (!settings_.begin_frame_scheduling_enabled) {
117 SetupSyntheticBeginFrames(); 122 SetupSyntheticBeginFrames();
118 } 123 }
119 } 124 }
120 125
121 Scheduler::~Scheduler() { 126 Scheduler::~Scheduler() {
127 if (settings_.high_latency_mode_on_battery) {
128 TeardownPowerMonitoring();
129 }
130
122 if (synthetic_begin_frame_source_) { 131 if (synthetic_begin_frame_source_) {
123 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, 132 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
124 &begin_retro_frame_args_); 133 &begin_retro_frame_args_);
125 } 134 }
126 } 135 }
127 136
128 void Scheduler::SetupSyntheticBeginFrames() { 137 void Scheduler::SetupSyntheticBeginFrames() {
129 DCHECK(!synthetic_begin_frame_source_); 138 DCHECK(!synthetic_begin_frame_source_);
130 synthetic_begin_frame_source_.reset( 139 synthetic_begin_frame_source_.reset(
131 new SyntheticBeginFrameSource(this, task_runner_.get())); 140 new SyntheticBeginFrameSource(this, task_runner_.get()));
132 } 141 }
133 142
143 void Scheduler::SetupPowerMonitoring() {
144 base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
145 DCHECK(power_monitor != NULL);
146 power_monitor->AddObserver(this);
147 }
148
149 void Scheduler::TeardownPowerMonitoring() {
150 base::PowerMonitor* power_monitor = base::PowerMonitor::Get();
151 DCHECK(power_monitor != NULL);
152 power_monitor->RemoveObserver(this);
153 }
154
155 void Scheduler::OnPowerStateChange(bool on_battery_power) {
156 on_battery_power_ = on_battery_power;
157 }
158
134 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, 159 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
135 base::TimeDelta interval) { 160 base::TimeDelta interval) {
136 // TODO(brianderson): We should not be receiving 0 intervals. 161 // TODO(brianderson): We should not be receiving 0 intervals.
137 if (interval == base::TimeDelta()) 162 if (interval == base::TimeDelta())
138 interval = BeginFrameArgs::DefaultInterval(); 163 interval = BeginFrameArgs::DefaultInterval();
139 vsync_interval_ = interval; 164 vsync_interval_ = interval;
140 if (!settings_.begin_frame_scheduling_enabled) 165 if (!settings_.begin_frame_scheduling_enabled)
141 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval); 166 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval);
142 } 167 }
143 168
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 DCHECK(!settings_.using_synchronous_renderer_compositor); 515 DCHECK(!settings_.using_synchronous_renderer_compositor);
491 516
492 if (state_machine_.begin_impl_frame_state() != 517 if (state_machine_.begin_impl_frame_state() !=
493 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) 518 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
494 return; 519 return;
495 520
496 begin_retro_frame_posted_ = true; 521 begin_retro_frame_posted_ = true;
497 task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_); 522 task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_);
498 } 523 }
499 524
525 bool Scheduler::ShouldPostBeginImplFrameDeadline() {
526 // The synchronous renderer compositor has to make its GL calls
527 // within this call.
brianderson 2014/09/09 17:59:05 this call -> within the BeginFrame call stack.
528 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks
529 // so the sychronous renderer compositor can take advantage of splitting
530 // up the BeginImplFrame and deadline as well.
531 if (settings_.using_synchronous_renderer_compositor)
532 return false;
533
534 if (settings_.high_latency_mode_on_battery && on_battery_power_)
535 return false;
536
537 // We are ready to draw a new active tree immediately.
538 if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly())
539 return false;
540
541 return true;
542 }
543
500 // BeginImplFrame starts a compositor frame that will wait up until a deadline 544 // BeginImplFrame starts a compositor frame that will wait up until a deadline
501 // for a BeginMainFrame+activation to complete before it times out and draws 545 // for a BeginMainFrame+activation to complete before it times out and draws
502 // any asynchronous animation and scroll/pinch updates. 546 // any asynchronous animation and scroll/pinch updates.
503 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 547 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
504 TRACE_EVENT1("cc", "Scheduler::BeginImplFrame", "args", args.AsValue()); 548 TRACE_EVENT1("cc", "Scheduler::BeginImplFrame", "args", args.AsValue());
505 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 549 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
506 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 550 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
507 DCHECK(state_machine_.HasInitializedOutputSurface()); 551 DCHECK(state_machine_.HasInitializedOutputSurface());
552 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
508 553
509 advance_commit_state_task_.Cancel(); 554 advance_commit_state_task_.Cancel();
510 555
511 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate(); 556 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate();
512 begin_impl_frame_args_ = args; 557 begin_impl_frame_args_ = args;
513 begin_impl_frame_args_.deadline -= draw_duration_estimate; 558 begin_impl_frame_args_.deadline -= draw_duration_estimate;
514 559
515 if (!state_machine_.impl_latency_takes_priority() && 560 if (!state_machine_.impl_latency_takes_priority() &&
516 state_machine_.MainThreadIsInHighLatencyMode() && 561 state_machine_.MainThreadIsInHighLatencyMode() &&
517 CanCommitAndActivateBeforeDeadline()) { 562 CanCommitAndActivateBeforeDeadline()) {
518 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 563 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
519 } 564 }
520 565
521 client_->WillBeginImplFrame(begin_impl_frame_args_); 566 client_->WillBeginImplFrame(begin_impl_frame_args_);
522 state_machine_.OnBeginImplFrame(begin_impl_frame_args_); 567 state_machine_.OnBeginImplFrame(begin_impl_frame_args_);
523 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); 568 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_);
524 569
525 ProcessScheduledActions(); 570 ProcessScheduledActions();
526 571
527 state_machine_.OnBeginImplFrameDeadlinePending(); 572 state_machine_.OnBeginImplFrameDeadlinePending();
528 ScheduleBeginImplFrameDeadline( 573
529 AdjustedBeginImplFrameDeadline(args, draw_duration_estimate)); 574 if (ShouldPostBeginImplFrameDeadline()) {
575 ScheduleBeginImplFrameDeadline(
576 AdjustedBeginImplFrameDeadline(args, draw_duration_estimate));
577 } else {
578 OnBeginImplFrameDeadline();
579 }
530 } 580 }
531 581
532 base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline( 582 base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline(
533 const BeginFrameArgs& args, 583 const BeginFrameArgs& args,
534 base::TimeDelta draw_duration_estimate) const { 584 base::TimeDelta draw_duration_estimate) const {
535 if (settings_.using_synchronous_renderer_compositor) { 585 if (state_machine_.needs_redraw()) {
brianderson 2014/09/09 17:59:05 AdjustedBeginImplFrameDeadline is used in more tha
536 // The synchronous compositor needs to draw right away.
537 return base::TimeTicks();
538 } else if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) {
539 // We are ready to draw a new active tree immediately.
540 return base::TimeTicks();
541 } else if (state_machine_.needs_redraw()) {
542 // We have an animation or fast input path on the impl thread that wants 586 // We have an animation or fast input path on the impl thread that wants
543 // to draw, so don't wait too long for a new active tree. 587 // to draw, so don't wait too long for a new active tree.
544 return args.deadline - draw_duration_estimate; 588 return args.deadline - draw_duration_estimate;
545 } else { 589 } else {
546 // The impl thread doesn't have anything it wants to draw and we are just 590 // The impl thread doesn't have anything it wants to draw and we are just
547 // waiting for a new active tree, so post the deadline for the next 591 // waiting for a new active tree, so post the deadline for the next
548 // expected BeginImplFrame start. This allows us to draw immediately when 592 // expected BeginImplFrame start. This allows us to draw immediately when
549 // there is a new active tree, instead of waiting for the next 593 // there is a new active tree, instead of waiting for the next
550 // BeginImplFrame. 594 // BeginImplFrame.
551 // TODO(brianderson): Handle long deadlines (that are past the next frame's 595 // TODO(brianderson): Handle long deadlines (that are past the next frame's
552 // frame time) properly instead of using this hack. 596 // frame time) properly instead of using this hack.
553 return args.frame_time + args.interval; 597 return args.frame_time + args.interval;
554 } 598 }
555 } 599 }
556 600
557 void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) { 601 void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) {
558 if (settings_.using_synchronous_renderer_compositor) {
559 // The synchronous renderer compositor has to make its GL calls
560 // within this call.
561 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks
562 // so the sychronous renderer compositor can take advantage of splitting
563 // up the BeginImplFrame and deadline as well.
564 OnBeginImplFrameDeadline();
565 return;
566 }
567 begin_impl_frame_deadline_task_.Cancel(); 602 begin_impl_frame_deadline_task_.Cancel();
568 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); 603 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_);
569 604
570 base::TimeDelta delta = deadline - gfx::FrameTime::Now(); 605 base::TimeDelta delta = deadline - gfx::FrameTime::Now();
571 if (delta <= base::TimeDelta()) 606 if (delta <= base::TimeDelta())
572 delta = base::TimeDelta(); 607 delta = base::TimeDelta();
573 task_runner_->PostDelayedTask( 608 task_runner_->PostDelayedTask(
574 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta); 609 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta);
575 } 610 }
576 611
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 } 788 }
754 789
755 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 790 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
756 return (state_machine_.commit_state() == 791 return (state_machine_.commit_state() ==
757 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 792 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
758 state_machine_.commit_state() == 793 state_machine_.commit_state() ==
759 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 794 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
760 } 795 }
761 796
762 } // namespace cc 797 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698