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

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

Issue 1887243002: cc: Remove retro frames from scheduler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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
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
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE), 57 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE),
58 begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE), 58 begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE),
59 state_machine_(settings), 59 state_machine_(settings),
60 inside_process_scheduled_actions_(false), 60 inside_process_scheduled_actions_(false),
61 inside_action_(SchedulerStateMachine::ACTION_NONE), 61 inside_action_(SchedulerStateMachine::ACTION_NONE),
62 weak_factory_(this) { 62 weak_factory_(this) {
63 TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue()); 63 TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue());
64 DCHECK(client_); 64 DCHECK(client_);
65 DCHECK(!state_machine_.BeginFrameNeeded()); 65 DCHECK(!state_machine_.BeginFrameNeeded());
66 66
67 begin_retro_frame_closure_ =
68 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
69 begin_impl_frame_deadline_closure_ = base::Bind( 67 begin_impl_frame_deadline_closure_ = base::Bind(
70 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 68 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
71 69
72 SetBeginFrameSource(begin_frame_source); 70 SetBeginFrameSource(begin_frame_source);
73 ProcessScheduledActions(); 71 ProcessScheduledActions();
74 } 72 }
75 73
76 Scheduler::~Scheduler() { 74 Scheduler::~Scheduler() {
77 SetBeginFrameSource(nullptr); 75 SetBeginFrameSource(nullptr);
78 } 76 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 compositor_timing_history_->WillPrepareTiles(); 193 compositor_timing_history_->WillPrepareTiles();
196 } 194 }
197 195
198 void Scheduler::DidPrepareTiles() { 196 void Scheduler::DidPrepareTiles() {
199 compositor_timing_history_->DidPrepareTiles(); 197 compositor_timing_history_->DidPrepareTiles();
200 state_machine_.DidPrepareTiles(); 198 state_machine_.DidPrepareTiles();
201 } 199 }
202 200
203 void Scheduler::DidLoseOutputSurface() { 201 void Scheduler::DidLoseOutputSurface() {
204 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 202 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
205 begin_retro_frame_args_.clear();
206 begin_retro_frame_task_.Cancel();
207 state_machine_.DidLoseOutputSurface(); 203 state_machine_.DidLoseOutputSurface();
208 UpdateCompositorTimingHistoryRecordingEnabled(); 204 UpdateCompositorTimingHistoryRecordingEnabled();
209 ProcessScheduledActions(); 205 ProcessScheduledActions();
210 } 206 }
211 207
212 void Scheduler::DidCreateAndInitializeOutputSurface() { 208 void Scheduler::DidCreateAndInitializeOutputSurface() {
213 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 209 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
214 DCHECK(!observing_begin_frame_source_); 210 DCHECK(!observing_begin_frame_source_);
215 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 211 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
216 state_machine_.DidCreateAndInitializeOutputSurface(); 212 state_machine_.DidCreateAndInitializeOutputSurface();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { 250 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) {
255 // Call RemoveObserver in between frames only. 251 // Call RemoveObserver in between frames only.
256 observing_begin_frame_source_ = false; 252 observing_begin_frame_source_ = false;
257 if (begin_frame_source_) 253 if (begin_frame_source_)
258 begin_frame_source_->RemoveObserver(this); 254 begin_frame_source_->RemoveObserver(this);
259 BeginImplFrameNotExpectedSoon(); 255 BeginImplFrameNotExpectedSoon();
260 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, 256 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
261 false); 257 false);
262 } 258 }
263 } 259 }
264
265 PostBeginRetroFrameIfNeeded();
266 } 260 }
267 261
268 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { 262 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) {
269 if (state_machine_.begin_frame_source_paused() == paused) 263 if (state_machine_.begin_frame_source_paused() == paused)
270 return; 264 return;
271 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused", 265 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused",
272 TRACE_EVENT_SCOPE_THREAD, "paused", paused); 266 TRACE_EVENT_SCOPE_THREAD, "paused", paused);
273 state_machine_.SetBeginFrameSourcePaused(paused); 267 state_machine_.SetBeginFrameSourcePaused(paused);
274 ProcessScheduledActions(); 268 ProcessScheduledActions();
275 } 269 }
276 270
271 const BeginFrameArgs& Scheduler::LastUsedBeginFrameArgs() const {
272 return begin_impl_frame_tracker_.DangerousMethodCurrentOrLast();
273 }
274
277 // BeginFrame is the mechanism that tells us that now is a good time to start 275 // BeginFrame is the mechanism that tells us that now is a good time to start
278 // making a frame. Usually this means that user input for the frame is complete. 276 // making a frame. Usually this means that user input for the frame is complete.
279 // If the scheduler is busy, we queue the BeginFrame to be handled later as 277 void Scheduler::OnBeginFrame(const BeginFrameArgs& args) {
280 // a BeginRetroFrame. 278 if (!observing_begin_frame_source_ ||
281 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { 279 state_machine_.begin_impl_frame_state() !=
280 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) {
281 return;
282 }
283
282 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); 284 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue());
283 285
284 // Trace this begin frame time through the Chrome stack 286 // Trace this begin frame time through the Chrome stack
285 TRACE_EVENT_FLOW_BEGIN0( 287 TRACE_EVENT_FLOW_BEGIN0(
286 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", 288 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs",
287 args.frame_time.ToInternalValue()); 289 args.frame_time.ToInternalValue());
288 290
289 // TODO(brianderson): Adjust deadline in the DisplayScheduler. 291 // TODO(brianderson): Adjust deadline in the DisplayScheduler.
290 BeginFrameArgs adjusted_args(args); 292 BeginFrameArgs adjusted_args(args);
291 adjusted_args.deadline -= EstimatedParentDrawTime(); 293 adjusted_args.deadline -= EstimatedParentDrawTime();
292 294
293 // Deliver BeginFrames to children. 295 // Deliver BeginFrames to children.
294 // TODO(brianderson): Move this responsibility to the DisplayScheduler. 296 // TODO(brianderson): Move this responsibility to the DisplayScheduler.
295 if (state_machine_.children_need_begin_frames()) 297 if (state_machine_.children_need_begin_frames())
296 client_->SendBeginFramesToChildren(adjusted_args); 298 client_->SendBeginFramesToChildren(adjusted_args);
297 299
298 if (settings_.using_synchronous_renderer_compositor) { 300 if (settings_.using_synchronous_renderer_compositor) {
299 BeginImplFrameSynchronous(adjusted_args); 301 BeginImplFrameSynchronous(adjusted_args);
300 return true;
301 }
302
303 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has
304 // sent us the last BeginFrame we have missed. As we might not be able to
305 // actually make rendering for this call, handle it like a "retro frame".
306 // TODO(brainderson): Add a test for this functionality ASAP!
307 if (adjusted_args.type == BeginFrameArgs::MISSED) {
enne (OOO) 2016/04/18 21:30:38 The removal of this might break https://codereview
308 begin_retro_frame_args_.push_back(adjusted_args);
309 PostBeginRetroFrameIfNeeded();
310 return true;
311 }
312
313 bool should_defer_begin_frame =
314 !begin_retro_frame_args_.empty() ||
315 !begin_retro_frame_task_.IsCancelled() ||
316 !observing_begin_frame_source_ ||
317 (state_machine_.begin_impl_frame_state() !=
318 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
319
320 if (should_defer_begin_frame) {
321 begin_retro_frame_args_.push_back(adjusted_args);
322 TRACE_EVENT_INSTANT0(
323 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD);
324 // Queuing the frame counts as "using it", so we need to return true.
325 } else { 302 } else {
326 BeginImplFrameWithDeadline(adjusted_args); 303 BeginImplFrameWithDeadline(adjusted_args);
327 } 304 }
328 return true;
329 } 305 }
330 306
331 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { 307 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) {
332 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); 308 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames);
333 ProcessScheduledActions(); 309 ProcessScheduledActions();
334 } 310 }
335 311
336 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { 312 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) {
337 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); 313 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames);
338 ProcessScheduledActions(); 314 ProcessScheduledActions();
339 } 315 }
340 316
341 void Scheduler::OnDrawForOutputSurface(bool resourceless_software_draw) { 317 void Scheduler::OnDrawForOutputSurface(bool resourceless_software_draw) {
342 DCHECK(settings_.using_synchronous_renderer_compositor); 318 DCHECK(settings_.using_synchronous_renderer_compositor);
343 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 319 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
344 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 320 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
345 DCHECK(!BeginImplFrameDeadlinePending()); 321 DCHECK(!BeginImplFrameDeadlinePending());
346 322
347 state_machine_.SetResourcelessSoftareDraw(resourceless_software_draw); 323 state_machine_.SetResourcelessSoftareDraw(resourceless_software_draw);
348 state_machine_.OnBeginImplFrameDeadline(); 324 state_machine_.OnBeginImplFrameDeadline();
349 ProcessScheduledActions(); 325 ProcessScheduledActions();
350 326
351 state_machine_.OnBeginImplFrameIdle(); 327 state_machine_.OnBeginImplFrameIdle();
352 ProcessScheduledActions(); 328 ProcessScheduledActions();
353 state_machine_.SetResourcelessSoftareDraw(false); 329 state_machine_.SetResourcelessSoftareDraw(false);
354 } 330 }
355 331
356 // BeginRetroFrame is called for BeginFrames that we've deferred because
357 // the scheduler was in the middle of processing a previous BeginFrame.
358 void Scheduler::BeginRetroFrame() {
359 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame");
360 DCHECK(!settings_.using_synchronous_renderer_compositor);
361 DCHECK(!begin_retro_frame_args_.empty());
362 DCHECK(!begin_retro_frame_task_.IsCancelled());
363 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
364 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
365
366 begin_retro_frame_task_.Cancel();
367
368 // Discard expired BeginRetroFrames
369 // Today, we should always end up with at most one un-expired BeginRetroFrame
370 // because deadlines will not be greater than the next frame time. We don't
371 // DCHECK though because some systems don't always have monotonic timestamps.
372 // TODO(brianderson): In the future, long deadlines could result in us not
373 // draining the queue if we don't catch up. If we consistently can't catch
374 // up, our fallback should be to lower our frame rate.
375 base::TimeTicks now = Now();
376
377 while (!begin_retro_frame_args_.empty()) {
378 const BeginFrameArgs& args = begin_retro_frame_args_.front();
379 base::TimeTicks expiration_time = args.deadline;
380 if (now <= expiration_time)
381 break;
382 TRACE_EVENT_INSTANT2(
383 "cc", "Scheduler::BeginRetroFrame discarding", TRACE_EVENT_SCOPE_THREAD,
384 "expiration_time - now", (expiration_time - now).InMillisecondsF(),
385 "BeginFrameArgs", begin_retro_frame_args_.front().AsValue());
386 begin_retro_frame_args_.pop_front();
387 if (begin_frame_source_)
388 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
389 }
390
391 if (begin_retro_frame_args_.empty()) {
392 TRACE_EVENT_INSTANT0("cc",
393 "Scheduler::BeginRetroFrames all expired",
394 TRACE_EVENT_SCOPE_THREAD);
395 } else {
396 BeginFrameArgs front = begin_retro_frame_args_.front();
397 begin_retro_frame_args_.pop_front();
398 BeginImplFrameWithDeadline(front);
399 }
400 }
401
402 // There could be a race between the posted BeginRetroFrame and a new
403 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
404 // will check if there is a pending BeginRetroFrame to ensure we handle
405 // BeginFrames in FIFO order.
406 void Scheduler::PostBeginRetroFrameIfNeeded() {
407 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
408 "Scheduler::PostBeginRetroFrameIfNeeded",
409 "state",
410 AsValue());
411 if (!observing_begin_frame_source_)
412 return;
413
414 if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled())
415 return;
416
417 // begin_retro_frame_args_ should always be empty for the
418 // synchronous compositor.
419 DCHECK(!settings_.using_synchronous_renderer_compositor);
420
421 if (state_machine_.begin_impl_frame_state() !=
422 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
423 return;
424
425 begin_retro_frame_task_.Reset(begin_retro_frame_closure_);
426
427 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback());
428 }
429
430 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { 332 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
431 bool main_thread_is_in_high_latency_mode = 333 bool main_thread_is_in_high_latency_mode =
432 state_machine_.main_thread_missed_last_deadline(); 334 state_machine_.main_thread_missed_last_deadline();
433 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", 335 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args",
434 args.AsValue(), "main_thread_missed_last_deadline", 336 args.AsValue(), "main_thread_missed_last_deadline",
435 main_thread_is_in_high_latency_mode); 337 main_thread_is_in_high_latency_mode);
436 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 338 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
437 "MainThreadLatency", main_thread_is_in_high_latency_mode); 339 "MainThreadLatency", main_thread_is_in_high_latency_mode);
438 340
439 BeginFrameArgs adjusted_args = args; 341 BeginFrameArgs adjusted_args = args;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 bmf_to_activate_estimate); 373 bmf_to_activate_estimate);
472 374
473 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { 375 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) {
474 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", 376 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency",
475 TRACE_EVENT_SCOPE_THREAD); 377 TRACE_EVENT_SCOPE_THREAD);
476 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 378 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
477 } else if (ShouldRecoverImplLatency(adjusted_args, 379 } else if (ShouldRecoverImplLatency(adjusted_args,
478 can_activate_before_deadline)) { 380 can_activate_before_deadline)) {
479 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", 381 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency",
480 TRACE_EVENT_SCOPE_THREAD); 382 TRACE_EVENT_SCOPE_THREAD);
481 if (begin_frame_source_)
482 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
483 return; 383 return;
484 } 384 }
485 385
486 BeginImplFrame(adjusted_args); 386 BeginImplFrame(adjusted_args);
487
488 // The deadline will be scheduled in ProcessScheduledActions.
489 state_machine_.OnBeginImplFrameDeadlinePending();
490 ProcessScheduledActions();
491 } 387 }
492 388
493 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { 389 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) {
494 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", 390 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args",
495 args.AsValue()); 391 args.AsValue());
496 392
497 // The main thread currently can't commit before we draw with the 393 // The main thread currently can't commit before we draw with the
498 // synchronous compositor, so never consider the BeginMainFrame fast. 394 // synchronous compositor, so never consider the BeginMainFrame fast.
499 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); 395 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false);
500 begin_main_frame_args_ = args; 396 begin_main_frame_args_ = args;
501 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); 397 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority();
502 398
503 BeginImplFrame(args); 399 BeginImplFrame(args);
504 compositor_timing_history_->WillFinishImplFrame( 400 compositor_timing_history_->WillFinishImplFrame(
505 state_machine_.needs_redraw()); 401 state_machine_.needs_redraw());
506 FinishImplFrame(); 402 FinishImplFrame();
507 } 403 }
508 404
509 void Scheduler::FinishImplFrame() { 405 void Scheduler::FinishImplFrame() {
510 state_machine_.OnBeginImplFrameIdle(); 406 state_machine_.OnBeginImplFrameIdle();
511 ProcessScheduledActions(); 407 ProcessScheduledActions();
512 408
409 begin_impl_frame_tracker_.Finish();
410
513 client_->DidFinishImplFrame(); 411 client_->DidFinishImplFrame();
412
514 if (begin_frame_source_) 413 if (begin_frame_source_)
515 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); 414 begin_frame_source_->DidFinishFrame(this);
516 begin_impl_frame_tracker_.Finish();
517 } 415 }
518 416
519 // BeginImplFrame starts a compositor frame that will wait up until a deadline 417 // BeginImplFrame starts a compositor frame that will wait up until a deadline
520 // for a BeginMainFrame+activation to complete before it times out and draws 418 // for a BeginMainFrame+activation to complete before it times out and draws
521 // any asynchronous animation and scroll/pinch updates. 419 // any asynchronous animation and scroll/pinch updates.
522 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 420 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
523 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 421 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
524 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 422 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
525 DCHECK(!BeginImplFrameDeadlinePending()); 423 DCHECK(!BeginImplFrameDeadlinePending());
526 DCHECK(state_machine_.HasInitializedOutputSurface()); 424 DCHECK(state_machine_.HasInitializedOutputSurface());
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 TRACE_EVENT1("cc", "Scheduler::SetDeferCommits", 552 TRACE_EVENT1("cc", "Scheduler::SetDeferCommits",
655 "defer_commits", 553 "defer_commits",
656 defer_commits); 554 defer_commits);
657 state_machine_.SetDeferCommits(defer_commits); 555 state_machine_.SetDeferCommits(defer_commits);
658 ProcessScheduledActions(); 556 ProcessScheduledActions();
659 } 557 }
660 558
661 void Scheduler::ProcessScheduledActions() { 559 void Scheduler::ProcessScheduledActions() {
662 // We do not allow ProcessScheduledActions to be recursive. 560 // We do not allow ProcessScheduledActions to be recursive.
663 // The top-level call will iteratively execute the next action for us anyway. 561 // The top-level call will iteratively execute the next action for us anyway.
664 if (inside_process_scheduled_actions_) 562 if (!inside_process_scheduled_actions_) {
665 return; 563 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true);
564 SchedulerStateMachine::Action action;
565 do {
566 action = state_machine_.NextAction();
567 PerformAction(action);
568 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
569 "SchedulerStateMachine", "state", AsValue());
570 } while (action != SchedulerStateMachine::ACTION_NONE);
571 }
572 SetupNextBeginFrameIfNeeded();
573 ScheduleBeginImplFrameDeadlineIfNeeded();
574 }
666 575
667 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); 576 void Scheduler::PerformAction(SchedulerStateMachine::Action action) {
668 577 base::AutoReset<SchedulerStateMachine::Action> mark_inside_action(
669 SchedulerStateMachine::Action action; 578 &inside_action_, action);
670 do { 579 switch (action) {
671 action = state_machine_.NextAction(); 580 case SchedulerStateMachine::ACTION_NONE:
672 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 581 break;
673 "SchedulerStateMachine", 582 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME:
674 "state", 583 compositor_timing_history_->WillBeginMainFrame(
675 AsValue()); 584 begin_main_frame_args_.on_critical_path,
676 base::AutoReset<SchedulerStateMachine::Action> 585 begin_main_frame_args_.frame_time);
677 mark_inside_action(&inside_action_, action); 586 state_machine_.WillSendBeginMainFrame();
678 switch (action) { 587 // TODO(brianderson): Pass begin_main_frame_args_ directly to client.
679 case SchedulerStateMachine::ACTION_NONE: 588 client_->ScheduledActionSendBeginMainFrame(begin_main_frame_args_);
680 break; 589 break;
681 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: 590 case SchedulerStateMachine::ACTION_COMMIT: {
682 compositor_timing_history_->WillBeginMainFrame( 591 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is
683 begin_main_frame_args_.on_critical_path, 592 // fixed.
684 begin_main_frame_args_.frame_time); 593 tracked_objects::ScopedTracker tracking_profile4(
685 state_machine_.WillSendBeginMainFrame(); 594 FROM_HERE_WITH_EXPLICIT_FUNCTION(
686 // TODO(brianderson): Pass begin_main_frame_args_ directly to client. 595 "461509 Scheduler::ProcessScheduledActions4"));
687 client_->ScheduledActionSendBeginMainFrame(begin_main_frame_args_); 596 bool commit_has_no_updates = false;
688 break; 597 state_machine_.WillCommit(commit_has_no_updates);
689 case SchedulerStateMachine::ACTION_COMMIT: { 598 client_->ScheduledActionCommit();
690 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is 599 break;
691 // fixed.
692 tracked_objects::ScopedTracker tracking_profile4(
693 FROM_HERE_WITH_EXPLICIT_FUNCTION(
694 "461509 Scheduler::ProcessScheduledActions4"));
695 bool commit_has_no_updates = false;
696 state_machine_.WillCommit(commit_has_no_updates);
697 client_->ScheduledActionCommit();
698 break;
699 }
700 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE:
701 compositor_timing_history_->WillActivate();
702 state_machine_.WillActivate();
703 client_->ScheduledActionActivateSyncTree();
704 compositor_timing_history_->DidActivate();
705 break;
706 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: {
707 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is
708 // fixed.
709 tracked_objects::ScopedTracker tracking_profile6(
710 FROM_HERE_WITH_EXPLICIT_FUNCTION(
711 "461509 Scheduler::ProcessScheduledActions6"));
712 DrawAndSwapIfPossible();
713 break;
714 }
715 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED:
716 DrawAndSwapForced();
717 break;
718 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: {
719 // No action is actually performed, but this allows the state machine to
720 // drain the pipeline without actually drawing.
721 state_machine_.AbortDrawAndSwap();
722 compositor_timing_history_->DrawAborted();
723 break;
724 }
725 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
726 state_machine_.WillBeginOutputSurfaceCreation();
727 client_->ScheduledActionBeginOutputSurfaceCreation();
728 break;
729 case SchedulerStateMachine::ACTION_PREPARE_TILES:
730 state_machine_.WillPrepareTiles();
731 client_->ScheduledActionPrepareTiles();
732 break;
733 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE: {
734 state_machine_.WillInvalidateOutputSurface();
735 client_->ScheduledActionInvalidateOutputSurface();
736 break;
737 }
738 } 600 }
739 } while (action != SchedulerStateMachine::ACTION_NONE); 601 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE:
740 602 compositor_timing_history_->WillActivate();
741 ScheduleBeginImplFrameDeadlineIfNeeded(); 603 state_machine_.WillActivate();
742 SetupNextBeginFrameIfNeeded(); 604 client_->ScheduledActionActivateSyncTree();
605 compositor_timing_history_->DidActivate();
606 break;
607 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: {
608 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is
609 // fixed.
610 tracked_objects::ScopedTracker tracking_profile6(
611 FROM_HERE_WITH_EXPLICIT_FUNCTION(
612 "461509 Scheduler::ProcessScheduledActions6"));
613 DrawAndSwapIfPossible();
614 break;
615 }
616 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED:
617 DrawAndSwapForced();
618 break;
619 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: {
620 // No action is actually performed, but this allows the state machine
621 // to
622 // drain the pipeline without actually drawing.
623 state_machine_.AbortDrawAndSwap();
624 compositor_timing_history_->DrawAborted();
625 break;
626 }
627 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
628 state_machine_.WillBeginOutputSurfaceCreation();
629 client_->ScheduledActionBeginOutputSurfaceCreation();
630 break;
631 case SchedulerStateMachine::ACTION_PREPARE_TILES:
632 state_machine_.WillPrepareTiles();
633 client_->ScheduledActionPrepareTiles();
634 break;
635 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE: {
636 state_machine_.WillInvalidateOutputSurface();
637 client_->ScheduledActionInvalidateOutputSurface();
638 break;
639 }
640 }
743 } 641 }
744 642
745 std::unique_ptr<base::trace_event::ConvertableToTraceFormat> 643 std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
746 Scheduler::AsValue() const { 644 Scheduler::AsValue() const {
747 std::unique_ptr<base::trace_event::TracedValue> state( 645 std::unique_ptr<base::trace_event::TracedValue> state(
748 new base::trace_event::TracedValue()); 646 new base::trace_event::TracedValue());
749 AsValueInto(state.get()); 647 AsValueInto(state.get());
750 return std::move(state); 648 return std::move(state);
751 } 649 }
752 650
(...skipping 15 matching lines...) Expand all
768 state->EndDictionary(); 666 state->EndDictionary();
769 } 667 }
770 668
771 state->BeginDictionary("scheduler_state"); 669 state->BeginDictionary("scheduler_state");
772 state->SetBoolean("throttle_frame_production_", 670 state->SetBoolean("throttle_frame_production_",
773 settings_.throttle_frame_production); 671 settings_.throttle_frame_production);
774 state->SetDouble("estimated_parent_draw_time_ms", 672 state->SetDouble("estimated_parent_draw_time_ms",
775 estimated_parent_draw_time_.InMillisecondsF()); 673 estimated_parent_draw_time_.InMillisecondsF());
776 state->SetBoolean("observing_begin_frame_source", 674 state->SetBoolean("observing_begin_frame_source",
777 observing_begin_frame_source_); 675 observing_begin_frame_source_);
778 state->SetInteger("begin_retro_frame_args",
779 static_cast<int>(begin_retro_frame_args_.size()));
780 state->SetBoolean("begin_retro_frame_task",
781 !begin_retro_frame_task_.IsCancelled());
782 state->SetBoolean("begin_impl_frame_deadline_task", 676 state->SetBoolean("begin_impl_frame_deadline_task",
783 !begin_impl_frame_deadline_task_.IsCancelled()); 677 !begin_impl_frame_deadline_task_.IsCancelled());
784 state->SetString("inside_action", 678 state->SetString("inside_action",
785 SchedulerStateMachine::ActionToString(inside_action_)); 679 SchedulerStateMachine::ActionToString(inside_action_));
786 680
787 state->BeginDictionary("begin_impl_frame_args"); 681 state->BeginDictionary("begin_impl_frame_args");
788 begin_impl_frame_tracker_.AsValueInto(now, state); 682 begin_impl_frame_tracker_.AsValueInto(now, state);
789 state->EndDictionary(); 683 state->EndDictionary();
790 684
791 state->SetString("begin_impl_frame_deadline_mode_", 685 state->SetString("begin_impl_frame_deadline_mode_",
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 } 763 }
870 764
871 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 765 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
872 return (state_machine_.begin_main_frame_state() == 766 return (state_machine_.begin_main_frame_state() ==
873 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || 767 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT ||
874 state_machine_.begin_main_frame_state() == 768 state_machine_.begin_main_frame_state() ==
875 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); 769 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED);
876 } 770 }
877 771
878 } // namespace cc 772 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698