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 |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 315 BeginFrameArgs adjusted_args = args; | 315 BeginFrameArgs adjusted_args = args; |
| 316 // Cancel the missed begin frame task in case the BFS sends a begin frame | 316 // Cancel the missed begin frame task in case the BFS sends a begin frame |
| 317 // before the missed frame task runs. | 317 // before the missed frame task runs. |
| 318 missed_begin_frame_task_.Cancel(); | 318 missed_begin_frame_task_.Cancel(); |
| 319 | 319 |
| 320 base::TimeTicks now = Now(); | 320 base::TimeTicks now = Now(); |
| 321 | 321 |
| 322 // Discard missed begin frames if they are too late. | 322 // Discard missed begin frames if they are too late. |
| 323 if (adjusted_args.type == BeginFrameArgs::MISSED && | 323 if (adjusted_args.type == BeginFrameArgs::MISSED && |
| 324 now > adjusted_args.deadline) { | 324 now > adjusted_args.deadline) { |
| 325 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. | 325 SendBeginFrameAck(adjusted_args, kBeginFrameSkipped); |
| 326 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number, | |
| 327 adjusted_args.sequence_number, 0, false); | |
| 328 begin_frame_source_->DidFinishFrame(this, ack); | |
| 329 return; | 326 return; |
| 330 } | 327 } |
| 331 | 328 |
| 332 // Run the previous deadline if any. | 329 // Run the previous deadline if any. |
| 333 if (state_machine_.begin_impl_frame_state() == | 330 if (state_machine_.begin_impl_frame_state() == |
| 334 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) { | 331 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) { |
| 335 OnBeginImplFrameDeadline(); | 332 OnBeginImplFrameDeadline(); |
| 336 // We may not need begin frames any longer. | 333 // We may not need begin frames any longer. |
| 337 if (!observing_begin_frame_source_) { | 334 if (!observing_begin_frame_source_) { |
|
Eric Seckler
2017/01/18 18:13:03
I'm trying to test this branch (see scheduler_unit
brianderson
2017/01/18 19:53:54
I think it doesn't show up in tests because the te
Eric Seckler
2017/01/18 20:27:23
Hm, I don't think that would help. If there was an
| |
| 338 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. | 335 // We need to confirm the ignored BeginFrame, since we don't have updates. |
| 339 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number, | 336 // To persist the confirmation for future BeginFrameAcks, we let the state |
| 340 adjusted_args.sequence_number, 0, false); | 337 // machine know about the BeginFrame. |
| 341 begin_frame_source_->DidFinishFrame(this, ack); | 338 state_machine_.OnBeginFrameDroppedNotObserving(args.source_id, |
| 339 args.sequence_number); | |
| 340 SendBeginFrameAck(adjusted_args, kBeginFrameSkipped); | |
| 342 return; | 341 return; |
| 343 } | 342 } |
| 344 } | 343 } |
| 345 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 344 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
| 346 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 345 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
| 347 | 346 |
| 348 bool main_thread_is_in_high_latency_mode = | 347 bool main_thread_is_in_high_latency_mode = |
| 349 state_machine_.main_thread_missed_last_deadline(); | 348 state_machine_.main_thread_missed_last_deadline(); |
| 350 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 349 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
| 351 adjusted_args.AsValue(), "main_thread_missed_last_deadline", | 350 adjusted_args.AsValue(), "main_thread_missed_last_deadline", |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 bmf_to_activate_estimate, now); | 389 bmf_to_activate_estimate, now); |
| 391 | 390 |
| 392 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { | 391 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { |
| 393 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", | 392 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", |
| 394 TRACE_EVENT_SCOPE_THREAD); | 393 TRACE_EVENT_SCOPE_THREAD); |
| 395 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); | 394 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
| 396 } else if (ShouldRecoverImplLatency(adjusted_args, | 395 } else if (ShouldRecoverImplLatency(adjusted_args, |
| 397 can_activate_before_deadline)) { | 396 can_activate_before_deadline)) { |
| 398 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", | 397 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", |
| 399 TRACE_EVENT_SCOPE_THREAD); | 398 TRACE_EVENT_SCOPE_THREAD); |
| 400 if (begin_frame_source_) { | 399 SendBeginFrameAck(begin_main_frame_args_, kBeginFrameSkipped); |
| 401 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. | |
| 402 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number, | |
| 403 adjusted_args.sequence_number, 0, false); | |
| 404 begin_frame_source_->DidFinishFrame(this, ack); | |
| 405 } | |
| 406 return; | 400 return; |
| 407 } | 401 } |
| 408 | 402 |
| 409 BeginImplFrame(adjusted_args); | 403 BeginImplFrame(adjusted_args); |
| 410 } | 404 } |
| 411 | 405 |
| 412 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { | 406 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { |
| 413 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 407 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
| 414 args.AsValue()); | 408 args.AsValue()); |
| 415 | 409 |
| 416 // The main thread currently can't commit before we draw with the | 410 // The main thread currently can't commit before we draw with the |
| 417 // synchronous compositor, so never consider the BeginMainFrame fast. | 411 // synchronous compositor, so never consider the BeginMainFrame fast. |
| 418 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); | 412 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); |
| 419 begin_main_frame_args_ = args; | 413 begin_main_frame_args_ = args; |
| 420 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); | 414 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); |
| 421 | 415 |
| 422 BeginImplFrame(args); | 416 BeginImplFrame(args); |
| 423 compositor_timing_history_->WillFinishImplFrame( | 417 compositor_timing_history_->WillFinishImplFrame( |
| 424 state_machine_.needs_redraw()); | 418 state_machine_.needs_redraw()); |
| 425 FinishImplFrame(); | 419 FinishImplFrame(); |
| 426 } | 420 } |
| 427 | 421 |
| 428 void Scheduler::FinishImplFrame() { | 422 void Scheduler::FinishImplFrame() { |
| 429 state_machine_.OnBeginImplFrameIdle(); | 423 state_machine_.OnBeginImplFrameIdle(); |
| 430 ProcessScheduledActions(); | 424 ProcessScheduledActions(); |
| 431 | 425 |
| 432 client_->DidFinishImplFrame(); | 426 client_->DidFinishImplFrame(); |
| 433 if (begin_frame_source_) { | 427 SendBeginFrameAck(begin_main_frame_args_, kBeginFrameFinished); |
| 434 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. | 428 begin_impl_frame_tracker_.Finish(); |
| 435 BeginFrameAck ack(begin_main_frame_args_.source_id, | 429 } |
| 436 begin_main_frame_args_.sequence_number, | 430 |
| 437 begin_main_frame_args_.sequence_number, 0, | 431 void Scheduler::SendBeginFrameAck(const BeginFrameArgs& args, |
| 438 state_machine_.did_submit_in_last_frame()); | 432 BeginFrameResult result) { |
| 439 begin_frame_source_->DidFinishFrame(this, ack); | 433 if (!begin_frame_source_) |
| 434 return; | |
| 435 | |
| 436 uint64_t latest_confirmed_frame = BeginFrameArgs::kInvalidFrameNumber; | |
| 437 if (args.source_id == state_machine_.begin_frame_source_id()) { | |
| 438 latest_confirmed_frame = | |
| 439 state_machine_ | |
| 440 .last_begin_frame_sequence_number_compositor_frame_was_fresh(); | |
| 440 } | 441 } |
| 441 begin_impl_frame_tracker_.Finish(); | 442 |
| 443 bool did_submit = false; | |
| 444 if (result == kBeginFrameFinished) { | |
| 445 did_submit = state_machine_.did_submit_in_last_frame(); | |
| 446 } | |
| 447 | |
| 448 BeginFrameAck ack(args.source_id, args.sequence_number, | |
| 449 latest_confirmed_frame, 0, did_submit); | |
| 450 begin_frame_source_->DidFinishFrame(this, ack); | |
| 442 } | 451 } |
| 443 | 452 |
| 444 // BeginImplFrame starts a compositor frame that will wait up until a deadline | 453 // BeginImplFrame starts a compositor frame that will wait up until a deadline |
| 445 // for a BeginMainFrame+activation to complete before it times out and draws | 454 // for a BeginMainFrame+activation to complete before it times out and draws |
| 446 // any asynchronous animation and scroll/pinch updates. | 455 // any asynchronous animation and scroll/pinch updates. |
| 447 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { | 456 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
| 448 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 457 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
| 449 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 458 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
| 450 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); | 459 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); |
| 451 DCHECK(state_machine_.HasInitializedCompositorFrameSink()); | 460 DCHECK(state_machine_.HasInitializedCompositorFrameSink()); |
| 452 | 461 |
| 453 begin_impl_frame_tracker_.Start(args); | 462 begin_impl_frame_tracker_.Start(args); |
| 454 state_machine_.OnBeginImplFrame(); | 463 state_machine_.OnBeginImplFrame(args.source_id, args.sequence_number); |
| 455 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); | 464 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); |
| 456 compositor_timing_history_->WillBeginImplFrame( | 465 compositor_timing_history_->WillBeginImplFrame( |
| 457 state_machine_.NewActiveTreeLikely()); | 466 state_machine_.NewActiveTreeLikely()); |
| 458 client_->WillBeginImplFrame(begin_impl_frame_tracker_.Current()); | 467 client_->WillBeginImplFrame(begin_impl_frame_tracker_.Current()); |
| 459 | 468 |
| 460 ProcessScheduledActions(); | 469 ProcessScheduledActions(); |
| 461 } | 470 } |
| 462 | 471 |
| 463 void Scheduler::ScheduleBeginImplFrameDeadline() { | 472 void Scheduler::ScheduleBeginImplFrameDeadline() { |
| 464 // The synchronous compositor does not post a deadline task. | 473 // The synchronous compositor does not post a deadline task. |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 767 } | 776 } |
| 768 | 777 |
| 769 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 778 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
| 770 return (state_machine_.begin_main_frame_state() == | 779 return (state_machine_.begin_main_frame_state() == |
| 771 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || | 780 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || |
| 772 state_machine_.begin_main_frame_state() == | 781 state_machine_.begin_main_frame_state() == |
| 773 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); | 782 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); |
| 774 } | 783 } |
| 775 | 784 |
| 776 } // namespace cc | 785 } // namespace cc |
| OLD | NEW |