| 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/format_macros.h" |     9 #include "base/format_macros.h" | 
|     9 #include "base/logging.h" |    10 #include "base/logging.h" | 
|    10 #include "base/strings/stringprintf.h" |    11 #include "base/strings/stringprintf.h" | 
|    11 #include "base/values.h" |    12 #include "base/values.h" | 
|    12 #include "ui/gfx/frame_time.h" |    13 #include "ui/gfx/frame_time.h" | 
|    13  |    14  | 
|    14 namespace cc { |    15 namespace cc { | 
|    15  |    16  | 
|    16 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |    17 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) | 
|    17     : settings_(settings), |    18     : settings_(settings), | 
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   140       return "ACTION_DRAW_AND_SWAP_ABORT"; |   141       return "ACTION_DRAW_AND_SWAP_ABORT"; | 
|   141     case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: |   142     case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: | 
|   142       return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; |   143       return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; | 
|   143     case ACTION_MANAGE_TILES: |   144     case ACTION_MANAGE_TILES: | 
|   144       return "ACTION_MANAGE_TILES"; |   145       return "ACTION_MANAGE_TILES"; | 
|   145   } |   146   } | 
|   146   NOTREACHED(); |   147   NOTREACHED(); | 
|   147   return "???"; |   148   return "???"; | 
|   148 } |   149 } | 
|   149  |   150  | 
|   150 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const  { |   151 scoped_refptr<base::debug::ConvertableToTraceFormat> | 
|   151   scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); |   152 SchedulerStateMachine::AsValue() const { | 
 |   153   scoped_refptr<base::debug::TracedValue> state = | 
 |   154       new base::debug::TracedValue(); | 
 |   155   AsValueInto(state); | 
 |   156   return state; | 
 |   157 } | 
