| 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|    47       active_tree_needs_first_draw_(false), |    47       active_tree_needs_first_draw_(false), | 
|    48       did_create_and_initialize_first_output_surface_(false), |    48       did_create_and_initialize_first_output_surface_(false), | 
|    49       impl_latency_takes_priority_(false), |    49       impl_latency_takes_priority_(false), | 
|    50       main_thread_missed_last_deadline_(false), |    50       main_thread_missed_last_deadline_(false), | 
|    51       skip_next_begin_main_frame_to_reduce_latency_(false), |    51       skip_next_begin_main_frame_to_reduce_latency_(false), | 
|    52       continuous_painting_(false), |    52       continuous_painting_(false), | 
|    53       children_need_begin_frames_(false), |    53       children_need_begin_frames_(false), | 
|    54       defer_commits_(false), |    54       defer_commits_(false), | 
|    55       video_needs_begin_frames_(false), |    55       video_needs_begin_frames_(false), | 
|    56       last_commit_had_no_updates_(false), |    56       last_commit_had_no_updates_(false), | 
|    57       wait_for_active_tree_ready_to_draw_(false), |    57       wait_for_ready_to_draw_(false), | 
|    58       did_request_swap_in_last_frame_(false), |    58       did_request_swap_in_last_frame_(false), | 
|    59       did_perform_swap_in_last_draw_(false) {} |    59       did_perform_swap_in_last_draw_(false) {} | 
|    60  |    60  | 
|    61 const char* SchedulerStateMachine::OutputSurfaceStateToString( |    61 const char* SchedulerStateMachine::OutputSurfaceStateToString( | 
|    62     OutputSurfaceState state) { |    62     OutputSurfaceState state) { | 
|    63   switch (state) { |    63   switch (state) { | 
|    64     case OUTPUT_SURFACE_ACTIVE: |    64     case OUTPUT_SURFACE_ACTIVE: | 
|    65       return "OUTPUT_SURFACE_ACTIVE"; |    65       return "OUTPUT_SURFACE_ACTIVE"; | 
|    66     case OUTPUT_SURFACE_LOST: |    66     case OUTPUT_SURFACE_LOST: | 
|    67       return "OUTPUT_SURFACE_LOST"; |    67       return "OUTPUT_SURFACE_LOST"; | 
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   224   state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_); |   224   state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_); | 
|   225   state->SetBoolean("needs_commit", needs_commit_); |   225   state->SetBoolean("needs_commit", needs_commit_); | 
|   226   state->SetBoolean("visible", visible_); |   226   state->SetBoolean("visible", visible_); | 
|   227   state->SetBoolean("can_start", can_start_); |   227   state->SetBoolean("can_start", can_start_); | 
|   228   state->SetBoolean("can_draw", can_draw_); |   228   state->SetBoolean("can_draw", can_draw_); | 
|   229   state->SetBoolean("has_pending_tree", has_pending_tree_); |   229   state->SetBoolean("has_pending_tree", has_pending_tree_); | 
|   230   state->SetBoolean("pending_tree_is_ready_for_activation", |   230   state->SetBoolean("pending_tree_is_ready_for_activation", | 
|   231                     pending_tree_is_ready_for_activation_); |   231                     pending_tree_is_ready_for_activation_); | 
|   232   state->SetBoolean("active_tree_needs_first_draw", |   232   state->SetBoolean("active_tree_needs_first_draw", | 
|   233                     active_tree_needs_first_draw_); |   233                     active_tree_needs_first_draw_); | 
|   234   state->SetBoolean("wait_for_active_tree_ready_to_draw", |   234   state->SetBoolean("wait_for_ready_to_draw", wait_for_ready_to_draw_); | 
|   235                     wait_for_active_tree_ready_to_draw_); |  | 
|   236   state->SetBoolean("did_create_and_initialize_first_output_surface", |   235   state->SetBoolean("did_create_and_initialize_first_output_surface", | 
|   237                     did_create_and_initialize_first_output_surface_); |   236                     did_create_and_initialize_first_output_surface_); | 
|   238   state->SetBoolean("impl_latency_takes_priority", |   237   state->SetBoolean("impl_latency_takes_priority", | 
|   239                     impl_latency_takes_priority_); |   238                     impl_latency_takes_priority_); | 
|   240   state->SetBoolean("main_thread_missed_last_deadline", |   239   state->SetBoolean("main_thread_missed_last_deadline", | 
|   241                     main_thread_missed_last_deadline_); |   240                     main_thread_missed_last_deadline_); | 
|   242   state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |   241   state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 
|   243                     skip_next_begin_main_frame_to_reduce_latency_); |   242                     skip_next_begin_main_frame_to_reduce_latency_); | 
|   244   state->SetBoolean("continuous_painting", continuous_painting_); |   243   state->SetBoolean("continuous_painting", continuous_painting_); | 
|   245   state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); |   244   state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); | 
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   637  |   636  | 
|   638   if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) { |   637   if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) { | 
|   639     commit_state_ = COMMIT_STATE_IDLE; |   638     commit_state_ = COMMIT_STATE_IDLE; | 
|   640   } else { |   639   } else { | 
|   641     commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION; |   640     commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION; | 
|   642   } |   641   } | 
|   643  |   642  | 
|   644   // If the commit was aborted, then there is no pending tree. |   643   // If the commit was aborted, then there is no pending tree. | 
|   645   has_pending_tree_ = !commit_has_no_updates; |   644   has_pending_tree_ = !commit_has_no_updates; | 
|   646  |   645  | 
 |   646   wait_for_ready_to_draw_ = | 
 |   647       !commit_has_no_updates && settings_.commit_to_active_tree; | 
 |   648  | 
