| 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 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 begin_retro_frame_closure_ = | 66 begin_retro_frame_closure_ = |
| 67 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); | 67 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); |
| 68 begin_impl_frame_deadline_closure_ = base::Bind( | 68 begin_impl_frame_deadline_closure_ = base::Bind( |
| 69 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); | 69 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); |
| 70 | 70 |
| 71 SetBeginFrameSource(begin_frame_source); | 71 SetBeginFrameSource(begin_frame_source); |
| 72 ProcessScheduledActions(); | 72 ProcessScheduledActions(); |
| 73 } | 73 } |
| 74 | 74 |
| 75 Scheduler::~Scheduler() { | 75 Scheduler::~Scheduler() { |
| 76 if (observing_begin_frame_source_) | 76 SetBeginFrameSource(nullptr); |
| 77 begin_frame_source_->RemoveObserver(this); | |
| 78 } | 77 } |
| 79 | 78 |
| 80 base::TimeTicks Scheduler::Now() const { | 79 base::TimeTicks Scheduler::Now() const { |
| 81 base::TimeTicks now = base::TimeTicks::Now(); | 80 base::TimeTicks now = base::TimeTicks::Now(); |
| 82 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"), | 81 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"), |
| 83 "Scheduler::Now", | 82 "Scheduler::Now", |
| 84 "now", | 83 "now", |
| 85 now); | 84 now); |
| 86 return now; | 85 return now; |
| 87 } | 86 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 108 ProcessScheduledActions(); | 107 ProcessScheduledActions(); |
| 109 } | 108 } |
| 110 | 109 |
| 111 void Scheduler::NotifyReadyToDraw() { | 110 void Scheduler::NotifyReadyToDraw() { |
| 112 // Future work might still needed for crbug.com/352894. | 111 // Future work might still needed for crbug.com/352894. |
| 113 state_machine_.NotifyReadyToDraw(); | 112 state_machine_.NotifyReadyToDraw(); |
| 114 ProcessScheduledActions(); | 113 ProcessScheduledActions(); |
| 115 } | 114 } |
| 116 | 115 |
| 117 void Scheduler::SetBeginFrameSource(BeginFrameSource* source) { | 116 void Scheduler::SetBeginFrameSource(BeginFrameSource* source) { |
| 118 DCHECK(source); | |
| 119 if (source == begin_frame_source_) | 117 if (source == begin_frame_source_) |
| 120 return; | 118 return; |
| 121 if (begin_frame_source_ && observing_begin_frame_source_) | 119 if (begin_frame_source_ && observing_begin_frame_source_) |
| 122 begin_frame_source_->RemoveObserver(this); | 120 begin_frame_source_->RemoveObserver(this); |
| 123 begin_frame_source_ = source; | 121 begin_frame_source_ = source; |
| 122 if (!begin_frame_source_) |
| 123 return; |
| 124 if (observing_begin_frame_source_) | 124 if (observing_begin_frame_source_) |
| 125 begin_frame_source_->AddObserver(this); | 125 begin_frame_source_->AddObserver(this); |
| 126 } | 126 } |
| 127 | 127 |
| 128 void Scheduler::SetNeedsBeginMainFrame() { | 128 void Scheduler::SetNeedsBeginMainFrame() { |
| 129 state_machine_.SetNeedsBeginMainFrame(); | 129 state_machine_.SetNeedsBeginMainFrame(); |
| 130 ProcessScheduledActions(); | 130 ProcessScheduledActions(); |
| 131 } | 131 } |
| 132 | 132 |
| 133 void Scheduler::SetNeedsOneBeginImplFrame() { | 133 void Scheduler::SetNeedsOneBeginImplFrame() { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 client_->SendBeginMainFrameNotExpectedSoon(); | 238 client_->SendBeginMainFrameNotExpectedSoon(); |
| 239 } | 239 } |
| 240 | 240 |
| 241 void Scheduler::SetupNextBeginFrameIfNeeded() { | 241 void Scheduler::SetupNextBeginFrameIfNeeded() { |
| 242 // Never call SetNeedsBeginFrames if the frame source already has the right | 242 // Never call SetNeedsBeginFrames if the frame source already has the right |
| 243 // value. | 243 // value. |
| 244 if (observing_begin_frame_source_ != state_machine_.BeginFrameNeeded()) { | 244 if (observing_begin_frame_source_ != state_machine_.BeginFrameNeeded()) { |
| 245 if (state_machine_.BeginFrameNeeded()) { | 245 if (state_machine_.BeginFrameNeeded()) { |
| 246 // Call AddObserver as soon as possible. | 246 // Call AddObserver as soon as possible. |
| 247 observing_begin_frame_source_ = true; | 247 observing_begin_frame_source_ = true; |
| 248 begin_frame_source_->AddObserver(this); | 248 if (begin_frame_source_) |
| 249 begin_frame_source_->AddObserver(this); |
| 249 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, | 250 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, |
| 250 true); | 251 true); |
| 251 } else if (state_machine_.begin_impl_frame_state() == | 252 } else if (state_machine_.begin_impl_frame_state() == |
| 252 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { | 253 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { |
| 253 // Call RemoveObserver in between frames only. | 254 // Call RemoveObserver in between frames only. |
| 254 observing_begin_frame_source_ = false; | 255 observing_begin_frame_source_ = false; |
| 255 begin_frame_source_->RemoveObserver(this); | 256 if (begin_frame_source_) |
| 257 begin_frame_source_->RemoveObserver(this); |
| 256 BeginImplFrameNotExpectedSoon(); | 258 BeginImplFrameNotExpectedSoon(); |
| 257 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, | 259 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, |
| 258 false); | 260 false); |
| 259 } | 261 } |
| 260 } | 262 } |
| 261 | 263 |
| 262 PostBeginRetroFrameIfNeeded(); | 264 PostBeginRetroFrameIfNeeded(); |
| 263 } | 265 } |
| 264 | 266 |
| 265 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { | 267 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 while (!begin_retro_frame_args_.empty()) { | 376 while (!begin_retro_frame_args_.empty()) { |
| 375 const BeginFrameArgs& args = begin_retro_frame_args_.front(); | 377 const BeginFrameArgs& args = begin_retro_frame_args_.front(); |
| 376 base::TimeTicks expiration_time = args.deadline; | 378 base::TimeTicks expiration_time = args.deadline; |
| 377 if (now <= expiration_time) | 379 if (now <= expiration_time) |
| 378 break; | 380 break; |
| 379 TRACE_EVENT_INSTANT2( | 381 TRACE_EVENT_INSTANT2( |
| 380 "cc", "Scheduler::BeginRetroFrame discarding", TRACE_EVENT_SCOPE_THREAD, | 382 "cc", "Scheduler::BeginRetroFrame discarding", TRACE_EVENT_SCOPE_THREAD, |
| 381 "expiration_time - now", (expiration_time - now).InMillisecondsF(), | 383 "expiration_time - now", (expiration_time - now).InMillisecondsF(), |
| 382 "BeginFrameArgs", begin_retro_frame_args_.front().AsValue()); | 384 "BeginFrameArgs", begin_retro_frame_args_.front().AsValue()); |
| 383 begin_retro_frame_args_.pop_front(); | 385 begin_retro_frame_args_.pop_front(); |
| 384 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | 386 if (begin_frame_source_) |
| 387 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); |
| 385 } | 388 } |
| 386 | 389 |
| 387 if (begin_retro_frame_args_.empty()) { | 390 if (begin_retro_frame_args_.empty()) { |
| 388 TRACE_EVENT_INSTANT0("cc", | 391 TRACE_EVENT_INSTANT0("cc", |
| 389 "Scheduler::BeginRetroFrames all expired", | 392 "Scheduler::BeginRetroFrames all expired", |
| 390 TRACE_EVENT_SCOPE_THREAD); | 393 TRACE_EVENT_SCOPE_THREAD); |
| 391 } else { | 394 } else { |
| 392 BeginFrameArgs front = begin_retro_frame_args_.front(); | 395 BeginFrameArgs front = begin_retro_frame_args_.front(); |
| 393 begin_retro_frame_args_.pop_front(); | 396 begin_retro_frame_args_.pop_front(); |
| 394 BeginImplFrameWithDeadline(front); | 397 BeginImplFrameWithDeadline(front); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 bmf_to_activate_estimate); | 470 bmf_to_activate_estimate); |
| 468 | 471 |
| 469 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { | 472 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { |
| 470 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", | 473 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", |
| 471 TRACE_EVENT_SCOPE_THREAD); | 474 TRACE_EVENT_SCOPE_THREAD); |
| 472 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); | 475 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
| 473 } else if (ShouldRecoverImplLatency(adjusted_args, | 476 } else if (ShouldRecoverImplLatency(adjusted_args, |
| 474 can_activate_before_deadline)) { | 477 can_activate_before_deadline)) { |
| 475 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", | 478 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", |
| 476 TRACE_EVENT_SCOPE_THREAD); | 479 TRACE_EVENT_SCOPE_THREAD); |
| 477 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | 480 if (begin_frame_source_) |
| 481 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); |
| 478 return; | 482 return; |
| 479 } | 483 } |
| 480 | 484 |
| 481 BeginImplFrame(adjusted_args); | 485 BeginImplFrame(adjusted_args); |
| 482 | 486 |
| 483 // The deadline will be scheduled in ProcessScheduledActions. | 487 // The deadline will be scheduled in ProcessScheduledActions. |
| 484 state_machine_.OnBeginImplFrameDeadlinePending(); | 488 state_machine_.OnBeginImplFrameDeadlinePending(); |
| 485 ProcessScheduledActions(); | 489 ProcessScheduledActions(); |
| 486 } | 490 } |
| 487 | 491 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 499 compositor_timing_history_->WillFinishImplFrame( | 503 compositor_timing_history_->WillFinishImplFrame( |
| 500 state_machine_.needs_redraw()); | 504 state_machine_.needs_redraw()); |
| 501 FinishImplFrame(); | 505 FinishImplFrame(); |
| 502 } | 506 } |
| 503 | 507 |
| 504 void Scheduler::FinishImplFrame() { | 508 void Scheduler::FinishImplFrame() { |
| 505 state_machine_.OnBeginImplFrameIdle(); | 509 state_machine_.OnBeginImplFrameIdle(); |
| 506 ProcessScheduledActions(); | 510 ProcessScheduledActions(); |
| 507 | 511 |
| 508 client_->DidFinishImplFrame(); | 512 client_->DidFinishImplFrame(); |
| 509 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | 513 if (begin_frame_source_) |
| 514 begin_frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); |
| 510 begin_impl_frame_tracker_.Finish(); | 515 begin_impl_frame_tracker_.Finish(); |
| 511 } | 516 } |
| 512 | 517 |
| 513 // BeginImplFrame starts a compositor frame that will wait up until a deadline | 518 // BeginImplFrame starts a compositor frame that will wait up until a deadline |
| 514 // for a BeginMainFrame+activation to complete before it times out and draws | 519 // for a BeginMainFrame+activation to complete before it times out and draws |
| 515 // any asynchronous animation and scroll/pinch updates. | 520 // any asynchronous animation and scroll/pinch updates. |
| 516 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { | 521 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
| 517 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 522 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
| 518 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 523 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
| 519 DCHECK(!BeginImplFrameDeadlinePending()); | 524 DCHECK(!BeginImplFrameDeadlinePending()); |
| (...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 863 } | 868 } |
| 864 | 869 |
| 865 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 870 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
| 866 return (state_machine_.begin_main_frame_state() == | 871 return (state_machine_.begin_main_frame_state() == |
| 867 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || | 872 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || |
| 868 state_machine_.begin_main_frame_state() == | 873 state_machine_.begin_main_frame_state() == |
| 869 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); | 874 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); |
| 870 } | 875 } |
| 871 | 876 |
| 872 } // namespace cc | 877 } // namespace cc |
| OLD | NEW |