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

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: Created 6 years, 2 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
« 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 Scheduler::Scheduler( 72 Scheduler::Scheduler(
72 SchedulerClient* client, 73 SchedulerClient* client,
73 const SchedulerSettings& scheduler_settings, 74 const SchedulerSettings& scheduler_settings,
74 int layer_tree_host_id, 75 int layer_tree_host_id,
75 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) 76 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
76 : settings_(scheduler_settings), 77 : settings_(scheduler_settings),
77 client_(client), 78 client_(client),
78 layer_tree_host_id_(layer_tree_host_id), 79 layer_tree_host_id_(layer_tree_host_id),
79 task_runner_(task_runner), 80 task_runner_(task_runner),
80 vsync_interval_(BeginFrameArgs::DefaultInterval()), 81 vsync_interval_(BeginFrameArgs::DefaultInterval()),
82 authoritative_vsync_interval_(base::TimeDelta()),
81 last_set_needs_begin_frame_(false), 83 last_set_needs_begin_frame_(false),
82 begin_unthrottled_frame_posted_(false), 84 begin_unthrottled_frame_posted_(false),
83 begin_retro_frame_posted_(false), 85 begin_retro_frame_posted_(false),
84 state_machine_(scheduler_settings), 86 state_machine_(scheduler_settings),
85 inside_process_scheduled_actions_(false), 87 inside_process_scheduled_actions_(false),
86 inside_action_(SchedulerStateMachine::ACTION_NONE), 88 inside_action_(SchedulerStateMachine::ACTION_NONE),
87 weak_factory_(this) { 89 weak_factory_(this) {
88 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 90 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
89 "Scheduler::Scheduler", 91 "Scheduler::Scheduler",
90 "settings", 92 "settings",
91 settings_.AsValue()); 93 settings_.AsValue());
92 DCHECK(client_); 94 DCHECK(client_);
93 DCHECK(!state_machine_.BeginFrameNeeded()); 95 DCHECK(!state_machine_.BeginFrameNeeded());
94 if (settings_.main_frame_before_activation_enabled) { 96 if (settings_.main_frame_before_activation_enabled) {
95 DCHECK(settings_.main_frame_before_draw_enabled); 97 DCHECK(settings_.main_frame_before_draw_enabled);
96 } 98 }
97
98 begin_retro_frame_closure_ = 99 begin_retro_frame_closure_ =
99 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); 100 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
100 begin_unthrottled_frame_closure_ = 101 begin_unthrottled_frame_closure_ =
101 base::Bind(&Scheduler::BeginUnthrottledFrame, weak_factory_.GetWeakPtr()); 102 base::Bind(&Scheduler::BeginUnthrottledFrame, weak_factory_.GetWeakPtr());
102 begin_impl_frame_deadline_closure_ = base::Bind( 103 begin_impl_frame_deadline_closure_ = base::Bind(
103 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 104 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
104 poll_for_draw_triggers_closure_ = base::Bind( 105 poll_for_draw_triggers_closure_ = base::Bind(
105 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); 106 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
106 advance_commit_state_closure_ = base::Bind( 107 advance_commit_state_closure_ = base::Bind(
107 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); 108 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
108 109
109 if (!settings_.begin_frame_scheduling_enabled) { 110 if (!settings_.begin_frame_receiver)
110 SetupSyntheticBeginFrames(); 111 SetupSyntheticBeginFrames();
111 }
112 } 112 }
113 113
114 Scheduler::~Scheduler() { 114 Scheduler::~Scheduler() {
115 if (synthetic_begin_frame_source_) { 115 if (synthetic_begin_frame_source_) {
116 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, 116 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
117 &begin_retro_frame_args_); 117 &begin_retro_frame_args_);
118 } 118 }
119 } 119 }
120 120
121 void Scheduler::SetupSyntheticBeginFrames() { 121 void Scheduler::SetupSyntheticBeginFrames() {
122 scoped_refptr<DelayBasedTimeSource> time_source; 122 scoped_refptr<DelayBasedTimeSource> time_source;
123 if (gfx::FrameTime::TimestampsAreHighRes()) { 123 if (gfx::FrameTime::TimestampsAreHighRes()) {
124 time_source = DelayBasedTimeSourceHighRes::Create(VSyncInterval(), 124 time_source = DelayBasedTimeSourceHighRes::Create(VSyncInterval(),
125 task_runner_.get()); 125 task_runner_.get());
126 } else { 126 } else {
127 time_source = 127 time_source =
128 DelayBasedTimeSource::Create(VSyncInterval(), task_runner_.get()); 128 DelayBasedTimeSource::Create(VSyncInterval(), task_runner_.get());
129 } 129 }
130 DCHECK(!synthetic_begin_frame_source_); 130 DCHECK(!synthetic_begin_frame_source_);
131 synthetic_begin_frame_source_.reset( 131 synthetic_begin_frame_source_.reset(
132 new SyntheticBeginFrameSource(this, time_source)); 132 new SyntheticBeginFrameSource(this, time_source));
133 } 133 }
134 134
135 base::TimeTicks Scheduler::Now() const { 135 base::TimeTicks Scheduler::Now() const {
136 return gfx::FrameTime::Now(); 136 return gfx::FrameTime::Now();
137 } 137 }
138 138
139 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, 139 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
140 base::TimeDelta interval) { 140 base::TimeDelta interval) {
141 // TODO(brianderson): We should not be receiving 0 intervals. 141 if (authoritative_vsync_interval_ == base::TimeDelta()) {
142 if (interval == base::TimeDelta()) 142 // TODO(brianderson): We should not be receiving 0 intervals.
143 interval = BeginFrameArgs::DefaultInterval(); 143 if (interval == base::TimeDelta())
144 vsync_interval_ = interval; 144 interval = BeginFrameArgs::DefaultInterval();
145 if (!settings_.begin_frame_scheduling_enabled) 145 vsync_interval_ = interval;
146 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval); 146 } else {
147 vsync_interval_ = authoritative_vsync_interval_;
148 }
149
150 last_timebase_ = timebase;
151
152 if (!settings_.begin_frame_receiver) {
153 synthetic_begin_frame_source_->CommitVSyncParameters(timebase,
154 vsync_interval_);
155 }
147 } 156 }
148 157
149 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { 158 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
150 DCHECK_GE(draw_time.ToInternalValue(), 0); 159 DCHECK_GE(draw_time.ToInternalValue(), 0);
151 estimated_parent_draw_time_ = draw_time; 160 estimated_parent_draw_time_ = draw_time;
152 } 161 }
153 162
154 void Scheduler::SetCanStart() { 163 void Scheduler::SetCanStart() {
155 state_machine_.SetCanStart(); 164 state_machine_.SetCanStart();
156 ProcessScheduledActions(); 165 ProcessScheduledActions();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 } 243 }
235 244
236 void Scheduler::DidManageTiles() { 245 void Scheduler::DidManageTiles() {
237 state_machine_.DidManageTiles(); 246 state_machine_.DidManageTiles();
238 } 247 }
239 248
240 void Scheduler::DidLoseOutputSurface() { 249 void Scheduler::DidLoseOutputSurface() {
241 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 250 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
242 state_machine_.DidLoseOutputSurface(); 251 state_machine_.DidLoseOutputSurface();
243 last_set_needs_begin_frame_ = false; 252 last_set_needs_begin_frame_ = false;
244 if (!settings_.begin_frame_scheduling_enabled) { 253 if (!settings_.begin_frame_receiver) {
245 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, 254 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
246 &begin_retro_frame_args_); 255 &begin_retro_frame_args_);
247 } 256 }
248 begin_retro_frame_args_.clear(); 257 begin_retro_frame_args_.clear();
249 ProcessScheduledActions(); 258 ProcessScheduledActions();
250 } 259 }
251 260
252 void Scheduler::DidCreateAndInitializeOutputSurface() { 261 void Scheduler::DidCreateAndInitializeOutputSurface() {
253 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 262 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
254 DCHECK(!last_set_needs_begin_frame_); 263 DCHECK(!last_set_needs_begin_frame_);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 state_machine_.begin_impl_frame_state() == 309 state_machine_.begin_impl_frame_state() ==
301 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; 310 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
302 311
303 bool should_call_set_needs_begin_frame = 312 bool should_call_set_needs_begin_frame =
304 // Always request the BeginFrame immediately if it wasn't needed before. 313 // Always request the BeginFrame immediately if it wasn't needed before.
305 (needs_begin_frame && !last_set_needs_begin_frame_) || 314 (needs_begin_frame && !last_set_needs_begin_frame_) ||
306 // Only stop requesting BeginFrames after a deadline. 315 // Only stop requesting BeginFrames after a deadline.
307 (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline); 316 (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline);
308 317
309 if (should_call_set_needs_begin_frame) { 318 if (should_call_set_needs_begin_frame) {
310 if (settings_.begin_frame_scheduling_enabled) { 319 if (settings_.begin_frame_receiver) {
311 client_->SetNeedsBeginFrame(needs_begin_frame); 320 client_->SetNeedsBeginFrame(needs_begin_frame);
312 } else { 321 } else {
313 synthetic_begin_frame_source_->SetNeedsBeginFrame( 322 synthetic_begin_frame_source_->SetNeedsBeginFrame(
314 needs_begin_frame, &begin_retro_frame_args_); 323 needs_begin_frame, &begin_retro_frame_args_);
315 } 324 }
316 last_set_needs_begin_frame_ = needs_begin_frame; 325 last_set_needs_begin_frame_ = needs_begin_frame;
317 } 326 }
318 327
319 PostBeginRetroFrameIfNeeded(); 328 PostBeginRetroFrameIfNeeded();
320 } 329 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 415
407 // BeginFrame is the mechanism that tells us that now is a good time to start 416 // BeginFrame is the mechanism that tells us that now is a good time to start
408 // making a frame. Usually this means that user input for the frame is complete. 417 // making a frame. Usually this means that user input for the frame is complete.
409 // If the scheduler is busy, we queue the BeginFrame to be handled later as 418 // If the scheduler is busy, we queue the BeginFrame to be handled later as
410 // a BeginRetroFrame. 419 // a BeginRetroFrame.
411 void Scheduler::BeginFrame(const BeginFrameArgs& args) { 420 void Scheduler::BeginFrame(const BeginFrameArgs& args) {
412 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue()); 421 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue());
413 DCHECK(settings_.throttle_frame_production); 422 DCHECK(settings_.throttle_frame_production);
414 423
415 BeginFrameArgs adjusted_args(args); 424 BeginFrameArgs adjusted_args(args);
425
426 if (settings_.begin_frame_publisher &&
427 state_machine_.children_need_begin_frames()) {
428 // Adjust a dealine for child schedulers.
429 // TODO(simonhong): Once we have commitless update, we can get rid of
430 // BeginMainFrameToCommitDurationEstimate() +
431 // CommitToActivateDurationEstimate().
432 adjusted_args.deadline -=
433 (client_->BeginMainFrameToCommitDurationEstimate() +
434 client_->CommitToActivateDurationEstimate() +
435 client_->DrawDurationEstimate() + EstimatedParentDrawTime());
436 client_->SendBeginFrameToChildren(args);
437 }
438
416 adjusted_args.deadline -= EstimatedParentDrawTime(); 439 adjusted_args.deadline -= EstimatedParentDrawTime();
417 440
418 bool should_defer_begin_frame; 441 bool should_defer_begin_frame;
419 if (settings_.using_synchronous_renderer_compositor) { 442 if (settings_.using_synchronous_renderer_compositor) {
420 should_defer_begin_frame = false; 443 should_defer_begin_frame = false;
421 } else { 444 } else {
422 should_defer_begin_frame = 445 should_defer_begin_frame =
423 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || 446 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ ||
424 !last_set_needs_begin_frame_ || 447 !last_set_needs_begin_frame_ ||
425 (state_machine_.begin_impl_frame_state() != 448 (state_machine_.begin_impl_frame_state() !=
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 ProcessScheduledActions(); 640 ProcessScheduledActions();
618 state_machine_.DidLeavePollForAnticipatedDrawTriggers(); 641 state_machine_.DidLeavePollForAnticipatedDrawTriggers();
619 } 642 }
620 643
621 void Scheduler::PollToAdvanceCommitState() { 644 void Scheduler::PollToAdvanceCommitState() {
622 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); 645 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState");
623 advance_commit_state_task_.Cancel(); 646 advance_commit_state_task_.Cancel();
624 ProcessScheduledActions(); 647 ProcessScheduledActions();
625 } 648 }
626 649
650 void Scheduler::SetChildrenNeedBeginFrames(bool need_begin_frame) {
651 DCHECK(settings_.begin_frame_publisher);
652
653 state_machine_.SetChildrenNeedBeginFrames(need_begin_frame);
654 ProcessScheduledActions();
655 }
656
657 void Scheduler::SetAuthoritativeVSyncInterval(base::TimeDelta interval) {
658 authoritative_vsync_interval_ = interval;
659 vsync_interval_ = interval;
660
661 if (!settings_.begin_frame_receiver) {
662 synthetic_begin_frame_source_->CommitVSyncParameters(last_timebase_,
663 interval);
664 }
665 }
666
627 void Scheduler::DrawAndSwapIfPossible() { 667 void Scheduler::DrawAndSwapIfPossible() {
628 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); 668 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible();
629 state_machine_.DidDrawIfPossibleCompleted(result); 669 state_machine_.DidDrawIfPossibleCompleted(result);
630 } 670 }
631 671
632 void Scheduler::ProcessScheduledActions() { 672 void Scheduler::ProcessScheduledActions() {
633 // We do not allow ProcessScheduledActions to be recursive. 673 // We do not allow ProcessScheduledActions to be recursive.
634 // The top-level call will iteratively execute the next action for us anyway. 674 // The top-level call will iteratively execute the next action for us anyway.
635 if (inside_process_scheduled_actions_) 675 if (inside_process_scheduled_actions_)
636 return; 676 return;
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 } 813 }
774 814
775 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 815 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
776 return (state_machine_.commit_state() == 816 return (state_machine_.commit_state() ==
777 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 817 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
778 state_machine_.commit_state() == 818 state_machine_.commit_state() ==
779 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 819 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
780 } 820 }
781 821
782 } // namespace cc 822 } // 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