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_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 |