|   152  |   158  | 
|   153   scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue); |   159 void SchedulerStateMachine::AsValueInto(base::debug::TracedValue* state) const { | 
|   154   major_state->SetString("next_action", ActionToString(NextAction())); |   160   state->BeginDictionary("major_state"); | 
|   155   major_state->SetString("begin_impl_frame_state", |   161   state->SetString("next_action", ActionToString(NextAction())); | 
|   156                          BeginImplFrameStateToString(begin_impl_frame_state_)); |   162   state->SetString("begin_impl_frame_state", | 
|   157   major_state->SetString("commit_state", CommitStateToString(commit_state_)); |   163                    BeginImplFrameStateToString(begin_impl_frame_state_)); | 
|   158   major_state->SetString("output_surface_state_", |   164   state->SetString("commit_state", CommitStateToString(commit_state_)); | 
|   159                          OutputSurfaceStateToString(output_surface_state_)); |   165   state->SetString("output_surface_state_", | 
|   160   major_state->SetString( |   166                    OutputSurfaceStateToString(output_surface_state_)); | 
|   161       "forced_redraw_state", |   167   state->SetString("forced_redraw_state", | 
|   162       ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); |   168                    ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); | 
|   163   state->Set("major_state", major_state.release()); |   169   state->EndDictionary(); | 
|   164  |   170  | 
|   165   scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue); |   171   state->BeginDictionary("major_timestamps_in_ms"); | 
|   166   base::TimeTicks now = gfx::FrameTime::Now(); |   172   base::TimeTicks now = gfx::FrameTime::Now(); | 
|   167   timestamps_state->SetDouble( |   173   state->SetDouble("0_interval", | 
|   168       "0_interval", begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L); |   174                    begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L); | 
|   169   timestamps_state->SetDouble( |   175   state->SetDouble( | 
|   170       "1_now_to_deadline", |   176       "1_now_to_deadline", | 
|   171       (begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L); |   177       (begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L); | 
|   172   timestamps_state->SetDouble( |   178   state->SetDouble( | 
|   173       "2_frame_time_to_now", |   179       "2_frame_time_to_now", | 
|   174       (now - begin_impl_frame_args_.frame_time).InMicroseconds() / 1000.0L); |   180       (now - begin_impl_frame_args_.frame_time).InMicroseconds() / 1000.0L); | 
|   175   timestamps_state->SetDouble( |   181   state->SetDouble("3_frame_time_to_deadline", | 
|   176       "3_frame_time_to_deadline", |   182                    (begin_impl_frame_args_.deadline - | 
|   177       (begin_impl_frame_args_.deadline - begin_impl_frame_args_.frame_time) |   183                     begin_impl_frame_args_.frame_time).InMicroseconds() / | 
|   178               .InMicroseconds() / |   184                        1000.0L); | 
|   179           1000.0L); |   185   state->SetDouble("4_now", | 
|   180   timestamps_state->SetDouble( |   186                    (now - base::TimeTicks()).InMicroseconds() / 1000.0L); | 
|   181       "4_now", (now - base::TimeTicks()).InMicroseconds() / 1000.0L); |   187   state->SetDouble( | 
|   182   timestamps_state->SetDouble( |  | 
|   183       "5_frame_time", |   188       "5_frame_time", | 
|   184       (begin_impl_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() / |   189       (begin_impl_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() / | 
|   185           1000.0L); |   190           1000.0L); | 
|   186   timestamps_state->SetDouble( |   191   state->SetDouble( | 
|   187       "6_deadline", |   192       "6_deadline", | 
|   188       (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / |   193       (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / | 
|   189           1000.0L); |   194           1000.0L); | 
|   190   state->Set("major_timestamps_in_ms", timestamps_state.release()); |   195   state->EndDictionary(); | 
|   191  |   196  | 
|   192   scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue); |   197   state->BeginDictionary("minor_state"); | 
|   193   minor_state->SetInteger("commit_count", commit_count_); |   198   state->SetInteger("commit_count", commit_count_); | 
|   194   minor_state->SetInteger("current_frame_number", current_frame_number_); |   199   state->SetInteger("current_frame_number", current_frame_number_); | 
|   195  |   200  | 
|   196   minor_state->SetInteger("last_frame_number_animate_performed", |   201   state->SetInteger("last_frame_number_animate_performed", | 
|   197                           last_frame_number_animate_performed_); |   202                     last_frame_number_animate_performed_); | 
|   198   minor_state->SetInteger("last_frame_number_swap_performed", |   203   state->SetInteger("last_frame_number_swap_performed", | 
|   199                           last_frame_number_swap_performed_); |   204                     last_frame_number_swap_performed_); | 
|   200   minor_state->SetInteger("last_frame_number_swap_requested", |   205   state->SetInteger("last_frame_number_swap_requested", | 
|   201                           last_frame_number_swap_requested_); |   206                     last_frame_number_swap_requested_); | 
|   202   minor_state->SetInteger( |   207   state->SetInteger("last_frame_number_begin_main_frame_sent", | 
|   203       "last_frame_number_begin_main_frame_sent", |   208                     last_frame_number_begin_main_frame_sent_); | 
|   204       last_frame_number_begin_main_frame_sent_); |   209   state->SetInteger("last_frame_number_update_visible_tiles_was_called", | 
|   205   minor_state->SetInteger( |   210                     last_frame_number_update_visible_tiles_was_called_); | 
|   206       "last_frame_number_update_visible_tiles_was_called", |  | 
|   207       last_frame_number_update_visible_tiles_was_called_); |  | 
|   208  |   211  | 
|   209   minor_state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_); |   212   state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_); | 
|   210   minor_state->SetInteger("consecutive_checkerboard_animations", |   213   state->SetInteger("consecutive_checkerboard_animations", | 
|   211                           consecutive_checkerboard_animations_); |   214                     consecutive_checkerboard_animations_); | 
|   212   minor_state->SetInteger("max_pending_swaps_", max_pending_swaps_); |   215   state->SetInteger("max_pending_swaps_", max_pending_swaps_); | 
|   213   minor_state->SetInteger("pending_swaps_", pending_swaps_); |   216   state->SetInteger("pending_swaps_", pending_swaps_); | 
|   214   minor_state->SetBoolean("needs_redraw", needs_redraw_); |   217   state->SetBoolean("needs_redraw", needs_redraw_); | 
|   215   minor_state->SetBoolean("needs_animate_", needs_animate_); |   218   state->SetBoolean("needs_animate_", needs_animate_); | 
|   216   minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); |   219   state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); | 
|   217   minor_state->SetBoolean("swap_used_incomplete_tile", |   220   state->SetBoolean("swap_used_incomplete_tile", swap_used_incomplete_tile_); | 
|   218                           swap_used_incomplete_tile_); |   221   state->SetBoolean("needs_commit", needs_commit_); | 
|   219   minor_state->SetBoolean("needs_commit", needs_commit_); |   222   state->SetBoolean("visible", visible_); | 
|   220   minor_state->SetBoolean("visible", visible_); |   223   state->SetBoolean("can_start", can_start_); | 
|   221   minor_state->SetBoolean("can_start", can_start_); |   224   state->SetBoolean("can_draw", can_draw_); | 
|   222   minor_state->SetBoolean("can_draw", can_draw_); |   225   state->SetBoolean("has_pending_tree", has_pending_tree_); | 
|   223   minor_state->SetBoolean("has_pending_tree", has_pending_tree_); |   226   state->SetBoolean("pending_tree_is_ready_for_activation", | 
|   224   minor_state->SetBoolean("pending_tree_is_ready_for_activation", |   227                     pending_tree_is_ready_for_activation_); | 
|   225                           pending_tree_is_ready_for_activation_); |   228   state->SetBoolean("active_tree_needs_first_draw", | 
|   226   minor_state->SetBoolean("active_tree_needs_first_draw", |   229                     active_tree_needs_first_draw_); | 
|   227                           active_tree_needs_first_draw_); |   230   state->SetBoolean("did_create_and_initialize_first_output_surface", | 
|   228   minor_state->SetBoolean("did_create_and_initialize_first_output_surface", |   231                     did_create_and_initialize_first_output_surface_); | 
|   229                           did_create_and_initialize_first_output_surface_); |   232   state->SetBoolean("smoothness_takes_priority", smoothness_takes_priority_); | 
|   230   minor_state->SetBoolean("smoothness_takes_priority", |   233   state->SetBoolean("main_thread_is_in_high_latency_mode", | 
|   231                           smoothness_takes_priority_); |   234                     MainThreadIsInHighLatencyMode()); | 
|   232   minor_state->SetBoolean("main_thread_is_in_high_latency_mode", |   235   state->SetBoolean("skip_begin_main_frame_to_reduce_latency", | 
|   233                           MainThreadIsInHighLatencyMode()); |   236                     skip_begin_main_frame_to_reduce_latency_); | 
|   234   minor_state->SetBoolean("skip_begin_main_frame_to_reduce_latency", |   237   state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 
|   235                           skip_begin_main_frame_to_reduce_latency_); |   238                     skip_next_begin_main_frame_to_reduce_latency_); | 
|   236   minor_state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |   239   state->SetBoolean("continuous_painting", continuous_painting_); | 
|   237                           skip_next_begin_main_frame_to_reduce_latency_); |   240   state->EndDictionary(); | 
|   238   minor_state->SetBoolean("continuous_painting", continuous_painting_); |  | 
|   239   state->Set("minor_state", minor_state.release()); |  | 
|   240  |  | 
|   241   return state.PassAs<base::Value>(); |  | 
|   242 } |   241 } | 
|   243  |   242  | 
|   244 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { |   243 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { | 
|   245   current_frame_number_++; |   244   current_frame_number_++; | 
|   246  |   245  | 
|   247   // "Drain" the ManageTiles funnel. |   246   // "Drain" the ManageTiles funnel. | 
|   248   if (manage_tiles_funnel_ > 0) |   247   if (manage_tiles_funnel_ > 0) | 
|   249     manage_tiles_funnel_--; |   248     manage_tiles_funnel_--; | 
|   250  |   249  | 
|   251   skip_begin_main_frame_to_reduce_latency_ = |   250   skip_begin_main_frame_to_reduce_latency_ = | 
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   803   // BeginImplFrame. |   802   // BeginImplFrame. | 
|   804   if (HasRequestedSwapThisFrame()) |   803   if (HasRequestedSwapThisFrame()) | 
|   805     return true; |   804     return true; | 
|   806  |   805  | 
|   807   return false; |   806   return false; | 
|   808 } |   807 } | 
|   809  |   808  | 
|   810 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { |   809 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { | 
|   811   AdvanceCurrentFrameNumber(); |   810   AdvanceCurrentFrameNumber(); | 
|   812   begin_impl_frame_args_ = args; |   811   begin_impl_frame_args_ = args; | 
|   813   DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) << *AsValue(); |   812   DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) | 
 |   813       << AsValue()->ToString(); | 
