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 |