Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: cc/scheduler/scheduler_state_machine.cc

Issue 2339633003: Reland of cc: Remove frame queuing from the scheduler. (Closed)
Patch Set: delay begin main frame until swap ack in browser compositor Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_state_machine.h" 5 #include "cc/scheduler/scheduler_state_machine.h"
6 6
7 #include "base/format_macros.h" 7 #include "base/format_macros.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 BeginMainFrameState state) { 116 BeginMainFrameState state) {
117 switch (state) { 117 switch (state) {
118 case BEGIN_MAIN_FRAME_STATE_IDLE: 118 case BEGIN_MAIN_FRAME_STATE_IDLE:
119 return "BEGIN_MAIN_FRAME_STATE_IDLE"; 119 return "BEGIN_MAIN_FRAME_STATE_IDLE";
120 case BEGIN_MAIN_FRAME_STATE_SENT: 120 case BEGIN_MAIN_FRAME_STATE_SENT:
121 return "BEGIN_MAIN_FRAME_STATE_SENT"; 121 return "BEGIN_MAIN_FRAME_STATE_SENT";
122 case BEGIN_MAIN_FRAME_STATE_STARTED: 122 case BEGIN_MAIN_FRAME_STATE_STARTED:
123 return "BEGIN_MAIN_FRAME_STATE_STARTED"; 123 return "BEGIN_MAIN_FRAME_STATE_STARTED";
124 case BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT: 124 case BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT:
125 return "BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT"; 125 return "BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT";
126 case BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION:
127 return "BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION";
128 case BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW:
129 return "BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW";
130 } 126 }
131 NOTREACHED(); 127 NOTREACHED();
132 return "???"; 128 return "???";
133 } 129 }
134 130
135 const char* SchedulerStateMachine::ForcedRedrawOnTimeoutStateToString( 131 const char* SchedulerStateMachine::ForcedRedrawOnTimeoutStateToString(
136 ForcedRedrawOnTimeoutState state) { 132 ForcedRedrawOnTimeoutState state) {
137 switch (state) { 133 switch (state) {
138 case FORCED_REDRAW_STATE_IDLE: 134 case FORCED_REDRAW_STATE_IDLE:
139 return "FORCED_REDRAW_STATE_IDLE"; 135 return "FORCED_REDRAW_STATE_IDLE";
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 356
361 // Do not queue too many swaps. 357 // Do not queue too many swaps.
362 if (SwapThrottled()) 358 if (SwapThrottled())
363 return false; 359 return false;
364 360
365 // Except for the cases above, do not draw outside of the BeginImplFrame 361 // Except for the cases above, do not draw outside of the BeginImplFrame
366 // deadline. 362 // deadline.
367 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 363 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
368 return false; 364 return false;
369 365
366 if (wait_for_ready_to_draw_)
367 return false;
368
370 // Only handle forced redraws due to timeouts on the regular deadline. 369 // Only handle forced redraws due to timeouts on the regular deadline.
371 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 370 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
372 return true; 371 return true;
373 372
374 return needs_redraw_; 373 return needs_redraw_;
375 } 374 }
376 375
377 bool SchedulerStateMachine::ShouldActivatePendingTree() const { 376 bool SchedulerStateMachine::ShouldActivatePendingTree() const {
378 // There is nothing to activate. 377 // There is nothing to activate.
379 if (!has_pending_tree_) 378 if (!has_pending_tree_)
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 if (send_begin_main_frame_funnel_) 421 if (send_begin_main_frame_funnel_)
423 return false; 422 return false;
424 423
425 // Only send BeginMainFrame when there isn't another commit pending already. 424 // Only send BeginMainFrame when there isn't another commit pending already.
426 // Other parts of the state machine indirectly defer the BeginMainFrame 425 // Other parts of the state machine indirectly defer the BeginMainFrame
427 // by transitioning to WAITING commit states rather than going 426 // by transitioning to WAITING commit states rather than going
428 // immediately to IDLE. 427 // immediately to IDLE.
429 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE) 428 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE)
430 return false; 429 return false;
431 430
431 // MFBA is disabled and we are waiting for previous activation.
432 if (!settings_.main_frame_before_activation_enabled && has_pending_tree_)
433 return false;
434
435 // We are waiting for previous frame to be drawn, swapped and acked.
436 if (settings_.commit_to_active_tree &&
437 (active_tree_needs_first_draw_ || SwapThrottled())) {
438 return false;
439 }
440
432 // Don't send BeginMainFrame early if we are prioritizing the active tree 441 // Don't send BeginMainFrame early if we are prioritizing the active tree
433 // because of ImplLatencyTakesPriority. 442 // because of ImplLatencyTakesPriority.
434 if (ImplLatencyTakesPriority() && 443 if (ImplLatencyTakesPriority() &&
435 (has_pending_tree_ || active_tree_needs_first_draw_)) { 444 (has_pending_tree_ || active_tree_needs_first_draw_)) {
436 return false; 445 return false;
437 } 446 }
438 447
439 // We should not send BeginMainFrame while we are in the idle state since we 448 // We should not send BeginMainFrame while we are in the idle state since we
440 // might have new user input arriving soon. It's okay to send BeginMainFrame 449 // might have new user input arriving soon. It's okay to send BeginMainFrame
441 // for the synchronous compositor because the main thread is always high 450 // for the synchronous compositor because the main thread is always high
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 bool SchedulerStateMachine::ShouldCommit() const { 486 bool SchedulerStateMachine::ShouldCommit() const {
478 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT) 487 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT)
479 return false; 488 return false;
480 489
481 // We must not finish the commit until the pending tree is free. 490 // We must not finish the commit until the pending tree is free.
482 if (has_pending_tree_) { 491 if (has_pending_tree_) {
483 DCHECK(settings_.main_frame_before_activation_enabled); 492 DCHECK(settings_.main_frame_before_activation_enabled);
484 return false; 493 return false;
485 } 494 }
486 495
496 // Active tree resources might still be in use until the Display draws.
497 // if (settings_.commit_to_active_tree && SwapThrottled())
enne (OOO) 2016/09/22 19:01:47 Leftover code?
sunnyps 2016/09/24 01:15:02 Removed.
498 // return false;
499 DCHECK(!settings_.commit_to_active_tree || !SwapThrottled());
enne (OOO) 2016/09/22 19:01:47 It's nice to DCHECK this.
sunnyps 2016/09/24 01:15:02 Yes, although this crashes when we have pure impl-
500
487 // If we only have an active tree, it is incorrect to replace it 501 // If we only have an active tree, it is incorrect to replace it
488 // before we've drawn it. 502 // before we've drawn it.
489 DCHECK(!settings_.commit_to_active_tree || !active_tree_needs_first_draw_); 503 DCHECK(!settings_.commit_to_active_tree || !active_tree_needs_first_draw_);
490 504
491 return true; 505 return true;
492 } 506 }
493 507
494 bool SchedulerStateMachine::ShouldPrepareTiles() const { 508 bool SchedulerStateMachine::ShouldPrepareTiles() const {
495 // PrepareTiles only really needs to be called immediately after commit 509 // PrepareTiles only really needs to be called immediately after commit
496 // and then periodically after that. Use a funnel to make sure we average 510 // and then periodically after that. Use a funnel to make sure we average
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 send_begin_main_frame_funnel_ = true; 573 send_begin_main_frame_funnel_ = true;
560 last_frame_number_begin_main_frame_sent_ = current_frame_number_; 574 last_frame_number_begin_main_frame_sent_ = current_frame_number_;
561 } 575 }
562 576
563 void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) { 577 void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) {
564 DCHECK(!has_pending_tree_ || 578 DCHECK(!has_pending_tree_ ||
565 (settings_.main_frame_before_activation_enabled && 579 (settings_.main_frame_before_activation_enabled &&
566 commit_has_no_updates)); 580 commit_has_no_updates));
567 commit_count_++; 581 commit_count_++;
568 last_commit_had_no_updates_ = commit_has_no_updates; 582 last_commit_had_no_updates_ = commit_has_no_updates;
569 583 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE;
570 if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) {
571 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE;
572 } else {
573 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION;
574 }
575 584
576 if (!commit_has_no_updates) { 585 if (!commit_has_no_updates) {
577 // Pending tree only exists if commit had updates. 586 // Pending tree only exists if commit had updates.
578 has_pending_tree_ = true; 587 has_pending_tree_ = true;
579 pending_tree_is_ready_for_activation_ = false; 588 pending_tree_is_ready_for_activation_ = false;
580 wait_for_ready_to_draw_ = settings_.commit_to_active_tree; 589 wait_for_ready_to_draw_ = settings_.commit_to_active_tree;
581 } 590 }
582 591
583 // Update state related to forced draws. 592 // Update state related to forced draws.
584 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) { 593 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) {
585 forced_redraw_state_ = has_pending_tree_ 594 forced_redraw_state_ = has_pending_tree_
586 ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION 595 ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
587 : FORCED_REDRAW_STATE_WAITING_FOR_DRAW; 596 : FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
588 } 597 }
589 598
590 // Update the output surface state. 599 // Update the output surface state.
591 if (compositor_frame_sink_state_ == 600 if (compositor_frame_sink_state_ ==
592 COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT) { 601 COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT) {
593 compositor_frame_sink_state_ = 602 compositor_frame_sink_state_ =
594 has_pending_tree_ ? COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION 603 has_pending_tree_ ? COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION
595 : COMPOSITOR_FRAME_SINK_ACTIVE; 604 : COMPOSITOR_FRAME_SINK_ACTIVE;
596 } 605 }
597 } 606 }
598 607
599 void SchedulerStateMachine::WillActivate() { 608 void SchedulerStateMachine::WillActivate() {
600 if (begin_main_frame_state_ ==
601 BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION) {
602 begin_main_frame_state_ = settings_.commit_to_active_tree
603 ? BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW
604 : BEGIN_MAIN_FRAME_STATE_IDLE;
605 }
606
607 if (compositor_frame_sink_state_ == 609 if (compositor_frame_sink_state_ ==
608 COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION) 610 COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION)
609 compositor_frame_sink_state_ = COMPOSITOR_FRAME_SINK_ACTIVE; 611 compositor_frame_sink_state_ = COMPOSITOR_FRAME_SINK_ACTIVE;
610 612
611 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) 613 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION)
612 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; 614 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
613 615
614 has_pending_tree_ = false; 616 has_pending_tree_ = false;
615 pending_tree_is_ready_for_activation_ = false; 617 pending_tree_is_ready_for_activation_ = false;
616 active_tree_needs_first_draw_ = true; 618 active_tree_needs_first_draw_ = true;
(...skipping 12 matching lines...) Expand all
629 // draw itself might request another draw. 631 // draw itself might request another draw.
630 needs_redraw_ = false; 632 needs_redraw_ = false;
631 633
632 draw_funnel_ = true; 634 draw_funnel_ = true;
633 active_tree_needs_first_draw_ = false; 635 active_tree_needs_first_draw_ = false;
634 did_draw_in_last_frame_ = true; 636 did_draw_in_last_frame_ = true;
635 last_frame_number_draw_performed_ = current_frame_number_; 637 last_frame_number_draw_performed_ = current_frame_number_;
636 638
637 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 639 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
638 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; 640 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
639
640 if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW)
641 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE;
642 } 641 }
643 642
644 void SchedulerStateMachine::DidDrawInternal(DrawResult draw_result) { 643 void SchedulerStateMachine::DidDrawInternal(DrawResult draw_result) {
645 switch (draw_result) { 644 switch (draw_result) {
646 case INVALID_RESULT: 645 case INVALID_RESULT:
647 case DRAW_ABORTED_CANT_DRAW: 646 case DRAW_ABORTED_CANT_DRAW:
648 case DRAW_ABORTED_CONTEXT_LOST: 647 case DRAW_ABORTED_CONTEXT_LOST:
649 NOTREACHED() << "Invalid return DrawResult:" << draw_result; 648 NOTREACHED() << "Invalid return DrawResult:" << draw_result;
650 break; 649 break;
651 case DRAW_ABORTED_DRAINING_PIPELINE: 650 case DRAW_ABORTED_DRAINING_PIPELINE:
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 last_frame_number_invalidate_compositor_frame_sink_performed_ = 721 last_frame_number_invalidate_compositor_frame_sink_performed_ =
723 current_frame_number_; 722 current_frame_number_;
724 723
725 // The synchronous compositor makes no guarantees about a draw coming in after 724 // The synchronous compositor makes no guarantees about a draw coming in after
726 // an invalidate so clear any flags that would cause the compositor's pipeline 725 // an invalidate so clear any flags that would cause the compositor's pipeline
727 // to stall. 726 // to stall.
728 active_tree_needs_first_draw_ = false; // blocks commit if true 727 active_tree_needs_first_draw_ = false; // blocks commit if true
729 } 728 }
730 729
731 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { 730 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() {
732 TRACE_EVENT_INSTANT0("cc", 731 TRACE_EVENT_INSTANT0("cc", "Scheduler: SkipNextBeginMainFrameToReduceLatency",
733 "Scheduler: SkipNextBeginMainFrameToReduceLatency",
734 TRACE_EVENT_SCOPE_THREAD); 732 TRACE_EVENT_SCOPE_THREAD);
735 skip_next_begin_main_frame_to_reduce_latency_ = true; 733 skip_next_begin_main_frame_to_reduce_latency_ = true;
736 } 734 }
737 735
738 bool SchedulerStateMachine::BeginFrameNeededForVideo() const { 736 bool SchedulerStateMachine::BeginFrameNeededForVideo() const {
739 return video_needs_begin_frames_; 737 return video_needs_begin_frames_;
740 } 738 }
741 739
742 bool SchedulerStateMachine::BeginFrameNeeded() const { 740 bool SchedulerStateMachine::BeginFrameNeeded() const {
743 // We can't handle BeginFrames when output surface isn't initialized. 741 // We can't handle BeginFrames when output surface isn't initialized.
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 944
947 void SchedulerStateMachine::SetBeginFrameSourcePaused(bool paused) { 945 void SchedulerStateMachine::SetBeginFrameSourcePaused(bool paused) {
948 begin_frame_source_paused_ = paused; 946 begin_frame_source_paused_ = paused;
949 } 947 }
950 948
951 void SchedulerStateMachine::SetResourcelessSoftwareDraw( 949 void SchedulerStateMachine::SetResourcelessSoftwareDraw(
952 bool resourceless_draw) { 950 bool resourceless_draw) {
953 resourceless_draw_ = resourceless_draw; 951 resourceless_draw_ = resourceless_draw;
954 } 952 }
955 953
956 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } 954 void SchedulerStateMachine::SetCanDraw(bool can_draw) {
955 can_draw_ = can_draw;
956 }
957 957
958 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 958 void SchedulerStateMachine::SetNeedsRedraw() {
959 needs_redraw_ = true;
960 }
959 961
960 bool SchedulerStateMachine::OnlyImplSideUpdatesExpected() const { 962 bool SchedulerStateMachine::OnlyImplSideUpdatesExpected() const {
961 bool has_impl_updates = needs_redraw_ || needs_one_begin_impl_frame_; 963 bool has_impl_updates = needs_redraw_ || needs_one_begin_impl_frame_;
962 bool main_updates_expected = 964 bool main_updates_expected =
963 needs_begin_main_frame_ || 965 needs_begin_main_frame_ ||
964 begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE || 966 begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE ||
965 has_pending_tree_; 967 has_pending_tree_;
966 return has_impl_updates && !main_updates_expected; 968 return has_impl_updates && !main_updates_expected;
967 } 969 }
968 970
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1022 } 1024 }
1023 1025
1024 void SchedulerStateMachine::SetNeedsOneBeginImplFrame() { 1026 void SchedulerStateMachine::SetNeedsOneBeginImplFrame() {
1025 needs_one_begin_impl_frame_ = true; 1027 needs_one_begin_impl_frame_ = true;
1026 } 1028 }
1027 1029
1028 void SchedulerStateMachine::NotifyReadyToCommit() { 1030 void SchedulerStateMachine::NotifyReadyToCommit() {
1029 DCHECK_EQ(begin_main_frame_state_, BEGIN_MAIN_FRAME_STATE_STARTED) 1031 DCHECK_EQ(begin_main_frame_state_, BEGIN_MAIN_FRAME_STATE_STARTED)
1030 << AsValue()->ToString(); 1032 << AsValue()->ToString();
1031 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT; 1033 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT;
1032 // In commit_to_active_tree mode, commit should happen right after
1033 // BeginFrame, meaning when this function is called, next action should be
1034 // commit.
1035 if (settings_.commit_to_active_tree)
1036 DCHECK(ShouldCommit());
1037 } 1034 }
1038 1035
1039 void SchedulerStateMachine::BeginMainFrameAborted(CommitEarlyOutReason reason) { 1036 void SchedulerStateMachine::BeginMainFrameAborted(CommitEarlyOutReason reason) {
1040 DCHECK_EQ(begin_main_frame_state_, BEGIN_MAIN_FRAME_STATE_STARTED); 1037 DCHECK_EQ(begin_main_frame_state_, BEGIN_MAIN_FRAME_STATE_STARTED);
1041 1038
1042 // If the main thread aborted, it doesn't matter if the main thread missed 1039 // If the main thread aborted, it doesn't matter if the main thread missed
1043 // the last deadline since it didn't have an update anyway. 1040 // the last deadline since it didn't have an update anyway.
1044 main_thread_missed_last_deadline_ = false; 1041 main_thread_missed_last_deadline_ = false;
1045 1042
1046 switch (reason) { 1043 switch (reason) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1110 case COMPOSITOR_FRAME_SINK_ACTIVE: 1107 case COMPOSITOR_FRAME_SINK_ACTIVE:
1111 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT: 1108 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT:
1112 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION: 1109 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION:
1113 return true; 1110 return true;
1114 } 1111 }
1115 NOTREACHED(); 1112 NOTREACHED();
1116 return false; 1113 return false;
1117 } 1114 }
1118 1115
1119 } // namespace cc 1116 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler_state_machine.h ('k') | cc/scheduler/scheduler_state_machine_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698