|   647   // Update state related to forced draws. |   649   // Update state related to forced draws. | 
|   648   if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) { |   650   if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) { | 
|   649     forced_redraw_state_ = has_pending_tree_ |   651     forced_redraw_state_ = has_pending_tree_ | 
|   650                                ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION |   652                                ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION | 
|   651                                : FORCED_REDRAW_STATE_WAITING_FOR_DRAW; |   653                                : FORCED_REDRAW_STATE_WAITING_FOR_DRAW; | 
|   652   } |   654   } | 
|   653  |   655  | 
|   654   // Update the output surface state. |   656   // Update the output surface state. | 
|   655   DCHECK_NE(output_surface_state_, OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION); |   657   DCHECK_NE(output_surface_state_, OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION); | 
|   656   if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { |   658   if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { | 
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   747 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { |   749 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { | 
|   748   TRACE_EVENT_INSTANT0("cc", |   750   TRACE_EVENT_INSTANT0("cc", | 
|   749                        "Scheduler: SkipNextBeginMainFrameToReduceLatency", |   751                        "Scheduler: SkipNextBeginMainFrameToReduceLatency", | 
|   750                        TRACE_EVENT_SCOPE_THREAD); |   752                        TRACE_EVENT_SCOPE_THREAD); | 
|   751   skip_next_begin_main_frame_to_reduce_latency_ = true; |   753   skip_next_begin_main_frame_to_reduce_latency_ = true; | 
|   752 } |   754 } | 
|   753  |   755  | 
|   754 bool SchedulerStateMachine::BeginFrameRequiredForChildren() const { |   756 bool SchedulerStateMachine::BeginFrameRequiredForChildren() const { | 
|   755   return children_need_begin_frames_; |   757   return children_need_begin_frames_; | 
|   756 } |   758 } | 
 |   759  | 
|   757 bool SchedulerStateMachine::BeginFrameNeededForVideo() const { |   760 bool SchedulerStateMachine::BeginFrameNeededForVideo() const { | 
|   758   return video_needs_begin_frames_; |   761   return video_needs_begin_frames_; | 
|   759 } |   762 } | 
|   760  |   763  | 
|   761 bool SchedulerStateMachine::BeginFrameNeeded() const { |   764 bool SchedulerStateMachine::BeginFrameNeeded() const { | 
|   762   // We can't handle BeginFrames when output surface isn't initialized. |   765   // We can't handle BeginFrames when output surface isn't initialized. | 
|   763   // TODO(brianderson): Support output surface creation inside a BeginFrame. |   766   // TODO(brianderson): Support output surface creation inside a BeginFrame. | 
|   764   if (!HasInitializedOutputSurface()) |   767   if (!HasInitializedOutputSurface()) | 
|   765     return false; |   768     return false; | 
|   766  |   769  | 
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   892   // funnels so that we don't perform any actions that we shouldn't. |   895   // funnels so that we don't perform any actions that we shouldn't. | 
|   893   if (!BeginFrameNeeded()) |   896   if (!BeginFrameNeeded()) | 
|   894     send_begin_main_frame_funnel_ = true; |   897     send_begin_main_frame_funnel_ = true; | 
|   895 } |   898 } | 
|   896  |   899  | 
|   897 SchedulerStateMachine::BeginImplFrameDeadlineMode |   900 SchedulerStateMachine::BeginImplFrameDeadlineMode | 
|   898 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { |   901 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { | 
|   899   if (settings_.using_synchronous_renderer_compositor) { |   902   if (settings_.using_synchronous_renderer_compositor) { | 
|   900     // No deadline for synchronous compositor. |   903     // No deadline for synchronous compositor. | 
|   901     return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE; |   904     return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE; | 
|   902   } else if (wait_for_active_tree_ready_to_draw_) { |   905   } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) { | 
 |   906     return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE; | 
 |   907   } else if (wait_for_ready_to_draw_) { | 
|   903     // When we are waiting for ready to draw signal, we do not wait to post a |   908     // When we are waiting for ready to draw signal, we do not wait to post a | 
|   904     // deadline yet. |   909     // deadline yet. | 
|   905     return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW; |   910     return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW; | 
|   906   } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) { |  | 
|   907     return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE; |  | 
|   908   } else if (needs_redraw_ && !SwapThrottled()) { |   911   } else if (needs_redraw_ && !SwapThrottled()) { | 
|   909     // We have an animation or fast input path on the impl thread that wants |   912     // We have an animation or fast input path on the impl thread that wants | 
|   910     // to draw, so don't wait too long for a new active tree. |   913     // to draw, so don't wait too long for a new active tree. | 
|   911     // If we are swap throttled we should wait until we are unblocked. |   914     // If we are swap throttled we should wait until we are unblocked. | 
|   912     return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR; |   915     return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR; | 
|   913   } else { |   916   } else { | 
|   914     // The impl thread doesn't have anything it wants to draw and we are just |   917     // The impl thread doesn't have anything it wants to draw and we are just | 
|   915     // waiting for a new active tree or we are swap throttled. In short we are |   918     // waiting for a new active tree or we are swap throttled. In short we are | 
|   916     // blocked. |   919     // blocked. | 
|   917     return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE; |   920     return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE; | 
|   918   } |   921   } | 
|   919 } |   922 } | 
|   920  |   923  | 
|   921 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() |   924 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() | 
|   922     const { |   925     const { | 
|   923   if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) |  | 
|   924     return false; |  | 
|   925  |  | 
|   926   // If we just forced activation, we should end the deadline right now. |   926   // If we just forced activation, we should end the deadline right now. | 
|   927   if (PendingActivationsShouldBeForced() && !has_pending_tree_) |   927   if (PendingActivationsShouldBeForced() && !has_pending_tree_) | 
|   928     return true; |   928     return true; | 
|   929  |   929  | 
 |   930   // Do not trigger deadline immediately if we're waiting for READY_TO_DRAW | 
 |   931   // unless it's one of the forced cases. | 
 |   932   if (wait_for_ready_to_draw_) | 
 |   933     return false; | 
 |   934  | 
|   930   // SwapAck throttle the deadline since we wont draw and swap anyway. |   935   // SwapAck throttle the deadline since we wont draw and swap anyway. | 
|   931   if (SwapThrottled()) |   936   if (SwapThrottled()) | 
|   932     return false; |   937     return false; | 
|   933  |   938  | 
|   934   if (active_tree_needs_first_draw_) |   939   if (active_tree_needs_first_draw_) | 
|   935     return true; |   940     return true; | 
|   936  |   941  | 
|   937   if (!needs_redraw_) |   942   if (!needs_redraw_) | 
|   938     return false; |   943     return false; | 
|   939  |   944  | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|   964   if (visible_ == visible) |   969   if (visible_ == visible) | 
|   965     return; |   970     return; | 
|   966  |   971  | 
|   967   visible_ = visible; |   972   visible_ = visible; | 
|   968  |   973  | 
|   969   if (visible) |   974   if (visible) | 
|   970     main_thread_missed_last_deadline_ = false; |   975     main_thread_missed_last_deadline_ = false; | 
|   971  |   976  | 
|   972   // TODO(sunnyps): Change the funnel to a bool to avoid hacks like this. |   977   // TODO(sunnyps): Change the funnel to a bool to avoid hacks like this. | 
|   973   prepare_tiles_funnel_ = 0; |   978   prepare_tiles_funnel_ = 0; | 
 |   979   wait_for_ready_to_draw_ = false; | 
|   974 } |   980 } | 
|   975  |   981  | 
|   976 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } |   982 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } | 
|   977  |   983  | 
|   978 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } |   984 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } | 
|   979  |   985  | 
|   980 void SchedulerStateMachine::SetNeedsAnimate() { |   986 void SchedulerStateMachine::SetNeedsAnimate() { | 
|   981   needs_animate_ = true; |   987   needs_animate_ = true; | 
|   982 } |   988 } | 
|   983  |   989  | 
|   984 void SchedulerStateMachine::SetWaitForReadyToDraw() { |  | 
|   985   wait_for_active_tree_ready_to_draw_ = true; |  | 
|   986 } |  | 
|   987  |  | 
|   988 bool SchedulerStateMachine::OnlyImplSideUpdatesExpected() const { |   990 bool SchedulerStateMachine::OnlyImplSideUpdatesExpected() const { | 
|   989   bool has_impl_updates = needs_redraw_ || needs_animate_; |   991   bool has_impl_updates = needs_redraw_ || needs_animate_; | 
|   990   bool main_updates_expected = |   992   bool main_updates_expected = | 
|   991       needs_commit_ || commit_state_ != COMMIT_STATE_IDLE || has_pending_tree_; |   993       needs_commit_ || commit_state_ != COMMIT_STATE_IDLE || has_pending_tree_; | 
|   992   return has_impl_updates && !main_updates_expected; |   994   return has_impl_updates && !main_updates_expected; | 
|   993 } |   995 } | 
|   994  |   996  | 
|   995 void SchedulerStateMachine::SetNeedsPrepareTiles() { |   997 void SchedulerStateMachine::SetNeedsPrepareTiles() { | 
|   996   if (!needs_prepare_tiles_) { |   998   if (!needs_prepare_tiles_) { | 
|   997     TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles"); |   999     TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles"); | 
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1101   // "Fill" the PrepareTiles funnel. |  1103   // "Fill" the PrepareTiles funnel. | 
|  1102   prepare_tiles_funnel_++; |  1104   prepare_tiles_funnel_++; | 
|  1103 } |  1105 } | 
|  1104  |  1106  | 
|  1105 void SchedulerStateMachine::DidLoseOutputSurface() { |  1107 void SchedulerStateMachine::DidLoseOutputSurface() { | 
|  1106   if (output_surface_state_ == OUTPUT_SURFACE_LOST || |  1108   if (output_surface_state_ == OUTPUT_SURFACE_LOST || | 
|  1107       output_surface_state_ == OUTPUT_SURFACE_CREATING) |  1109       output_surface_state_ == OUTPUT_SURFACE_CREATING) | 
|  1108     return; |  1110     return; | 
|  1109   output_surface_state_ = OUTPUT_SURFACE_LOST; |  1111   output_surface_state_ = OUTPUT_SURFACE_LOST; | 
|  1110   needs_redraw_ = false; |  1112   needs_redraw_ = false; | 
|  1111   wait_for_active_tree_ready_to_draw_ = false; |  1113   wait_for_ready_to_draw_ = false; | 
|  1112 } |  1114 } | 
|  1113  |  1115  | 
|  1114 void SchedulerStateMachine::NotifyReadyToActivate() { |  1116 void SchedulerStateMachine::NotifyReadyToActivate() { | 
|  1115   if (has_pending_tree_) |  1117   if (has_pending_tree_) | 
|  1116     pending_tree_is_ready_for_activation_ = true; |  1118     pending_tree_is_ready_for_activation_ = true; | 
|  1117 } |  1119 } | 
|  1118  |  1120  | 
|  1119 void SchedulerStateMachine::NotifyReadyToDraw() { |  1121 void SchedulerStateMachine::NotifyReadyToDraw() { | 
|  1120   wait_for_active_tree_ready_to_draw_ = false; |  1122   wait_for_ready_to_draw_ = false; | 
|  1121 } |  1123 } | 
|  1122  |  1124  | 
|  1123 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { |  1125 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { | 
|  1124   DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); |  1126   DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); | 
|  1125   output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; |  1127   output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; | 
|  1126  |  1128  | 
|  1127   if (did_create_and_initialize_first_output_surface_) { |  1129   if (did_create_and_initialize_first_output_surface_) { | 
|  1128     // TODO(boliu): See if we can remove this when impl-side painting is always |  1130     // TODO(boliu): See if we can remove this when impl-side painting is always | 
|  1129     // on. Does anything on the main thread need to update after recreate? |  1131     // on. Does anything on the main thread need to update after recreate? | 
|  1130     needs_commit_ = true; |  1132     needs_commit_ = true; | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
|  1149     case OUTPUT_SURFACE_ACTIVE: |  1151     case OUTPUT_SURFACE_ACTIVE: | 
|  1150     case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: |  1152     case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: | 
|  1151     case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: |  1153     case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: | 
|  1152       return true; |  1154       return true; | 
|  1153   } |  1155   } | 
|  1154   NOTREACHED(); |  1156   NOTREACHED(); | 
|  1155   return false; |  1157   return false; | 
|  1156 } |  1158 } | 
|  1157  |  1159  | 
|  1158 }  // namespace cc |  1160 }  // namespace cc | 
| OLD | NEW |