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/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 18 matching lines...) Expand all Loading... |
29 animate_funnel_(false), | 29 animate_funnel_(false), |
30 request_swap_funnel_(false), | 30 request_swap_funnel_(false), |
31 send_begin_main_frame_funnel_(true), | 31 send_begin_main_frame_funnel_(true), |
32 invalidate_output_surface_funnel_(false), | 32 invalidate_output_surface_funnel_(false), |
33 prepare_tiles_funnel_(0), | 33 prepare_tiles_funnel_(0), |
34 consecutive_checkerboard_animations_(0), | 34 consecutive_checkerboard_animations_(0), |
35 max_pending_swaps_(1), | 35 max_pending_swaps_(1), |
36 pending_swaps_(0), | 36 pending_swaps_(0), |
37 swaps_with_current_output_surface_(0), | 37 swaps_with_current_output_surface_(0), |
38 needs_redraw_(false), | 38 needs_redraw_(false), |
| 39 last_draw_result_(DRAW_SUCCESS), |
39 needs_animate_(false), | 40 needs_animate_(false), |
40 needs_prepare_tiles_(false), | 41 needs_prepare_tiles_(false), |
41 needs_begin_main_frame_(false), | 42 needs_begin_main_frame_(false), |
42 visible_(false), | 43 visible_(false), |
43 can_start_(false), | 44 can_start_(false), |
44 can_draw_(false), | 45 can_draw_(false), |
45 has_pending_tree_(false), | 46 has_pending_tree_(false), |
46 pending_tree_is_ready_for_activation_(false), | 47 pending_tree_is_ready_for_activation_(false), |
47 active_tree_needs_first_draw_(false), | 48 active_tree_needs_first_draw_(false), |
48 did_create_and_initialize_first_output_surface_(false), | 49 did_create_and_initialize_first_output_surface_(false), |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 WillSendBeginMainFrame(); | 578 WillSendBeginMainFrame(); |
578 return; | 579 return; |
579 | 580 |
580 case ACTION_COMMIT: { | 581 case ACTION_COMMIT: { |
581 bool commit_has_no_updates = false; | 582 bool commit_has_no_updates = false; |
582 WillCommit(commit_has_no_updates); | 583 WillCommit(commit_has_no_updates); |
583 return; | 584 return; |
584 } | 585 } |
585 | 586 |
586 case ACTION_DRAW_AND_SWAP_FORCED: | 587 case ACTION_DRAW_AND_SWAP_FORCED: |
587 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { | 588 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: |
588 bool did_request_swap = true; | 589 case ACTION_DRAW_AND_SWAP_ABORT: |
589 WillDraw(did_request_swap); | 590 WillDraw(); |
590 return; | 591 return; |
591 } | |
592 | |
593 case ACTION_DRAW_AND_SWAP_ABORT: { | |
594 bool did_request_swap = false; | |
595 WillDraw(did_request_swap); | |
596 return; | |
597 } | |
598 | 592 |
599 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: | 593 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: |
600 WillBeginOutputSurfaceCreation(); | 594 WillBeginOutputSurfaceCreation(); |
601 return; | 595 return; |
602 | 596 |
603 case ACTION_PREPARE_TILES: | 597 case ACTION_PREPARE_TILES: |
604 WillPrepareTiles(); | 598 WillPrepareTiles(); |
605 return; | 599 return; |
606 | 600 |
607 case ACTION_INVALIDATE_OUTPUT_SURFACE: | 601 case ACTION_INVALIDATE_OUTPUT_SURFACE: |
608 WillInvalidateOutputSurface(); | 602 WillInvalidateOutputSurface(); |
609 return; | 603 return; |
610 } | 604 } |
611 } | 605 } |
| 606 |
| 607 void SchedulerStateMachine::DidAction(Action action) { |
| 608 switch (action) { |
| 609 case ACTION_NONE: |
| 610 return; |
| 611 |
| 612 case ACTION_ACTIVATE_SYNC_TREE: |
| 613 return; |
| 614 |
| 615 case ACTION_ANIMATE: |
| 616 return; |
| 617 |
| 618 case ACTION_SEND_BEGIN_MAIN_FRAME: |
| 619 return; |
| 620 |
| 621 case ACTION_COMMIT: { |
| 622 return; |
| 623 } |
| 624 |
| 625 case ACTION_DRAW_AND_SWAP_FORCED: |
| 626 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { |
| 627 bool did_request_swap = true; |
| 628 DidDraw(did_request_swap); |
| 629 return; |
| 630 } |
| 631 |
| 632 case ACTION_DRAW_AND_SWAP_ABORT: { |
| 633 bool did_request_swap = false; |
| 634 DidDraw(did_request_swap); |
| 635 return; |
| 636 } |
| 637 |
| 638 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: |
| 639 return; |
| 640 |
| 641 case ACTION_PREPARE_TILES: |
| 642 return; |
| 643 |
| 644 case ACTION_INVALIDATE_OUTPUT_SURFACE: |
| 645 return; |
| 646 } |
| 647 } |
612 | 648 |
613 void SchedulerStateMachine::WillAnimate() { | 649 void SchedulerStateMachine::WillAnimate() { |
614 DCHECK(!animate_funnel_); | 650 DCHECK(!animate_funnel_); |
615 last_frame_number_animate_performed_ = current_frame_number_; | 651 last_frame_number_animate_performed_ = current_frame_number_; |
616 animate_funnel_ = true; | 652 animate_funnel_ = true; |
617 needs_animate_ = false; | 653 needs_animate_ = false; |
618 // TODO(skyostil): Instead of assuming this, require the client to tell us. | 654 // TODO(skyostil): Instead of assuming this, require the client to tell us. |
619 SetNeedsRedraw(); | 655 SetNeedsRedraw(); |
620 } | 656 } |
621 | 657 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 | 732 |
697 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) | 733 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) |
698 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; | 734 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; |
699 | 735 |
700 has_pending_tree_ = false; | 736 has_pending_tree_ = false; |
701 pending_tree_is_ready_for_activation_ = false; | 737 pending_tree_is_ready_for_activation_ = false; |
702 active_tree_needs_first_draw_ = true; | 738 active_tree_needs_first_draw_ = true; |
703 needs_redraw_ = true; | 739 needs_redraw_ = true; |
704 } | 740 } |
705 | 741 |
706 void SchedulerStateMachine::WillDraw(bool did_request_swap) { | 742 void SchedulerStateMachine::WillDraw() { |
| 743 // We need to reset needs_redraw_ before we draw since the |
| 744 // draw itself might request another draw. |
| 745 needs_redraw_ = false; |
| 746 } |
| 747 |
| 748 void SchedulerStateMachine::DidDraw(bool did_request_swap) { |
| 749 active_tree_needs_first_draw_ = false; |
| 750 |
707 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) | 751 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
708 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; | 752 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; |
709 | 753 |
710 if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW) | 754 if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW) |
711 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; | 755 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; |
712 | 756 |
713 needs_redraw_ = false; | |
714 active_tree_needs_first_draw_ = false; | |
715 | |
716 if (did_request_swap) { | 757 if (did_request_swap) { |
717 DCHECK(!request_swap_funnel_); | 758 DCHECK(!request_swap_funnel_); |
718 request_swap_funnel_ = true; | 759 request_swap_funnel_ = true; |
719 did_request_swap_in_last_frame_ = true; | 760 did_request_swap_in_last_frame_ = true; |
720 last_frame_number_swap_requested_ = current_frame_number_; | 761 last_frame_number_swap_requested_ = current_frame_number_; |
721 } | 762 } |
| 763 |
| 764 switch (last_draw_result_) { |
| 765 case INVALID_RESULT: |
| 766 NOTREACHED() << "Uninitialized DrawResult."; |
| 767 break; |
| 768 case DRAW_ABORTED_CANT_DRAW: |
| 769 case DRAW_ABORTED_CONTEXT_LOST: |
| 770 NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:" |
| 771 << last_draw_result_; |
| 772 break; |
| 773 case DRAW_SUCCESS: |
| 774 consecutive_checkerboard_animations_ = 0; |
| 775 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; |
| 776 break; |
| 777 case DRAW_ABORTED_CHECKERBOARD_ANIMATIONS: |
| 778 needs_redraw_ = true; |
| 779 |
| 780 // If we're already in the middle of a redraw, we don't need to |
| 781 // restart it. |
| 782 if (forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE) |
| 783 return; |
| 784 |
| 785 needs_begin_main_frame_ = true; |
| 786 consecutive_checkerboard_animations_++; |
| 787 if (settings_.timeout_and_draw_when_animation_checkerboards && |
| 788 consecutive_checkerboard_animations_ >= |
| 789 settings_.maximum_number_of_failed_draws_before_draw_is_forced) { |
| 790 consecutive_checkerboard_animations_ = 0; |
| 791 // We need to force a draw, but it doesn't make sense to do this until |
| 792 // we've committed and have new textures. |
| 793 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT; |
| 794 } |
| 795 break; |
| 796 case DRAW_ABORTED_MISSING_HIGH_RES_CONTENT: |
| 797 // It's not clear whether this missing content is because of missing |
| 798 // pictures (which requires a commit) or because of memory pressure |
| 799 // removing textures (which might not). To be safe, request a commit |
| 800 // anyway. |
| 801 needs_begin_main_frame_ = true; |
| 802 break; |
| 803 } |
| 804 |
| 805 last_draw_result_ = DRAW_SUCCESS; |
722 } | 806 } |
723 | 807 |
724 void SchedulerStateMachine::WillPrepareTiles() { | 808 void SchedulerStateMachine::WillPrepareTiles() { |
725 needs_prepare_tiles_ = false; | 809 needs_prepare_tiles_ = false; |
726 } | 810 } |
727 | 811 |
728 void SchedulerStateMachine::WillBeginOutputSurfaceCreation() { | 812 void SchedulerStateMachine::WillBeginOutputSurfaceCreation() { |
729 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST); | 813 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST); |
730 output_surface_state_ = OUTPUT_SURFACE_CREATING; | 814 output_surface_state_ = OUTPUT_SURFACE_CREATING; |
731 | 815 |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 | 1109 |
1026 void SchedulerStateMachine::DidSwapBuffersComplete() { | 1110 void SchedulerStateMachine::DidSwapBuffersComplete() { |
1027 pending_swaps_--; | 1111 pending_swaps_--; |
1028 } | 1112 } |
1029 | 1113 |
1030 void SchedulerStateMachine::SetImplLatencyTakesPriority( | 1114 void SchedulerStateMachine::SetImplLatencyTakesPriority( |
1031 bool impl_latency_takes_priority) { | 1115 bool impl_latency_takes_priority) { |
1032 impl_latency_takes_priority_ = impl_latency_takes_priority; | 1116 impl_latency_takes_priority_ = impl_latency_takes_priority; |
1033 } | 1117 } |
1034 | 1118 |
1035 void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) { | 1119 void SchedulerStateMachine::SetDrawResult(DrawResult result) { |
1036 switch (result) { | 1120 last_draw_result_ = result; |
1037 case INVALID_RESULT: | |
1038 NOTREACHED() << "Uninitialized DrawResult."; | |
1039 break; | |
1040 case DRAW_ABORTED_CANT_DRAW: | |
1041 case DRAW_ABORTED_CONTEXT_LOST: | |
1042 NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:" | |
1043 << result; | |
1044 break; | |
1045 case DRAW_SUCCESS: | |
1046 consecutive_checkerboard_animations_ = 0; | |
1047 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; | |
1048 break; | |
1049 case DRAW_ABORTED_CHECKERBOARD_ANIMATIONS: | |
1050 needs_redraw_ = true; | |
1051 | |
1052 // If we're already in the middle of a redraw, we don't need to | |
1053 // restart it. | |
1054 if (forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE) | |
1055 return; | |
1056 | |
1057 needs_begin_main_frame_ = true; | |
1058 consecutive_checkerboard_animations_++; | |
1059 if (settings_.timeout_and_draw_when_animation_checkerboards && | |
1060 consecutive_checkerboard_animations_ >= | |
1061 settings_.maximum_number_of_failed_draws_before_draw_is_forced) { | |
1062 consecutive_checkerboard_animations_ = 0; | |
1063 // We need to force a draw, but it doesn't make sense to do this until | |
1064 // we've committed and have new textures. | |
1065 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT; | |
1066 } | |
1067 break; | |
1068 case DRAW_ABORTED_MISSING_HIGH_RES_CONTENT: | |
1069 // It's not clear whether this missing content is because of missing | |
1070 // pictures (which requires a commit) or because of memory pressure | |
1071 // removing textures (which might not). To be safe, request a commit | |
1072 // anyway. | |
1073 needs_begin_main_frame_ = true; | |
1074 break; | |
1075 } | |
1076 } | 1121 } |
1077 | 1122 |
1078 void SchedulerStateMachine::SetNeedsBeginMainFrame() { | 1123 void SchedulerStateMachine::SetNeedsBeginMainFrame() { |
1079 needs_begin_main_frame_ = true; | 1124 needs_begin_main_frame_ = true; |
1080 } | 1125 } |
1081 | 1126 |
1082 void SchedulerStateMachine::NotifyReadyToCommit() { | 1127 void SchedulerStateMachine::NotifyReadyToCommit() { |
1083 DCHECK(begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_STARTED) | 1128 DCHECK(begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_STARTED) |
1084 << AsValue()->ToString(); | 1129 << AsValue()->ToString(); |
1085 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT; | 1130 begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1159 case OUTPUT_SURFACE_ACTIVE: | 1204 case OUTPUT_SURFACE_ACTIVE: |
1160 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: | 1205 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: |
1161 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: | 1206 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: |
1162 return true; | 1207 return true; |
1163 } | 1208 } |
1164 NOTREACHED(); | 1209 NOTREACHED(); |
1165 return false; | 1210 return false; |
1166 } | 1211 } |
1167 | 1212 |
1168 } // namespace cc | 1213 } // namespace cc |
OLD | NEW |