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_state_machine.h" | 5 #include "cc/scheduler/scheduler_state_machine.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/debug/trace_event_argument.h" | 8 #include "base/debug/trace_event_argument.h" |
9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
411 return false; | 411 return false; |
412 | 412 |
413 // We can not perform commits if we are not visible. | 413 // We can not perform commits if we are not visible. |
414 if (!visible_) | 414 if (!visible_) |
415 return false; | 415 return false; |
416 | 416 |
417 return true; | 417 return true; |
418 } | 418 } |
419 | 419 |
420 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { | 420 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { |
421 // If begin frames are not needed, we shouldn't be sending an BeginMainFrame. | |
422 if (!BeginFrameNeeded()) | |
423 return false; | |
424 | |
421 if (!CouldSendBeginMainFrame()) | 425 if (!CouldSendBeginMainFrame()) |
422 return false; | 426 return false; |
423 | 427 |
424 // Only send BeginMainFrame when there isn't another commit pending already. | 428 // Only send BeginMainFrame when there isn't another commit pending already. |
425 if (commit_state_ != COMMIT_STATE_IDLE) | 429 if (commit_state_ != COMMIT_STATE_IDLE) |
426 return false; | 430 return false; |
427 | 431 |
428 // Don't send BeginMainFrame early if we are prioritizing the active tree | 432 // Don't send BeginMainFrame early if we are prioritizing the active tree |
429 // because of impl_latency_takes_priority_. | 433 // because of impl_latency_takes_priority_. |
430 if (impl_latency_takes_priority_ && | 434 if (impl_latency_takes_priority_ && |
431 (has_pending_tree_ || active_tree_needs_first_draw_)) { | 435 (has_pending_tree_ || active_tree_needs_first_draw_)) { |
432 return false; | 436 return false; |
433 } | 437 } |
434 | 438 |
435 // We should not send BeginMainFrame while we are in | 439 // We should not send BeginMainFrame while we are in |
436 // BEGIN_IMPL_FRAME_STATE_IDLE since we might have new | 440 // BEGIN_IMPL_FRAME_STATE_IDLE since we might have new |
437 // user input arriving soon. | 441 // user input arriving soon. |
438 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main | 442 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main |
439 // thread isn't consuming user input. | 443 // thread isn't consuming user input. |
440 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE && | 444 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE) |
441 BeginFrameNeeded()) | |
brianderson
2014/12/19 23:34:06
The check for BeginFrameNeeded is so we can commit
| |
442 return false; | 445 return false; |
443 | 446 |
444 // We need a new commit for the forced redraw. This honors the | 447 // We need a new commit for the forced redraw. This honors the |
445 // single commit per interval because the result will be swapped to screen. | 448 // single commit per interval because the result will be swapped to screen. |
446 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) | 449 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) |
447 return true; | 450 return true; |
448 | 451 |
449 // After this point, we only start a commit once per frame. | 452 // After this point, we only start a commit once per frame. |
450 if (HasSentBeginMainFrameThisFrame()) | 453 if (HasSentBeginMainFrameThisFrame()) |
451 return false; | 454 return false; |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
690 | 693 |
691 bool SchedulerStateMachine::BeginFrameNeededForChildren() const { | 694 bool SchedulerStateMachine::BeginFrameNeededForChildren() const { |
692 if (HasInitializedOutputSurface()) | 695 if (HasInitializedOutputSurface()) |
693 return children_need_begin_frames_; | 696 return children_need_begin_frames_; |
694 | 697 |
695 return false; | 698 return false; |
696 } | 699 } |
697 | 700 |
698 bool SchedulerStateMachine::BeginFrameNeeded() const { | 701 bool SchedulerStateMachine::BeginFrameNeeded() const { |
699 if (SupportsProactiveBeginFrame()) { | 702 if (SupportsProactiveBeginFrame()) { |
700 return (BeginFrameNeededToAnimateOrDraw() || | 703 return (BeginFrameNeededToAnimateOrDrawOrCommit() || |
701 BeginFrameNeededForChildren() || | 704 BeginFrameNeededForChildren() || ProactiveBeginFrameWanted()); |
sunnyps
2015/03/05 00:19:47
OR needs_commit_ here.
| |
702 ProactiveBeginFrameWanted()); | |
703 } | 705 } |
704 | 706 |
705 // Proactive BeginFrames are bad for the synchronous compositor because we | 707 // Proactive BeginFrames are bad for the synchronous compositor because we |
706 // have to draw when we get the BeginFrame and could end up drawing many | 708 // have to draw when we get the BeginFrame and could end up drawing many |
707 // duplicate frames if our new frame isn't ready in time. | 709 // duplicate frames if our new frame isn't ready in time. |
708 // To poll for state with the synchronous compositor without having to draw, | 710 // To poll for state with the synchronous compositor without having to draw, |
709 // we rely on ShouldPollForAnticipatedDrawTriggers instead. | 711 // we rely on ShouldPollForAnticipatedDrawTriggers instead. |
710 // Synchronous compositor doesn't have a browser. | 712 // Synchronous compositor doesn't have a browser. |
711 DCHECK(!children_need_begin_frames_); | 713 DCHECK(!children_need_begin_frames_); |
712 return BeginFrameNeededToAnimateOrDraw(); | 714 return BeginFrameNeededToAnimateOrDrawOrCommit(); |
713 } | 715 } |
714 | 716 |
715 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const { | 717 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const { |
716 // ShouldPollForAnticipatedDrawTriggers is what we use in place of | 718 // ShouldPollForAnticipatedDrawTriggers is what we use in place of |
717 // ProactiveBeginFrameWanted when we are using the synchronous | 719 // ProactiveBeginFrameWanted when we are using the synchronous |
718 // compositor. | 720 // compositor. |
719 if (!SupportsProactiveBeginFrame()) { | 721 if (!SupportsProactiveBeginFrame()) { |
720 return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted(); | 722 return !BeginFrameNeededToAnimateOrDrawOrCommit() && |
723 ProactiveBeginFrameWanted(); | |
721 } | 724 } |
722 | 725 |
723 // Non synchronous compositors should rely on | 726 // Non synchronous compositors should rely on |
724 // ProactiveBeginFrameWanted to poll for state instead. | 727 // ProactiveBeginFrameWanted to poll for state instead. |
725 return false; | 728 return false; |
726 } | 729 } |
727 | 730 |
728 // Note: If SupportsProactiveBeginFrame is false, the scheduler should poll | 731 // Note: If SupportsProactiveBeginFrame is false, the scheduler should poll |
729 // for changes in it's draw state so it can request a BeginFrame when it's | 732 // for changes in it's draw state so it can request a BeginFrame when it's |
730 // actually ready. | 733 // actually ready. |
731 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const { | 734 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const { |
732 // It is undesirable to proactively request BeginFrames if we are | 735 // It is undesirable to proactively request BeginFrames if we are |
733 // using a synchronous compositor because we *must* draw for every | 736 // using a synchronous compositor because we *must* draw for every |
734 // BeginFrame, which could cause duplicate draws. | 737 // BeginFrame, which could cause duplicate draws. |
735 return !settings_.using_synchronous_renderer_compositor; | 738 return !settings_.using_synchronous_renderer_compositor; |
736 } | 739 } |
737 | 740 |
738 void SchedulerStateMachine::SetChildrenNeedBeginFrames( | 741 void SchedulerStateMachine::SetChildrenNeedBeginFrames( |
739 bool children_need_begin_frames) { | 742 bool children_need_begin_frames) { |
740 DCHECK(settings_.forward_begin_frames_to_children); | 743 DCHECK(settings_.forward_begin_frames_to_children); |
741 children_need_begin_frames_ = children_need_begin_frames; | 744 children_need_begin_frames_ = children_need_begin_frames; |
742 } | 745 } |
743 | 746 |
744 // These are the cases where we definitely (or almost definitely) have a | 747 // These are the cases where we definitely (or almost definitely) have a |
745 // new frame to animate and/or draw and can draw. | 748 // new frame to animate and/or draw and can draw. |
746 bool SchedulerStateMachine::BeginFrameNeededToAnimateOrDraw() const { | 749 bool SchedulerStateMachine::BeginFrameNeededToAnimateOrDrawOrCommit() const { |
747 // The output surface is the provider of BeginImplFrames, so we are not going | 750 // The output surface is the provider of BeginImplFrames, so we are not going |
748 // to get them even if we ask for them. | 751 // to get them even if we ask for them. |
749 if (!HasInitializedOutputSurface()) | 752 if (!HasInitializedOutputSurface()) |
750 return false; | 753 return false; |
751 | 754 |
752 // The forced draw respects our normal draw scheduling, so we need to | 755 // The forced draw respects our normal draw scheduling, so we need to |
753 // request a BeginImplFrame for it. | 756 // request a BeginImplFrame for it. |
754 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) | 757 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
755 return true; | 758 return true; |
756 | 759 |
757 return needs_animate_ || needs_redraw_; | 760 return needs_animate_ || needs_redraw_ || needs_commit_; |
sunnyps
2015/03/05 00:19:47
Remove needs_commit_ from here.
| |
758 } | 761 } |
759 | 762 |
760 // These are cases where we are very likely to draw soon, but might not | 763 // These are cases where we are very likely to draw soon, but might not |
761 // actually have a new frame to draw when we receive the next BeginImplFrame. | 764 // actually have a new frame to draw when we receive the next BeginImplFrame. |
762 // Proactively requesting the BeginImplFrame helps hide the round trip latency | 765 // Proactively requesting the BeginImplFrame helps hide the round trip latency |
763 // of the SetNeedsBeginFrame request that has to go to the Browser. | 766 // of the SetNeedsBeginFrame request that has to go to the Browser. |
764 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { | 767 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { |
765 // The output surface is the provider of BeginImplFrames, | 768 // The output surface is the provider of BeginImplFrames, |
766 // so we are not going to get them even if we ask for them. | 769 // so we are not going to get them even if we ask for them. |
767 if (!HasInitializedOutputSurface()) | 770 if (!HasInitializedOutputSurface()) |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1103 static_cast<int>(begin_impl_frame_state_), | 1106 static_cast<int>(begin_impl_frame_state_), |
1104 static_cast<int>(commit_state_), | 1107 static_cast<int>(commit_state_), |
1105 has_pending_tree_ ? 'T' : 'F', | 1108 has_pending_tree_ ? 'T' : 'F', |
1106 pending_tree_is_ready_for_activation_ ? 'T' : 'F', | 1109 pending_tree_is_ready_for_activation_ ? 'T' : 'F', |
1107 active_tree_needs_first_draw_ ? 'T' : 'F', | 1110 active_tree_needs_first_draw_ ? 'T' : 'F', |
1108 max_pending_swaps_, | 1111 max_pending_swaps_, |
1109 pending_swaps_); | 1112 pending_swaps_); |
1110 } | 1113 } |
1111 | 1114 |
1112 } // namespace cc | 1115 } // namespace cc |
OLD | NEW |