| 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" |
| 11 #include "base/trace_event/trace_event_argument.h" | 11 #include "base/trace_event/trace_event_argument.h" |
| 12 #include "base/values.h" | 12 #include "base/values.h" |
| 13 #include "ui/gfx/frame_time.h" | 13 #include "ui/gfx/frame_time.h" |
| 14 | 14 |
| 15 namespace cc { | 15 namespace cc { |
| 16 | 16 |
| 17 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) | 17 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
| 18 : settings_(settings), | 18 : settings_(settings), |
| 19 output_surface_state_(OUTPUT_SURFACE_LOST), | 19 output_surface_state_(OUTPUT_SURFACE_LOST), |
| 20 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), | 20 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), |
| 21 commit_state_(COMMIT_STATE_IDLE), | 21 commit_state_(COMMIT_STATE_IDLE), |
| 22 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), | 22 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), |
| 23 commit_count_(0), | 23 commit_count_(0), |
| 24 current_frame_number_(0), | 24 current_frame_number_(0), |
| 25 last_frame_number_animate_performed_(-1), | 25 last_frame_number_animate_performed_(-1), |
| 26 last_frame_number_swap_performed_(-1), | 26 last_frame_number_swap_performed_(-1), |
| 27 last_frame_number_swap_requested_(-1), | 27 last_frame_number_swap_requested_(-1), |
| 28 last_frame_number_begin_main_frame_sent_(-1), | 28 last_frame_number_begin_main_frame_sent_(-1), |
| 29 animate_funnel_(false), |
| 30 perform_swap_funnel_(false), |
| 31 request_swap_funnel_(false), |
| 32 send_begin_main_frame_funnel_(false), |
| 29 prepare_tiles_funnel_(0), | 33 prepare_tiles_funnel_(0), |
| 30 consecutive_checkerboard_animations_(0), | 34 consecutive_checkerboard_animations_(0), |
| 31 max_pending_swaps_(1), | 35 max_pending_swaps_(1), |
| 32 pending_swaps_(0), | 36 pending_swaps_(0), |
| 33 needs_redraw_(false), | 37 needs_redraw_(false), |
| 34 needs_animate_(false), | 38 needs_animate_(false), |
| 35 needs_prepare_tiles_(false), | 39 needs_prepare_tiles_(false), |
| 36 needs_commit_(false), | 40 needs_commit_(false), |
| 37 inside_poll_for_anticipated_draw_triggers_(false), | 41 inside_poll_for_anticipated_draw_triggers_(false), |
| 38 visible_(false), | 42 visible_(false), |
| 39 can_start_(false), | 43 can_start_(false), |
| 40 can_draw_(false), | 44 can_draw_(false), |
| 41 has_pending_tree_(false), | 45 has_pending_tree_(false), |
| 42 pending_tree_is_ready_for_activation_(false), | 46 pending_tree_is_ready_for_activation_(false), |
| 43 active_tree_needs_first_draw_(false), | 47 active_tree_needs_first_draw_(false), |
| 44 did_commit_after_animating_(false), | |
| 45 did_create_and_initialize_first_output_surface_(false), | 48 did_create_and_initialize_first_output_surface_(false), |
| 46 impl_latency_takes_priority_(false), | 49 impl_latency_takes_priority_(false), |
| 47 skip_next_begin_main_frame_to_reduce_latency_(false), | 50 skip_next_begin_main_frame_to_reduce_latency_(false), |
| 48 skip_begin_main_frame_to_reduce_latency_(false), | 51 skip_begin_main_frame_to_reduce_latency_(false), |
| 49 continuous_painting_(false), | 52 continuous_painting_(false), |
| 50 children_need_begin_frames_(false), | 53 children_need_begin_frames_(false), |
| 51 defer_commits_(false) { | 54 defer_commits_(false) { |
| 52 } | 55 } |
| 53 | 56 |
| 54 const char* SchedulerStateMachine::OutputSurfaceStateToString( | 57 const char* SchedulerStateMachine::OutputSurfaceStateToString( |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 state->SetString("commit_state", CommitStateToString(commit_state_)); | 167 state->SetString("commit_state", CommitStateToString(commit_state_)); |
| 165 state->SetString("output_surface_state_", | 168 state->SetString("output_surface_state_", |
| 166 OutputSurfaceStateToString(output_surface_state_)); | 169 OutputSurfaceStateToString(output_surface_state_)); |
| 167 state->SetString("forced_redraw_state", | 170 state->SetString("forced_redraw_state", |
| 168 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); | 171 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); |
| 169 state->EndDictionary(); | 172 state->EndDictionary(); |
| 170 | 173 |
| 171 state->BeginDictionary("minor_state"); | 174 state->BeginDictionary("minor_state"); |
| 172 state->SetInteger("commit_count", commit_count_); | 175 state->SetInteger("commit_count", commit_count_); |
| 173 state->SetInteger("current_frame_number", current_frame_number_); | 176 state->SetInteger("current_frame_number", current_frame_number_); |
| 174 | |
| 175 state->SetInteger("last_frame_number_animate_performed", | 177 state->SetInteger("last_frame_number_animate_performed", |
| 176 last_frame_number_animate_performed_); | 178 last_frame_number_animate_performed_); |
| 177 state->SetInteger("last_frame_number_swap_performed", | 179 state->SetInteger("last_frame_number_swap_performed", |
| 178 last_frame_number_swap_performed_); | 180 last_frame_number_swap_performed_); |
| 179 state->SetInteger("last_frame_number_swap_requested", | 181 state->SetInteger("last_frame_number_swap_requested", |
| 180 last_frame_number_swap_requested_); | 182 last_frame_number_swap_requested_); |
| 181 state->SetInteger("last_frame_number_begin_main_frame_sent", | 183 state->SetInteger("last_frame_number_begin_main_frame_sent", |
| 182 last_frame_number_begin_main_frame_sent_); | 184 last_frame_number_begin_main_frame_sent_); |
| 183 | 185 state->SetBoolean("funnel: animate_funnel", animate_funnel_); |
| 184 state->SetInteger("prepare_tiles_funnel", prepare_tiles_funnel_); | 186 state->SetBoolean("funnel: perform_swap_funnel", perform_swap_funnel_); |
| 187 state->SetBoolean("funnel: request_swap_funnel", request_swap_funnel_); |
| 188 state->SetBoolean("funnel: send_begin_main_frame_funnel", |
| 189 send_begin_main_frame_funnel_); |
| 190 state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_); |
| 185 state->SetInteger("consecutive_checkerboard_animations", | 191 state->SetInteger("consecutive_checkerboard_animations", |
| 186 consecutive_checkerboard_animations_); | 192 consecutive_checkerboard_animations_); |
| 187 state->SetInteger("max_pending_swaps_", max_pending_swaps_); | 193 state->SetInteger("max_pending_swaps_", max_pending_swaps_); |
| 188 state->SetInteger("pending_swaps_", pending_swaps_); | 194 state->SetInteger("pending_swaps_", pending_swaps_); |
| 189 state->SetBoolean("needs_redraw", needs_redraw_); | 195 state->SetBoolean("needs_redraw", needs_redraw_); |
| 190 state->SetBoolean("needs_animate_", needs_animate_); | 196 state->SetBoolean("needs_animate_", needs_animate_); |
| 191 state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_); | 197 state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_); |
| 192 state->SetBoolean("needs_commit", needs_commit_); | 198 state->SetBoolean("needs_commit", needs_commit_); |
| 193 state->SetBoolean("visible", visible_); | 199 state->SetBoolean("visible", visible_); |
| 194 state->SetBoolean("can_start", can_start_); | 200 state->SetBoolean("can_start", can_start_); |
| 195 state->SetBoolean("can_draw", can_draw_); | 201 state->SetBoolean("can_draw", can_draw_); |
| 196 state->SetBoolean("has_pending_tree", has_pending_tree_); | 202 state->SetBoolean("has_pending_tree", has_pending_tree_); |
| 197 state->SetBoolean("pending_tree_is_ready_for_activation", | 203 state->SetBoolean("pending_tree_is_ready_for_activation", |
| 198 pending_tree_is_ready_for_activation_); | 204 pending_tree_is_ready_for_activation_); |
| 199 state->SetBoolean("active_tree_needs_first_draw", | 205 state->SetBoolean("active_tree_needs_first_draw", |
| 200 active_tree_needs_first_draw_); | 206 active_tree_needs_first_draw_); |
| 201 state->SetBoolean("did_commit_after_animating", did_commit_after_animating_); | |
| 202 state->SetBoolean("did_create_and_initialize_first_output_surface", | 207 state->SetBoolean("did_create_and_initialize_first_output_surface", |
| 203 did_create_and_initialize_first_output_surface_); | 208 did_create_and_initialize_first_output_surface_); |
| 204 state->SetBoolean("impl_latency_takes_priority", | 209 state->SetBoolean("impl_latency_takes_priority", |
| 205 impl_latency_takes_priority_); | 210 impl_latency_takes_priority_); |
| 206 state->SetBoolean("main_thread_is_in_high_latency_mode", | 211 state->SetBoolean("main_thread_is_in_high_latency_mode", |
| 207 MainThreadIsInHighLatencyMode()); | 212 MainThreadIsInHighLatencyMode()); |
| 208 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", | 213 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", |
| 209 skip_begin_main_frame_to_reduce_latency_); | 214 skip_begin_main_frame_to_reduce_latency_); |
| 210 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 215 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |
| 211 skip_next_begin_main_frame_to_reduce_latency_); | 216 skip_next_begin_main_frame_to_reduce_latency_); |
| 212 state->SetBoolean("continuous_painting", continuous_painting_); | 217 state->SetBoolean("continuous_painting", continuous_painting_); |
| 213 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); | 218 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); |
| 214 state->SetBoolean("defer_commits", defer_commits_); | 219 state->SetBoolean("defer_commits", defer_commits_); |
| 215 state->EndDictionary(); | 220 state->EndDictionary(); |
| 216 } | 221 } |
| 217 | 222 |
| 218 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { | 223 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { |
| 219 current_frame_number_++; | 224 current_frame_number_++; |
| 220 | 225 |
| 226 animate_funnel_ = false; |
| 227 perform_swap_funnel_ = false; |
| 228 request_swap_funnel_ = false; |
| 229 send_begin_main_frame_funnel_ = false; |
| 230 |
| 221 // "Drain" the PrepareTiles funnel. | 231 // "Drain" the PrepareTiles funnel. |
| 222 if (prepare_tiles_funnel_ > 0) | 232 if (prepare_tiles_funnel_ > 0) |
| 223 prepare_tiles_funnel_--; | 233 prepare_tiles_funnel_--; |
| 224 | 234 |
| 225 skip_begin_main_frame_to_reduce_latency_ = | 235 skip_begin_main_frame_to_reduce_latency_ = |
| 226 skip_next_begin_main_frame_to_reduce_latency_; | 236 skip_next_begin_main_frame_to_reduce_latency_; |
| 227 skip_next_begin_main_frame_to_reduce_latency_ = false; | 237 skip_next_begin_main_frame_to_reduce_latency_ = false; |
| 228 } | 238 } |
| 229 | 239 |
| 230 bool SchedulerStateMachine::HasAnimatedThisFrame() const { | |
| 231 return last_frame_number_animate_performed_ == current_frame_number_; | |
| 232 } | |
| 233 | |
| 234 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { | |
| 235 return current_frame_number_ == | |
| 236 last_frame_number_begin_main_frame_sent_; | |
| 237 } | |
| 238 | |
| 239 bool SchedulerStateMachine::HasSwappedThisFrame() const { | |
| 240 return current_frame_number_ == last_frame_number_swap_performed_; | |
| 241 } | |
| 242 | |
| 243 bool SchedulerStateMachine::HasRequestedSwapThisFrame() const { | |
| 244 return current_frame_number_ == last_frame_number_swap_requested_; | |
| 245 } | |
| 246 | |
| 247 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { | 240 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { |
| 248 // These are all the cases where we normally cannot or do not want to draw | 241 // These are all the cases where we normally cannot or do not want to draw |
| 249 // but, if needs_redraw_ is true and we do not draw to make forward progress, | 242 // but, if needs_redraw_ is true and we do not draw to make forward progress, |
| 250 // we might deadlock with the main thread. | 243 // we might deadlock with the main thread. |
| 251 // This should be a superset of PendingActivationsShouldBeForced() since | 244 // This should be a superset of PendingActivationsShouldBeForced() since |
| 252 // activation of the pending tree is blocked by drawing of the active tree and | 245 // activation of the pending tree is blocked by drawing of the active tree and |
| 253 // the main thread might be blocked on activation of the most recent commit. | 246 // the main thread might be blocked on activation of the most recent commit. |
| 254 if (PendingActivationsShouldBeForced()) | 247 if (PendingActivationsShouldBeForced()) |
| 255 return true; | 248 return true; |
| 256 | 249 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 | 302 |
| 310 bool SchedulerStateMachine::ShouldDraw() const { | 303 bool SchedulerStateMachine::ShouldDraw() const { |
| 311 // If we need to abort draws, we should do so ASAP since the draw could | 304 // If we need to abort draws, we should do so ASAP since the draw could |
| 312 // be blocking other important actions (like output surface initialization), | 305 // be blocking other important actions (like output surface initialization), |
| 313 // from occuring. If we are waiting for the first draw, then perfom the | 306 // from occuring. If we are waiting for the first draw, then perfom the |
| 314 // aborted draw to keep things moving. If we are not waiting for the first | 307 // aborted draw to keep things moving. If we are not waiting for the first |
| 315 // draw however, we don't want to abort for no reason. | 308 // draw however, we don't want to abort for no reason. |
| 316 if (PendingDrawsShouldBeAborted()) | 309 if (PendingDrawsShouldBeAborted()) |
| 317 return active_tree_needs_first_draw_; | 310 return active_tree_needs_first_draw_; |
| 318 | 311 |
| 312 // Do not draw too many times in a single frame. It's okay that we don't check |
| 313 // this before checking for aborted draws because aborted draws do not request |
| 314 // a swap. |
| 315 if (request_swap_funnel_) |
| 316 return false; |
| 317 |
| 319 // Don't draw if we are waiting on the first commit after a surface. | 318 // Don't draw if we are waiting on the first commit after a surface. |
| 320 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) | 319 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) |
| 321 return false; | 320 return false; |
| 322 | 321 |
| 323 // If a commit has occurred after the animate call, we need to call animate | |
| 324 // again before we should draw. | |
| 325 if (did_commit_after_animating_) | |
| 326 return false; | |
| 327 | |
| 328 // After this line, we only want to send a swap request once per frame. | |
| 329 if (HasRequestedSwapThisFrame()) | |
| 330 return false; | |
| 331 | |
| 332 // Do not queue too many swaps. | 322 // Do not queue too many swaps. |
| 333 if (pending_swaps_ >= max_pending_swaps_) | 323 if (pending_swaps_ >= max_pending_swaps_) |
| 334 return false; | 324 return false; |
| 335 | 325 |
| 336 // Except for the cases above, do not draw outside of the BeginImplFrame | 326 // Except for the cases above, do not draw outside of the BeginImplFrame |
| 337 // deadline. | 327 // deadline. |
| 338 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) | 328 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) |
| 339 return false; | 329 return false; |
| 340 | 330 |
| 341 // Only handle forced redraws due to timeouts on the regular deadline. | 331 // Only handle forced redraws due to timeouts on the regular deadline. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 358 | 348 |
| 359 // If we want to force activation, do so ASAP. | 349 // If we want to force activation, do so ASAP. |
| 360 if (PendingActivationsShouldBeForced()) | 350 if (PendingActivationsShouldBeForced()) |
| 361 return true; | 351 return true; |
| 362 | 352 |
| 363 // At this point, only activate if we are ready to activate. | 353 // At this point, only activate if we are ready to activate. |
| 364 return pending_tree_is_ready_for_activation_; | 354 return pending_tree_is_ready_for_activation_; |
| 365 } | 355 } |
| 366 | 356 |
| 367 bool SchedulerStateMachine::ShouldAnimate() const { | 357 bool SchedulerStateMachine::ShouldAnimate() const { |
| 358 // Do not animate too many times in a single frame. |
| 359 if (animate_funnel_) |
| 360 return false; |
| 361 |
| 368 // Don't animate if we are waiting on the first commit after a surface. | 362 // Don't animate if we are waiting on the first commit after a surface. |
| 369 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) | 363 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) |
| 370 return false; | 364 return false; |
| 371 | 365 |
| 372 // If a commit occurred after our last call, we need to do animation again. | |
| 373 if (HasAnimatedThisFrame() && !did_commit_after_animating_) | |
| 374 return false; | |
| 375 | |
| 376 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && | 366 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && |
| 377 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) | 367 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) |
| 378 return false; | 368 return false; |
| 379 | 369 |
| 380 return needs_redraw_ || needs_animate_; | 370 return needs_redraw_ || needs_animate_; |
| 381 } | 371 } |
| 382 | 372 |
| 383 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { | 373 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { |
| 374 // Do not send begin main frame too many times in a single frame. |
| 375 if (send_begin_main_frame_funnel_) |
| 376 return false; |
| 377 |
| 384 if (!needs_commit_) | 378 if (!needs_commit_) |
| 385 return false; | 379 return false; |
| 386 | 380 |
| 387 // We can not perform commits if we are not visible. | 381 // We can not perform commits if we are not visible. |
| 388 if (!visible_) | 382 if (!visible_) |
| 389 return false; | 383 return false; |
| 390 | 384 |
| 391 // Do not make a new commits when it is deferred. | 385 // Do not make a new commits when it is deferred. |
| 392 if (defer_commits_) | 386 if (defer_commits_) |
| 393 return false; | 387 return false; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 417 // thread isn't consuming user input. | 411 // thread isn't consuming user input. |
| 418 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE && | 412 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE && |
| 419 BeginFrameNeeded()) | 413 BeginFrameNeeded()) |
| 420 return false; | 414 return false; |
| 421 | 415 |
| 422 // We need a new commit for the forced redraw. This honors the | 416 // We need a new commit for the forced redraw. This honors the |
| 423 // single commit per interval because the result will be swapped to screen. | 417 // single commit per interval because the result will be swapped to screen. |
| 424 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) | 418 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) |
| 425 return true; | 419 return true; |
| 426 | 420 |
| 427 // After this point, we only start a commit once per frame. | |
| 428 if (HasSentBeginMainFrameThisFrame()) | |
| 429 return false; | |
| 430 | |
| 431 // We shouldn't normally accept commits if there isn't an OutputSurface. | 421 // We shouldn't normally accept commits if there isn't an OutputSurface. |
| 432 if (!HasInitializedOutputSurface()) | 422 if (!HasInitializedOutputSurface()) |
| 433 return false; | 423 return false; |
| 434 | 424 |
| 435 // SwapAck throttle the BeginMainFrames unless we just swapped. | 425 // SwapAck throttle the BeginMainFrames unless we just swapped. |
| 436 // TODO(brianderson): Remove this restriction to improve throughput. | 426 // TODO(brianderson): Remove this restriction to improve throughput. |
| 437 bool just_swapped_in_deadline = | 427 bool just_swapped_in_deadline = |
| 438 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && | 428 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && |
| 439 HasSwappedThisFrame(); | 429 perform_swap_funnel_; |
| 440 if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline) | 430 if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline) |
| 441 return false; | 431 return false; |
| 442 | 432 |
| 443 if (skip_begin_main_frame_to_reduce_latency_) | 433 if (skip_begin_main_frame_to_reduce_latency_) |
| 444 return false; | 434 return false; |
| 445 | 435 |
| 446 return true; | 436 return true; |
| 447 } | 437 } |
| 448 | 438 |
| 449 bool SchedulerStateMachine::ShouldCommit() const { | 439 bool SchedulerStateMachine::ShouldCommit() const { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 void SchedulerStateMachine::UpdateState(Action action) { | 496 void SchedulerStateMachine::UpdateState(Action action) { |
| 507 switch (action) { | 497 switch (action) { |
| 508 case ACTION_NONE: | 498 case ACTION_NONE: |
| 509 return; | 499 return; |
| 510 | 500 |
| 511 case ACTION_ACTIVATE_SYNC_TREE: | 501 case ACTION_ACTIVATE_SYNC_TREE: |
| 512 UpdateStateOnActivation(); | 502 UpdateStateOnActivation(); |
| 513 return; | 503 return; |
| 514 | 504 |
| 515 case ACTION_ANIMATE: | 505 case ACTION_ANIMATE: |
| 506 DCHECK(!animate_funnel_); |
| 516 last_frame_number_animate_performed_ = current_frame_number_; | 507 last_frame_number_animate_performed_ = current_frame_number_; |
| 508 animate_funnel_ = true; |
| 517 needs_animate_ = false; | 509 needs_animate_ = false; |
| 518 did_commit_after_animating_ = false; | |
| 519 // TODO(skyostil): Instead of assuming this, require the client to tell | 510 // TODO(skyostil): Instead of assuming this, require the client to tell |
| 520 // us. | 511 // us. |
| 521 SetNeedsRedraw(); | 512 SetNeedsRedraw(); |
| 522 return; | 513 return; |
| 523 | 514 |
| 524 case ACTION_SEND_BEGIN_MAIN_FRAME: | 515 case ACTION_SEND_BEGIN_MAIN_FRAME: |
| 525 DCHECK(!has_pending_tree_ || | 516 DCHECK(!has_pending_tree_ || |
| 526 settings_.main_frame_before_activation_enabled); | 517 settings_.main_frame_before_activation_enabled); |
| 527 DCHECK(visible_); | 518 DCHECK(visible_); |
| 519 DCHECK(!send_begin_main_frame_funnel_); |
| 528 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; | 520 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; |
| 529 needs_commit_ = false; | 521 needs_commit_ = false; |
| 522 send_begin_main_frame_funnel_ = true; |
| 530 last_frame_number_begin_main_frame_sent_ = | 523 last_frame_number_begin_main_frame_sent_ = |
| 531 current_frame_number_; | 524 current_frame_number_; |
| 532 return; | 525 return; |
| 533 | 526 |
| 534 case ACTION_COMMIT: { | 527 case ACTION_COMMIT: { |
| 535 bool commit_has_no_updates = false; | 528 bool commit_has_no_updates = false; |
| 536 UpdateStateOnCommit(commit_has_no_updates); | 529 UpdateStateOnCommit(commit_has_no_updates); |
| 537 return; | 530 return; |
| 538 } | 531 } |
| 539 | 532 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 564 | 557 |
| 565 case ACTION_PREPARE_TILES: | 558 case ACTION_PREPARE_TILES: |
| 566 UpdateStateOnPrepareTiles(); | 559 UpdateStateOnPrepareTiles(); |
| 567 return; | 560 return; |
| 568 } | 561 } |
| 569 } | 562 } |
| 570 | 563 |
| 571 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) { | 564 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) { |
| 572 commit_count_++; | 565 commit_count_++; |
| 573 | 566 |
| 574 if (!commit_has_no_updates && HasAnimatedThisFrame()) | 567 if (!commit_has_no_updates) |
| 575 did_commit_after_animating_ = true; | 568 animate_funnel_ = false; |
| 576 | 569 |
| 577 if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) { | 570 if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) { |
| 578 commit_state_ = COMMIT_STATE_IDLE; | 571 commit_state_ = COMMIT_STATE_IDLE; |
| 579 } else if (settings_.impl_side_painting) { | 572 } else if (settings_.impl_side_painting) { |
| 580 commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION; | 573 commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION; |
| 581 } else { | 574 } else { |
| 582 commit_state_ = settings_.main_thread_should_always_be_low_latency | 575 commit_state_ = settings_.main_thread_should_always_be_low_latency |
| 583 ? COMMIT_STATE_WAITING_FOR_DRAW | 576 ? COMMIT_STATE_WAITING_FOR_DRAW |
| 584 : COMMIT_STATE_IDLE; | 577 : COMMIT_STATE_IDLE; |
| 585 } | 578 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) { | 637 void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) { |
| 645 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) | 638 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
| 646 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; | 639 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; |
| 647 | 640 |
| 648 if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW) | 641 if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW) |
| 649 commit_state_ = COMMIT_STATE_IDLE; | 642 commit_state_ = COMMIT_STATE_IDLE; |
| 650 | 643 |
| 651 needs_redraw_ = false; | 644 needs_redraw_ = false; |
| 652 active_tree_needs_first_draw_ = false; | 645 active_tree_needs_first_draw_ = false; |
| 653 | 646 |
| 654 if (did_request_swap) | 647 if (did_request_swap) { |
| 648 DCHECK(!request_swap_funnel_); |
| 649 request_swap_funnel_ = true; |
| 655 last_frame_number_swap_requested_ = current_frame_number_; | 650 last_frame_number_swap_requested_ = current_frame_number_; |
| 651 } |
| 656 } | 652 } |
| 657 | 653 |
| 658 void SchedulerStateMachine::UpdateStateOnPrepareTiles() { | 654 void SchedulerStateMachine::UpdateStateOnPrepareTiles() { |
| 659 needs_prepare_tiles_ = false; | 655 needs_prepare_tiles_ = false; |
| 660 } | 656 } |
| 661 | 657 |
| 662 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { | 658 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { |
| 663 TRACE_EVENT_INSTANT0("cc", | 659 TRACE_EVENT_INSTANT0("cc", |
| 664 "Scheduler: SkipNextBeginMainFrameToReduceLatency", | 660 "Scheduler: SkipNextBeginMainFrameToReduceLatency", |
| 665 TRACE_EVENT_SCOPE_THREAD); | 661 TRACE_EVENT_SCOPE_THREAD); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 760 // Changing priorities may allow us to activate (given the new priorities), | 756 // Changing priorities may allow us to activate (given the new priorities), |
| 761 // which may result in a new frame. | 757 // which may result in a new frame. |
| 762 if (needs_prepare_tiles_) | 758 if (needs_prepare_tiles_) |
| 763 return true; | 759 return true; |
| 764 | 760 |
| 765 // If we just sent a swap request, it's likely that we are going to produce | 761 // If we just sent a swap request, it's likely that we are going to produce |
| 766 // another frame soon. This helps avoid negative glitches in our | 762 // another frame soon. This helps avoid negative glitches in our |
| 767 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame | 763 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame |
| 768 // provider and get sampled at an inopportune time, delaying the next | 764 // provider and get sampled at an inopportune time, delaying the next |
| 769 // BeginImplFrame. | 765 // BeginImplFrame. |
| 770 if (HasRequestedSwapThisFrame()) | 766 if (request_swap_funnel_) |
| 771 return true; | 767 return true; |
| 772 | 768 |
| 773 return false; | 769 return false; |
| 774 } | 770 } |
| 775 | 771 |
| 776 void SchedulerStateMachine::OnBeginImplFrame() { | 772 void SchedulerStateMachine::OnBeginImplFrame() { |
| 777 AdvanceCurrentFrameNumber(); | 773 AdvanceCurrentFrameNumber(); |
| 778 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) | 774 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) |
| 779 << AsValue()->ToString(); | 775 << AsValue()->ToString(); |
| 780 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; | 776 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 } | 850 } |
| 855 | 851 |
| 856 bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const { | 852 bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const { |
| 857 // If a commit is pending before the previous commit has been drawn, we | 853 // If a commit is pending before the previous commit has been drawn, we |
| 858 // are definitely in a high latency mode. | 854 // are definitely in a high latency mode. |
| 859 if (CommitPending() && (active_tree_needs_first_draw_ || has_pending_tree_)) | 855 if (CommitPending() && (active_tree_needs_first_draw_ || has_pending_tree_)) |
| 860 return true; | 856 return true; |
| 861 | 857 |
| 862 // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main | 858 // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main |
| 863 // thread is in a low latency mode. | 859 // thread is in a low latency mode. |
| 864 if (HasSentBeginMainFrameThisFrame() && | 860 if (send_begin_main_frame_funnel_ && |
| 865 (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING || | 861 (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING || |
| 866 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)) | 862 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)) |
| 867 return false; | 863 return false; |
| 868 | 864 |
| 869 // If there's a commit in progress it must either be from the previous frame | 865 // If there's a commit in progress it must either be from the previous frame |
| 870 // or it started after the impl thread's deadline. In either case the main | 866 // or it started after the impl thread's deadline. In either case the main |
| 871 // thread is in high latency mode. | 867 // thread is in high latency mode. |
| 872 if (CommitPending()) | 868 if (CommitPending()) |
| 873 return true; | 869 return true; |
| 874 | 870 |
| 875 // Similarly, if there's a pending tree the main thread is in high latency | 871 // Similarly, if there's a pending tree the main thread is in high latency |
| 876 // mode, because either | 872 // mode, because either |
| 877 // it's from the previous frame | 873 // it's from the previous frame |
| 878 // or | 874 // or |
| 879 // we're currently drawing the active tree and the pending tree will thus | 875 // we're currently drawing the active tree and the pending tree will thus |
| 880 // only be drawn in the next frame. | 876 // only be drawn in the next frame. |
| 881 if (has_pending_tree_) | 877 if (has_pending_tree_) |
| 882 return true; | 878 return true; |
| 883 | 879 |
| 884 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) { | 880 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) { |
| 885 // Even if there's a new active tree to draw at the deadline or we've just | 881 // Even if there's a new active tree to draw at the deadline or we've just |
| 886 // swapped it, it may have been triggered by a previous BeginImplFrame, in | 882 // swapped it, it may have been triggered by a previous BeginImplFrame, in |
| 887 // which case the main thread is in a high latency mode. | 883 // which case the main thread is in a high latency mode. |
| 888 return (active_tree_needs_first_draw_ || HasSwappedThisFrame()) && | 884 return (active_tree_needs_first_draw_ || perform_swap_funnel_) && |
| 889 !HasSentBeginMainFrameThisFrame(); | 885 !send_begin_main_frame_funnel_; |
| 890 } | 886 } |
| 891 | 887 |
| 892 // If the active tree needs its first draw in any other state, we know the | 888 // If the active tree needs its first draw in any other state, we know the |
| 893 // main thread is in a high latency mode. | 889 // main thread is in a high latency mode. |
| 894 return active_tree_needs_first_draw_; | 890 return active_tree_needs_first_draw_; |
| 895 } | 891 } |
| 896 | 892 |
| 897 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { | 893 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { |
| 898 AdvanceCurrentFrameNumber(); | 894 AdvanceCurrentFrameNumber(); |
| 899 inside_poll_for_anticipated_draw_triggers_ = true; | 895 inside_poll_for_anticipated_draw_triggers_ = true; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 920 } | 916 } |
| 921 } | 917 } |
| 922 | 918 |
| 923 void SchedulerStateMachine::SetMaxSwapsPending(int max) { | 919 void SchedulerStateMachine::SetMaxSwapsPending(int max) { |
| 924 max_pending_swaps_ = max; | 920 max_pending_swaps_ = max; |
| 925 } | 921 } |
| 926 | 922 |
| 927 void SchedulerStateMachine::DidSwapBuffers() { | 923 void SchedulerStateMachine::DidSwapBuffers() { |
| 928 pending_swaps_++; | 924 pending_swaps_++; |
| 929 DCHECK_LE(pending_swaps_, max_pending_swaps_); | 925 DCHECK_LE(pending_swaps_, max_pending_swaps_); |
| 926 DCHECK(!perform_swap_funnel_); |
| 930 | 927 |
| 928 perform_swap_funnel_ = true; |
| 931 last_frame_number_swap_performed_ = current_frame_number_; | 929 last_frame_number_swap_performed_ = current_frame_number_; |
| 932 } | 930 } |
| 933 | 931 |
| 934 void SchedulerStateMachine::DidSwapBuffersComplete() { | 932 void SchedulerStateMachine::DidSwapBuffersComplete() { |
| 935 DCHECK_GT(pending_swaps_, 0); | 933 DCHECK_GT(pending_swaps_, 0); |
| 936 pending_swaps_--; | 934 pending_swaps_--; |
| 937 } | 935 } |
| 938 | 936 |
| 939 void SchedulerStateMachine::SetImplLatencyTakesPriority( | 937 void SchedulerStateMachine::SetImplLatencyTakesPriority( |
| 940 bool impl_latency_takes_priority) { | 938 bool impl_latency_takes_priority) { |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 static_cast<int>(begin_impl_frame_state_), | 1072 static_cast<int>(begin_impl_frame_state_), |
| 1075 static_cast<int>(commit_state_), | 1073 static_cast<int>(commit_state_), |
| 1076 has_pending_tree_ ? 'T' : 'F', | 1074 has_pending_tree_ ? 'T' : 'F', |
| 1077 pending_tree_is_ready_for_activation_ ? 'T' : 'F', | 1075 pending_tree_is_ready_for_activation_ ? 'T' : 'F', |
| 1078 active_tree_needs_first_draw_ ? 'T' : 'F', | 1076 active_tree_needs_first_draw_ ? 'T' : 'F', |
| 1079 max_pending_swaps_, | 1077 max_pending_swaps_, |
| 1080 pending_swaps_); | 1078 pending_swaps_); |
| 1081 } | 1079 } |
| 1082 | 1080 |
| 1083 } // namespace cc | 1081 } // namespace cc |
| OLD | NEW |