Chromium Code Reviews| 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/values.h" | 10 #include "base/values.h" |
| 11 | 11 |
| 12 namespace cc { | 12 namespace cc { |
| 13 | 13 |
| 14 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) | 14 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
| 15 : settings_(settings), | 15 : settings_(settings), |
| 16 output_surface_state_(OUTPUT_SURFACE_LOST), | 16 output_surface_state_(OUTPUT_SURFACE_LOST), |
| 17 commit_state_(COMMIT_STATE_IDLE), | 17 commit_state_(COMMIT_STATE_IDLE), |
| 18 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED), | 18 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED), |
| 19 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), | 19 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), |
| 20 readback_state_(READBACK_STATE_IDLE), | 20 readback_state_(READBACK_STATE_IDLE), |
| 21 commit_count_(0), | 21 commit_count_(0), |
| 22 current_frame_number_(0), | 22 begin_frame_count_(0), |
| 23 last_frame_number_where_begin_frame_sent_to_main_thread_(-1), | 23 draw_attempt_count_(0), |
| 24 last_frame_number_swap_performed_(-1), | 24 last_begin_frame_count_swap_performed_(-1), |
| 25 last_frame_number_where_update_visible_tiles_was_called_(-1), | 25 last_draw_attempt_count_draw_was_called_(-1), |
| 26 last_begin_frame_count_begin_frame_sent_to_main_thread_(-1), | |
| 27 last_draw_attempt_count_tree_activation_attempted_(-1), | |
| 28 last_draw_attempt_count_completed_tile_uploads_checked_(-1), | |
| 29 last_draw_attempt_count_update_visible_tiles_was_called_(-1), | |
| 26 consecutive_failed_draws_(0), | 30 consecutive_failed_draws_(0), |
| 27 maximum_number_of_failed_draws_before_draw_is_forced_(3), | 31 maximum_number_of_failed_draws_before_draw_is_forced_(3), |
| 28 needs_redraw_(false), | 32 needs_redraw_(false), |
| 29 swap_used_incomplete_tile_(false), | 33 swap_used_incomplete_tile_(false), |
| 30 needs_commit_(false), | 34 needs_commit_(false), |
| 31 main_thread_needs_layer_textures_(false), | 35 main_thread_needs_layer_textures_(false), |
| 32 inside_begin_frame_(false), | |
| 33 visible_(false), | 36 visible_(false), |
| 34 can_start_(false), | 37 can_start_(false), |
| 35 can_draw_(false), | 38 can_draw_(false), |
| 36 has_pending_tree_(false), | 39 has_pending_tree_(false), |
| 37 pending_tree_is_ready_for_activation_(false), | 40 pending_tree_is_ready_for_activation_(false), |
| 38 active_tree_has_been_drawn_(true), | 41 active_tree_has_been_drawn_(true), |
| 39 draw_if_possible_failed_(false), | 42 draw_if_possible_failed_(false), |
| 40 did_create_and_initialize_first_output_surface_(false) {} | 43 did_create_and_initialize_first_output_surface_(false) {} |
| 41 | 44 |
| 42 const char* SchedulerStateMachine::OutputSurfaceStateToString( | 45 const char* SchedulerStateMachine::OutputSurfaceStateToString( |
| 43 OutputSurfaceState state) { | 46 OutputSurfaceState state) { |
| 44 switch (state) { | 47 switch (state) { |
| 45 case OUTPUT_SURFACE_ACTIVE: | 48 case OUTPUT_SURFACE_ACTIVE: |
| 46 return "OUTPUT_SURFACE_ACTIVE"; | 49 return "OUTPUT_SURFACE_ACTIVE"; |
| 47 case OUTPUT_SURFACE_LOST: | 50 case OUTPUT_SURFACE_LOST: |
| 48 return "OUTPUT_SURFACE_LOST"; | 51 return "OUTPUT_SURFACE_LOST"; |
| 49 case OUTPUT_SURFACE_CREATING: | 52 case OUTPUT_SURFACE_CREATING: |
| 50 return "OUTPUT_SURFACE_CREATING"; | 53 return "OUTPUT_SURFACE_CREATING"; |
| 51 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: | 54 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: |
| 52 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT"; | 55 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT"; |
| 53 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: | 56 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: |
| 54 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION"; | 57 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION"; |
| 55 } | 58 } |
| 56 NOTREACHED(); | 59 NOTREACHED(); |
| 57 return "???"; | 60 return "???"; |
| 58 } | 61 } |
| 59 | 62 |
| 63 const char* SchedulerStateMachine::BeginFrameStateToString( | |
| 64 BeginFrameState state) { | |
| 65 switch (state) { | |
| 66 case BEGIN_FRAME_STATE_IDLE: | |
| 67 return "BEGIN_FRAME_STATE_IDLE"; | |
| 68 case BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME: | |
| 69 return "BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME"; | |
| 70 case BEGIN_FRAME_STATE_DEADLINE_PENDING: | |
| 71 return "BEGIN_FRAME_STATE_DEADLINE_PENDING"; | |
| 72 case BEGIN_FRAME_STATE_INSIDE_DEADLINE: | |
| 73 return "BEGIN_FRAME_STATE_INSIDE_DEADLINE"; | |
| 74 } | |
| 75 NOTREACHED(); | |
| 76 return "???"; | |
| 77 } | |
| 78 | |
| 60 const char* SchedulerStateMachine::CommitStateToString(CommitState state) { | 79 const char* SchedulerStateMachine::CommitStateToString(CommitState state) { |
| 61 switch (state) { | 80 switch (state) { |
| 62 case COMMIT_STATE_IDLE: | 81 case COMMIT_STATE_IDLE: |
| 63 return "COMMIT_STATE_IDLE"; | 82 return "COMMIT_STATE_IDLE"; |
| 64 case COMMIT_STATE_FRAME_IN_PROGRESS: | 83 case COMMIT_STATE_FRAME_IN_PROGRESS: |
| 65 return "COMMIT_STATE_FRAME_IN_PROGRESS"; | 84 return "COMMIT_STATE_FRAME_IN_PROGRESS"; |
| 66 case COMMIT_STATE_READY_TO_COMMIT: | 85 case COMMIT_STATE_READY_TO_COMMIT: |
| 67 return "COMMIT_STATE_READY_TO_COMMIT"; | 86 return "COMMIT_STATE_READY_TO_COMMIT"; |
| 68 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: | 87 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: |
| 69 return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW"; | 88 return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW"; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 } | 169 } |
| 151 NOTREACHED(); | 170 NOTREACHED(); |
| 152 return "???"; | 171 return "???"; |
| 153 } | 172 } |
| 154 | 173 |
| 155 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { | 174 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { |
| 156 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); | 175 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); |
| 157 | 176 |
| 158 scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue); | 177 scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue); |
| 159 major_state->SetString("next_action", ActionToString(NextAction())); | 178 major_state->SetString("next_action", ActionToString(NextAction())); |
| 179 major_state->SetString("commit_state", | |
| 180 BeginFrameStateToString(begin_frame_state_)); | |
| 160 major_state->SetString("commit_state", CommitStateToString(commit_state_)); | 181 major_state->SetString("commit_state", CommitStateToString(commit_state_)); |
| 161 major_state->SetString("texture_state_", | 182 major_state->SetString("texture_state_", |
| 162 TextureStateToString(texture_state_)); | 183 TextureStateToString(texture_state_)); |
| 163 major_state->SetString("output_surface_state_", | 184 major_state->SetString("output_surface_state_", |
| 164 OutputSurfaceStateToString(output_surface_state_)); | 185 OutputSurfaceStateToString(output_surface_state_)); |
| 165 major_state->SetString( | 186 major_state->SetString( |
| 166 "forced_redraw_state", | 187 "forced_redraw_state", |
| 167 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); | 188 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); |
| 168 major_state->SetString("readback_state", | 189 major_state->SetString("readback_state", |
| 169 SynchronousReadbackStateToString(readback_state_)); | 190 SynchronousReadbackStateToString(readback_state_)); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 191 (last_begin_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() / | 212 (last_begin_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() / |
| 192 1000.0L); | 213 1000.0L); |
| 193 timestamps_state->SetDouble( | 214 timestamps_state->SetDouble( |
| 194 "6_deadline", | 215 "6_deadline", |
| 195 (last_begin_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / | 216 (last_begin_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / |
| 196 1000.0L); | 217 1000.0L); |
| 197 state->Set("major_timestamps_in_ms", timestamps_state.release()); | 218 state->Set("major_timestamps_in_ms", timestamps_state.release()); |
| 198 | 219 |
| 199 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue); | 220 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue); |
| 200 minor_state->SetInteger("commit_count", commit_count_); | 221 minor_state->SetInteger("commit_count", commit_count_); |
| 201 minor_state->SetInteger("current_frame_number", current_frame_number_); | 222 minor_state->SetInteger("begin_frame_count_", begin_frame_count_); |
| 223 minor_state->SetInteger("draw_attempt_count_", draw_attempt_count_); | |
| 224 | |
| 225 minor_state->SetInteger("last_begin_frame_count_swap_performed_", | |
| 226 last_begin_frame_count_swap_performed_); | |
| 227 minor_state->SetInteger("last_draw_attempt_count_draw_was_called_", | |
| 228 last_draw_attempt_count_draw_was_called_); | |
| 202 minor_state->SetInteger( | 229 minor_state->SetInteger( |
| 203 "last_frame_number_where_begin_frame_sent_to_main_thread", | 230 "last_begin_frame_count_begin_frame_sent_to_main_thread_", |
| 204 last_frame_number_where_begin_frame_sent_to_main_thread_); | 231 last_begin_frame_count_begin_frame_sent_to_main_thread_); |
| 205 minor_state->SetInteger("last_frame_number_where_draw_was_called", | 232 minor_state->SetInteger("last_draw_attempt_count_tree_activation_attempted_", |
| 206 last_frame_number_swap_performed_); | 233 last_draw_attempt_count_tree_activation_attempted_); |
| 207 minor_state->SetInteger( | 234 minor_state->SetInteger( |
| 208 "last_frame_number_where_update_visible_tiles_was_called", | 235 "last_draw_attempt_count_completed_tile_uploads_checked_", |
| 209 last_frame_number_where_update_visible_tiles_was_called_); | 236 last_draw_attempt_count_completed_tile_uploads_checked_); |
| 210 minor_state->SetInteger("consecutive_failed_draws", | 237 minor_state->SetInteger( |
| 238 "last_draw_attempt_count_update_visible_tiles_was_called_", | |
| 239 last_draw_attempt_count_update_visible_tiles_was_called_); | |
| 240 | |
| 241 minor_state->SetInteger("consecutive_failed_draws_", | |
| 211 consecutive_failed_draws_); | 242 consecutive_failed_draws_); |
| 212 minor_state->SetInteger( | 243 minor_state->SetInteger( |
| 213 "maximum_number_of_failed_draws_before_draw_is_forced", | 244 "maximum_number_of_failed_draws_before_draw_is_forced_", |
| 214 maximum_number_of_failed_draws_before_draw_is_forced_); | 245 maximum_number_of_failed_draws_before_draw_is_forced_); |
| 246 | |
| 215 minor_state->SetBoolean("needs_redraw", needs_redraw_); | 247 minor_state->SetBoolean("needs_redraw", needs_redraw_); |
| 216 minor_state->SetBoolean("swap_used_incomplete_tile", | 248 minor_state->SetBoolean("swap_used_incomplete_tile", |
| 217 swap_used_incomplete_tile_); | 249 swap_used_incomplete_tile_); |
| 218 minor_state->SetBoolean("needs_commit", needs_commit_); | 250 minor_state->SetBoolean("needs_commit", needs_commit_); |
| 219 minor_state->SetBoolean("main_thread_needs_layer_textures", | 251 minor_state->SetBoolean("main_thread_needs_layer_textures", |
| 220 main_thread_needs_layer_textures_); | 252 main_thread_needs_layer_textures_); |
| 221 minor_state->SetBoolean("inside_begin_frame", inside_begin_frame_); | |
| 222 minor_state->SetBoolean("visible", visible_); | 253 minor_state->SetBoolean("visible", visible_); |
| 223 minor_state->SetBoolean("can_start", can_start_); | 254 minor_state->SetBoolean("can_start", can_start_); |
| 224 minor_state->SetBoolean("can_draw", can_draw_); | 255 minor_state->SetBoolean("can_draw", can_draw_); |
| 225 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); | 256 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); |
| 226 minor_state->SetBoolean("pending_tree_is_ready_for_activation_", | 257 minor_state->SetBoolean("pending_tree_is_ready_for_activation_", |
| 227 pending_tree_is_ready_for_activation_); | 258 pending_tree_is_ready_for_activation_); |
| 228 minor_state->SetBoolean("active_tree_has_been_drawn_", | 259 minor_state->SetBoolean("active_tree_has_been_drawn_", |
| 229 active_tree_has_been_drawn_); | 260 active_tree_has_been_drawn_); |
| 230 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_); | 261 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_); |
| 231 minor_state->SetBoolean("did_create_and_initialize_first_output_surface", | 262 minor_state->SetBoolean("did_create_and_initialize_first_output_surface", |
| 232 did_create_and_initialize_first_output_surface_); | 263 did_create_and_initialize_first_output_surface_); |
| 233 state->Set("minor_state", minor_state.release()); | 264 state->Set("minor_state", minor_state.release()); |
| 234 | 265 |
| 235 return state.PassAs<base::Value>(); | 266 return state.PassAs<base::Value>(); |
| 236 } | 267 } |
| 237 | 268 |
| 238 bool SchedulerStateMachine::HasDrawnThisFrame() const { | 269 bool SchedulerStateMachine::HasDrawnThisFrame() const { |
| 239 return current_frame_number_ == last_frame_number_swap_performed_; | 270 return begin_frame_count_ == last_begin_frame_count_swap_performed_; |
| 240 } | 271 } |
| 241 | 272 |
| 242 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { | 273 bool SchedulerStateMachine::HasDrawnThisDrawAttempt() const { |
| 243 return current_frame_number_ == | 274 return draw_attempt_count_ == last_draw_attempt_count_draw_was_called_; |
| 244 last_frame_number_where_update_visible_tiles_was_called_; | |
| 245 } | 275 } |
| 246 | 276 |
| 247 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const { | 277 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const { |
| 248 return current_frame_number_ == | 278 return begin_frame_count_ == |
| 249 last_frame_number_where_begin_frame_sent_to_main_thread_; | 279 last_begin_frame_count_begin_frame_sent_to_main_thread_; |
| 280 } | |
| 281 | |
| 282 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisDrawAttempt() const { | |
| 283 return draw_attempt_count_ == | |
| 284 last_draw_attempt_count_update_visible_tiles_was_called_; | |
| 285 } | |
| 286 | |
| 287 bool SchedulerStateMachine::HasActivatedPendingTreeThisDrawAttempt() const { | |
| 288 return draw_attempt_count_ == | |
| 289 last_draw_attempt_count_tree_activation_attempted_; | |
| 250 } | 290 } |
| 251 | 291 |
| 252 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { | 292 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { |
| 253 // These are all the cases where we normally cannot or do not want to draw | 293 // These are all the cases where we normally cannot or do not want to draw |
| 254 // but, if needs_redraw_ is true and we do not draw to make forward progress, | 294 // but, if needs_redraw_ is true and we do not draw to make forward progress, |
| 255 // we might deadlock with the main thread. | 295 // we might deadlock with the main thread. |
| 256 // This should be a superset of PendingActivationsShouldBeForced() since | 296 // This should be a superset of PendingActivationsShouldBeForced() since |
| 257 // activation of the pending tree is blocked by drawing of the active tree and | 297 // activation of the pending tree is blocked by drawing of the active tree and |
| 258 // the main thread might be blocked on activation of the most recent commit. | 298 // the main thread might be blocked on activation of the most recent commit. |
| 259 if (PendingActivationsShouldBeForced()) | 299 if (PendingActivationsShouldBeForced()) |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 299 // readback. | 339 // readback. |
| 300 if (!active_tree_has_been_drawn_ || has_pending_tree_) | 340 if (!active_tree_has_been_drawn_ || has_pending_tree_) |
| 301 return false; | 341 return false; |
| 302 | 342 |
| 303 // We need to create the output surface if we don't have one and we haven't | 343 // We need to create the output surface if we don't have one and we haven't |
| 304 // started creating one yet. | 344 // started creating one yet. |
| 305 return output_surface_state_ == OUTPUT_SURFACE_LOST; | 345 return output_surface_state_ == OUTPUT_SURFACE_LOST; |
| 306 } | 346 } |
| 307 | 347 |
| 308 bool SchedulerStateMachine::ShouldDraw() const { | 348 bool SchedulerStateMachine::ShouldDraw() const { |
| 349 if (HasDrawnThisDrawAttempt()) | |
| 350 return false; | |
| 351 | |
| 309 // After a readback, make sure not to draw again until we've replaced the | 352 // After a readback, make sure not to draw again until we've replaced the |
| 310 // readback commit with a real one. | 353 // readback commit with a real one. |
| 311 if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING || | 354 if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING || |
| 312 readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING) | 355 readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING) |
| 313 return false; | 356 return false; |
| 314 | 357 |
| 315 // Draw immediately for readbacks to unblock the main thread quickly. | 358 // Draw immediately for readbacks to unblock the main thread quickly. |
| 316 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) { | 359 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) { |
| 317 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); | 360 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); |
| 318 return true; | 361 return true; |
| 319 } | 362 } |
| 320 | 363 |
| 321 // If we need to abort draws, we should do so ASAP since the draw could | 364 // If we need to abort draws, we should do so ASAP since the draw could |
| 322 // be blocking other important actions (like output surface initialization), | 365 // be blocking other important actions (like output surface initialization), |
| 323 // from occuring. If we are waiting for the first draw, then perfom the | 366 // from occuring. If we are waiting for the first draw, then perfom the |
| 324 // aborted draw to keep things moving. If we are not waiting for the first | 367 // aborted draw to keep things moving. If we are not waiting for the first |
| 325 // draw however, we don't want to abort for no reason. | 368 // draw however, we don't want to abort for no reason. |
| 326 if (PendingDrawsShouldBeAborted()) | 369 if (PendingDrawsShouldBeAborted()) |
| 327 return !active_tree_has_been_drawn_; | 370 return !active_tree_has_been_drawn_; |
| 328 | 371 |
| 329 // After this line, we only want to draw once per frame. | 372 // After this line, we only want to draw once per frame. |
| 330 if (HasDrawnThisFrame()) | 373 if (HasDrawnThisFrame()) |
| 331 return false; | 374 return false; |
| 332 | 375 |
| 333 // We currently only draw within the BeginFrame. | 376 // Except for the cases above, do not draw outside of the BeginFrame deadline. |
| 334 if (!inside_begin_frame_) | 377 if (begin_frame_state_ != BEGIN_FRAME_STATE_INSIDE_DEADLINE) |
| 335 return false; | 378 return false; |
| 336 | 379 |
| 337 // Only handle forced redraws due to timeouts on the regular deadline. | 380 // Only handle forced redraws due to timeouts on the regular deadline. |
| 338 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) { | 381 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) { |
| 339 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); | 382 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); |
| 340 return true; | 383 return true; |
| 341 } | 384 } |
| 342 | 385 |
| 343 return needs_redraw_; | 386 return needs_redraw_; |
| 344 } | 387 } |
| 345 | 388 |
| 346 bool SchedulerStateMachine::ShouldAcquireLayerTexturesForMainThread() const { | 389 bool SchedulerStateMachine::ShouldAcquireLayerTexturesForMainThread() const { |
| 347 if (!main_thread_needs_layer_textures_) | 390 if (!main_thread_needs_layer_textures_) |
| 348 return false; | 391 return false; |
| 349 if (texture_state_ == LAYER_TEXTURE_STATE_UNLOCKED) | 392 if (texture_state_ == LAYER_TEXTURE_STATE_UNLOCKED) |
| 350 return true; | 393 return true; |
| 351 DCHECK_EQ(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD); | 394 DCHECK_EQ(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD); |
| 352 return false; | 395 return false; |
| 353 } | 396 } |
| 354 | 397 |
| 355 bool SchedulerStateMachine::ShouldActivatePendingTree() const { | 398 bool SchedulerStateMachine::ShouldActivatePendingTree() const { |
| 356 // There is nothing to activate. | 399 // There is nothing to activate. |
| 357 if (!has_pending_tree_) | 400 if (!has_pending_tree_) |
| 358 return false; | 401 return false; |
| 402 if (HasActivatedPendingTreeThisDrawAttempt()) | |
| 403 return false; | |
| 359 | 404 |
| 360 // If this is our first activation, we don't want to activate early. | 405 // If this is our first activation, we don't want to activate early. |
| 361 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) | 406 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) |
| 362 return pending_tree_is_ready_for_activation_; | 407 return pending_tree_is_ready_for_activation_; |
| 363 | 408 |
| 364 // We don't want to activate a second tree before drawing the first one. | 409 // We don't want to activate a second tree before drawing the first one. |
| 365 if (!active_tree_has_been_drawn_) | 410 if (!active_tree_has_been_drawn_) |
| 366 return false; | 411 return false; |
| 367 | 412 |
| 368 // If we want to force activation, do so ASAP. | 413 // If we want to force activation, do so ASAP. |
| 369 if (PendingActivationsShouldBeForced()) | 414 if (PendingActivationsShouldBeForced()) |
| 370 return true; | 415 return true; |
| 371 | 416 |
| 372 // At this point, only activate if we are ready to activate. | 417 // At this point, only activate if we are ready to activate. |
| 373 return pending_tree_is_ready_for_activation_; | 418 return pending_tree_is_ready_for_activation_; |
| 374 } | 419 } |
| 375 | 420 |
| 376 bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const { | 421 bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const { |
| 377 if (!settings_.impl_side_painting) | 422 if (!settings_.impl_side_painting) |
| 378 return false; | 423 return false; |
| 379 if (HasUpdatedVisibleTilesThisFrame()) | 424 if (HasUpdatedVisibleTilesThisDrawAttempt()) |
| 380 return false; | 425 return false; |
| 381 | 426 |
| 382 // There's no reason to check for tiles if we don't have an output surface. | 427 // There's no reason to check for tiles if we don't have an output surface. |
| 383 if (!HasInitializedOutputSurface()) | 428 if (!HasInitializedOutputSurface()) |
| 384 return false; | 429 return false; |
| 385 | 430 |
| 386 // We always want to update the most recent visible tiles before drawing | 431 // We always want to update the most recent visible tiles before drawing |
| 387 // so we draw with fewer missing tiles. | 432 // so we draw with fewer missing tiles. |
| 388 if (ShouldDraw()) | 433 if (ShouldDraw()) |
| 389 return true; | 434 return true; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 410 return false; | 455 return false; |
| 411 | 456 |
| 412 // We want to handle readback commits immediately to unblock the main thread. | 457 // We want to handle readback commits immediately to unblock the main thread. |
| 413 // Note: This BeginFrame will correspond to the replacement commit that comes | 458 // Note: This BeginFrame will correspond to the replacement commit that comes |
| 414 // after the readback commit itself, so we only send the BeginFrame if a | 459 // after the readback commit itself, so we only send the BeginFrame if a |
| 415 // commit isn't already pending behind the readback. | 460 // commit isn't already pending behind the readback. |
| 416 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED) | 461 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED) |
| 417 return !CommitPending(); | 462 return !CommitPending(); |
| 418 | 463 |
| 419 // We do not need commits if we are not visible, unless there's a | 464 // We do not need commits if we are not visible, unless there's a |
| 420 // request for a forced commit. | 465 // request for a readback. |
| 421 if (!visible_) | 466 if (!visible_) |
| 422 return false; | 467 return false; |
| 423 | 468 |
| 469 // We shouldn't normally accept commits if there isn't an OutputSurface. | |
| 470 if (!HasInitializedOutputSurface()) | |
| 471 return false; | |
| 472 | |
| 424 // We want to start the first commit after we get a new output surface ASAP. | 473 // We want to start the first commit after we get a new output surface ASAP. |
| 425 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) | 474 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) |
| 426 return true; | 475 return true; |
| 427 | 476 |
| 477 // We usually want to slave the main thread's BeginFrame to the impl thread's | |
| 478 // BeginFrame. However, if we aren't expecting a BeginFrame on the impl | |
| 479 // thread, we should send a BeginFrame to the main thread anyway to make | |
| 480 // progress. | |
| 481 // TODO(brianderson): Also allow sending BeginFrame to main thread while idle | |
| 482 // when the main thread isn't consuming user input. | |
| 483 if (begin_frame_state_ == BEGIN_FRAME_STATE_IDLE && | |
| 484 BeginFrameNeededByImplThread()) | |
| 485 return false; | |
| 486 | |
| 428 // We need a new commit for the forced redraw. This honors the | 487 // We need a new commit for the forced redraw. This honors the |
| 429 // single commit per interval because the result will be swapped to screen. | 488 // single commit per interval because the result will be swapped to screen. |
| 430 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) | 489 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) |
| 431 return true; | 490 return true; |
| 432 | 491 |
| 433 // After this point, we only start a commit once per frame. | 492 // After this point, we only start a commit once per frame. |
| 434 if (HasSentBeginFrameToMainThreadThisFrame()) | 493 if (HasSentBeginFrameToMainThreadThisFrame()) |
| 435 return false; | 494 return false; |
| 436 | 495 |
| 437 // We shouldn't normally accept commits if there isn't an OutputSurface. | |
| 438 if (!HasInitializedOutputSurface()) | |
| 439 return false; | |
| 440 | |
| 441 return true; | 496 return true; |
| 442 } | 497 } |
| 443 | 498 |
| 444 bool SchedulerStateMachine::ShouldCommit() const { | 499 bool SchedulerStateMachine::ShouldCommit() const { |
| 445 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; | 500 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; |
| 446 } | 501 } |
| 447 | 502 |
| 448 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { | 503 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { |
| 449 if (ShouldAcquireLayerTexturesForMainThread()) | 504 if (ShouldAcquireLayerTexturesForMainThread()) |
| 450 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; | 505 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 477 DCHECK(!(forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW && | 532 DCHECK(!(forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW && |
| 478 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK)); | 533 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK)); |
| 479 } | 534 } |
| 480 | 535 |
| 481 void SchedulerStateMachine::UpdateState(Action action) { | 536 void SchedulerStateMachine::UpdateState(Action action) { |
| 482 switch (action) { | 537 switch (action) { |
| 483 case ACTION_NONE: | 538 case ACTION_NONE: |
| 484 return; | 539 return; |
| 485 | 540 |
| 486 case ACTION_UPDATE_VISIBLE_TILES: | 541 case ACTION_UPDATE_VISIBLE_TILES: |
| 487 last_frame_number_where_update_visible_tiles_was_called_ = | 542 last_draw_attempt_count_update_visible_tiles_was_called_ = |
| 488 current_frame_number_; | 543 draw_attempt_count_; |
| 489 return; | 544 return; |
| 490 | 545 |
| 491 case ACTION_ACTIVATE_PENDING_TREE: | 546 case ACTION_ACTIVATE_PENDING_TREE: |
| 492 UpdateStateOnActivation(); | 547 UpdateStateOnActivation(); |
| 493 return; | 548 return; |
| 494 | 549 |
| 495 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: | 550 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: |
| 496 DCHECK(!has_pending_tree_); | 551 DCHECK(!has_pending_tree_); |
| 497 DCHECK(visible_ || | 552 DCHECK(visible_ || |
| 498 readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED || | 553 readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED || |
| 499 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT || | 554 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT || |
| 500 output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT); | 555 output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT); |
| 501 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; | 556 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; |
| 502 needs_commit_ = false; | 557 needs_commit_ = false; |
| 503 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED) | 558 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED) |
| 504 readback_state_ = READBACK_STATE_FORCED_COMMIT_PENDING; | 559 readback_state_ = READBACK_STATE_FORCED_COMMIT_PENDING; |
| 505 last_frame_number_where_begin_frame_sent_to_main_thread_ = | 560 last_begin_frame_count_begin_frame_sent_to_main_thread_ = |
| 506 current_frame_number_; | 561 begin_frame_count_; |
| 507 return; | 562 return; |
| 508 | 563 |
| 509 case ACTION_COMMIT: { | 564 case ACTION_COMMIT: { |
| 510 bool commit_was_aborted = false; | 565 bool commit_was_aborted = false; |
| 511 UpdateStateOnCommit(commit_was_aborted); | 566 UpdateStateOnCommit(commit_was_aborted); |
| 512 return; | 567 return; |
| 513 } | 568 } |
| 514 | 569 |
| 515 case ACTION_DRAW_AND_SWAP_FORCED: | 570 case ACTION_DRAW_AND_SWAP_FORCED: |
| 516 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { | 571 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 536 | 591 |
| 537 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: | 592 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: |
| 538 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD; | 593 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD; |
| 539 main_thread_needs_layer_textures_ = false; | 594 main_thread_needs_layer_textures_ = false; |
| 540 return; | 595 return; |
| 541 } | 596 } |
| 542 } | 597 } |
| 543 | 598 |
| 544 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { | 599 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { |
| 545 commit_count_++; | 600 commit_count_++; |
| 601 draw_attempt_count_++; | |
| 546 | 602 |
| 547 // If we are impl-side-painting but the commit was aborted, then we behave | 603 // If we are impl-side-painting but the commit was aborted, then we behave |
| 548 // mostly as if we are not impl-side-painting since there is no pending tree. | 604 // mostly as if we are not impl-side-painting since there is no pending tree. |
| 549 has_pending_tree_ = settings_.impl_side_painting && !commit_was_aborted; | 605 has_pending_tree_ = settings_.impl_side_painting && !commit_was_aborted; |
| 550 | 606 |
| 551 // Update state related to readbacks. | 607 // Update state related to readbacks. |
| 552 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING) { | 608 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING) { |
| 553 // Update the state if this is the readback commit. | 609 // Update the state if this is the readback commit. |
| 554 readback_state_ = has_pending_tree_ | 610 readback_state_ = has_pending_tree_ |
| 555 ? READBACK_STATE_WAITING_FOR_ACTIVATION | 611 ? READBACK_STATE_WAITING_FOR_ACTIVATION |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 604 (!commit_was_aborted || | 660 (!commit_was_aborted || |
| 605 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK || | 661 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK || |
| 606 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) { | 662 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) { |
| 607 needs_redraw_ = true; | 663 needs_redraw_ = true; |
| 608 active_tree_has_been_drawn_ = false; | 664 active_tree_has_been_drawn_ = false; |
| 609 } | 665 } |
| 610 | 666 |
| 611 // This post-commit work is common to both completed and aborted commits. | 667 // This post-commit work is common to both completed and aborted commits. |
| 612 pending_tree_is_ready_for_activation_ = false; | 668 pending_tree_is_ready_for_activation_ = false; |
| 613 | 669 |
| 614 if (draw_if_possible_failed_) | 670 if (draw_if_possible_failed_) { |
| 615 last_frame_number_swap_performed_ = -1; | 671 last_begin_frame_count_swap_performed_ = -1; |
| 672 last_draw_attempt_count_draw_was_called_ = -1; | |
| 673 } | |
| 616 | 674 |
| 617 // If we are planing to draw with the new commit, lock the layer textures for | 675 // If we are planing to draw with the new commit, lock the layer textures for |
| 618 // use on the impl thread. Otherwise, leave them unlocked. | 676 // use on the impl thread. Otherwise, leave them unlocked. |
| 619 if (has_pending_tree_ || needs_redraw_) | 677 if (has_pending_tree_ || needs_redraw_) |
| 620 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD; | 678 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD; |
| 621 else | 679 else |
| 622 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; | 680 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; |
| 623 } | 681 } |
| 624 | 682 |
| 625 void SchedulerStateMachine::UpdateStateOnActivation() { | 683 void SchedulerStateMachine::UpdateStateOnActivation() { |
| 684 draw_attempt_count_++; | |
| 685 | |
| 626 // Update output surface state. | 686 // Update output surface state. |
| 627 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) | 687 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) |
| 628 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; | 688 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; |
| 629 | 689 |
| 630 // Update readback state | 690 // Update readback state |
| 631 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) | 691 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) |
| 632 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; | 692 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; |
| 633 | 693 |
| 634 // Update forced redraw state | 694 // Update forced redraw state |
| 635 if (readback_state_ == READBACK_STATE_WAITING_FOR_ACTIVATION) | 695 if (readback_state_ == READBACK_STATE_WAITING_FOR_ACTIVATION) |
| 636 readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK; | 696 readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK; |
| 637 else if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING) | 697 else if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING) |
| 638 readback_state_ = READBACK_STATE_IDLE; | 698 readback_state_ = READBACK_STATE_IDLE; |
| 639 | 699 |
| 640 has_pending_tree_ = false; | 700 has_pending_tree_ = false; |
| 641 pending_tree_is_ready_for_activation_ = false; | 701 pending_tree_is_ready_for_activation_ = false; |
| 642 active_tree_has_been_drawn_ = false; | 702 active_tree_has_been_drawn_ = false; |
| 643 needs_redraw_ = true; | 703 needs_redraw_ = true; |
| 704 last_draw_attempt_count_tree_activation_attempted_ = draw_attempt_count_; | |
| 644 } | 705 } |
| 645 | 706 |
| 646 void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) { | 707 void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) { |
| 647 DCHECK(readback_state_ != READBACK_STATE_REPLACEMENT_COMMIT_PENDING && | 708 DCHECK(readback_state_ != READBACK_STATE_REPLACEMENT_COMMIT_PENDING && |
| 648 readback_state_ != READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING) | 709 readback_state_ != READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING) |
| 649 << *AsValue(); | 710 << *AsValue(); |
| 650 | 711 |
| 651 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) { | 712 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) { |
| 652 // The draw correspons to a readback commit. | 713 // The draw correspons to a readback commit. |
| 653 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); | 714 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 666 !has_pending_tree_) { | 727 !has_pending_tree_) { |
| 667 commit_state_ = COMMIT_STATE_IDLE; | 728 commit_state_ = COMMIT_STATE_IDLE; |
| 668 } | 729 } |
| 669 | 730 |
| 670 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD) | 731 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD) |
| 671 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; | 732 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; |
| 672 | 733 |
| 673 needs_redraw_ = false; | 734 needs_redraw_ = false; |
| 674 draw_if_possible_failed_ = false; | 735 draw_if_possible_failed_ = false; |
| 675 active_tree_has_been_drawn_ = true; | 736 active_tree_has_been_drawn_ = true; |
| 737 last_draw_attempt_count_draw_was_called_ = draw_attempt_count_; | |
| 676 | 738 |
| 677 if (did_swap) { | 739 if (did_swap) { |
| 678 swap_used_incomplete_tile_ = false; | 740 swap_used_incomplete_tile_ = false; |
| 679 last_frame_number_swap_performed_ = current_frame_number_; | 741 last_begin_frame_count_swap_performed_ = begin_frame_count_; |
| 680 } | 742 } |
| 681 } | 743 } |
| 682 | 744 |
| 745 void SchedulerStateMachine::AdvanceBeginFrameStateWhenNoActionsRemain() { | |
| 746 switch (begin_frame_state_) { | |
| 747 case BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME: | |
| 748 begin_frame_state_ = BEGIN_FRAME_STATE_DEADLINE_PENDING; | |
| 749 break; | |
| 750 case BEGIN_FRAME_STATE_INSIDE_DEADLINE: | |
| 751 begin_frame_state_ = BEGIN_FRAME_STATE_IDLE; | |
| 752 break; | |
| 753 case BEGIN_FRAME_STATE_IDLE: | |
| 754 case BEGIN_FRAME_STATE_DEADLINE_PENDING: | |
| 755 break; | |
| 756 } | |
| 757 } | |
| 758 | |
| 683 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { | 759 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { |
| 684 DCHECK(!main_thread_needs_layer_textures_); | 760 DCHECK(!main_thread_needs_layer_textures_); |
| 685 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); | 761 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); |
| 686 main_thread_needs_layer_textures_ = true; | 762 main_thread_needs_layer_textures_ = true; |
| 687 } | 763 } |
| 688 | 764 |
| 765 bool SchedulerStateMachine::BeginFrameNeededByImplThread() const { | |
| 766 return BeginFrameNeededToDrawByImplThread() || | |
| 767 ProactiveBeginFrameWantedByImplThread(); | |
| 768 } | |
| 769 | |
| 689 // These are the cases where we definitely (or almost definitely) have a | 770 // These are the cases where we definitely (or almost definitely) have a |
| 690 // new frame to draw and can draw. | 771 // new frame to draw and can draw. |
| 691 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { | 772 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { |
| 692 // The output surface is the provider of BeginFrames for the impl thread, | 773 // The output surface is the provider of BeginFrames for the impl thread, |
| 693 // so we are not going to get them even if we ask for them. | 774 // so we are not going to get them even if we ask for them. |
| 694 if (!HasInitializedOutputSurface()) | 775 if (!HasInitializedOutputSurface()) |
| 695 return false; | 776 return false; |
| 696 | 777 |
| 697 // If we can't draw, don't tick until we are notified that we can draw again. | 778 // If we can't draw, don't tick until we are notified that we can draw again. |
| 698 if (!can_draw_) | 779 if (!can_draw_) |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 713 if (swap_used_incomplete_tile_) | 794 if (swap_used_incomplete_tile_) |
| 714 return true; | 795 return true; |
| 715 | 796 |
| 716 return needs_redraw_; | 797 return needs_redraw_; |
| 717 } | 798 } |
| 718 | 799 |
| 719 // These are cases where we are very likely to draw soon, but might not | 800 // These are cases where we are very likely to draw soon, but might not |
| 720 // actually have a new frame to draw when we receive the next BeginFrame. | 801 // actually have a new frame to draw when we receive the next BeginFrame. |
| 721 // Proactively requesting the BeginFrame helps hide the round trip latency of | 802 // Proactively requesting the BeginFrame helps hide the round trip latency of |
| 722 // the SetNeedsBeginFrame request that has to go to the Browser. | 803 // the SetNeedsBeginFrame request that has to go to the Browser. |
| 723 // However, this is bad for the synchronous compoisitor because we have to | |
| 724 // draw when we get the BeginFrame and could end up drawing many duplicate | |
| 725 // frames. | |
| 726 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const { | 804 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const { |
| 727 // The output surface is the provider of BeginFrames for the impl thread, | 805 // The output surface is the provider of BeginFrames for the impl thread, |
| 728 // so we are not going to get them even if we ask for them. | 806 // so we are not going to get them even if we ask for them. |
| 729 if (!HasInitializedOutputSurface()) | 807 if (!HasInitializedOutputSurface()) |
| 730 return false; | 808 return false; |
| 731 | 809 |
| 810 // Proactive BeginFrames are bad for the synchronous compoisitor because we | |
|
Sami
2013/08/30 13:49:06
Typo: compositor
| |
| 811 // have to draw when we get the BeginFrame and could end up drawing many | |
| 812 // duplicate frames if our new frame isn't ready in time. | |
| 813 if (settings_.using_synchronous_renderer_compositor) | |
| 814 return false; | |
| 815 | |
| 816 // Do not be proactive if vsync is off. | |
| 817 if (!settings_.throttle_frame_production) | |
| 818 return false; | |
| 819 | |
| 732 // Do not be proactive when invisible. | 820 // Do not be proactive when invisible. |
| 733 if (!visible_) | 821 if (!visible_) |
| 734 return false; | 822 return false; |
| 735 | 823 |
| 736 // We should proactively request a BeginFrame if a commit is pending | 824 // We should proactively request a BeginFrame if a commit is pending |
| 737 // because we will want to draw if the commit completes quickly. | 825 // because we will want to draw if the commit completes quickly. |
| 738 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) | 826 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) |
| 739 return true; | 827 return true; |
| 740 | 828 |
| 741 // If the pending tree activates quickly, we'll want a BeginFrame soon | 829 // If the pending tree activates quickly, we'll want a BeginFrame soon |
| 742 // to draw the new active tree. | 830 // to draw the new active tree. |
| 743 if (has_pending_tree_) | 831 if (has_pending_tree_) |
| 744 return true; | 832 return true; |
| 745 | 833 |
| 746 return false; | 834 return false; |
| 747 } | 835 } |
| 748 | 836 |
| 749 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { | 837 void SchedulerStateMachine::OnBeginFrame(const BeginFrameArgs& args) { |
| 750 current_frame_number_++; | 838 begin_frame_count_++; |
| 751 inside_begin_frame_ = true; | 839 draw_attempt_count_++; |
| 752 last_begin_frame_args_ = args; | 840 last_begin_frame_args_ = args; |
| 841 begin_frame_state_ = BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME; | |
| 753 } | 842 } |
| 754 | 843 |
| 755 void SchedulerStateMachine::DidLeaveBeginFrame() { | 844 bool SchedulerStateMachine::ShouldTriggerBeginFrameDeadlineEarly() const { |
| 756 inside_begin_frame_ = false; | 845 // TODO(brianderson): This should take into account multiple commit sources. |
|
Sami
2013/08/30 13:49:06
When could something like this happen? If there's
brianderson
2013/09/03 22:51:47
This isn't so much an issue for Android as it is f
| |
| 846 return begin_frame_state_ == BEGIN_FRAME_STATE_DEADLINE_PENDING && | |
| 847 !active_tree_has_been_drawn_; | |
| 848 } | |
| 849 | |
| 850 bool SchedulerStateMachine::InsideBeginFrame() const { | |
| 851 return begin_frame_state_ != BEGIN_FRAME_STATE_IDLE; | |
| 852 } | |
| 853 | |
| 854 void SchedulerStateMachine::OnBeginFrameDeadline() { | |
| 855 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_DEADLINE_PENDING); | |
| 856 draw_attempt_count_++; | |
| 857 begin_frame_state_ = BEGIN_FRAME_STATE_INSIDE_DEADLINE; | |
| 757 } | 858 } |
| 758 | 859 |
| 759 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } | 860 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } |
| 760 | 861 |
| 862 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } | |
| 863 | |
| 761 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } | 864 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } |
| 762 | 865 |
| 763 void SchedulerStateMachine::DidSwapUseIncompleteTile() { | 866 void SchedulerStateMachine::DidSwapUseIncompleteTile() { |
| 764 swap_used_incomplete_tile_ = true; | 867 swap_used_incomplete_tile_ = true; |
| 765 } | 868 } |
| 766 | 869 |
| 767 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) { | 870 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) { |
| 768 draw_if_possible_failed_ = !success; | 871 draw_if_possible_failed_ = !success; |
| 769 if (draw_if_possible_failed_) { | 872 if (draw_if_possible_failed_) { |
| 770 needs_redraw_ = true; | 873 needs_redraw_ = true; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 830 return; | 933 return; |
| 831 output_surface_state_ = OUTPUT_SURFACE_LOST; | 934 output_surface_state_ = OUTPUT_SURFACE_LOST; |
| 832 needs_redraw_ = false; | 935 needs_redraw_ = false; |
| 833 } | 936 } |
| 834 | 937 |
| 835 void SchedulerStateMachine::NotifyReadyToActivate() { | 938 void SchedulerStateMachine::NotifyReadyToActivate() { |
| 836 if (has_pending_tree_) | 939 if (has_pending_tree_) |
| 837 pending_tree_is_ready_for_activation_ = true; | 940 pending_tree_is_ready_for_activation_ = true; |
| 838 } | 941 } |
| 839 | 942 |
| 840 void SchedulerStateMachine::SetCanDraw(bool can) { can_draw_ = can; } | |
| 841 | |
| 842 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { | 943 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { |
| 843 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); | 944 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); |
| 844 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; | 945 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; |
| 845 | 946 |
| 846 if (did_create_and_initialize_first_output_surface_) { | 947 if (did_create_and_initialize_first_output_surface_) { |
| 847 // TODO(boliu): See if we can remove this when impl-side painting is always | 948 // TODO(boliu): See if we can remove this when impl-side painting is always |
| 848 // on. Does anything on the main thread need to update after recreate? | 949 // on. Does anything on the main thread need to update after recreate? |
| 849 needs_commit_ = true; | 950 needs_commit_ = true; |
| 850 } | 951 } |
| 851 did_create_and_initialize_first_output_surface_ = true; | 952 did_create_and_initialize_first_output_surface_ = true; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 865 NOTREACHED(); | 966 NOTREACHED(); |
| 866 return false; | 967 return false; |
| 867 } | 968 } |
| 868 | 969 |
| 869 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced( | 970 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced( |
| 870 int num_draws) { | 971 int num_draws) { |
| 871 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws; | 972 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws; |
| 872 } | 973 } |
| 873 | 974 |
| 874 } // namespace cc | 975 } // namespace cc |
| OLD | NEW |