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

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

Issue 1051273003: Revert of cc: Make scheduling be driven by vsync for android webview. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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') | cc/scheduler/scheduler_state_machine.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
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 primary_frame_source_internal_(external_begin_frame_source.Pass()), 87 primary_frame_source_internal_(external_begin_frame_source.Pass()),
88 background_frame_source_internal_(), 88 background_frame_source_internal_(),
89 vsync_observer_(NULL), 89 vsync_observer_(NULL),
90 authoritative_vsync_interval_(base::TimeDelta()), 90 authoritative_vsync_interval_(base::TimeDelta()),
91 last_vsync_timebase_(base::TimeTicks()), 91 last_vsync_timebase_(base::TimeTicks()),
92 throttle_frame_production_(scheduler_settings.throttle_frame_production), 92 throttle_frame_production_(scheduler_settings.throttle_frame_production),
93 settings_(scheduler_settings), 93 settings_(scheduler_settings),
94 client_(client), 94 client_(client),
95 layer_tree_host_id_(layer_tree_host_id), 95 layer_tree_host_id_(layer_tree_host_id),
96 task_runner_(task_runner), 96 task_runner_(task_runner),
97 begin_impl_frame_deadline_mode_(
98 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE),
99 state_machine_(scheduler_settings), 97 state_machine_(scheduler_settings),
100 inside_process_scheduled_actions_(false), 98 inside_process_scheduled_actions_(false),
101 inside_action_(SchedulerStateMachine::ACTION_NONE), 99 inside_action_(SchedulerStateMachine::ACTION_NONE),
102 weak_factory_(this) { 100 weak_factory_(this) {
103 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 101 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
104 "Scheduler::Scheduler", 102 "Scheduler::Scheduler",
105 "settings", 103 "settings",
106 settings_.AsValue()); 104 settings_.AsValue());
107 DCHECK(client_); 105 DCHECK(client_);
108 DCHECK(!state_machine_.BeginFrameNeeded()); 106 DCHECK(!state_machine_.BeginFrameNeeded());
109 107
110 begin_retro_frame_closure_ = 108 begin_retro_frame_closure_ =
111 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); 109 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
112 begin_impl_frame_deadline_closure_ = base::Bind( 110 begin_impl_frame_deadline_closure_ = base::Bind(
113 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 111 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
112 poll_for_draw_triggers_closure_ = base::Bind(
113 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
114 advance_commit_state_closure_ = base::Bind( 114 advance_commit_state_closure_ = base::Bind(
115 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); 115 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
116 116
117 frame_source_ = BeginFrameSourceMultiplexer::Create(); 117 frame_source_ = BeginFrameSourceMultiplexer::Create();
118 frame_source_->AddObserver(this); 118 frame_source_->AddObserver(this);
119 119
120 // Primary frame source 120 // Primary frame source
121 primary_frame_source_ = 121 primary_frame_source_ =
122 frame_sources_constructor->ConstructPrimaryFrameSource(this); 122 frame_sources_constructor->ConstructPrimaryFrameSource(this);
123 frame_source_->AddSource(primary_frame_source_); 123 frame_source_->AddSource(primary_frame_source_);
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 client_->SendBeginMainFrameNotExpectedSoon(); 330 client_->SendBeginMainFrameNotExpectedSoon();
331 } 331 }
332 } 332 }
333 333
334 PostBeginRetroFrameIfNeeded(); 334 PostBeginRetroFrameIfNeeded();
335 } 335 }
336 336
337 // We may need to poll when we can't rely on BeginFrame to advance certain 337 // We may need to poll when we can't rely on BeginFrame to advance certain
338 // state or to avoid deadlock. 338 // state or to avoid deadlock.
339 void Scheduler::SetupPollingMechanisms() { 339 void Scheduler::SetupPollingMechanisms() {
340 // At this point we'd prefer to advance through the commit flow by 340 bool needs_advance_commit_state_timer = false;
341 // drawing a frame, however it's possible that the frame rate controller 341 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but
342 // will not give us a BeginFrame until the commit completes. See 342 // aren't expecting any more BeginFrames. This should only be needed by
343 // crbug.com/317430 for an example of a swap ack being held on commit. Thus 343 // the synchronous compositor when BeginFrameNeeded is false.
344 // we set a repeating timer to poll on ProcessScheduledActions until we 344 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
345 // successfully reach BeginFrame. Synchronous compositor does not use 345 DCHECK(!state_machine_.SupportsProactiveBeginFrame());
346 // frame rate controller or have the circular wait in the bug. 346 if (poll_for_draw_triggers_task_.IsCancelled()) {
347 if (IsBeginMainFrameSentOrStarted() && 347 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_);
348 !settings_.using_synchronous_renderer_compositor) { 348 base::TimeDelta delay = begin_impl_frame_args_.IsValid()
349 ? begin_impl_frame_args_.interval
350 : BeginFrameArgs::DefaultInterval();
351 task_runner_->PostDelayedTask(
352 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay);
353 }
354 } else {
355 poll_for_draw_triggers_task_.Cancel();
356
357 // At this point we'd prefer to advance through the commit flow by
358 // drawing a frame, however it's possible that the frame rate controller
359 // will not give us a BeginFrame until the commit completes. See
360 // crbug.com/317430 for an example of a swap ack being held on commit. Thus
361 // we set a repeating timer to poll on ProcessScheduledActions until we
362 // successfully reach BeginFrame. Synchronous compositor does not use
363 // frame rate controller or have the circular wait in the bug.
364 if (IsBeginMainFrameSentOrStarted() &&
365 !settings_.using_synchronous_renderer_compositor) {
366 needs_advance_commit_state_timer = true;
367 }
368 }
369
370 if (needs_advance_commit_state_timer) {
349 if (advance_commit_state_task_.IsCancelled() && 371 if (advance_commit_state_task_.IsCancelled() &&
350 begin_impl_frame_args_.IsValid()) { 372 begin_impl_frame_args_.IsValid()) {
351 // Since we'd rather get a BeginImplFrame by the normal mechanism, we 373 // Since we'd rather get a BeginImplFrame by the normal mechanism, we
352 // set the interval to twice the interval from the previous frame. 374 // set the interval to twice the interval from the previous frame.
353 advance_commit_state_task_.Reset(advance_commit_state_closure_); 375 advance_commit_state_task_.Reset(advance_commit_state_closure_);
354 task_runner_->PostDelayedTask(FROM_HERE, 376 task_runner_->PostDelayedTask(FROM_HERE,
355 advance_commit_state_task_.callback(), 377 advance_commit_state_task_.callback(),
356 begin_impl_frame_args_.interval * 2); 378 begin_impl_frame_args_.interval * 2);
357 } 379 }
358 } else { 380 } else {
(...skipping 18 matching lines...) Expand all
377 adjusted_args_for_children.deadline -= 399 adjusted_args_for_children.deadline -=
378 (client_->BeginMainFrameToCommitDurationEstimate() + 400 (client_->BeginMainFrameToCommitDurationEstimate() +
379 client_->CommitToActivateDurationEstimate() + 401 client_->CommitToActivateDurationEstimate() +
380 client_->DrawDurationEstimate() + EstimatedParentDrawTime()); 402 client_->DrawDurationEstimate() + EstimatedParentDrawTime());
381 client_->SendBeginFramesToChildren(adjusted_args_for_children); 403 client_->SendBeginFramesToChildren(adjusted_args_for_children);
382 } 404 }
383 405
384 BeginFrameArgs adjusted_args(args); 406 BeginFrameArgs adjusted_args(args);
385 adjusted_args.deadline -= EstimatedParentDrawTime(); 407 adjusted_args.deadline -= EstimatedParentDrawTime();
386 408
387 if (settings_.using_synchronous_renderer_compositor) {
388 BeginImplFrameSynchronous(adjusted_args);
389 return true;
390 }
391
392 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has 409 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has
393 // sent us the last BeginFrame we have missed. As we might not be able to 410 // sent us the last BeginFrame we have missed. As we might not be able to
394 // actually make rendering for this call, handle it like a "retro frame". 411 // actually make rendering for this call, handle it like a "retro frame".
395 // TODO(brainderson): Add a test for this functionality ASAP! 412 // TODO(brainderson): Add a test for this functionality ASAP!
396 if (adjusted_args.type == BeginFrameArgs::MISSED) { 413 if (adjusted_args.type == BeginFrameArgs::MISSED) {
397 begin_retro_frame_args_.push_back(adjusted_args); 414 begin_retro_frame_args_.push_back(adjusted_args);
398 PostBeginRetroFrameIfNeeded(); 415 PostBeginRetroFrameIfNeeded();
399 return true; 416 return true;
400 } 417 }
401 418
402 bool should_defer_begin_frame = 419 bool should_defer_begin_frame;
403 !begin_retro_frame_args_.empty() || 420 if (settings_.using_synchronous_renderer_compositor) {
404 !begin_retro_frame_task_.IsCancelled() || 421 should_defer_begin_frame = false;
405 !frame_source_->NeedsBeginFrames() || 422 } else {
406 (state_machine_.begin_impl_frame_state() != 423 should_defer_begin_frame =
407 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 424 !begin_retro_frame_args_.empty() ||
425 !begin_retro_frame_task_.IsCancelled() ||
426 !frame_source_->NeedsBeginFrames() ||
427 (state_machine_.begin_impl_frame_state() !=
428 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
429 }
408 430
409 if (should_defer_begin_frame) { 431 if (should_defer_begin_frame) {
410 begin_retro_frame_args_.push_back(adjusted_args); 432 begin_retro_frame_args_.push_back(adjusted_args);
411 TRACE_EVENT_INSTANT0( 433 TRACE_EVENT_INSTANT0(
412 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); 434 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD);
413 // Queuing the frame counts as "using it", so we need to return true. 435 // Queuing the frame counts as "using it", so we need to return true.
414 } else { 436 } else {
415 BeginImplFrameWithDeadline(adjusted_args); 437 BeginImplFrame(adjusted_args);
416 } 438 }
417 return true; 439 return true;
418 } 440 }
419 441
420 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { 442 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) {
421 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); 443 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames);
422 ProcessScheduledActions(); 444 ProcessScheduledActions();
423 } 445 }
424 446
425 void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) { 447 void Scheduler::SetAuthoritativeVSyncInterval(const base::TimeDelta& interval) {
426 authoritative_vsync_interval_ = interval; 448 authoritative_vsync_interval_ = interval;
427 if (vsync_observer_) 449 if (vsync_observer_)
428 vsync_observer_->OnUpdateVSyncParameters(last_vsync_timebase_, interval); 450 vsync_observer_->OnUpdateVSyncParameters(last_vsync_timebase_, interval);
429 } 451 }
430 452
431 void Scheduler::OnDrawForOutputSurface() {
432 DCHECK(settings_.using_synchronous_renderer_compositor);
433 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
434 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
435 DCHECK(!BeginImplFrameDeadlinePending());
436
437 state_machine_.OnBeginImplFrameDeadline();
438 ProcessScheduledActions();
439
440 state_machine_.OnBeginImplFrameIdle();
441 ProcessScheduledActions();
442 }
443
444 // BeginRetroFrame is called for BeginFrames that we've deferred because 453 // BeginRetroFrame is called for BeginFrames that we've deferred because
445 // the scheduler was in the middle of processing a previous BeginFrame. 454 // the scheduler was in the middle of processing a previous BeginFrame.
446 void Scheduler::BeginRetroFrame() { 455 void Scheduler::BeginRetroFrame() {
447 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame"); 456 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame");
448 DCHECK(!settings_.using_synchronous_renderer_compositor); 457 DCHECK(!settings_.using_synchronous_renderer_compositor);
449 DCHECK(!begin_retro_frame_args_.empty()); 458 DCHECK(!begin_retro_frame_args_.empty());
450 DCHECK(!begin_retro_frame_task_.IsCancelled()); 459 DCHECK(!begin_retro_frame_task_.IsCancelled());
451 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 460 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
452 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 461 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
453 462
(...skipping 21 matching lines...) Expand all
475 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); 484 frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
476 } 485 }
477 486
478 if (begin_retro_frame_args_.empty()) { 487 if (begin_retro_frame_args_.empty()) {
479 TRACE_EVENT_INSTANT0("cc", 488 TRACE_EVENT_INSTANT0("cc",
480 "Scheduler::BeginRetroFrames all expired", 489 "Scheduler::BeginRetroFrames all expired",
481 TRACE_EVENT_SCOPE_THREAD); 490 TRACE_EVENT_SCOPE_THREAD);
482 } else { 491 } else {
483 BeginFrameArgs front = begin_retro_frame_args_.front(); 492 BeginFrameArgs front = begin_retro_frame_args_.front();
484 begin_retro_frame_args_.pop_front(); 493 begin_retro_frame_args_.pop_front();
485 BeginImplFrameWithDeadline(front); 494 BeginImplFrame(front);
486 } 495 }
487 } 496 }
488 497
489 // There could be a race between the posted BeginRetroFrame and a new 498 // There could be a race between the posted BeginRetroFrame and a new
490 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame 499 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
491 // will check if there is a pending BeginRetroFrame to ensure we handle 500 // will check if there is a pending BeginRetroFrame to ensure we handle
492 // BeginFrames in FIFO order. 501 // BeginFrames in FIFO order.
493 void Scheduler::PostBeginRetroFrameIfNeeded() { 502 void Scheduler::PostBeginRetroFrameIfNeeded() {
494 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 503 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
495 "Scheduler::PostBeginRetroFrameIfNeeded", 504 "Scheduler::PostBeginRetroFrameIfNeeded",
(...skipping 11 matching lines...) Expand all
507 516
508 if (state_machine_.begin_impl_frame_state() != 517 if (state_machine_.begin_impl_frame_state() !=
509 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) 518 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
510 return; 519 return;
511 520
512 begin_retro_frame_task_.Reset(begin_retro_frame_closure_); 521 begin_retro_frame_task_.Reset(begin_retro_frame_closure_);
513 522
514 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback()); 523 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback());
515 } 524 }
516 525
517 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
518 BeginImplFrame(args);
519
520 // The deadline will be scheduled in ProcessScheduledActions.
521 state_machine_.OnBeginImplFrameDeadlinePending();
522 ProcessScheduledActions();
523 }
524
525 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) {
526 BeginImplFrame(args);
527 FinishImplFrame();
528 }
529
530 void Scheduler::FinishImplFrame() {
531 state_machine_.OnBeginImplFrameIdle();
532 ProcessScheduledActions();
533
534 client_->DidBeginImplFrameDeadline();
535 frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
536 }
537
538 // BeginImplFrame starts a compositor frame that will wait up until a deadline 526 // BeginImplFrame starts a compositor frame that will wait up until a deadline
539 // for a BeginMainFrame+activation to complete before it times out and draws 527 // for a BeginMainFrame+activation to complete before it times out and draws
540 // any asynchronous animation and scroll/pinch updates. 528 // any asynchronous animation and scroll/pinch updates.
541 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 529 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
542 bool main_thread_is_in_high_latency_mode = 530 bool main_thread_is_in_high_latency_mode =
543 state_machine_.MainThreadIsInHighLatencyMode(); 531 state_machine_.MainThreadIsInHighLatencyMode();
544 TRACE_EVENT2("cc,benchmark", 532 TRACE_EVENT2("cc,benchmark",
545 "Scheduler::BeginImplFrame", 533 "Scheduler::BeginImplFrame",
546 "args", 534 "args",
547 args.AsValue(), 535 args.AsValue(),
548 "main_thread_is_high_latency", 536 "main_thread_is_high_latency",
549 main_thread_is_in_high_latency_mode); 537 main_thread_is_in_high_latency_mode);
550 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 538 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
551 "MainThreadLatency", 539 "MainThreadLatency",
552 main_thread_is_in_high_latency_mode); 540 main_thread_is_in_high_latency_mode);
553 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 541 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
554 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 542 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
555 DCHECK(!BeginImplFrameDeadlinePending());
556 DCHECK(state_machine_.HasInitializedOutputSurface()); 543 DCHECK(state_machine_.HasInitializedOutputSurface());
557 544
558 advance_commit_state_task_.Cancel(); 545 advance_commit_state_task_.Cancel();
559 546
560 begin_impl_frame_args_ = args; 547 begin_impl_frame_args_ = args;
561 begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); 548 begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate();
562 549
563 if (!state_machine_.impl_latency_takes_priority() && 550 if (!state_machine_.impl_latency_takes_priority() &&
564 main_thread_is_in_high_latency_mode && 551 main_thread_is_in_high_latency_mode &&
565 CanCommitAndActivateBeforeDeadline()) { 552 CanCommitAndActivateBeforeDeadline()) {
566 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 553 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
567 } 554 }
568 555
569 state_machine_.OnBeginImplFrame(); 556 state_machine_.OnBeginImplFrame();
570 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); 557 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_);
571 client_->WillBeginImplFrame(begin_impl_frame_args_); 558 client_->WillBeginImplFrame(begin_impl_frame_args_);
572 559
573 ProcessScheduledActions(); 560 ProcessScheduledActions();
561
562 state_machine_.OnBeginImplFrameDeadlinePending();
563
564 if (settings_.using_synchronous_renderer_compositor) {
565 // The synchronous renderer compositor has to make its GL calls
566 // within this call.
567 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks
568 // so the synchronous renderer compositor can take advantage of splitting
569 // up the BeginImplFrame and deadline as well.
570 OnBeginImplFrameDeadline();
571 } else {
572 ScheduleBeginImplFrameDeadline();
573 }
574 } 574 }
575 575
576 void Scheduler::ScheduleBeginImplFrameDeadline() { 576 void Scheduler::ScheduleBeginImplFrameDeadline() {
577 // The synchronous compositor does not post a deadline task. 577 // The synchronous compositor does not post a deadline task.
578 DCHECK(!settings_.using_synchronous_renderer_compositor); 578 DCHECK(!settings_.using_synchronous_renderer_compositor);
579 579
580 begin_impl_frame_deadline_task_.Cancel(); 580 begin_impl_frame_deadline_task_.Cancel();
581 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); 581 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_);
582 582
583 begin_impl_frame_deadline_mode_ = 583 begin_impl_frame_deadline_mode_ =
584 state_machine_.CurrentBeginImplFrameDeadlineMode(); 584 state_machine_.CurrentBeginImplFrameDeadlineMode();
585 585
586 base::TimeTicks deadline; 586 base::TimeTicks deadline;
587 switch (begin_impl_frame_deadline_mode_) { 587 switch (begin_impl_frame_deadline_mode_) {
588 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE:
589 // No deadline.
590 return;
591 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE: 588 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE:
592 // We are ready to draw a new active tree immediately. 589 // We are ready to draw a new active tree immediately.
593 // We don't use Now() here because it's somewhat expensive to call. 590 // We don't use Now() here because it's somewhat expensive to call.
594 deadline = base::TimeTicks(); 591 deadline = base::TimeTicks();
595 break; 592 break;
596 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR: 593 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR:
597 // We are animating on the impl thread but we can wait for some time. 594 // We are animating on the impl thread but we can wait for some time.
598 deadline = begin_impl_frame_args_.deadline; 595 deadline = begin_impl_frame_args_.deadline;
599 break; 596 break;
600 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: 597 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE:
601 // We are blocked for one reason or another and we should wait. 598 // We are blocked for one reason or another and we should wait.
602 // TODO(brianderson): Handle long deadlines (that are past the next 599 // TODO(brianderson): Handle long deadlines (that are past the next
603 // frame's frame time) properly instead of using this hack. 600 // frame's frame time) properly instead of using this hack.
604 deadline = 601 deadline =
605 begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval; 602 begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval;
606 break; 603 break;
607 case SchedulerStateMachine:: 604 case SchedulerStateMachine::
608 BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW: 605 BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW:
609 // We are blocked because we are waiting for ReadyToDraw signal. We would 606 // We are blocked because we are waiting for ReadyToDraw signal. We would
610 // post deadline after we received ReadyToDraw singal. 607 // post deadline after we received ReadyToDraw singal.
611 TRACE_EVENT1("cc", "Scheduler::ScheduleBeginImplFrameDeadline", 608 TRACE_EVENT1("cc", "Scheduler::ScheduleBeginImplFrameDeadline",
612 "deadline_mode", "blocked_on_ready_to_draw"); 609 "deadline_mode", "blocked_on_ready_to_draw");
613 return; 610 return;
614 } 611 }
615 612
616 TRACE_EVENT2("cc", "Scheduler::ScheduleBeginImplFrameDeadline", "mode", 613 TRACE_EVENT1(
617 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( 614 "cc", "Scheduler::ScheduleBeginImplFrameDeadline", "deadline", deadline);
618 begin_impl_frame_deadline_mode_),
619 "deadline", deadline);
620 615
621 base::TimeDelta delta = std::max(deadline - Now(), base::TimeDelta()); 616 base::TimeDelta delta = deadline - Now();
617 if (delta <= base::TimeDelta())
618 delta = base::TimeDelta();
622 task_runner_->PostDelayedTask( 619 task_runner_->PostDelayedTask(
623 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta); 620 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta);
624 } 621 }
625 622
626 void Scheduler::ScheduleBeginImplFrameDeadlineIfNeeded() { 623 void Scheduler::RescheduleBeginImplFrameDeadlineIfNeeded() {
627 if (settings_.using_synchronous_renderer_compositor) 624 if (settings_.using_synchronous_renderer_compositor)
628 return; 625 return;
629 626
630 if (state_machine_.begin_impl_frame_state() != 627 if (state_machine_.begin_impl_frame_state() !=
631 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) 628 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
632 return; 629 return;
633 630
634 if (begin_impl_frame_deadline_mode_ == 631 if (begin_impl_frame_deadline_mode_ !=
635 state_machine_.CurrentBeginImplFrameDeadlineMode() && 632 state_machine_.CurrentBeginImplFrameDeadlineMode())
636 BeginImplFrameDeadlinePending()) 633 ScheduleBeginImplFrameDeadline();
637 return;
638
639 ScheduleBeginImplFrameDeadline();
640 } 634 }
641 635
642 void Scheduler::OnBeginImplFrameDeadline() { 636 void Scheduler::OnBeginImplFrameDeadline() {
643 TRACE_EVENT0("cc,benchmark", "Scheduler::OnBeginImplFrameDeadline"); 637 TRACE_EVENT0("cc,benchmark", "Scheduler::OnBeginImplFrameDeadline");
644 begin_impl_frame_deadline_task_.Cancel(); 638 begin_impl_frame_deadline_task_.Cancel();
645 // We split the deadline actions up into two phases so the state machine 639 // We split the deadline actions up into two phases so the state machine
646 // has a chance to trigger actions that should occur durring and after 640 // has a chance to trigger actions that should occur durring and after
647 // the deadline separately. For example: 641 // the deadline separately. For example:
648 // * Sending the BeginMainFrame will not occur after the deadline in 642 // * Sending the BeginMainFrame will not occur after the deadline in
649 // order to wait for more user-input before starting the next commit. 643 // order to wait for more user-input before starting the next commit.
650 // * Creating a new OuputSurface will not occur during the deadline in 644 // * Creating a new OuputSurface will not occur during the deadline in
651 // order to allow the state machine to "settle" first. 645 // order to allow the state machine to "settle" first.
652 646
653 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed. 647 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed.
654 tracked_objects::ScopedTracker tracking_profile1( 648 tracked_objects::ScopedTracker tracking_profile1(
655 FROM_HERE_WITH_EXPLICIT_FUNCTION( 649 FROM_HERE_WITH_EXPLICIT_FUNCTION(
656 "461509 Scheduler::OnBeginImplFrameDeadline1")); 650 "461509 Scheduler::OnBeginImplFrameDeadline1"));
657 state_machine_.OnBeginImplFrameDeadline(); 651 state_machine_.OnBeginImplFrameDeadline();
658 ProcessScheduledActions(); 652 ProcessScheduledActions();
659 FinishImplFrame(); 653 state_machine_.OnBeginImplFrameIdle();
654 ProcessScheduledActions();
655
656 client_->DidBeginImplFrameDeadline();
657 frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
660 } 658 }
661 659
660 void Scheduler::PollForAnticipatedDrawTriggers() {
661 TRACE_EVENT0("cc", "Scheduler::PollForAnticipatedDrawTriggers");
662 poll_for_draw_triggers_task_.Cancel();
663 state_machine_.DidEnterPollForAnticipatedDrawTriggers();
664 ProcessScheduledActions();
665 state_machine_.DidLeavePollForAnticipatedDrawTriggers();
666 }
662 667
663 void Scheduler::PollToAdvanceCommitState() { 668 void Scheduler::PollToAdvanceCommitState() {
664 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); 669 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState");
665 advance_commit_state_task_.Cancel(); 670 advance_commit_state_task_.Cancel();
666 ProcessScheduledActions(); 671 ProcessScheduledActions();
667 } 672 }
668 673
669 void Scheduler::DrawAndSwapIfPossible() { 674 void Scheduler::DrawAndSwapIfPossible() {
670 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); 675 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible();
671 state_machine_.DidDrawIfPossibleCompleted(result); 676 state_machine_.DidDrawIfPossibleCompleted(result);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: 741 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT:
737 // No action is actually performed, but this allows the state machine to 742 // No action is actually performed, but this allows the state machine to
738 // advance out of its waiting to draw state without actually drawing. 743 // advance out of its waiting to draw state without actually drawing.
739 break; 744 break;
740 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 745 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
741 client_->ScheduledActionBeginOutputSurfaceCreation(); 746 client_->ScheduledActionBeginOutputSurfaceCreation();
742 break; 747 break;
743 case SchedulerStateMachine::ACTION_PREPARE_TILES: 748 case SchedulerStateMachine::ACTION_PREPARE_TILES:
744 client_->ScheduledActionPrepareTiles(); 749 client_->ScheduledActionPrepareTiles();
745 break; 750 break;
746 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE: {
747 client_->ScheduledActionInvalidateOutputSurface();
748 break;
749 }
750 } 751 }
751 } while (action != SchedulerStateMachine::ACTION_NONE); 752 } while (action != SchedulerStateMachine::ACTION_NONE);
752 753
753 SetupPollingMechanisms(); 754 SetupPollingMechanisms();
754 755
755 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); 756 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());
756 757
757 ScheduleBeginImplFrameDeadlineIfNeeded(); 758 RescheduleBeginImplFrameDeadlineIfNeeded();
758 759
759 SetupNextBeginFrameIfNeeded(); 760 SetupNextBeginFrameIfNeeded();
760 } 761 }
761 762
762 scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue() 763 scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue()
763 const { 764 const {
764 scoped_refptr<base::trace_event::TracedValue> state = 765 scoped_refptr<base::trace_event::TracedValue> state =
765 new base::trace_event::TracedValue(); 766 new base::trace_event::TracedValue();
766 AsValueInto(state.get()); 767 AsValueInto(state.get());
767 return state; 768 return state;
(...skipping 20 matching lines...) Expand all
788 (AnticipatedDrawTime() - Now()).InMillisecondsF()); 789 (AnticipatedDrawTime() - Now()).InMillisecondsF());
789 state->SetDouble("estimated_parent_draw_time_ms", 790 state->SetDouble("estimated_parent_draw_time_ms",
790 estimated_parent_draw_time_.InMillisecondsF()); 791 estimated_parent_draw_time_.InMillisecondsF());
791 state->SetBoolean("last_set_needs_begin_frame_", 792 state->SetBoolean("last_set_needs_begin_frame_",
792 frame_source_->NeedsBeginFrames()); 793 frame_source_->NeedsBeginFrames());
793 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size()); 794 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size());
794 state->SetBoolean("begin_retro_frame_task_", 795 state->SetBoolean("begin_retro_frame_task_",
795 !begin_retro_frame_task_.IsCancelled()); 796 !begin_retro_frame_task_.IsCancelled());
796 state->SetBoolean("begin_impl_frame_deadline_task_", 797 state->SetBoolean("begin_impl_frame_deadline_task_",
797 !begin_impl_frame_deadline_task_.IsCancelled()); 798 !begin_impl_frame_deadline_task_.IsCancelled());
799 state->SetBoolean("poll_for_draw_triggers_task_",
800 !poll_for_draw_triggers_task_.IsCancelled());
798 state->SetBoolean("advance_commit_state_task_", 801 state->SetBoolean("advance_commit_state_task_",
799 !advance_commit_state_task_.IsCancelled()); 802 !advance_commit_state_task_.IsCancelled());
800 state->BeginDictionary("begin_impl_frame_args"); 803 state->BeginDictionary("begin_impl_frame_args");
801 begin_impl_frame_args_.AsValueInto(state); 804 begin_impl_frame_args_.AsValueInto(state);
802 state->EndDictionary(); 805 state->EndDictionary();
803 806
804 base::TimeTicks now = Now(); 807 base::TimeTicks now = Now();
805 base::TimeTicks frame_time = begin_impl_frame_args_.frame_time; 808 base::TimeTicks frame_time = begin_impl_frame_args_.frame_time;
806 base::TimeTicks deadline = begin_impl_frame_args_.deadline; 809 base::TimeTicks deadline = begin_impl_frame_args_.deadline;
807 base::TimeDelta interval = begin_impl_frame_args_.interval; 810 base::TimeDelta interval = begin_impl_frame_args_.interval;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 } 855 }
853 856
854 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 857 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
855 return (state_machine_.commit_state() == 858 return (state_machine_.commit_state() ==
856 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 859 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
857 state_machine_.commit_state() == 860 state_machine_.commit_state() ==
858 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 861 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
859 } 862 }
860 863
861 } // namespace cc 864 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698