|   814   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; |   814   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; | 
|   815 } |   815 } | 
|   816  |   816  | 
|   817 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { |   817 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { | 
|   818   DCHECK_EQ(begin_impl_frame_state_, |   818   DCHECK_EQ(begin_impl_frame_state_, | 
|   819             BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) |   819             BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) | 
|   820       << *AsValue(); |   820       << AsValue()->ToString(); | 
|   821   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; |   821   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; | 
|   822 } |   822 } | 
|   823  |   823  | 
|   824 void SchedulerStateMachine::OnBeginImplFrameDeadline() { |   824 void SchedulerStateMachine::OnBeginImplFrameDeadline() { | 
|   825   DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) |   825   DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) | 
|   826       << *AsValue(); |   826       << AsValue()->ToString(); | 
|   827   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; |   827   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; | 
|   828 } |   828 } | 
|   829  |   829  | 
|   830 void SchedulerStateMachine::OnBeginImplFrameIdle() { |   830 void SchedulerStateMachine::OnBeginImplFrameIdle() { | 
|   831   DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) |   831   DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) | 
|   832       << *AsValue(); |   832       << AsValue()->ToString(); | 
|   833   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE; |   833   begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE; | 
|   834 } |   834 } | 
|   835  |   835  | 
|   836 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineEarly() const { |   836 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineEarly() const { | 
|   837   // TODO(brianderson): This should take into account multiple commit sources. |   837   // TODO(brianderson): This should take into account multiple commit sources. | 
|   838  |   838  | 
|   839   if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) |   839   if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) | 
|   840     return false; |   840     return false; | 
|   841  |   841  | 
|   842   // If we've lost the output surface, end the current BeginImplFrame ASAP |   842   // If we've lost the output surface, end the current BeginImplFrame ASAP | 
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1002       // removing textures (which might not).  To be safe, request a commit |  1002       // removing textures (which might not).  To be safe, request a commit | 
|  1003       // anyway. |  1003       // anyway. | 
|  1004       needs_commit_ = true; |  1004       needs_commit_ = true; | 
|  1005       break; |  1005       break; | 
|  1006   } |  1006   } | 
|  1007 } |  1007 } | 
|  1008  |  1008  | 
|  1009 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; } |  1009 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; } | 
|  1010  |  1010  | 
|  1011 void SchedulerStateMachine::NotifyReadyToCommit() { |  1011 void SchedulerStateMachine::NotifyReadyToCommit() { | 
|  1012   DCHECK(commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED) << *AsValue(); |  1012   DCHECK(commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED) | 
 |  1013       << AsValue()->ToString(); | 
|  1013   commit_state_ = COMMIT_STATE_READY_TO_COMMIT; |  1014   commit_state_ = COMMIT_STATE_READY_TO_COMMIT; | 
|  1014 } |  1015 } | 
|  1015  |  1016  | 
|  1016 void SchedulerStateMachine::BeginMainFrameAborted(bool did_handle) { |  1017 void SchedulerStateMachine::BeginMainFrameAborted(bool did_handle) { | 
|  1017   DCHECK_EQ(commit_state_, COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); |  1018   DCHECK_EQ(commit_state_, COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | 
|  1018   if (did_handle) { |  1019   if (did_handle) { | 
|  1019     bool commit_was_aborted = true; |  1020     bool commit_was_aborted = true; | 
|  1020     UpdateStateOnCommit(commit_was_aborted); |  1021     UpdateStateOnCommit(commit_was_aborted); | 
|  1021   } else { |  1022   } else { | 
|  1022     commit_state_ = COMMIT_STATE_IDLE; |  1023     commit_state_ = COMMIT_STATE_IDLE; | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1070     case OUTPUT_SURFACE_ACTIVE: |  1071     case OUTPUT_SURFACE_ACTIVE: | 
|  1071     case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: |  1072     case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: | 
|  1072     case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: |  1073     case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: | 
|  1073       return true; |  1074       return true; | 
|  1074   } |  1075   } | 
|  1075   NOTREACHED(); |  1076   NOTREACHED(); | 
|  1076   return false; |  1077   return false; | 
|  1077 } |  1078 } | 
|  1078  |  1079  | 
|  1079 }  // namespace cc |  1080 }  // namespace cc | 
| OLD | NEW |