| 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 25 matching lines...) Expand all Loading... |
| 36 needs_manage_tiles_(false), | 36 needs_manage_tiles_(false), |
| 37 swap_used_incomplete_tile_(false), | 37 swap_used_incomplete_tile_(false), |
| 38 needs_commit_(false), | 38 needs_commit_(false), |
| 39 inside_poll_for_anticipated_draw_triggers_(false), | 39 inside_poll_for_anticipated_draw_triggers_(false), |
| 40 visible_(false), | 40 visible_(false), |
| 41 can_start_(false), | 41 can_start_(false), |
| 42 can_draw_(false), | 42 can_draw_(false), |
| 43 has_pending_tree_(false), | 43 has_pending_tree_(false), |
| 44 pending_tree_is_ready_for_activation_(false), | 44 pending_tree_is_ready_for_activation_(false), |
| 45 active_tree_needs_first_draw_(false), | 45 active_tree_needs_first_draw_(false), |
| 46 did_commit_after_animating_(false), | |
| 47 did_create_and_initialize_first_output_surface_(false), | 46 did_create_and_initialize_first_output_surface_(false), |
| 48 impl_latency_takes_priority_(false), | 47 impl_latency_takes_priority_(false), |
| 49 skip_next_begin_main_frame_to_reduce_latency_(false), | 48 skip_next_begin_main_frame_to_reduce_latency_(false), |
| 50 skip_begin_main_frame_to_reduce_latency_(false), | 49 skip_begin_main_frame_to_reduce_latency_(false), |
| 51 continuous_painting_(false) { | 50 continuous_painting_(false) { |
| 52 } | 51 } |
| 53 | 52 |
| 54 const char* SchedulerStateMachine::OutputSurfaceStateToString( | 53 const char* SchedulerStateMachine::OutputSurfaceStateToString( |
| 55 OutputSurfaceState state) { | 54 OutputSurfaceState state) { |
| 56 switch (state) { | 55 switch (state) { |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 state->SetBoolean("swap_used_incomplete_tile", swap_used_incomplete_tile_); | 218 state->SetBoolean("swap_used_incomplete_tile", swap_used_incomplete_tile_); |
| 220 state->SetBoolean("needs_commit", needs_commit_); | 219 state->SetBoolean("needs_commit", needs_commit_); |
| 221 state->SetBoolean("visible", visible_); | 220 state->SetBoolean("visible", visible_); |
| 222 state->SetBoolean("can_start", can_start_); | 221 state->SetBoolean("can_start", can_start_); |
| 223 state->SetBoolean("can_draw", can_draw_); | 222 state->SetBoolean("can_draw", can_draw_); |
| 224 state->SetBoolean("has_pending_tree", has_pending_tree_); | 223 state->SetBoolean("has_pending_tree", has_pending_tree_); |
| 225 state->SetBoolean("pending_tree_is_ready_for_activation", | 224 state->SetBoolean("pending_tree_is_ready_for_activation", |
| 226 pending_tree_is_ready_for_activation_); | 225 pending_tree_is_ready_for_activation_); |
| 227 state->SetBoolean("active_tree_needs_first_draw", | 226 state->SetBoolean("active_tree_needs_first_draw", |
| 228 active_tree_needs_first_draw_); | 227 active_tree_needs_first_draw_); |
| 229 state->SetBoolean("did_commit_after_animating", did_commit_after_animating_); | |
| 230 state->SetBoolean("did_create_and_initialize_first_output_surface", | 228 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("impl_latency_takes_priority", | 230 state->SetBoolean("impl_latency_takes_priority", |
| 233 impl_latency_takes_priority_); | 231 impl_latency_takes_priority_); |
| 234 state->SetBoolean("main_thread_is_in_high_latency_mode", | 232 state->SetBoolean("main_thread_is_in_high_latency_mode", |
| 235 MainThreadIsInHighLatencyMode()); | 233 MainThreadIsInHighLatencyMode()); |
| 236 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", | 234 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", |
| 237 skip_begin_main_frame_to_reduce_latency_); | 235 skip_begin_main_frame_to_reduce_latency_); |
| 238 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 236 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |
| 239 skip_next_begin_main_frame_to_reduce_latency_); | 237 skip_next_begin_main_frame_to_reduce_latency_); |
| 240 state->SetBoolean("continuous_painting", continuous_painting_); | 238 state->SetBoolean("continuous_painting", continuous_painting_); |
| 241 state->EndDictionary(); | 239 state->EndDictionary(); |
| 242 } | 240 } |
| 243 | 241 |
| 244 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { | 242 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { |
| 245 current_frame_number_++; | 243 current_frame_number_++; |
| 246 | 244 |
| 247 // "Drain" the ManageTiles funnel. | 245 // "Drain" the ManageTiles funnel. |
| 248 if (manage_tiles_funnel_ > 0) | 246 if (manage_tiles_funnel_ > 0) |
| 249 manage_tiles_funnel_--; | 247 manage_tiles_funnel_--; |
| 250 | 248 |
| 251 skip_begin_main_frame_to_reduce_latency_ = | 249 skip_begin_main_frame_to_reduce_latency_ = |
| 252 skip_next_begin_main_frame_to_reduce_latency_; | 250 skip_next_begin_main_frame_to_reduce_latency_; |
| 253 skip_next_begin_main_frame_to_reduce_latency_ = false; | 251 skip_next_begin_main_frame_to_reduce_latency_ = false; |
| 254 } | 252 } |
| 255 | 253 |
| 256 bool SchedulerStateMachine::HasAnimatedThisFrame() const { | |
| 257 return last_frame_number_animate_performed_ == current_frame_number_; | |
| 258 } | |
| 259 | |
| 260 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { | 254 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { |
| 261 return current_frame_number_ == | 255 return current_frame_number_ == |
| 262 last_frame_number_begin_main_frame_sent_; | 256 last_frame_number_begin_main_frame_sent_; |
| 263 } | 257 } |
| 264 | 258 |
| 265 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { | 259 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { |
| 266 return current_frame_number_ == | 260 return current_frame_number_ == |
| 267 last_frame_number_update_visible_tiles_was_called_; | 261 last_frame_number_update_visible_tiles_was_called_; |
| 268 } | 262 } |
| 269 | 263 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 | 334 |
| 341 bool SchedulerStateMachine::ShouldDraw() const { | 335 bool SchedulerStateMachine::ShouldDraw() const { |
| 342 // If we need to abort draws, we should do so ASAP since the draw could | 336 // If we need to abort draws, we should do so ASAP since the draw could |
| 343 // be blocking other important actions (like output surface initialization), | 337 // be blocking other important actions (like output surface initialization), |
| 344 // from occuring. If we are waiting for the first draw, then perfom the | 338 // from occuring. If we are waiting for the first draw, then perfom the |
| 345 // aborted draw to keep things moving. If we are not waiting for the first | 339 // aborted draw to keep things moving. If we are not waiting for the first |
| 346 // draw however, we don't want to abort for no reason. | 340 // draw however, we don't want to abort for no reason. |
| 347 if (PendingDrawsShouldBeAborted()) | 341 if (PendingDrawsShouldBeAborted()) |
| 348 return active_tree_needs_first_draw_; | 342 return active_tree_needs_first_draw_; |
| 349 | 343 |
| 350 // If a commit has occurred after the animate call, we need to call animate | |
| 351 // again before we should draw. | |
| 352 if (did_commit_after_animating_) | |
| 353 return false; | |
| 354 | |
| 355 // After this line, we only want to send a swap request once per frame. | 344 // After this line, we only want to send a swap request once per frame. |
| 356 if (HasRequestedSwapThisFrame()) | 345 if (HasRequestedSwapThisFrame()) |
| 357 return false; | 346 return false; |
| 358 | 347 |
| 359 // Do not queue too many swaps. | 348 // Do not queue too many swaps. |
| 360 if (pending_swaps_ >= max_pending_swaps_) | 349 if (pending_swaps_ >= max_pending_swaps_) |
| 361 return false; | 350 return false; |
| 362 | 351 |
| 363 // Except for the cases above, do not draw outside of the BeginImplFrame | 352 // Except for the cases above, do not draw outside of the BeginImplFrame |
| 364 // deadline. | 353 // deadline. |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 if (swap_used_incomplete_tile_) | 405 if (swap_used_incomplete_tile_) |
| 417 return true; | 406 return true; |
| 418 | 407 |
| 419 return false; | 408 return false; |
| 420 } | 409 } |
| 421 | 410 |
| 422 bool SchedulerStateMachine::ShouldAnimate() const { | 411 bool SchedulerStateMachine::ShouldAnimate() const { |
| 423 if (!can_draw_) | 412 if (!can_draw_) |
| 424 return false; | 413 return false; |
| 425 | 414 |
| 426 // If a commit occurred after our last call, we need to do animation again. | 415 if (last_frame_number_animate_performed_ == current_frame_number_) |
| 427 if (HasAnimatedThisFrame() && !did_commit_after_animating_) | |
| 428 return false; | 416 return false; |
| 429 | 417 |
| 430 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && | 418 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && |
| 431 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) | 419 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) |
| 432 return false; | 420 return false; |
| 433 | 421 |
| 434 return needs_redraw_ || needs_animate_; | 422 return needs_redraw_ || needs_animate_; |
| 435 } | 423 } |
| 436 | 424 |
| 437 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { | 425 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 current_frame_number_; | 557 current_frame_number_; |
| 570 return; | 558 return; |
| 571 | 559 |
| 572 case ACTION_ACTIVATE_SYNC_TREE: | 560 case ACTION_ACTIVATE_SYNC_TREE: |
| 573 UpdateStateOnActivation(); | 561 UpdateStateOnActivation(); |
| 574 return; | 562 return; |
| 575 | 563 |
| 576 case ACTION_ANIMATE: | 564 case ACTION_ANIMATE: |
| 577 last_frame_number_animate_performed_ = current_frame_number_; | 565 last_frame_number_animate_performed_ = current_frame_number_; |
| 578 needs_animate_ = false; | 566 needs_animate_ = false; |
| 579 did_commit_after_animating_ = false; | |
| 580 // TODO(skyostil): Instead of assuming this, require the client to tell | 567 // TODO(skyostil): Instead of assuming this, require the client to tell |
| 581 // us. | 568 // us. |
| 582 SetNeedsRedraw(); | 569 SetNeedsRedraw(); |
| 583 return; | 570 return; |
| 584 | 571 |
| 585 case ACTION_SEND_BEGIN_MAIN_FRAME: | 572 case ACTION_SEND_BEGIN_MAIN_FRAME: |
| 586 DCHECK(!has_pending_tree_ || | 573 DCHECK(!has_pending_tree_ || |
| 587 settings_.main_frame_before_activation_enabled); | 574 settings_.main_frame_before_activation_enabled); |
| 588 DCHECK(visible_); | 575 DCHECK(visible_); |
| 589 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; | 576 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 | 612 |
| 626 case ACTION_MANAGE_TILES: | 613 case ACTION_MANAGE_TILES: |
| 627 UpdateStateOnManageTiles(); | 614 UpdateStateOnManageTiles(); |
| 628 return; | 615 return; |
| 629 } | 616 } |
| 630 } | 617 } |
| 631 | 618 |
| 632 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { | 619 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { |
| 633 commit_count_++; | 620 commit_count_++; |
| 634 | 621 |
| 635 if (!commit_was_aborted && HasAnimatedThisFrame()) | |
| 636 did_commit_after_animating_ = true; | |
| 637 | |
| 638 if (commit_was_aborted || settings_.main_frame_before_activation_enabled) { | 622 if (commit_was_aborted || settings_.main_frame_before_activation_enabled) { |
| 639 commit_state_ = COMMIT_STATE_IDLE; | 623 commit_state_ = COMMIT_STATE_IDLE; |
| 640 } else { | 624 } else { |
| 641 commit_state_ = settings_.impl_side_painting | 625 commit_state_ = settings_.impl_side_painting |
| 642 ? COMMIT_STATE_WAITING_FOR_ACTIVATION | 626 ? COMMIT_STATE_WAITING_FOR_ACTIVATION |
| 643 : COMMIT_STATE_IDLE; | 627 : COMMIT_STATE_IDLE; |
| 644 } | 628 } |
| 645 | 629 |
| 646 // If we are impl-side-painting but the commit was aborted, then we behave | 630 // If we are impl-side-painting but the commit was aborted, then we behave |
| 647 // mostly as if we are not impl-side-painting since there is no pending tree. | 631 // mostly as if we are not impl-side-painting since there is no pending tree. |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1107 static_cast<int>(begin_impl_frame_state_), | 1091 static_cast<int>(begin_impl_frame_state_), |
| 1108 static_cast<int>(commit_state_), | 1092 static_cast<int>(commit_state_), |
| 1109 has_pending_tree_ ? 'T' : 'F', | 1093 has_pending_tree_ ? 'T' : 'F', |
| 1110 pending_tree_is_ready_for_activation_ ? 'T' : 'F', | 1094 pending_tree_is_ready_for_activation_ ? 'T' : 'F', |
| 1111 active_tree_needs_first_draw_ ? 'T' : 'F', | 1095 active_tree_needs_first_draw_ ? 'T' : 'F', |
| 1112 max_pending_swaps_, | 1096 max_pending_swaps_, |
| 1113 pending_swaps_); | 1097 pending_swaps_); |
| 1114 } | 1098 } |
| 1115 | 1099 |
| 1116 } // namespace cc | 1100 } // namespace cc |
| OLD | NEW |