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

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

Issue 222743004: cc: Avoid dynamic calls to base::Bind in scheduler (Closed) Base URL: http://git.chromium.org/chromium/src.git@pollForCommit3
Patch Set: rebase on bo's patch Created 6 years, 8 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') | no next file » | 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 #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/logging.h" 10 #include "base/logging.h"
(...skipping 15 matching lines...) Expand all
26 last_set_needs_begin_impl_frame_(false), 26 last_set_needs_begin_impl_frame_(false),
27 state_machine_(scheduler_settings), 27 state_machine_(scheduler_settings),
28 inside_process_scheduled_actions_(false), 28 inside_process_scheduled_actions_(false),
29 inside_action_(SchedulerStateMachine::ACTION_NONE), 29 inside_action_(SchedulerStateMachine::ACTION_NONE),
30 weak_factory_(this) { 30 weak_factory_(this) {
31 DCHECK(client_); 31 DCHECK(client_);
32 DCHECK(!state_machine_.BeginImplFrameNeeded()); 32 DCHECK(!state_machine_.BeginImplFrameNeeded());
33 if (settings_.main_frame_before_activation_enabled) { 33 if (settings_.main_frame_before_activation_enabled) {
34 DCHECK(settings_.main_frame_before_draw_enabled); 34 DCHECK(settings_.main_frame_before_draw_enabled);
35 } 35 }
36
37 begin_impl_frame_deadline_closure_ = base::Bind(
38 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
39 poll_for_draw_triggers_closure_ = base::Bind(
40 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
41 advance_commit_state_closure_ = base::Bind(
42 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
36 } 43 }
37 44
38 Scheduler::~Scheduler() {} 45 Scheduler::~Scheduler() {}
39 46
40 void Scheduler::SetCanStart() { 47 void Scheduler::SetCanStart() {
41 state_machine_.SetCanStart(); 48 state_machine_.SetCanStart();
42 ProcessScheduledActions(); 49 ProcessScheduledActions();
43 } 50 }
44 51
45 void Scheduler::SetVisible(bool visible) { 52 void Scheduler::SetVisible(bool visible) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 void Scheduler::DidLoseOutputSurface() { 123 void Scheduler::DidLoseOutputSurface() {
117 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 124 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
118 state_machine_.DidLoseOutputSurface(); 125 state_machine_.DidLoseOutputSurface();
119 last_set_needs_begin_impl_frame_ = false; 126 last_set_needs_begin_impl_frame_ = false;
120 ProcessScheduledActions(); 127 ProcessScheduledActions();
121 } 128 }
122 129
123 void Scheduler::DidCreateAndInitializeOutputSurface() { 130 void Scheduler::DidCreateAndInitializeOutputSurface() {
124 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 131 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
125 DCHECK(!last_set_needs_begin_impl_frame_); 132 DCHECK(!last_set_needs_begin_impl_frame_);
126 DCHECK(begin_impl_frame_deadline_closure_.IsCancelled()); 133 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
127 state_machine_.DidCreateAndInitializeOutputSurface(); 134 state_machine_.DidCreateAndInitializeOutputSurface();
128 ProcessScheduledActions(); 135 ProcessScheduledActions();
129 } 136 }
130 137
131 void Scheduler::NotifyBeginMainFrameStarted() { 138 void Scheduler::NotifyBeginMainFrameStarted() {
132 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted"); 139 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted");
133 state_machine_.NotifyBeginMainFrameStarted(); 140 state_machine_.NotifyBeginMainFrameStarted();
134 } 141 }
135 142
136 base::TimeTicks Scheduler::AnticipatedDrawTime() const { 143 base::TimeTicks Scheduler::AnticipatedDrawTime() const {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 last_set_needs_begin_impl_frame_ = needs_begin_impl_frame; 177 last_set_needs_begin_impl_frame_ = needs_begin_impl_frame;
171 } 178 }
172 179
173 bool needs_advance_commit_state_timer = false; 180 bool needs_advance_commit_state_timer = false;
174 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but 181 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but
175 // aren't expecting any more BeginImplFrames. This should only be needed by 182 // aren't expecting any more BeginImplFrames. This should only be needed by
176 // the synchronous compositor when BeginImplFrameNeeded is false. 183 // the synchronous compositor when BeginImplFrameNeeded is false.
177 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { 184 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
178 DCHECK(!state_machine_.SupportsProactiveBeginImplFrame()); 185 DCHECK(!state_machine_.SupportsProactiveBeginImplFrame());
179 DCHECK(!needs_begin_impl_frame); 186 DCHECK(!needs_begin_impl_frame);
180 if (poll_for_draw_triggers_closure_.IsCancelled()) { 187 if (poll_for_draw_triggers_task_.IsCancelled()) {
181 poll_for_draw_triggers_closure_.Reset( 188 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_);
182 base::Bind(&Scheduler::PollForAnticipatedDrawTriggers,
183 weak_factory_.GetWeakPtr()));
184 base::TimeDelta delay = last_begin_impl_frame_args_.IsValid() 189 base::TimeDelta delay = last_begin_impl_frame_args_.IsValid()
185 ? last_begin_impl_frame_args_.interval 190 ? last_begin_impl_frame_args_.interval
186 : BeginFrameArgs::DefaultInterval(); 191 : BeginFrameArgs::DefaultInterval();
187 impl_task_runner_->PostDelayedTask( 192 impl_task_runner_->PostDelayedTask(
188 FROM_HERE, poll_for_draw_triggers_closure_.callback(), delay); 193 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay);
189 } 194 }
190 } else { 195 } else {
191 poll_for_draw_triggers_closure_.Cancel(); 196 poll_for_draw_triggers_task_.Cancel();
192 197
193 // At this point we'd prefer to advance through the commit flow by 198 // At this point we'd prefer to advance through the commit flow by
194 // drawing a frame, however it's possible that the frame rate controller 199 // drawing a frame, however it's possible that the frame rate controller
195 // will not give us a BeginImplFrame until the commit completes. See 200 // will not give us a BeginImplFrame until the commit completes. See
196 // crbug.com/317430 for an example of a swap ack being held on commit. Thus 201 // crbug.com/317430 for an example of a swap ack being held on commit. Thus
197 // we set a repeating timer to poll on ProcessScheduledActions until we 202 // we set a repeating timer to poll on ProcessScheduledActions until we
198 // successfully reach BeginImplFrame. Synchronous compositor does not use 203 // successfully reach BeginImplFrame. Synchronous compositor does not use
199 // frame rate controller or have the circular wait in the bug. 204 // frame rate controller or have the circular wait in the bug.
200 if (IsBeginMainFrameSentOrStarted() && 205 if (IsBeginMainFrameSentOrStarted() &&
201 !settings_.using_synchronous_renderer_compositor) { 206 !settings_.using_synchronous_renderer_compositor) {
202 needs_advance_commit_state_timer = true; 207 needs_advance_commit_state_timer = true;
203 } 208 }
204 } 209 }
205 210
206 if (needs_advance_commit_state_timer) { 211 if (needs_advance_commit_state_timer) {
207 if (advance_commit_state_closure_.IsCancelled() && 212 if (advance_commit_state_task_.IsCancelled() &&
208 last_begin_impl_frame_args_.IsValid()) { 213 last_begin_impl_frame_args_.IsValid()) {
209 // Since we'd rather get a BeginImplFrame by the normal mechanism, we 214 // Since we'd rather get a BeginImplFrame by the normal mechanism, we
210 // set the interval to twice the interval from the previous frame. 215 // set the interval to twice the interval from the previous frame.
211 advance_commit_state_closure_.Reset(base::Bind( 216 advance_commit_state_task_.Reset(advance_commit_state_closure_);
212 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()));
213 impl_task_runner_->PostDelayedTask( 217 impl_task_runner_->PostDelayedTask(
214 FROM_HERE, 218 FROM_HERE,
215 advance_commit_state_closure_.callback(), 219 advance_commit_state_task_.callback(),
216 last_begin_impl_frame_args_.interval * 2); 220 last_begin_impl_frame_args_.interval * 2);
217 } 221 }
218 } else { 222 } else {
219 advance_commit_state_closure_.Cancel(); 223 advance_commit_state_task_.Cancel();
220 } 224 }
221 } 225 }
222 226
223 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 227 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
224 TRACE_EVENT0("cc", "Scheduler::BeginImplFrame"); 228 TRACE_EVENT0("cc", "Scheduler::BeginImplFrame");
225 DCHECK(state_machine_.begin_impl_frame_state() == 229 DCHECK(state_machine_.begin_impl_frame_state() ==
226 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 230 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
227 DCHECK(state_machine_.HasInitializedOutputSurface()); 231 DCHECK(state_machine_.HasInitializedOutputSurface());
228 232
229 advance_commit_state_closure_.Cancel(); 233 advance_commit_state_task_.Cancel();
230 234
231 last_begin_impl_frame_args_ = args; 235 last_begin_impl_frame_args_ = args;
232 last_begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); 236 last_begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate();
233 237
234 if (!state_machine_.smoothness_takes_priority() && 238 if (!state_machine_.smoothness_takes_priority() &&
235 state_machine_.MainThreadIsInHighLatencyMode() && 239 state_machine_.MainThreadIsInHighLatencyMode() &&
236 CanCommitAndActivateBeforeDeadline()) { 240 CanCommitAndActivateBeforeDeadline()) {
237 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 241 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
238 } 242 }
239 243
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) { 281 void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) {
278 if (settings_.using_synchronous_renderer_compositor) { 282 if (settings_.using_synchronous_renderer_compositor) {
279 // The synchronous renderer compositor has to make its GL calls 283 // The synchronous renderer compositor has to make its GL calls
280 // within this call. 284 // within this call.
281 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks 285 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks
282 // so the sychronous renderer compositor can take advantage of splitting 286 // so the sychronous renderer compositor can take advantage of splitting
283 // up the BeginImplFrame and deadline as well. 287 // up the BeginImplFrame and deadline as well.
284 OnBeginImplFrameDeadline(); 288 OnBeginImplFrameDeadline();
285 return; 289 return;
286 } 290 }
287 begin_impl_frame_deadline_closure_.Cancel(); 291 begin_impl_frame_deadline_task_.Cancel();
288 begin_impl_frame_deadline_closure_.Reset( 292 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_);
289 base::Bind(&Scheduler::OnBeginImplFrameDeadline,
290 weak_factory_.GetWeakPtr()));
291 293
292 base::TimeDelta delta = deadline - gfx::FrameTime::Now(); 294 base::TimeDelta delta = deadline - gfx::FrameTime::Now();
293 if (delta <= base::TimeDelta()) 295 if (delta <= base::TimeDelta())
294 delta = base::TimeDelta(); 296 delta = base::TimeDelta();
295 impl_task_runner_->PostDelayedTask( 297 impl_task_runner_->PostDelayedTask(
296 FROM_HERE, begin_impl_frame_deadline_closure_.callback(), delta); 298 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta);
297 } 299 }
298 300
299 void Scheduler::OnBeginImplFrameDeadline() { 301 void Scheduler::OnBeginImplFrameDeadline() {
300 TRACE_EVENT0("cc", "Scheduler::OnBeginImplFrameDeadline"); 302 TRACE_EVENT0("cc", "Scheduler::OnBeginImplFrameDeadline");
301 begin_impl_frame_deadline_closure_.Cancel(); 303 begin_impl_frame_deadline_task_.Cancel();
302 304
303 // We split the deadline actions up into two phases so the state machine 305 // We split the deadline actions up into two phases so the state machine
304 // has a chance to trigger actions that should occur durring and after 306 // has a chance to trigger actions that should occur durring and after
305 // the deadline separately. For example: 307 // the deadline separately. For example:
306 // * Sending the BeginMainFrame will not occur after the deadline in 308 // * Sending the BeginMainFrame will not occur after the deadline in
307 // order to wait for more user-input before starting the next commit. 309 // order to wait for more user-input before starting the next commit.
308 // * Creating a new OuputSurface will not occur during the deadline in 310 // * Creating a new OuputSurface will not occur during the deadline in
309 // order to allow the state machine to "settle" first. 311 // order to allow the state machine to "settle" first.
310 state_machine_.OnBeginImplFrameDeadline(); 312 state_machine_.OnBeginImplFrameDeadline();
311 ProcessScheduledActions(); 313 ProcessScheduledActions();
312 state_machine_.OnBeginImplFrameIdle(); 314 state_machine_.OnBeginImplFrameIdle();
313 ProcessScheduledActions(); 315 ProcessScheduledActions();
314 316
315 client_->DidBeginImplFrameDeadline(); 317 client_->DidBeginImplFrameDeadline();
316 } 318 }
317 319
318 void Scheduler::PollForAnticipatedDrawTriggers() { 320 void Scheduler::PollForAnticipatedDrawTriggers() {
319 TRACE_EVENT0("cc", "Scheduler::PollForAnticipatedDrawTriggers"); 321 TRACE_EVENT0("cc", "Scheduler::PollForAnticipatedDrawTriggers");
320 poll_for_draw_triggers_closure_.Cancel(); 322 poll_for_draw_triggers_task_.Cancel();
321 state_machine_.DidEnterPollForAnticipatedDrawTriggers(); 323 state_machine_.DidEnterPollForAnticipatedDrawTriggers();
322 ProcessScheduledActions(); 324 ProcessScheduledActions();
323 state_machine_.DidLeavePollForAnticipatedDrawTriggers(); 325 state_machine_.DidLeavePollForAnticipatedDrawTriggers();
324 } 326 }
325 327
326 void Scheduler::PollToAdvanceCommitState() { 328 void Scheduler::PollToAdvanceCommitState() {
327 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); 329 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState");
328 advance_commit_state_closure_.Cancel(); 330 advance_commit_state_task_.Cancel();
329 ProcessScheduledActions(); 331 ProcessScheduledActions();
330 } 332 }
331 333
332 bool Scheduler::IsBeginMainFrameSent() const { 334 bool Scheduler::IsBeginMainFrameSent() const {
333 return state_machine_.commit_state() == 335 return state_machine_.commit_state() ==
334 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; 336 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT;
335 } 337 }
336 338
337 void Scheduler::DrawAndSwapIfPossible() { 339 void Scheduler::DrawAndSwapIfPossible() {
338 DrawSwapReadbackResult result = 340 DrawSwapReadbackResult result =
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 scoped_ptr<base::Value> Scheduler::StateAsValue() const { 426 scoped_ptr<base::Value> Scheduler::StateAsValue() const {
425 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); 427 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
426 state->Set("state_machine", state_machine_.AsValue().release()); 428 state->Set("state_machine", state_machine_.AsValue().release());
427 429
428 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue); 430 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue);
429 scheduler_state->SetDouble( 431 scheduler_state->SetDouble(
430 "time_until_anticipated_draw_time_ms", 432 "time_until_anticipated_draw_time_ms",
431 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); 433 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF());
432 scheduler_state->SetBoolean("last_set_needs_begin_impl_frame_", 434 scheduler_state->SetBoolean("last_set_needs_begin_impl_frame_",
433 last_set_needs_begin_impl_frame_); 435 last_set_needs_begin_impl_frame_);
434 scheduler_state->SetBoolean( 436 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_",
435 "begin_impl_frame_deadline_closure_", 437 !begin_impl_frame_deadline_task_.IsCancelled());
436 !begin_impl_frame_deadline_closure_.IsCancelled()); 438 scheduler_state->SetBoolean("poll_for_draw_triggers_task_",
437 scheduler_state->SetBoolean("poll_for_draw_triggers_closure_", 439 !poll_for_draw_triggers_task_.IsCancelled());
438 !poll_for_draw_triggers_closure_.IsCancelled()); 440 scheduler_state->SetBoolean("advance_commit_state_task_",
439 scheduler_state->SetBoolean("advance_commit_state_closure_", 441 !advance_commit_state_task_.IsCancelled());
440 !advance_commit_state_closure_.IsCancelled());
441 state->Set("scheduler_state", scheduler_state.release()); 442 state->Set("scheduler_state", scheduler_state.release());
442 443
443 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue); 444 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue);
444 client_state->SetDouble("draw_duration_estimate_ms", 445 client_state->SetDouble("draw_duration_estimate_ms",
445 client_->DrawDurationEstimate().InMillisecondsF()); 446 client_->DrawDurationEstimate().InMillisecondsF());
446 client_state->SetDouble( 447 client_state->SetDouble(
447 "begin_main_frame_to_commit_duration_estimate_ms", 448 "begin_main_frame_to_commit_duration_estimate_ms",
448 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); 449 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF());
449 client_state->SetDouble( 450 client_state->SetDouble(
450 "commit_to_activate_duration_estimate_ms", 451 "commit_to_activate_duration_estimate_ms",
(...skipping 22 matching lines...) Expand all
473 } 474 }
474 475
475 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 476 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
476 return (state_machine_.commit_state() == 477 return (state_machine_.commit_state() ==
477 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 478 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
478 state_machine_.commit_state() == 479 state_machine_.commit_state() ==
479 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 480 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
480 } 481 }
481 482
482 } // namespace cc 483 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698