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 | |
| 8 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 9 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| 10 #include "base/debug/trace_event_argument.h" | 11 #include "base/debug/trace_event_argument.h" |
| 11 #include "base/logging.h" | 12 #include "base/logging.h" |
| 12 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
| 13 #include "cc/debug/devtools_instrumentation.h" | 14 #include "cc/debug/devtools_instrumentation.h" |
| 14 #include "cc/debug/traced_value.h" | 15 #include "cc/debug/traced_value.h" |
| 15 #include "cc/scheduler/delay_based_time_source.h" | 16 #include "cc/scheduler/delay_based_time_source.h" |
| 16 #include "ui/gfx/frame_time.h" | 17 #include "ui/gfx/frame_time.h" |
| 17 | 18 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 base::TimeTicks frame_time) { | 73 base::TimeTicks frame_time) { |
| 73 base::TimeTicks deadline = time_source_->NextTickTime(); | 74 base::TimeTicks deadline = time_source_->NextTickTime(); |
| 74 return BeginFrameArgs::Create( | 75 return BeginFrameArgs::Create( |
| 75 frame_time, deadline, scheduler_->VSyncInterval()); | 76 frame_time, deadline, scheduler_->VSyncInterval()); |
| 76 } | 77 } |
| 77 | 78 |
| 78 Scheduler::Scheduler( | 79 Scheduler::Scheduler( |
| 79 SchedulerClient* client, | 80 SchedulerClient* client, |
| 80 const SchedulerSettings& scheduler_settings, | 81 const SchedulerSettings& scheduler_settings, |
| 81 int layer_tree_host_id, | 82 int layer_tree_host_id, |
| 82 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) | 83 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 84 BeginFrameManager* begin_frame_manager) | |
| 83 : settings_(scheduler_settings), | 85 : settings_(scheduler_settings), |
| 84 client_(client), | 86 client_(client), |
| 85 layer_tree_host_id_(layer_tree_host_id), | 87 layer_tree_host_id_(layer_tree_host_id), |
| 86 task_runner_(task_runner), | 88 task_runner_(task_runner), |
| 87 vsync_interval_(BeginFrameArgs::DefaultInterval()), | 89 vsync_interval_(BeginFrameArgs::DefaultInterval()), |
| 90 authoritative_vsync_interval_(base::TimeDelta()), | |
| 88 last_set_needs_begin_frame_(false), | 91 last_set_needs_begin_frame_(false), |
| 89 begin_unthrottled_frame_posted_(false), | 92 begin_unthrottled_frame_posted_(false), |
| 90 begin_retro_frame_posted_(false), | 93 begin_retro_frame_posted_(false), |
| 91 state_machine_(scheduler_settings), | 94 state_machine_(scheduler_settings), |
| 92 inside_process_scheduled_actions_(false), | 95 inside_process_scheduled_actions_(false), |
| 93 inside_action_(SchedulerStateMachine::ACTION_NONE), | 96 inside_action_(SchedulerStateMachine::ACTION_NONE), |
| 97 begin_frame_manager_(begin_frame_manager), | |
| 94 weak_factory_(this) { | 98 weak_factory_(this) { |
| 95 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 99 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
| 96 "Scheduler::Scheduler", | 100 "Scheduler::Scheduler", |
| 97 "settings", | 101 "settings", |
| 98 settings_.AsValue()); | 102 settings_.AsValue()); |
| 99 DCHECK(client_); | 103 DCHECK(client_); |
| 100 DCHECK(!state_machine_.BeginFrameNeeded()); | 104 DCHECK(!state_machine_.BeginFrameNeeded()); |
| 101 if (settings_.main_frame_before_activation_enabled) { | 105 if (settings_.main_frame_before_activation_enabled) { |
| 102 DCHECK(settings_.main_frame_before_draw_enabled); | 106 DCHECK(settings_.main_frame_before_draw_enabled); |
| 103 } | 107 } |
| 104 | 108 if (settings_.begin_frame_publisher) { |
| 109 DCHECK(begin_frame_manager_); | |
| 110 begin_frame_manager_->set_delegate(this); | |
| 111 } | |
| 105 begin_retro_frame_closure_ = | 112 begin_retro_frame_closure_ = |
| 106 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); | 113 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); |
| 107 begin_unthrottled_frame_closure_ = | 114 begin_unthrottled_frame_closure_ = |
| 108 base::Bind(&Scheduler::BeginUnthrottledFrame, weak_factory_.GetWeakPtr()); | 115 base::Bind(&Scheduler::BeginUnthrottledFrame, weak_factory_.GetWeakPtr()); |
| 109 begin_impl_frame_deadline_closure_ = base::Bind( | 116 begin_impl_frame_deadline_closure_ = base::Bind( |
| 110 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); | 117 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); |
| 111 poll_for_draw_triggers_closure_ = base::Bind( | 118 poll_for_draw_triggers_closure_ = base::Bind( |
| 112 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); | 119 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); |
| 113 advance_commit_state_closure_ = base::Bind( | 120 advance_commit_state_closure_ = base::Bind( |
| 114 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); | 121 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); |
| 115 | 122 |
| 116 if (!settings_.begin_frame_scheduling_enabled) { | 123 if (!settings_.begin_frame_receiver) |
| 117 SetupSyntheticBeginFrames(); | 124 SetupSyntheticBeginFrames(); |
| 118 } | |
| 119 } | 125 } |
| 120 | 126 |
| 121 Scheduler::~Scheduler() { | 127 Scheduler::~Scheduler() { |
| 122 if (synthetic_begin_frame_source_) { | 128 if (synthetic_begin_frame_source_) { |
| 123 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, | 129 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, |
| 124 &begin_retro_frame_args_); | 130 &begin_retro_frame_args_); |
| 125 } | 131 } |
| 126 } | 132 } |
| 127 | 133 |
| 128 void Scheduler::SetupSyntheticBeginFrames() { | 134 void Scheduler::SetupSyntheticBeginFrames() { |
| 129 DCHECK(!synthetic_begin_frame_source_); | 135 DCHECK(!synthetic_begin_frame_source_); |
| 130 synthetic_begin_frame_source_.reset( | 136 synthetic_begin_frame_source_.reset( |
| 131 new SyntheticBeginFrameSource(this, task_runner_.get())); | 137 new SyntheticBeginFrameSource(this, task_runner_.get())); |
| 132 } | 138 } |
| 133 | 139 |
| 134 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, | 140 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, |
| 135 base::TimeDelta interval) { | 141 base::TimeDelta interval) { |
| 136 // TODO(brianderson): We should not be receiving 0 intervals. | 142 // TODO(brianderson): We should not be receiving 0 intervals. |
| 137 if (interval == base::TimeDelta()) | 143 if (interval == base::TimeDelta()) |
|
brianderson
2014/08/28 02:48:07
Might as well roll this condition into your if/els
simonhong
2014/09/03 21:02:22
Done.
| |
| 138 interval = BeginFrameArgs::DefaultInterval(); | 144 interval = BeginFrameArgs::DefaultInterval(); |
| 139 vsync_interval_ = interval; | 145 |
| 140 if (!settings_.begin_frame_scheduling_enabled) | 146 if (authoritative_vsync_interval_ == base::TimeDelta()) |
| 141 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval); | 147 vsync_interval_ = interval; |
| 148 else | |
| 149 vsync_interval_ = authoritative_vsync_interval_; | |
| 150 | |
| 151 last_timebase_ = timebase; | |
| 152 | |
| 153 if (!settings_.begin_frame_receiver) { | |
| 154 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, | |
| 155 vsync_interval_); | |
| 156 } | |
| 142 } | 157 } |
| 143 | 158 |
| 144 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { | 159 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { |
| 145 DCHECK_GE(draw_time.ToInternalValue(), 0); | 160 DCHECK_GE(draw_time.ToInternalValue(), 0); |
| 146 estimated_parent_draw_time_ = draw_time; | 161 estimated_parent_draw_time_ = draw_time; |
| 147 } | 162 } |
| 148 | 163 |
| 149 void Scheduler::SetCanStart() { | 164 void Scheduler::SetCanStart() { |
| 150 state_machine_.SetCanStart(); | 165 state_machine_.SetCanStart(); |
| 151 ProcessScheduledActions(); | 166 ProcessScheduledActions(); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 } | 244 } |
| 230 | 245 |
| 231 void Scheduler::DidManageTiles() { | 246 void Scheduler::DidManageTiles() { |
| 232 state_machine_.DidManageTiles(); | 247 state_machine_.DidManageTiles(); |
| 233 } | 248 } |
| 234 | 249 |
| 235 void Scheduler::DidLoseOutputSurface() { | 250 void Scheduler::DidLoseOutputSurface() { |
| 236 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); | 251 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); |
| 237 state_machine_.DidLoseOutputSurface(); | 252 state_machine_.DidLoseOutputSurface(); |
| 238 last_set_needs_begin_frame_ = false; | 253 last_set_needs_begin_frame_ = false; |
| 239 if (!settings_.begin_frame_scheduling_enabled) { | 254 if (!settings_.begin_frame_receiver) { |
| 240 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, | 255 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, |
| 241 &begin_retro_frame_args_); | 256 &begin_retro_frame_args_); |
| 242 } | 257 } |
| 243 begin_retro_frame_args_.clear(); | 258 begin_retro_frame_args_.clear(); |
| 244 ProcessScheduledActions(); | 259 ProcessScheduledActions(); |
| 245 } | 260 } |
| 246 | 261 |
| 247 void Scheduler::DidCreateAndInitializeOutputSurface() { | 262 void Scheduler::DidCreateAndInitializeOutputSurface() { |
| 248 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); | 263 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); |
| 249 DCHECK(!last_set_needs_begin_frame_); | 264 DCHECK(!last_set_needs_begin_frame_); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 state_machine_.begin_impl_frame_state() == | 310 state_machine_.begin_impl_frame_state() == |
| 296 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; | 311 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; |
| 297 | 312 |
| 298 bool should_call_set_needs_begin_frame = | 313 bool should_call_set_needs_begin_frame = |
| 299 // Always request the BeginFrame immediately if it wasn't needed before. | 314 // Always request the BeginFrame immediately if it wasn't needed before. |
| 300 (needs_begin_frame && !last_set_needs_begin_frame_) || | 315 (needs_begin_frame && !last_set_needs_begin_frame_) || |
| 301 // Only stop requesting BeginFrames after a deadline. | 316 // Only stop requesting BeginFrames after a deadline. |
| 302 (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline); | 317 (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline); |
| 303 | 318 |
| 304 if (should_call_set_needs_begin_frame) { | 319 if (should_call_set_needs_begin_frame) { |
| 305 if (settings_.begin_frame_scheduling_enabled) { | 320 if (settings_.begin_frame_receiver) { |
| 306 client_->SetNeedsBeginFrame(needs_begin_frame); | 321 client_->SetNeedsBeginFrame(needs_begin_frame); |
| 307 } else { | 322 } else { |
| 308 synthetic_begin_frame_source_->SetNeedsBeginFrame( | 323 synthetic_begin_frame_source_->SetNeedsBeginFrame( |
| 309 needs_begin_frame, &begin_retro_frame_args_); | 324 needs_begin_frame, &begin_retro_frame_args_); |
| 310 } | 325 } |
| 311 last_set_needs_begin_frame_ = needs_begin_frame; | 326 last_set_needs_begin_frame_ = needs_begin_frame; |
| 312 } | 327 } |
| 313 | 328 |
| 314 PostBeginRetroFrameIfNeeded(); | 329 PostBeginRetroFrameIfNeeded(); |
| 315 } | 330 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 | 416 |
| 402 // BeginFrame is the mechanism that tells us that now is a good time to start | 417 // BeginFrame is the mechanism that tells us that now is a good time to start |
| 403 // making a frame. Usually this means that user input for the frame is complete. | 418 // making a frame. Usually this means that user input for the frame is complete. |
| 404 // If the scheduler is busy, we queue the BeginFrame to be handled later as | 419 // If the scheduler is busy, we queue the BeginFrame to be handled later as |
| 405 // a BeginRetroFrame. | 420 // a BeginRetroFrame. |
| 406 void Scheduler::BeginFrame(const BeginFrameArgs& args) { | 421 void Scheduler::BeginFrame(const BeginFrameArgs& args) { |
| 407 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue()); | 422 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue()); |
| 408 DCHECK(settings_.throttle_frame_production); | 423 DCHECK(settings_.throttle_frame_production); |
| 409 | 424 |
| 410 BeginFrameArgs adjusted_args(args); | 425 BeginFrameArgs adjusted_args(args); |
| 426 | |
| 427 if (settings_.begin_frame_publisher && | |
| 428 state_machine_.children_need_begin_frames()) { | |
| 429 // |arg.deadline| should be adjusted by child Scheduler. | |
|
brianderson
2014/08/28 02:48:07
Today, the deadline the Browser sends to the Rende
simonhong
2014/09/03 21:02:22
Done.
| |
| 430 begin_frame_manager_->SendBeginFrameToChildren(args); | |
| 431 } | |
| 432 | |
| 411 adjusted_args.deadline -= EstimatedParentDrawTime(); | 433 adjusted_args.deadline -= EstimatedParentDrawTime(); |
| 412 | 434 |
| 413 bool should_defer_begin_frame; | 435 bool should_defer_begin_frame; |
| 414 if (settings_.using_synchronous_renderer_compositor) { | 436 if (settings_.using_synchronous_renderer_compositor) { |
| 415 should_defer_begin_frame = false; | 437 should_defer_begin_frame = false; |
| 416 } else { | 438 } else { |
| 417 should_defer_begin_frame = | 439 should_defer_begin_frame = |
| 418 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || | 440 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || |
| 419 !last_set_needs_begin_frame_ || | 441 !last_set_needs_begin_frame_ || |
| 420 (state_machine_.begin_impl_frame_state() != | 442 (state_machine_.begin_impl_frame_state() != |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 605 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); | 627 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); |
| 606 advance_commit_state_task_.Cancel(); | 628 advance_commit_state_task_.Cancel(); |
| 607 ProcessScheduledActions(); | 629 ProcessScheduledActions(); |
| 608 } | 630 } |
| 609 | 631 |
| 610 bool Scheduler::IsBeginMainFrameSent() const { | 632 bool Scheduler::IsBeginMainFrameSent() const { |
| 611 return state_machine_.commit_state() == | 633 return state_machine_.commit_state() == |
| 612 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; | 634 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; |
| 613 } | 635 } |
| 614 | 636 |
| 637 void Scheduler::SetChildrenNeedBeginFrames(bool need_begin_frame) { | |
| 638 DCHECK(settings_.begin_frame_publisher); | |
| 639 | |
| 640 state_machine_.SetChildrenNeedBeginFrames(need_begin_frame); | |
| 641 ProcessScheduledActions(); | |
| 642 } | |
| 643 | |
| 644 void Scheduler::SetAuthoritativeVSyncInterval(base::TimeDelta interval) { | |
| 645 authoritative_vsync_interval_ = interval; | |
| 646 vsync_interval_ = interval; | |
| 647 | |
| 648 if (!settings_.begin_frame_receiver) { | |
| 649 synthetic_begin_frame_source_->CommitVSyncParameters(last_timebase_, | |
| 650 interval); | |
| 651 } | |
| 652 } | |
| 653 | |
| 654 void Scheduler::StartBeginFrame(const BeginFrameArgs& args) { | |
| 655 DCHECK(settings_.begin_frame_publisher && settings_.using_platform_vsync); | |
| 656 BeginFrame(args); | |
| 657 } | |
| 658 | |
| 615 void Scheduler::DrawAndSwapIfPossible() { | 659 void Scheduler::DrawAndSwapIfPossible() { |
| 616 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); | 660 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); |
| 617 state_machine_.DidDrawIfPossibleCompleted(result); | 661 state_machine_.DidDrawIfPossibleCompleted(result); |
| 618 } | 662 } |
| 619 | 663 |
| 620 void Scheduler::ProcessScheduledActions() { | 664 void Scheduler::ProcessScheduledActions() { |
| 621 // We do not allow ProcessScheduledActions to be recursive. | 665 // We do not allow ProcessScheduledActions to be recursive. |
| 622 // The top-level call will iteratively execute the next action for us anyway. | 666 // The top-level call will iteratively execute the next action for us anyway. |
| 623 if (inside_process_scheduled_actions_) | 667 if (inside_process_scheduled_actions_) |
| 624 return; | 668 return; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 755 } | 799 } |
| 756 | 800 |
| 757 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 801 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
| 758 return (state_machine_.commit_state() == | 802 return (state_machine_.commit_state() == |
| 759 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 803 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
| 760 state_machine_.commit_state() == | 804 state_machine_.commit_state() == |
| 761 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 805 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
| 762 } | 806 } |
| 763 | 807 |
| 764 } // namespace cc | 808 } // namespace cc |
| OLD | NEW |