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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 void Scheduler::SetCanDraw(bool can_draw) { | 162 void Scheduler::SetCanDraw(bool can_draw) { |
163 state_machine_.SetCanDraw(can_draw); | 163 state_machine_.SetCanDraw(can_draw); |
164 ProcessScheduledActions(); | 164 ProcessScheduledActions(); |
165 } | 165 } |
166 | 166 |
167 void Scheduler::NotifyReadyToActivate() { | 167 void Scheduler::NotifyReadyToActivate() { |
168 state_machine_.NotifyReadyToActivate(); | 168 state_machine_.NotifyReadyToActivate(); |
169 ProcessScheduledActions(); | 169 ProcessScheduledActions(); |
170 } | 170 } |
171 | 171 |
| 172 void Scheduler::SetRequiresHighResToDraw(bool required) { |
| 173 state_machine_.SetRequiresHighResToDraw(required); |
| 174 ProcessScheduledActions(); |
| 175 } |
| 176 |
172 void Scheduler::NotifyReadyToDraw() { | 177 void Scheduler::NotifyReadyToDraw() { |
173 // Future work might still needed for crbug.com/352894. | 178 // Future work might still needed for crbug.com/352894. |
174 state_machine_.NotifyReadyToDraw(); | 179 state_machine_.NotifyReadyToDraw(); |
175 ProcessScheduledActions(); | 180 ProcessScheduledActions(); |
176 } | 181 } |
177 | 182 |
178 void Scheduler::SetThrottleFrameProduction(bool throttle) { | 183 void Scheduler::SetThrottleFrameProduction(bool throttle) { |
179 throttle_frame_production_ = throttle; | 184 throttle_frame_production_ = throttle; |
180 if (throttle) { | 185 if (throttle) { |
181 frame_source_->SetActiveSource(primary_frame_source_); | 186 frame_source_->SetActiveSource(primary_frame_source_); |
(...skipping 11 matching lines...) Expand all Loading... |
193 void Scheduler::SetNeedsRedraw() { | 198 void Scheduler::SetNeedsRedraw() { |
194 state_machine_.SetNeedsRedraw(); | 199 state_machine_.SetNeedsRedraw(); |
195 ProcessScheduledActions(); | 200 ProcessScheduledActions(); |
196 } | 201 } |
197 | 202 |
198 void Scheduler::SetNeedsAnimate() { | 203 void Scheduler::SetNeedsAnimate() { |
199 state_machine_.SetNeedsAnimate(); | 204 state_machine_.SetNeedsAnimate(); |
200 ProcessScheduledActions(); | 205 ProcessScheduledActions(); |
201 } | 206 } |
202 | 207 |
203 void Scheduler::SetNeedsPrepareTiles() { | 208 void Scheduler::SetNeedsPrepareTiles(bool for_commit) { |
204 DCHECK(!IsInsideAction(SchedulerStateMachine::ACTION_PREPARE_TILES)); | 209 DCHECK(!IsInsideAction(SchedulerStateMachine::ACTION_PREPARE_TILES)); |
205 state_machine_.SetNeedsPrepareTiles(); | 210 state_machine_.SetNeedsPrepareTiles(for_commit); |
206 ProcessScheduledActions(); | 211 ProcessScheduledActions(); |
207 } | 212 } |
208 | 213 |
209 void Scheduler::SetWaitForReadyToDraw() { | 214 void Scheduler::SetWaitForReadyToDraw() { |
210 state_machine_.SetWaitForReadyToDraw(); | 215 state_machine_.SetWaitForReadyToDraw(); |
211 ProcessScheduledActions(); | 216 ProcessScheduledActions(); |
212 } | 217 } |
213 | 218 |
214 void Scheduler::SetMaxSwapsPending(int max) { | 219 void Scheduler::SetMaxSwapsPending(int max) { |
215 state_machine_.SetMaxSwapsPending(max); | 220 state_machine_.SetMaxSwapsPending(max); |
(...skipping 25 matching lines...) Expand all Loading... |
241 ProcessScheduledActions(); | 246 ProcessScheduledActions(); |
242 } | 247 } |
243 | 248 |
244 void Scheduler::BeginMainFrameAborted(CommitEarlyOutReason reason) { | 249 void Scheduler::BeginMainFrameAborted(CommitEarlyOutReason reason) { |
245 TRACE_EVENT1("cc", "Scheduler::BeginMainFrameAborted", "reason", | 250 TRACE_EVENT1("cc", "Scheduler::BeginMainFrameAborted", "reason", |
246 CommitEarlyOutReasonToString(reason)); | 251 CommitEarlyOutReasonToString(reason)); |
247 state_machine_.BeginMainFrameAborted(reason); | 252 state_machine_.BeginMainFrameAborted(reason); |
248 ProcessScheduledActions(); | 253 ProcessScheduledActions(); |
249 } | 254 } |
250 | 255 |
251 void Scheduler::DidPrepareTiles() { | |
252 state_machine_.DidPrepareTiles(); | |
253 } | |
254 | |
255 void Scheduler::DidLoseOutputSurface() { | 256 void Scheduler::DidLoseOutputSurface() { |
256 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); | 257 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); |
257 begin_retro_frame_args_.clear(); | 258 begin_retro_frame_args_.clear(); |
258 begin_retro_frame_task_.Cancel(); | 259 begin_retro_frame_task_.Cancel(); |
259 state_machine_.DidLoseOutputSurface(); | 260 state_machine_.DidLoseOutputSurface(); |
260 ProcessScheduledActions(); | 261 ProcessScheduledActions(); |
261 } | 262 } |
262 | 263 |
263 void Scheduler::DidCreateAndInitializeOutputSurface() { | 264 void Scheduler::DidCreateAndInitializeOutputSurface() { |
264 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); | 265 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); |
(...skipping 20 matching lines...) Expand all Loading... |
285 return timebase + (begin_impl_frame_args_.interval * intervals); | 286 return timebase + (begin_impl_frame_args_.interval * intervals); |
286 } | 287 } |
287 | 288 |
288 base::TimeTicks Scheduler::LastBeginImplFrameTime() { | 289 base::TimeTicks Scheduler::LastBeginImplFrameTime() { |
289 return begin_impl_frame_args_.frame_time; | 290 return begin_impl_frame_args_.frame_time; |
290 } | 291 } |
291 | 292 |
292 void Scheduler::SetupNextBeginFrameIfNeeded() { | 293 void Scheduler::SetupNextBeginFrameIfNeeded() { |
293 // Never call SetNeedsBeginFrames if the frame source already has the right | 294 // Never call SetNeedsBeginFrames if the frame source already has the right |
294 // value. | 295 // value. |
295 if (frame_source_->NeedsBeginFrames() != state_machine_.BeginFrameNeeded()) { | 296 bool begin_frames_needed = state_machine_.BeginFrameNeeded(); |
296 if (state_machine_.BeginFrameNeeded()) { | 297 if (frame_source_->NeedsBeginFrames() != begin_frames_needed) { |
| 298 if (begin_frames_needed) { |
297 // Call SetNeedsBeginFrames(true) as soon as possible. | 299 // Call SetNeedsBeginFrames(true) as soon as possible. |
298 frame_source_->SetNeedsBeginFrames(true); | 300 frame_source_->SetNeedsBeginFrames(true); |
299 } else if (state_machine_.begin_impl_frame_state() == | 301 } else if (state_machine_.begin_impl_frame_state() == |
300 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { | 302 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { |
301 // Call SetNeedsBeginFrames(false) in between frames only. | 303 // Call SetNeedsBeginFrames(false) in between frames only. |
302 frame_source_->SetNeedsBeginFrames(false); | 304 frame_source_->SetNeedsBeginFrames(false); |
303 client_->SendBeginMainFrameNotExpectedSoon(); | 305 client_->SendBeginMainFrameNotExpectedSoon(); |
304 } | 306 } |
| 307 state_machine_.NotifyBeginFrameSourceActive(begin_frames_needed); |
305 } | 308 } |
306 | 309 |
307 PostBeginRetroFrameIfNeeded(); | 310 PostBeginRetroFrameIfNeeded(); |
308 } | 311 } |
309 | 312 |
310 // We may need to poll when we can't rely on BeginFrame to advance certain | 313 // We may need to poll when we can't rely on BeginFrame to advance certain |
311 // state or to avoid deadlock. | 314 // state or to avoid deadlock. |
312 void Scheduler::SetupPollingMechanisms() { | 315 void Scheduler::SetupPollingMechanisms() { |
313 // At this point we'd prefer to advance through the commit flow by | 316 // At this point we'd prefer to advance through the commit flow by |
314 // drawing a frame, however it's possible that the frame rate controller | 317 // drawing a frame, however it's possible that the frame rate controller |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 deadline = begin_impl_frame_args_.deadline; | 572 deadline = begin_impl_frame_args_.deadline; |
570 break; | 573 break; |
571 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: | 574 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: |
572 // We are blocked for one reason or another and we should wait. | 575 // We are blocked for one reason or another and we should wait. |
573 // TODO(brianderson): Handle long deadlines (that are past the next | 576 // TODO(brianderson): Handle long deadlines (that are past the next |
574 // frame's frame time) properly instead of using this hack. | 577 // frame's frame time) properly instead of using this hack. |
575 deadline = | 578 deadline = |
576 begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval; | 579 begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval; |
577 break; | 580 break; |
578 case SchedulerStateMachine:: | 581 case SchedulerStateMachine:: |
| 582 BEGIN_IMPL_FRAME_DEADLINE_MODE_TRY_TO_AVOID_CHECKERBOARD: |
| 583 // We will wait up until this deadline for the ReadyToDraw signal. |
| 584 // TODO(brianderson): Use a different timeout for touch vs. mouse wheel. |
| 585 deadline = begin_impl_frame_args_.frame_time + |
| 586 (1 * begin_impl_frame_args_.interval); |
| 587 break; |
| 588 case SchedulerStateMachine:: |
579 BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW: | 589 BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW: |
580 // We are blocked because we are waiting for ReadyToDraw signal. We would | 590 // We are blocked because we are waiting for ReadyToDraw signal. We would |
581 // post deadline after we received ReadyToDraw singal. | 591 // post deadline after we received ReadyToDraw singal. |
582 TRACE_EVENT1("cc", "Scheduler::ScheduleBeginImplFrameDeadline", | 592 TRACE_EVENT1("cc", "Scheduler::ScheduleBeginImplFrameDeadline", |
583 "deadline_mode", "blocked_on_ready_to_draw"); | 593 "deadline_mode", "blocked_on_ready_to_draw"); |
584 return; | 594 return; |
585 } | 595 } |
586 | 596 |
587 TRACE_EVENT2("cc", "Scheduler::ScheduleBeginImplFrameDeadline", "mode", | 597 TRACE_EVENT2("cc", "Scheduler::ScheduleBeginImplFrameDeadline", "mode", |
588 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( | 598 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 | 642 |
633 | 643 |
634 void Scheduler::PollToAdvanceCommitState() { | 644 void Scheduler::PollToAdvanceCommitState() { |
635 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); | 645 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); |
636 advance_commit_state_task_.Cancel(); | 646 advance_commit_state_task_.Cancel(); |
637 ProcessScheduledActions(); | 647 ProcessScheduledActions(); |
638 } | 648 } |
639 | 649 |
640 void Scheduler::DrawAndSwapIfPossible() { | 650 void Scheduler::DrawAndSwapIfPossible() { |
641 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); | 651 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); |
642 state_machine_.DidDrawIfPossibleCompleted(result); | 652 state_machine_.SetDrawResult(result); |
| 653 } |
| 654 |
| 655 void Scheduler::DrawAndSwapForced() { |
| 656 DrawResult result = client_->ScheduledActionDrawAndSwapForced(); |
| 657 state_machine_.SetDrawResult(result); |
643 } | 658 } |
644 | 659 |
645 void Scheduler::SetDeferCommits(bool defer_commits) { | 660 void Scheduler::SetDeferCommits(bool defer_commits) { |
646 TRACE_EVENT1("cc", "Scheduler::SetDeferCommits", | 661 TRACE_EVENT1("cc", "Scheduler::SetDeferCommits", |
647 "defer_commits", | 662 "defer_commits", |
648 defer_commits); | 663 defer_commits); |
649 state_machine_.SetDeferCommits(defer_commits); | 664 state_machine_.SetDeferCommits(defer_commits); |
650 ProcessScheduledActions(); | 665 ProcessScheduledActions(); |
651 } | 666 } |
652 | 667 |
653 void Scheduler::ProcessScheduledActions() { | 668 void Scheduler::ProcessScheduledActions() { |
654 // We do not allow ProcessScheduledActions to be recursive. | 669 // We do not allow ProcessScheduledActions to be recursive. |
655 // The top-level call will iteratively execute the next action for us anyway. | 670 // The top-level call will iteratively execute the next action for us anyway. |
656 if (inside_process_scheduled_actions_) | 671 if (inside_process_scheduled_actions_) |
657 return; | 672 return; |
658 | 673 |
659 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); | 674 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); |
660 | 675 |
661 SchedulerStateMachine::Action action; | 676 SchedulerStateMachine::Action action; |
662 do { | 677 do { |
663 action = state_machine_.NextAction(); | 678 action = state_machine_.NextAction(); |
664 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 679 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
665 "SchedulerStateMachine", | 680 "SchedulerStateMachine", |
666 "state", | 681 "state", |
667 AsValue()); | 682 AsValue()); |
668 VLOG(2) << "Scheduler::ProcessScheduledActions: " | 683 VLOG(2) << "Scheduler::ProcessScheduledActions: " |
669 << SchedulerStateMachine::ActionToString(action) << " " | 684 << SchedulerStateMachine::ActionToString(action) << " " |
670 << state_machine_.GetStatesForDebugging(); | 685 << state_machine_.GetStatesForDebugging(); |
671 state_machine_.UpdateState(action); | 686 { |
672 base::AutoReset<SchedulerStateMachine::Action> | 687 base::AutoReset<SchedulerStateMachine::Action> mark_inside_action( |
673 mark_inside_action(&inside_action_, action); | 688 &inside_action_, action); |
674 switch (action) { | 689 switch (action) { |
675 case SchedulerStateMachine::ACTION_NONE: | 690 case SchedulerStateMachine::ACTION_NONE: |
676 break; | 691 break; |
677 case SchedulerStateMachine::ACTION_ANIMATE: | 692 case SchedulerStateMachine::ACTION_ANIMATE: |
678 client_->ScheduledActionAnimate(); | 693 client_->ScheduledActionAnimate(); |
679 break; | 694 break; |
680 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: | 695 case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME: |
681 client_->ScheduledActionSendBeginMainFrame(); | 696 client_->ScheduledActionSendBeginMainFrame(); |
682 break; | 697 break; |
683 case SchedulerStateMachine::ACTION_COMMIT: { | 698 case SchedulerStateMachine::ACTION_COMMIT: { |
684 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is | 699 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
685 // fixed. | 700 // fixed. |
686 tracked_objects::ScopedTracker tracking_profile4( | 701 tracked_objects::ScopedTracker tracking_profile4( |
687 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 702 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
688 "461509 Scheduler::ProcessScheduledActions4")); | 703 "461509 Scheduler::ProcessScheduledActions4")); |
689 client_->ScheduledActionCommit(); | 704 client_->ScheduledActionCommit(); |
690 break; | 705 break; |
| 706 } |
| 707 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE: |
| 708 client_->ScheduledActionActivateSyncTree(); |
| 709 break; |
| 710 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { |
| 711 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is |
| 712 // fixed. |
| 713 tracked_objects::ScopedTracker tracking_profile6( |
| 714 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
| 715 "461509 Scheduler::ProcessScheduledActions6")); |
| 716 DrawAndSwapIfPossible(); |
| 717 break; |
| 718 } |
| 719 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED: |
| 720 DrawAndSwapForced(); |
| 721 break; |
| 722 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: |
| 723 // No action is actually performed, but this allows the state machine |
| 724 // to |
| 725 // advance out of its waiting to draw state without actually drawing. |
| 726 state_machine_.SetDrawResult(DRAW_SUCCESS); |
| 727 break; |
| 728 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: |
| 729 client_->ScheduledActionBeginOutputSurfaceCreation(); |
| 730 break; |
| 731 case SchedulerStateMachine::ACTION_PREPARE_TILES: |
| 732 client_->ScheduledActionPrepareTiles(); |
| 733 break; |
| 734 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE: { |
| 735 client_->ScheduledActionInvalidateOutputSurface(); |
| 736 break; |
| 737 } |
691 } | 738 } |
692 case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE: | 739 state_machine_.UpdateState(action); |
693 client_->ScheduledActionActivateSyncTree(); | |
694 break; | |
695 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { | |
696 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is | |
697 // fixed. | |
698 tracked_objects::ScopedTracker tracking_profile6( | |
699 FROM_HERE_WITH_EXPLICIT_FUNCTION( | |
700 "461509 Scheduler::ProcessScheduledActions6")); | |
701 DrawAndSwapIfPossible(); | |
702 break; | |
703 } | |
704 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED: | |
705 client_->ScheduledActionDrawAndSwapForced(); | |
706 break; | |
707 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: | |
708 // No action is actually performed, but this allows the state machine to | |
709 // advance out of its waiting to draw state without actually drawing. | |
710 break; | |
711 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: | |
712 client_->ScheduledActionBeginOutputSurfaceCreation(); | |
713 break; | |
714 case SchedulerStateMachine::ACTION_PREPARE_TILES: | |
715 client_->ScheduledActionPrepareTiles(); | |
716 break; | |
717 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE: { | |
718 client_->ScheduledActionInvalidateOutputSurface(); | |
719 break; | |
720 } | |
721 } | 740 } |
722 } while (action != SchedulerStateMachine::ACTION_NONE); | 741 } while (action != SchedulerStateMachine::ACTION_NONE); |
723 | 742 |
724 SetupPollingMechanisms(); | 743 SetupPollingMechanisms(); |
725 | 744 |
726 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); | 745 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); |
727 | 746 |
728 ScheduleBeginImplFrameDeadlineIfNeeded(); | 747 ScheduleBeginImplFrameDeadlineIfNeeded(); |
729 | 748 |
730 SetupNextBeginFrameIfNeeded(); | 749 SetupNextBeginFrameIfNeeded(); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 } | 842 } |
824 | 843 |
825 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 844 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
826 return (state_machine_.commit_state() == | 845 return (state_machine_.commit_state() == |
827 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 846 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
828 state_machine_.commit_state() == | 847 state_machine_.commit_state() == |
829 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 848 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
830 } | 849 } |
831 | 850 |
832 } // namespace cc | 851 } // namespace cc |
OLD | NEW |