Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 } else { | 387 } else { |
| 388 advance_commit_state_task_.Cancel(); | 388 advance_commit_state_task_.Cancel(); |
| 389 } | 389 } |
| 390 } | 390 } |
| 391 | 391 |
| 392 // BeginFrame is the mechanism that tells us that now is a good time to start | 392 // BeginFrame is the mechanism that tells us that now is a good time to start |
| 393 // making a frame. Usually this means that user input for the frame is complete. | 393 // making a frame. Usually this means that user input for the frame is complete. |
| 394 // If the scheduler is busy, we queue the BeginFrame to be handled later as | 394 // If the scheduler is busy, we queue the BeginFrame to be handled later as |
| 395 // a BeginRetroFrame. | 395 // a BeginRetroFrame. |
| 396 void Scheduler::BeginFrame(const BeginFrameArgs& args) { | 396 void Scheduler::BeginFrame(const BeginFrameArgs& args) { |
| 397 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "frame_time", args.frame_time); | 397 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", ToTrace(args)); |
| 398 DCHECK(settings_.throttle_frame_production); | 398 DCHECK(settings_.throttle_frame_production); |
| 399 | 399 |
| 400 bool should_defer_begin_frame; | 400 bool should_defer_begin_frame; |
| 401 if (settings_.using_synchronous_renderer_compositor) { | 401 if (settings_.using_synchronous_renderer_compositor) { |
| 402 should_defer_begin_frame = false; | 402 should_defer_begin_frame = false; |
| 403 } else { | 403 } else { |
| 404 should_defer_begin_frame = | 404 should_defer_begin_frame = |
| 405 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || | 405 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || |
| 406 !last_set_needs_begin_frame_ || | 406 !last_set_needs_begin_frame_ || |
| 407 (state_machine_.begin_impl_frame_state() != | 407 (state_machine_.begin_impl_frame_state() != |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 481 return; | 481 return; |
| 482 | 482 |
| 483 begin_retro_frame_posted_ = true; | 483 begin_retro_frame_posted_ = true; |
| 484 impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_); | 484 impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_); |
| 485 } | 485 } |
| 486 | 486 |
| 487 // BeginImplFrame starts a compositor frame that will wait up until a deadline | 487 // BeginImplFrame starts a compositor frame that will wait up until a deadline |
| 488 // for a BeginMainFrame+activation to complete before it times out and draws | 488 // for a BeginMainFrame+activation to complete before it times out and draws |
| 489 // any asynchronous animation and scroll/pinch updates. | 489 // any asynchronous animation and scroll/pinch updates. |
| 490 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { | 490 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
| 491 TRACE_EVENT1( | 491 TRACE_EVENT1("cc", "Scheduler::BeginImplFrame", "args", ToTrace(args)); |
| 492 "cc", "Scheduler::BeginImplFrame", "frame_time", args.frame_time); | |
| 493 DCHECK(state_machine_.begin_impl_frame_state() == | 492 DCHECK(state_machine_.begin_impl_frame_state() == |
| 494 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 493 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
| 495 DCHECK(state_machine_.HasInitializedOutputSurface()); | 494 DCHECK(state_machine_.HasInitializedOutputSurface()); |
| 496 | 495 |
| 497 advance_commit_state_task_.Cancel(); | 496 advance_commit_state_task_.Cancel(); |
| 498 | 497 |
| 499 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate(); | 498 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate(); |
| 500 begin_impl_frame_args_ = args; | 499 begin_impl_frame_args_ = args; |
| 501 begin_impl_frame_args_.deadline -= draw_duration_estimate; | 500 begin_impl_frame_args_.deadline -= draw_duration_estimate; |
| 502 | 501 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 623 | 622 |
| 624 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); | 623 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); |
| 625 | 624 |
| 626 SchedulerStateMachine::Action action; | 625 SchedulerStateMachine::Action action; |
| 627 do { | 626 do { |
| 628 state_machine_.CheckInvariants(); | 627 state_machine_.CheckInvariants(); |
| 629 action = state_machine_.NextAction(); | 628 action = state_machine_.NextAction(); |
| 630 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 629 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
| 631 "SchedulerStateMachine", | 630 "SchedulerStateMachine", |
| 632 "state", | 631 "state", |
| 633 TracedValue::FromValue(StateAsValue().release())); | 632 ToTrace(this)); |
| 634 state_machine_.UpdateState(action); | 633 state_machine_.UpdateState(action); |
| 635 base::AutoReset<SchedulerStateMachine::Action> | 634 base::AutoReset<SchedulerStateMachine::Action> |
| 636 mark_inside_action(&inside_action_, action); | 635 mark_inside_action(&inside_action_, action); |
| 637 switch (action) { | 636 switch (action) { |
| 638 case SchedulerStateMachine::ACTION_NONE: | 637 case SchedulerStateMachine::ACTION_NONE: |
| 639 break; | 638 break; |
| 640 case SchedulerStateMachine::ACTION_ANIMATE: | 639 case SchedulerStateMachine::ACTION_ANIMATE: |
| 641 client_->ScheduledActionAnimate(); | 640 client_->ScheduledActionAnimate(); |
| 642 break; | 641 break; |
| 643 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: | 642 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 680 if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { | 679 if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { |
| 681 DCHECK(!settings_.using_synchronous_renderer_compositor); | 680 DCHECK(!settings_.using_synchronous_renderer_compositor); |
| 682 ScheduleBeginImplFrameDeadline(base::TimeTicks()); | 681 ScheduleBeginImplFrameDeadline(base::TimeTicks()); |
| 683 } | 682 } |
| 684 } | 683 } |
| 685 | 684 |
| 686 bool Scheduler::WillDrawIfNeeded() const { | 685 bool Scheduler::WillDrawIfNeeded() const { |
| 687 return !state_machine_.PendingDrawsShouldBeAborted(); | 686 return !state_machine_.PendingDrawsShouldBeAborted(); |
| 688 } | 687 } |
| 689 | 688 |
| 690 scoped_ptr<base::Value> Scheduler::StateAsValue() const { | 689 scoped_ptr<base::Value> Scheduler::StateAsValue() const { |
|
brianderson
2014/05/08 21:25:49
Feel free to rename this to AsValue() - I think As
| |
| 691 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); | 690 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); |
| 692 state->Set("state_machine", state_machine_.AsValue().release()); | 691 state->Set("state_machine", state_machine_.AsValue().release()); |
| 693 | 692 |
| 694 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue); | 693 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue); |
| 695 scheduler_state->SetDouble( | 694 scheduler_state->SetDouble( |
| 696 "time_until_anticipated_draw_time_ms", | 695 "time_until_anticipated_draw_time_ms", |
| 697 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); | 696 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); |
| 698 scheduler_state->SetDouble("vsync_interval_ms", | 697 scheduler_state->SetDouble("vsync_interval_ms", |
| 699 vsync_interval_.InMillisecondsF()); | 698 vsync_interval_.InMillisecondsF()); |
| 700 scheduler_state->SetDouble("estimated_parent_draw_time_ms", | 699 scheduler_state->SetDouble("estimated_parent_draw_time_ms", |
| 701 estimated_parent_draw_time_.InMillisecondsF()); | 700 estimated_parent_draw_time_.InMillisecondsF()); |
| 702 scheduler_state->SetBoolean("last_set_needs_begin_frame_", | 701 scheduler_state->SetBoolean("last_set_needs_begin_frame_", |
| 703 last_set_needs_begin_frame_); | 702 last_set_needs_begin_frame_); |
| 704 scheduler_state->SetBoolean("begin_unthrottled_frame_posted_", | 703 scheduler_state->SetBoolean("begin_unthrottled_frame_posted_", |
| 705 begin_unthrottled_frame_posted_); | 704 begin_unthrottled_frame_posted_); |
| 706 scheduler_state->SetBoolean("begin_retro_frame_posted_", | 705 scheduler_state->SetBoolean("begin_retro_frame_posted_", |
| 707 begin_retro_frame_posted_); | 706 begin_retro_frame_posted_); |
| 708 scheduler_state->SetInteger("begin_retro_frame_args_", | 707 scheduler_state->SetInteger("begin_retro_frame_args_", |
| 709 begin_retro_frame_args_.size()); | 708 begin_retro_frame_args_.size()); |
| 710 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_", | 709 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_", |
| 711 !begin_impl_frame_deadline_task_.IsCancelled()); | 710 !begin_impl_frame_deadline_task_.IsCancelled()); |
| 712 scheduler_state->SetBoolean("poll_for_draw_triggers_task_", | 711 scheduler_state->SetBoolean("poll_for_draw_triggers_task_", |
| 713 !poll_for_draw_triggers_task_.IsCancelled()); | 712 !poll_for_draw_triggers_task_.IsCancelled()); |
| 714 scheduler_state->SetBoolean("advance_commit_state_task_", | 713 scheduler_state->SetBoolean("advance_commit_state_task_", |
| 715 !advance_commit_state_task_.IsCancelled()); | 714 !advance_commit_state_task_.IsCancelled()); |
| 715 scheduler_state->Set("begin_impl_frame_args", | |
| 716 begin_impl_frame_args_.StateAsValue().release()); | |
| 717 | |
| 716 state->Set("scheduler_state", scheduler_state.release()); | 718 state->Set("scheduler_state", scheduler_state.release()); |
| 717 | 719 |
| 718 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue); | 720 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue); |
| 719 client_state->SetDouble("draw_duration_estimate_ms", | 721 client_state->SetDouble("draw_duration_estimate_ms", |
| 720 client_->DrawDurationEstimate().InMillisecondsF()); | 722 client_->DrawDurationEstimate().InMillisecondsF()); |
| 721 client_state->SetDouble( | 723 client_state->SetDouble( |
| 722 "begin_main_frame_to_commit_duration_estimate_ms", | 724 "begin_main_frame_to_commit_duration_estimate_ms", |
| 723 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); | 725 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); |
| 724 client_state->SetDouble( | 726 client_state->SetDouble( |
| 725 "commit_to_activate_duration_estimate_ms", | 727 "commit_to_activate_duration_estimate_ms", |
| 726 client_->CommitToActivateDurationEstimate().InMillisecondsF()); | 728 client_->CommitToActivateDurationEstimate().InMillisecondsF()); |
| 727 state->Set("client_state", client_state.release()); | 729 state->Set("client_state", client_state.release()); |
| 728 return state.PassAs<base::Value>(); | 730 return state.PassAs<base::Value>(); |
| 729 } | 731 } |
| 730 | 732 |
| 731 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { | 733 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { |
| 732 // Check if the main thread computation and commit can be finished before the | 734 // Check if the main thread computation and commit can be finished before the |
| 733 // impl thread's deadline. | 735 // impl thread's deadline. |
| 734 base::TimeTicks estimated_draw_time = | 736 base::TimeTicks estimated_draw_time = |
| 735 begin_impl_frame_args_.frame_time + | 737 begin_impl_frame_args_.frame_time + |
| 736 client_->BeginMainFrameToCommitDurationEstimate() + | 738 client_->BeginMainFrameToCommitDurationEstimate() + |
| 737 client_->CommitToActivateDurationEstimate(); | 739 client_->CommitToActivateDurationEstimate(); |
| 738 | 740 |
| 739 TRACE_EVENT2( | 741 TRACE_EVENT2( |
| 740 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 742 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
| 741 "CanCommitAndActivateBeforeDeadline", | 743 "CanCommitAndActivateBeforeDeadline", |
| 742 "time_left_after_drawing_ms", | 744 "time_left_after_drawing_ms", |
| 743 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(), | 745 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(), |
| 744 "state", | 746 "state", |
| 745 TracedValue::FromValue(StateAsValue().release())); | 747 ToTrace(this)); |
| 746 | 748 |
| 747 return estimated_draw_time < begin_impl_frame_args_.deadline; | 749 return estimated_draw_time < begin_impl_frame_args_.deadline; |
| 748 } | 750 } |
| 749 | 751 |
| 750 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 752 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
| 751 return (state_machine_.commit_state() == | 753 return (state_machine_.commit_state() == |
| 752 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 754 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
| 753 state_machine_.commit_state() == | 755 state_machine_.commit_state() == |
| 754 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 756 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
| 755 } | 757 } |
| 756 | 758 |
| 757 } // namespace cc | 759 } // namespace cc |
| OLD | NEW |