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

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

Issue 423773002: Unified BeginFrame scheduling (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: WIP in mac and android 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 | Annotate | Revision Log
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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 base::TimeTicks frame_time) { 73 base::TimeTicks frame_time) {
73 base::TimeTicks deadline = time_source_->NextTickTime(); 74 base::TimeTicks deadline = time_source_->NextTickTime();
74 return BeginFrameArgs::Create( 75 return BeginFrameArgs::Create(
75 frame_time, deadline, scheduler_->VSyncInterval()); 76 frame_time, deadline, scheduler_->VSyncInterval());
76 } 77 }
77 78
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,
84 BeginFrameManager* begin_frame_manager)
83 : settings_(scheduler_settings), 85 : settings_(scheduler_settings),
84 client_(client), 86 client_(client),
85 layer_tree_host_id_(layer_tree_host_id), 87 layer_tree_host_id_(layer_tree_host_id),
86 task_runner_(task_runner), 88 task_runner_(task_runner),
87 vsync_interval_(BeginFrameArgs::DefaultInterval()), 89 vsync_interval_(BeginFrameArgs::DefaultInterval()),
90 authoritative_vsync_interval_(base::TimeDelta()),
88 last_set_needs_begin_frame_(false), 91 last_set_needs_begin_frame_(false),
89 begin_unthrottled_frame_posted_(false), 92 begin_unthrottled_frame_posted_(false),
90 begin_retro_frame_posted_(false), 93 begin_retro_frame_posted_(false),
91 state_machine_(scheduler_settings), 94 state_machine_(scheduler_settings),
92 inside_process_scheduled_actions_(false), 95 inside_process_scheduled_actions_(false),
93 inside_action_(SchedulerStateMachine::ACTION_NONE), 96 inside_action_(SchedulerStateMachine::ACTION_NONE),
97 begin_frame_manager_(begin_frame_manager),
94 weak_factory_(this) { 98 weak_factory_(this) {
95 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 99 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
96 "Scheduler::Scheduler", 100 "Scheduler::Scheduler",
97 "settings", 101 "settings",
98 settings_.AsValue()); 102 settings_.AsValue());
99 DCHECK(client_); 103 DCHECK(client_);
100 DCHECK(!state_machine_.BeginFrameNeeded()); 104 DCHECK(!state_machine_.BeginFrameNeeded());
101 if (settings_.main_frame_before_activation_enabled) { 105 if (settings_.main_frame_before_activation_enabled) {
102 DCHECK(settings_.main_frame_before_draw_enabled); 106 DCHECK(settings_.main_frame_before_draw_enabled);
103 } 107 }
104 108 if (settings_.begin_frame_publisher) {
109 DCHECK(begin_frame_manager_);
110 begin_frame_manager_->set_delegate(this);
111 }
105 begin_retro_frame_closure_ = 112 begin_retro_frame_closure_ =
106 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); 113 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
107 begin_unthrottled_frame_closure_ = 114 begin_unthrottled_frame_closure_ =
108 base::Bind(&Scheduler::BeginUnthrottledFrame, weak_factory_.GetWeakPtr()); 115 base::Bind(&Scheduler::BeginUnthrottledFrame, weak_factory_.GetWeakPtr());
109 begin_impl_frame_deadline_closure_ = base::Bind( 116 begin_impl_frame_deadline_closure_ = base::Bind(
110 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 117 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
111 poll_for_draw_triggers_closure_ = base::Bind( 118 poll_for_draw_triggers_closure_ = base::Bind(
112 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); 119 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
113 advance_commit_state_closure_ = base::Bind( 120 advance_commit_state_closure_ = base::Bind(
114 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); 121 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
115 122
116 if (!settings_.begin_frame_scheduling_enabled) { 123 if (!settings_.begin_frame_receiver)
117 SetupSyntheticBeginFrames(); 124 SetupSyntheticBeginFrames();
118 }
119 } 125 }
120 126
121 Scheduler::~Scheduler() { 127 Scheduler::~Scheduler() {
122 if (synthetic_begin_frame_source_) { 128 if (synthetic_begin_frame_source_) {
123 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, 129 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
124 &begin_retro_frame_args_); 130 &begin_retro_frame_args_);
125 } 131 }
126 } 132 }
127 133
128 void Scheduler::SetupSyntheticBeginFrames() { 134 void Scheduler::SetupSyntheticBeginFrames() {
129 DCHECK(!synthetic_begin_frame_source_); 135 DCHECK(!synthetic_begin_frame_source_);
130 synthetic_begin_frame_source_.reset( 136 synthetic_begin_frame_source_.reset(
131 new SyntheticBeginFrameSource(this, task_runner_.get())); 137 new SyntheticBeginFrameSource(this, task_runner_.get()));
132 } 138 }
133 139
134 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, 140 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
135 base::TimeDelta interval) { 141 base::TimeDelta interval) {
136 // TODO(brianderson): We should not be receiving 0 intervals. 142 // TODO(brianderson): We should not be receiving 0 intervals.
137 if (interval == base::TimeDelta()) 143 if (interval == base::TimeDelta())
brianderson 2014/08/28 02:48:07 Might as well roll this condition into your if/els
simonhong 2014/09/03 21:02:22 Done.
138 interval = BeginFrameArgs::DefaultInterval(); 144 interval = BeginFrameArgs::DefaultInterval();
139 vsync_interval_ = interval; 145
140 if (!settings_.begin_frame_scheduling_enabled) 146 if (authoritative_vsync_interval_ == base::TimeDelta())
141 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval); 147 vsync_interval_ = interval;
148 else
149 vsync_interval_ = authoritative_vsync_interval_;
150
151 last_timebase_ = timebase;
152
153 if (!settings_.begin_frame_receiver) {
154 synthetic_begin_frame_source_->CommitVSyncParameters(timebase,
155 vsync_interval_);
156 }
142 } 157 }
143 158
144 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { 159 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
145 DCHECK_GE(draw_time.ToInternalValue(), 0); 160 DCHECK_GE(draw_time.ToInternalValue(), 0);
146 estimated_parent_draw_time_ = draw_time; 161 estimated_parent_draw_time_ = draw_time;
147 } 162 }
148 163
149 void Scheduler::SetCanStart() { 164 void Scheduler::SetCanStart() {
150 state_machine_.SetCanStart(); 165 state_machine_.SetCanStart();
151 ProcessScheduledActions(); 166 ProcessScheduledActions();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 } 244 }
230 245
231 void Scheduler::DidManageTiles() { 246 void Scheduler::DidManageTiles() {
232 state_machine_.DidManageTiles(); 247 state_machine_.DidManageTiles();
233 } 248 }
234 249
235 void Scheduler::DidLoseOutputSurface() { 250 void Scheduler::DidLoseOutputSurface() {
236 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 251 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
237 state_machine_.DidLoseOutputSurface(); 252 state_machine_.DidLoseOutputSurface();
238 last_set_needs_begin_frame_ = false; 253 last_set_needs_begin_frame_ = false;
239 if (!settings_.begin_frame_scheduling_enabled) { 254 if (!settings_.begin_frame_receiver) {
240 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, 255 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
241 &begin_retro_frame_args_); 256 &begin_retro_frame_args_);
242 } 257 }
243 begin_retro_frame_args_.clear(); 258 begin_retro_frame_args_.clear();
244 ProcessScheduledActions(); 259 ProcessScheduledActions();
245 } 260 }
246 261
247 void Scheduler::DidCreateAndInitializeOutputSurface() { 262 void Scheduler::DidCreateAndInitializeOutputSurface() {
248 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 263 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
249 DCHECK(!last_set_needs_begin_frame_); 264 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() == 310 state_machine_.begin_impl_frame_state() ==
296 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; 311 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
297 312
298 bool should_call_set_needs_begin_frame = 313 bool should_call_set_needs_begin_frame =
299 // Always request the BeginFrame immediately if it wasn't needed before. 314 // Always request the BeginFrame immediately if it wasn't needed before.
300 (needs_begin_frame && !last_set_needs_begin_frame_) || 315 (needs_begin_frame && !last_set_needs_begin_frame_) ||
301 // Only stop requesting BeginFrames after a deadline. 316 // Only stop requesting BeginFrames after a deadline.
302 (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline); 317 (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline);
303 318
304 if (should_call_set_needs_begin_frame) { 319 if (should_call_set_needs_begin_frame) {
305 if (settings_.begin_frame_scheduling_enabled) { 320 if (settings_.begin_frame_receiver) {
306 client_->SetNeedsBeginFrame(needs_begin_frame); 321 client_->SetNeedsBeginFrame(needs_begin_frame);
307 } else { 322 } else {
308 synthetic_begin_frame_source_->SetNeedsBeginFrame( 323 synthetic_begin_frame_source_->SetNeedsBeginFrame(
309 needs_begin_frame, &begin_retro_frame_args_); 324 needs_begin_frame, &begin_retro_frame_args_);
310 } 325 }
311 last_set_needs_begin_frame_ = needs_begin_frame; 326 last_set_needs_begin_frame_ = needs_begin_frame;
312 } 327 }
313 328
314 PostBeginRetroFrameIfNeeded(); 329 PostBeginRetroFrameIfNeeded();
315 } 330 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 416
402 // BeginFrame is the mechanism that tells us that now is a good time to start 417 // 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. 418 // 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 419 // If the scheduler is busy, we queue the BeginFrame to be handled later as
405 // a BeginRetroFrame. 420 // a BeginRetroFrame.
406 void Scheduler::BeginFrame(const BeginFrameArgs& args) { 421 void Scheduler::BeginFrame(const BeginFrameArgs& args) {
407 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue()); 422 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue());
408 DCHECK(settings_.throttle_frame_production); 423 DCHECK(settings_.throttle_frame_production);
409 424
410 BeginFrameArgs adjusted_args(args); 425 BeginFrameArgs adjusted_args(args);
426
427 if (settings_.begin_frame_publisher &&
428 state_machine_.children_need_begin_frames()) {
429 // |arg.deadline| should be adjusted by child Scheduler.
brianderson 2014/08/28 02:48:07 Today, the deadline the Browser sends to the Rende
simonhong 2014/09/03 21:02:22 Done.
430 begin_frame_manager_->SendBeginFrameToChildren(args);
431 }
432
411 adjusted_args.deadline -= EstimatedParentDrawTime(); 433 adjusted_args.deadline -= EstimatedParentDrawTime();
412 434
413 bool should_defer_begin_frame; 435 bool should_defer_begin_frame;
414 if (settings_.using_synchronous_renderer_compositor) { 436 if (settings_.using_synchronous_renderer_compositor) {
415 should_defer_begin_frame = false; 437 should_defer_begin_frame = false;
416 } else { 438 } else {
417 should_defer_begin_frame = 439 should_defer_begin_frame =
418 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || 440 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ ||
419 !last_set_needs_begin_frame_ || 441 !last_set_needs_begin_frame_ ||
420 (state_machine_.begin_impl_frame_state() != 442 (state_machine_.begin_impl_frame_state() !=
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); 627 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState");
606 advance_commit_state_task_.Cancel(); 628 advance_commit_state_task_.Cancel();
607 ProcessScheduledActions(); 629 ProcessScheduledActions();
608 } 630 }
609 631
610 bool Scheduler::IsBeginMainFrameSent() const { 632 bool Scheduler::IsBeginMainFrameSent() const {
611 return state_machine_.commit_state() == 633 return state_machine_.commit_state() ==
612 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; 634 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT;
613 } 635 }
614 636
637 void Scheduler::SetChildrenNeedBeginFrames(bool need_begin_frame) {
638 DCHECK(settings_.begin_frame_publisher);
639
640 state_machine_.SetChildrenNeedBeginFrames(need_begin_frame);
641 ProcessScheduledActions();
642 }
643
644 void Scheduler::SetAuthoritativeVSyncInterval(base::TimeDelta interval) {
645 authoritative_vsync_interval_ = interval;
646 vsync_interval_ = interval;
647
648 if (!settings_.begin_frame_receiver) {
649 synthetic_begin_frame_source_->CommitVSyncParameters(last_timebase_,
650 interval);
651 }
652 }
653
654 void Scheduler::StartBeginFrame(const BeginFrameArgs& args) {
655 DCHECK(settings_.begin_frame_publisher && settings_.using_platform_vsync);
656 BeginFrame(args);
657 }
658
615 void Scheduler::DrawAndSwapIfPossible() { 659 void Scheduler::DrawAndSwapIfPossible() {
616 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); 660 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible();
617 state_machine_.DidDrawIfPossibleCompleted(result); 661 state_machine_.DidDrawIfPossibleCompleted(result);
618 } 662 }
619 663
620 void Scheduler::ProcessScheduledActions() { 664 void Scheduler::ProcessScheduledActions() {
621 // We do not allow ProcessScheduledActions to be recursive. 665 // We do not allow ProcessScheduledActions to be recursive.
622 // The top-level call will iteratively execute the next action for us anyway. 666 // The top-level call will iteratively execute the next action for us anyway.
623 if (inside_process_scheduled_actions_) 667 if (inside_process_scheduled_actions_)
624 return; 668 return;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 } 799 }
756 800
757 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 801 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
758 return (state_machine_.commit_state() == 802 return (state_machine_.commit_state() ==
759 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 803 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
760 state_machine_.commit_state() == 804 state_machine_.commit_state() ==
761 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 805 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
762 } 806 }
763 807
764 } // namespace cc 808 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698