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 |