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

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

Issue 548153004: Unified BeginFrame scheduling (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: git cl format 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
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_settings.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
8 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
9 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
10 #include "base/debug/trace_event_argument.h" 11 #include "base/debug/trace_event_argument.h"
11 #include "base/logging.h" 12 #include "base/logging.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
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 Scheduler::Scheduler( 79 Scheduler::Scheduler(
79 SchedulerClient* client, 80 SchedulerClient* client,
80 const SchedulerSettings& scheduler_settings, 81 const SchedulerSettings& scheduler_settings,
81 int layer_tree_host_id, 82 int layer_tree_host_id,
82 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) 83 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
83 : settings_(scheduler_settings), 84 : settings_(scheduler_settings),
84 client_(client), 85 client_(client),
85 layer_tree_host_id_(layer_tree_host_id), 86 layer_tree_host_id_(layer_tree_host_id),
86 task_runner_(task_runner), 87 task_runner_(task_runner),
87 vsync_interval_(BeginFrameArgs::DefaultInterval()), 88 vsync_interval_(BeginFrameArgs::DefaultInterval()),
89 authoritative_vsync_interval_(base::TimeDelta()),
88 last_set_needs_begin_frame_(false), 90 last_set_needs_begin_frame_(false),
89 begin_unthrottled_frame_posted_(false), 91 begin_unthrottled_frame_posted_(false),
90 begin_retro_frame_posted_(false), 92 begin_retro_frame_posted_(false),
91 state_machine_(scheduler_settings), 93 state_machine_(scheduler_settings),
92 inside_process_scheduled_actions_(false), 94 inside_process_scheduled_actions_(false),
93 inside_action_(SchedulerStateMachine::ACTION_NONE), 95 inside_action_(SchedulerStateMachine::ACTION_NONE),
94 weak_factory_(this) { 96 weak_factory_(this) {
95 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 97 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
96 "Scheduler::Scheduler", 98 "Scheduler::Scheduler",
97 "settings", 99 "settings",
98 settings_.AsValue()); 100 settings_.AsValue());
99 DCHECK(client_); 101 DCHECK(client_);
100 DCHECK(!state_machine_.BeginFrameNeeded()); 102 DCHECK(!state_machine_.BeginFrameNeeded());
101 if (settings_.main_frame_before_activation_enabled) { 103 if (settings_.main_frame_before_activation_enabled) {
102 DCHECK(settings_.main_frame_before_draw_enabled); 104 DCHECK(settings_.main_frame_before_draw_enabled);
103 } 105 }
104
105 begin_retro_frame_closure_ = 106 begin_retro_frame_closure_ =
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
116 if (!settings_.begin_frame_scheduling_enabled) { 117 if (!settings_.begin_frame_receiver)
117 SetupSyntheticBeginFrames(); 118 SetupSyntheticBeginFrames();
118 }
119 } 119 }
120 120
121 Scheduler::~Scheduler() { 121 Scheduler::~Scheduler() {
122 if (synthetic_begin_frame_source_) { 122 if (synthetic_begin_frame_source_) {
123 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, 123 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
124 &begin_retro_frame_args_); 124 &begin_retro_frame_args_);
125 } 125 }
126 } 126 }
127 127
128 void Scheduler::SetupSyntheticBeginFrames() { 128 void Scheduler::SetupSyntheticBeginFrames() {
129 DCHECK(!synthetic_begin_frame_source_); 129 DCHECK(!synthetic_begin_frame_source_);
130 synthetic_begin_frame_source_.reset( 130 synthetic_begin_frame_source_.reset(
131 new SyntheticBeginFrameSource(this, task_runner_.get())); 131 new SyntheticBeginFrameSource(this, task_runner_.get()));
132 } 132 }
133 133
134 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, 134 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
135 base::TimeDelta interval) { 135 base::TimeDelta interval) {
136 // TODO(brianderson): We should not be receiving 0 intervals. 136 if (authoritative_vsync_interval_ == base::TimeDelta()) {
137 if (interval == base::TimeDelta()) 137 // TODO(brianderson): We should not be receiving 0 intervals.
138 interval = BeginFrameArgs::DefaultInterval(); 138 if (interval == base::TimeDelta())
139 vsync_interval_ = interval; 139 interval = BeginFrameArgs::DefaultInterval();
140 if (!settings_.begin_frame_scheduling_enabled) 140 vsync_interval_ = interval;
141 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval); 141 } else {
142 vsync_interval_ = authoritative_vsync_interval_;
143 }
144
145 last_timebase_ = timebase;
146
147 if (!settings_.begin_frame_receiver) {
148 synthetic_begin_frame_source_->CommitVSyncParameters(timebase,
149 vsync_interval_);
150 }
142 } 151 }
143 152
144 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { 153 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
145 DCHECK_GE(draw_time.ToInternalValue(), 0); 154 DCHECK_GE(draw_time.ToInternalValue(), 0);
146 estimated_parent_draw_time_ = draw_time; 155 estimated_parent_draw_time_ = draw_time;
147 } 156 }
148 157
149 void Scheduler::SetCanStart() { 158 void Scheduler::SetCanStart() {
150 state_machine_.SetCanStart(); 159 state_machine_.SetCanStart();
151 ProcessScheduledActions(); 160 ProcessScheduledActions();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 } 238 }
230 239
231 void Scheduler::DidManageTiles() { 240 void Scheduler::DidManageTiles() {
232 state_machine_.DidManageTiles(); 241 state_machine_.DidManageTiles();
233 } 242 }
234 243
235 void Scheduler::DidLoseOutputSurface() { 244 void Scheduler::DidLoseOutputSurface() {
236 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 245 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
237 state_machine_.DidLoseOutputSurface(); 246 state_machine_.DidLoseOutputSurface();
238 last_set_needs_begin_frame_ = false; 247 last_set_needs_begin_frame_ = false;
239 if (!settings_.begin_frame_scheduling_enabled) { 248 if (!settings_.begin_frame_receiver) {
240 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, 249 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
241 &begin_retro_frame_args_); 250 &begin_retro_frame_args_);
242 } 251 }
243 begin_retro_frame_args_.clear(); 252 begin_retro_frame_args_.clear();
244 ProcessScheduledActions(); 253 ProcessScheduledActions();
245 } 254 }
246 255
247 void Scheduler::DidCreateAndInitializeOutputSurface() { 256 void Scheduler::DidCreateAndInitializeOutputSurface() {
248 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 257 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
249 DCHECK(!last_set_needs_begin_frame_); 258 DCHECK(!last_set_needs_begin_frame_);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 state_machine_.begin_impl_frame_state() == 304 state_machine_.begin_impl_frame_state() ==
296 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; 305 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
297 306
298 bool should_call_set_needs_begin_frame = 307 bool should_call_set_needs_begin_frame =
299 // Always request the BeginFrame immediately if it wasn't needed before. 308 // Always request the BeginFrame immediately if it wasn't needed before.
300 (needs_begin_frame && !last_set_needs_begin_frame_) || 309 (needs_begin_frame && !last_set_needs_begin_frame_) ||
301 // Only stop requesting BeginFrames after a deadline. 310 // Only stop requesting BeginFrames after a deadline.
302 (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline); 311 (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline);
303 312
304 if (should_call_set_needs_begin_frame) { 313 if (should_call_set_needs_begin_frame) {
305 if (settings_.begin_frame_scheduling_enabled) { 314 if (settings_.begin_frame_receiver) {
306 client_->SetNeedsBeginFrame(needs_begin_frame); 315 client_->SetNeedsBeginFrame(needs_begin_frame);
307 } else { 316 } else {
308 synthetic_begin_frame_source_->SetNeedsBeginFrame( 317 synthetic_begin_frame_source_->SetNeedsBeginFrame(
309 needs_begin_frame, &begin_retro_frame_args_); 318 needs_begin_frame, &begin_retro_frame_args_);
310 } 319 }
311 last_set_needs_begin_frame_ = needs_begin_frame; 320 last_set_needs_begin_frame_ = needs_begin_frame;
312 } 321 }
313 322
314 PostBeginRetroFrameIfNeeded(); 323 PostBeginRetroFrameIfNeeded();
315 } 324 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 410
402 // BeginFrame is the mechanism that tells us that now is a good time to start 411 // BeginFrame is the mechanism that tells us that now is a good time to start
403 // making a frame. Usually this means that user input for the frame is complete. 412 // making a frame. Usually this means that user input for the frame is complete.
404 // If the scheduler is busy, we queue the BeginFrame to be handled later as 413 // If the scheduler is busy, we queue the BeginFrame to be handled later as
405 // a BeginRetroFrame. 414 // a BeginRetroFrame.
406 void Scheduler::BeginFrame(const BeginFrameArgs& args) { 415 void Scheduler::BeginFrame(const BeginFrameArgs& args) {
407 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue()); 416 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue());
408 DCHECK(settings_.throttle_frame_production); 417 DCHECK(settings_.throttle_frame_production);
409 418
410 BeginFrameArgs adjusted_args(args); 419 BeginFrameArgs adjusted_args(args);
420
421 if (settings_.begin_frame_publisher &&
422 state_machine_.children_need_begin_frames()) {
423 // Adjust a dealine for child schedulers.
424 // TODO(simonhong): Once we have commitless update, we can get rid of
425 // BeginMainFrameToCommitDurationEstimate() +
426 // CommitToActivateDurationEstimate().
427 adjusted_args.deadline -=
428 (client_->BeginMainFrameToCommitDurationEstimate() +
429 client_->CommitToActivateDurationEstimate() +
430 client_->DrawDurationEstimate() + EstimatedParentDrawTime());
431 client_->SendBeginFrameToChildren(args);
432 }
433
411 adjusted_args.deadline -= EstimatedParentDrawTime(); 434 adjusted_args.deadline -= EstimatedParentDrawTime();
412 435
413 bool should_defer_begin_frame; 436 bool should_defer_begin_frame;
414 if (settings_.using_synchronous_renderer_compositor) { 437 if (settings_.using_synchronous_renderer_compositor) {
415 should_defer_begin_frame = false; 438 should_defer_begin_frame = false;
416 } else { 439 } else {
417 should_defer_begin_frame = 440 should_defer_begin_frame =
418 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || 441 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ ||
419 !last_set_needs_begin_frame_ || 442 !last_set_needs_begin_frame_ ||
420 (state_machine_.begin_impl_frame_state() != 443 (state_machine_.begin_impl_frame_state() !=
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 ProcessScheduledActions(); 623 ProcessScheduledActions();
601 state_machine_.DidLeavePollForAnticipatedDrawTriggers(); 624 state_machine_.DidLeavePollForAnticipatedDrawTriggers();
602 } 625 }
603 626
604 void Scheduler::PollToAdvanceCommitState() { 627 void Scheduler::PollToAdvanceCommitState() {
605 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); 628 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState");
606 advance_commit_state_task_.Cancel(); 629 advance_commit_state_task_.Cancel();
607 ProcessScheduledActions(); 630 ProcessScheduledActions();
608 } 631 }
609 632
633 void Scheduler::SetChildrenNeedBeginFrames(bool need_begin_frame) {
634 DCHECK(settings_.begin_frame_publisher);
635
636 state_machine_.SetChildrenNeedBeginFrames(need_begin_frame);
637 ProcessScheduledActions();
638 }
639
640 void Scheduler::SetAuthoritativeVSyncInterval(base::TimeDelta interval) {
641 authoritative_vsync_interval_ = interval;
642 vsync_interval_ = interval;
643
644 if (!settings_.begin_frame_receiver) {
645 synthetic_begin_frame_source_->CommitVSyncParameters(last_timebase_,
646 interval);
647 }
648 }
649
610 void Scheduler::DrawAndSwapIfPossible() { 650 void Scheduler::DrawAndSwapIfPossible() {
611 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); 651 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible();
612 state_machine_.DidDrawIfPossibleCompleted(result); 652 state_machine_.DidDrawIfPossibleCompleted(result);
613 } 653 }
614 654
615 void Scheduler::ProcessScheduledActions() { 655 void Scheduler::ProcessScheduledActions() {
616 // We do not allow ProcessScheduledActions to be recursive. 656 // We do not allow ProcessScheduledActions to be recursive.
617 // The top-level call will iteratively execute the next action for us anyway. 657 // The top-level call will iteratively execute the next action for us anyway.
618 if (inside_process_scheduled_actions_) 658 if (inside_process_scheduled_actions_)
619 return; 659 return;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
753 } 793 }
754 794
755 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 795 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
756 return (state_machine_.commit_state() == 796 return (state_machine_.commit_state() ==
757 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 797 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
758 state_machine_.commit_state() == 798 state_machine_.commit_state() ==
759 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 799 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
760 } 800 }
761 801
762 } // namespace cc 802 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_settings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698