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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 // BeginFrame is the mechanism that tells us that now is a good time to start | 254 // BeginFrame is the mechanism that tells us that now is a good time to start |
| 255 // making a frame. Usually this means that user input for the frame is complete. | 255 // making a frame. Usually this means that user input for the frame is complete. |
| 256 // If the scheduler is busy, we queue the BeginFrame to be handled later as | 256 // If the scheduler is busy, we queue the BeginFrame to be handled later as |
| 257 // a BeginRetroFrame. | 257 // a BeginRetroFrame. |
| 258 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { | 258 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { |
| 259 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); | 259 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); |
| 260 | 260 |
| 261 if (!state_machine_.BeginFrameNeeded()) { | 261 if (!state_machine_.BeginFrameNeeded()) { |
| 262 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped", | 262 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped", |
| 263 TRACE_EVENT_SCOPE_THREAD); | 263 TRACE_EVENT_SCOPE_THREAD); |
| 264 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. | 264 // Since we don't use the BeginFrame, we may later receive the same |
| 265 BeginFrameAck ack(args.source_id, args.sequence_number, | 265 // BeginFrame again. Thus, we can't confirm it at this point, even though we |
| 266 args.sequence_number, 0, false); | 266 // don't have any updates right now. |
| 267 begin_frame_source_->DidFinishFrame(this, ack); | 267 SendBeginFrameAck(args, kBeginFrameSkipped); |
|
Eric Seckler
2017/02/23 12:58:00
Since we require an ack here now, I've added a com
| |
| 268 return false; | 268 return false; |
| 269 } | 269 } |
| 270 | 270 |
| 271 // Trace this begin frame time through the Chrome stack | 271 // Trace this begin frame time through the Chrome stack |
| 272 TRACE_EVENT_FLOW_BEGIN0( | 272 TRACE_EVENT_FLOW_BEGIN0( |
| 273 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", | 273 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", |
| 274 args.frame_time.ToInternalValue()); | 274 args.frame_time.ToInternalValue()); |
| 275 | 275 |
| 276 if (settings_.using_synchronous_renderer_compositor) { | 276 if (settings_.using_synchronous_renderer_compositor) { |
| 277 BeginImplFrameSynchronous(args); | 277 BeginImplFrameSynchronous(args); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 BeginFrameArgs adjusted_args = args; | 319 BeginFrameArgs adjusted_args = args; |
| 320 // Cancel the missed begin frame task in case the BFS sends a begin frame | 320 // Cancel the missed begin frame task in case the BFS sends a begin frame |
| 321 // before the missed frame task runs. | 321 // before the missed frame task runs. |
| 322 missed_begin_frame_task_.Cancel(); | 322 missed_begin_frame_task_.Cancel(); |
| 323 | 323 |
| 324 base::TimeTicks now = Now(); | 324 base::TimeTicks now = Now(); |
| 325 | 325 |
| 326 // Discard missed begin frames if they are too late. | 326 // Discard missed begin frames if they are too late. |
| 327 if (adjusted_args.type == BeginFrameArgs::MISSED && | 327 if (adjusted_args.type == BeginFrameArgs::MISSED && |
| 328 now > adjusted_args.deadline) { | 328 now > adjusted_args.deadline) { |
| 329 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. | 329 SendBeginFrameAck(adjusted_args, kBeginFrameSkipped); |
| 330 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number, | |
| 331 adjusted_args.sequence_number, 0, false); | |
| 332 begin_frame_source_->DidFinishFrame(this, ack); | |
| 333 return; | 330 return; |
| 334 } | 331 } |
| 335 | 332 |
| 336 // Run the previous deadline if any. | 333 // Run the previous deadline if any. |
| 337 if (state_machine_.begin_impl_frame_state() == | 334 if (state_machine_.begin_impl_frame_state() == |
| 338 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) { | 335 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) { |
| 339 OnBeginImplFrameDeadline(); | 336 OnBeginImplFrameDeadline(); |
| 340 // We may not need begin frames any longer. | 337 // We may not need begin frames any longer. |
| 341 if (!observing_begin_frame_source_) { | 338 if (!observing_begin_frame_source_) { |
| 342 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. | 339 // We need to confirm the ignored BeginFrame, since we don't have updates. |
| 343 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number, | 340 // To persist the confirmation for future BeginFrameAcks, we let the state |
| 344 adjusted_args.sequence_number, 0, false); | 341 // machine know about the BeginFrame. |
| 345 begin_frame_source_->DidFinishFrame(this, ack); | 342 state_machine_.OnBeginFrameDroppedNotObserving(args.source_id, |
| 343 args.sequence_number); | |
| 344 SendBeginFrameAck(adjusted_args, kBeginFrameSkipped); | |
| 346 return; | 345 return; |
| 347 } | 346 } |
| 348 } | 347 } |
| 349 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 348 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
| 350 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 349 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
| 351 | 350 |
| 352 bool main_thread_is_in_high_latency_mode = | 351 bool main_thread_is_in_high_latency_mode = |
| 353 state_machine_.main_thread_missed_last_deadline(); | 352 state_machine_.main_thread_missed_last_deadline(); |
| 354 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 353 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
| 355 adjusted_args.AsValue(), "main_thread_missed_last_deadline", | 354 adjusted_args.AsValue(), "main_thread_missed_last_deadline", |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 bmf_to_activate_estimate, now); | 393 bmf_to_activate_estimate, now); |
| 395 | 394 |
| 396 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { | 395 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { |
| 397 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", | 396 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", |
| 398 TRACE_EVENT_SCOPE_THREAD); | 397 TRACE_EVENT_SCOPE_THREAD); |
| 399 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); | 398 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
| 400 } else if (ShouldRecoverImplLatency(adjusted_args, | 399 } else if (ShouldRecoverImplLatency(adjusted_args, |
| 401 can_activate_before_deadline)) { | 400 can_activate_before_deadline)) { |
| 402 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", | 401 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", |
| 403 TRACE_EVENT_SCOPE_THREAD); | 402 TRACE_EVENT_SCOPE_THREAD); |
| 404 if (begin_frame_source_) { | 403 SendBeginFrameAck(begin_main_frame_args_, kBeginFrameSkipped); |
| 405 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. | |
| 406 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number, | |
| 407 adjusted_args.sequence_number, 0, false); | |
| 408 begin_frame_source_->DidFinishFrame(this, ack); | |
| 409 } | |
| 410 return; | 404 return; |
| 411 } | 405 } |
| 412 | 406 |
| 413 BeginImplFrame(adjusted_args); | 407 BeginImplFrame(adjusted_args); |
| 414 } | 408 } |
| 415 | 409 |
| 416 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { | 410 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { |
| 417 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 411 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
| 418 args.AsValue()); | 412 args.AsValue()); |
| 419 | 413 |
| 420 // The main thread currently can't commit before we draw with the | 414 // The main thread currently can't commit before we draw with the |
| 421 // synchronous compositor, so never consider the BeginMainFrame fast. | 415 // synchronous compositor, so never consider the BeginMainFrame fast. |
| 422 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); | 416 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); |
| 423 begin_main_frame_args_ = args; | 417 begin_main_frame_args_ = args; |
| 424 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); | 418 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); |
| 425 | 419 |
| 426 BeginImplFrame(args); | 420 BeginImplFrame(args); |
| 427 compositor_timing_history_->WillFinishImplFrame( | 421 compositor_timing_history_->WillFinishImplFrame( |
| 428 state_machine_.needs_redraw()); | 422 state_machine_.needs_redraw()); |
| 429 FinishImplFrame(); | 423 FinishImplFrame(); |
| 430 } | 424 } |
| 431 | 425 |
| 432 void Scheduler::FinishImplFrame() { | 426 void Scheduler::FinishImplFrame() { |
| 433 state_machine_.OnBeginImplFrameIdle(); | 427 state_machine_.OnBeginImplFrameIdle(); |
| 434 ProcessScheduledActions(); | 428 ProcessScheduledActions(); |
| 435 | 429 |
| 436 client_->DidFinishImplFrame(); | 430 client_->DidFinishImplFrame(); |
| 437 if (begin_frame_source_) { | 431 SendBeginFrameAck(begin_main_frame_args_, kBeginFrameFinished); |
| 438 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. | 432 begin_impl_frame_tracker_.Finish(); |
| 439 BeginFrameAck ack(begin_main_frame_args_.source_id, | 433 } |
| 440 begin_main_frame_args_.sequence_number, | 434 |
| 441 begin_main_frame_args_.sequence_number, 0, | 435 void Scheduler::SendBeginFrameAck(const BeginFrameArgs& args, |
| 442 state_machine_.did_submit_in_last_frame()); | 436 BeginFrameResult result) { |
| 443 begin_frame_source_->DidFinishFrame(this, ack); | 437 if (!begin_frame_source_) |
| 438 return; | |
| 439 | |
| 440 uint64_t latest_confirmed_sequence_number = | |
| 441 BeginFrameArgs::kInvalidFrameNumber; | |
| 442 if (args.source_id == state_machine_.begin_frame_source_id()) { | |
| 443 latest_confirmed_sequence_number = | |
| 444 state_machine_ | |
| 445 .last_begin_frame_sequence_number_compositor_frame_was_fresh(); | |
| 444 } | 446 } |
| 445 begin_impl_frame_tracker_.Finish(); | 447 |
| 448 bool did_submit = false; | |
| 449 if (result == kBeginFrameFinished) { | |
| 450 did_submit = state_machine_.did_submit_in_last_frame(); | |
| 451 } | |
| 452 | |
| 453 BeginFrameAck ack(args.source_id, args.sequence_number, | |
| 454 latest_confirmed_sequence_number, 0, did_submit); | |
| 455 begin_frame_source_->DidFinishFrame(this, ack); | |
| 446 } | 456 } |
| 447 | 457 |
| 448 // BeginImplFrame starts a compositor frame that will wait up until a deadline | 458 // BeginImplFrame starts a compositor frame that will wait up until a deadline |
| 449 // for a BeginMainFrame+activation to complete before it times out and draws | 459 // for a BeginMainFrame+activation to complete before it times out and draws |
| 450 // any asynchronous animation and scroll/pinch updates. | 460 // any asynchronous animation and scroll/pinch updates. |
| 451 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { | 461 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
| 452 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 462 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
| 453 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 463 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
| 454 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); | 464 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); |
| 455 DCHECK(state_machine_.HasInitializedCompositorFrameSink()); | 465 DCHECK(state_machine_.HasInitializedCompositorFrameSink()); |
| 456 | 466 |
| 457 begin_impl_frame_tracker_.Start(args); | 467 begin_impl_frame_tracker_.Start(args); |
| 458 state_machine_.OnBeginImplFrame(); | 468 state_machine_.OnBeginImplFrame(args.source_id, args.sequence_number); |
| 459 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); | 469 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); |
| 460 compositor_timing_history_->WillBeginImplFrame( | 470 compositor_timing_history_->WillBeginImplFrame( |
| 461 state_machine_.NewActiveTreeLikely()); | 471 state_machine_.NewActiveTreeLikely()); |
| 462 client_->WillBeginImplFrame(begin_impl_frame_tracker_.Current()); | 472 client_->WillBeginImplFrame(begin_impl_frame_tracker_.Current()); |
| 463 | 473 |
| 464 ProcessScheduledActions(); | 474 ProcessScheduledActions(); |
| 465 } | 475 } |
| 466 | 476 |
| 467 void Scheduler::ScheduleBeginImplFrameDeadline() { | 477 void Scheduler::ScheduleBeginImplFrameDeadline() { |
| 468 // The synchronous compositor does not post a deadline task. | 478 // The synchronous compositor does not post a deadline task. |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 771 } | 781 } |
| 772 | 782 |
| 773 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 783 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
| 774 return (state_machine_.begin_main_frame_state() == | 784 return (state_machine_.begin_main_frame_state() == |
| 775 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || | 785 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || |
| 776 state_machine_.begin_main_frame_state() == | 786 state_machine_.begin_main_frame_state() == |
| 777 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); | 787 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); |
| 778 } | 788 } |
| 779 | 789 |
| 780 } // namespace cc | 790 } // namespace cc |
| OLD | NEW |