Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(195)

Side by Side Diff: cc/scheduler/scheduler_state_machine.cc

Issue 23796002: cc: Implement deadine scheduling disabled by default (Closed) Base URL: http://git.chromium.org/chromium/src.git@schedReadback4
Patch Set: Fix context lost race conditions Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 begin_frame_state_(BEGIN_FRAME_STATE_IDLE),
17 commit_state_(COMMIT_STATE_IDLE), 18 commit_state_(COMMIT_STATE_IDLE),
18 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED), 19 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED),
19 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), 20 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE),
20 readback_state_(READBACK_STATE_IDLE), 21 readback_state_(READBACK_STATE_IDLE),
21 commit_count_(0), 22 commit_count_(0),
22 current_frame_number_(0), 23 begin_frame_count_(0),
23 last_frame_number_where_begin_frame_sent_to_main_thread_(-1), 24 last_begin_frame_count_swap_performed_(-1),
24 last_frame_number_swap_performed_(-1), 25 last_begin_frame_count_begin_frame_sent_to_main_thread_(-1),
25 last_frame_number_where_update_visible_tiles_was_called_(-1), 26 last_begin_frame_count_update_visible_tiles_was_called_(-1),
26 consecutive_failed_draws_(0), 27 consecutive_failed_draws_(0),
27 needs_redraw_(false), 28 needs_redraw_(false),
28 swap_used_incomplete_tile_(false), 29 swap_used_incomplete_tile_(false),
29 needs_commit_(false), 30 needs_commit_(false),
30 main_thread_needs_layer_textures_(false), 31 main_thread_needs_layer_textures_(false),
31 inside_begin_frame_(false),
32 visible_(false), 32 visible_(false),
33 can_start_(false), 33 can_start_(false),
34 can_draw_(false), 34 can_draw_(false),
35 has_pending_tree_(false), 35 has_pending_tree_(false),
36 pending_tree_is_ready_for_activation_(false), 36 pending_tree_is_ready_for_activation_(false),
37 active_tree_needs_first_draw_(false), 37 active_tree_needs_first_draw_(false),
38 draw_if_possible_failed_(false), 38 draw_if_possible_failed_(false),
39 did_create_and_initialize_first_output_surface_(false) {} 39 did_create_and_initialize_first_output_surface_(false) {}
40 40
41 const char* SchedulerStateMachine::OutputSurfaceStateToString( 41 const char* SchedulerStateMachine::OutputSurfaceStateToString(
42 OutputSurfaceState state) { 42 OutputSurfaceState state) {
43 switch (state) { 43 switch (state) {
44 case OUTPUT_SURFACE_ACTIVE: 44 case OUTPUT_SURFACE_ACTIVE:
45 return "OUTPUT_SURFACE_ACTIVE"; 45 return "OUTPUT_SURFACE_ACTIVE";
46 case OUTPUT_SURFACE_LOST: 46 case OUTPUT_SURFACE_LOST:
47 return "OUTPUT_SURFACE_LOST"; 47 return "OUTPUT_SURFACE_LOST";
48 case OUTPUT_SURFACE_CREATING: 48 case OUTPUT_SURFACE_CREATING:
49 return "OUTPUT_SURFACE_CREATING"; 49 return "OUTPUT_SURFACE_CREATING";
50 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 50 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
51 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT"; 51 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT";
52 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 52 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
53 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION"; 53 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION";
54 } 54 }
55 NOTREACHED(); 55 NOTREACHED();
56 return "???"; 56 return "???";
57 } 57 }
58 58
59 const char* SchedulerStateMachine::BeginFrameStateToString(
60 BeginFrameState state) {
61 switch (state) {
62 case BEGIN_FRAME_STATE_IDLE:
63 return "BEGIN_FRAME_STATE_IDLE";
64 case BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME:
65 return "BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME";
66 case BEGIN_FRAME_STATE_DEADLINE_PENDING:
67 return "BEGIN_FRAME_STATE_DEADLINE_PENDING";
68 case BEGIN_FRAME_STATE_INSIDE_DEADLINE:
69 return "BEGIN_FRAME_STATE_INSIDE_DEADLINE";
70 }
71 NOTREACHED();
72 return "???";
73 }
74
59 const char* SchedulerStateMachine::CommitStateToString(CommitState state) { 75 const char* SchedulerStateMachine::CommitStateToString(CommitState state) {
60 switch (state) { 76 switch (state) {
61 case COMMIT_STATE_IDLE: 77 case COMMIT_STATE_IDLE:
62 return "COMMIT_STATE_IDLE"; 78 return "COMMIT_STATE_IDLE";
63 case COMMIT_STATE_FRAME_IN_PROGRESS: 79 case COMMIT_STATE_FRAME_IN_PROGRESS:
64 return "COMMIT_STATE_FRAME_IN_PROGRESS"; 80 return "COMMIT_STATE_FRAME_IN_PROGRESS";
65 case COMMIT_STATE_READY_TO_COMMIT: 81 case COMMIT_STATE_READY_TO_COMMIT:
66 return "COMMIT_STATE_READY_TO_COMMIT"; 82 return "COMMIT_STATE_READY_TO_COMMIT";
67 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: 83 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW:
68 return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW"; 84 return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW";
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 } 165 }
150 NOTREACHED(); 166 NOTREACHED();
151 return "???"; 167 return "???";
152 } 168 }
153 169
154 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { 170 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const {
155 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); 171 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
156 172
157 scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue); 173 scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue);
158 major_state->SetString("next_action", ActionToString(NextAction())); 174 major_state->SetString("next_action", ActionToString(NextAction()));
175 major_state->SetString("begin_frame_state",
176 BeginFrameStateToString(begin_frame_state_));
159 major_state->SetString("commit_state", CommitStateToString(commit_state_)); 177 major_state->SetString("commit_state", CommitStateToString(commit_state_));
160 major_state->SetString("texture_state_", 178 major_state->SetString("texture_state_",
161 TextureStateToString(texture_state_)); 179 TextureStateToString(texture_state_));
162 major_state->SetString("output_surface_state_", 180 major_state->SetString("output_surface_state_",
163 OutputSurfaceStateToString(output_surface_state_)); 181 OutputSurfaceStateToString(output_surface_state_));
164 major_state->SetString( 182 major_state->SetString(
165 "forced_redraw_state", 183 "forced_redraw_state",
166 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); 184 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_));
167 major_state->SetString("readback_state", 185 major_state->SetString("readback_state",
168 SynchronousReadbackStateToString(readback_state_)); 186 SynchronousReadbackStateToString(readback_state_));
(...skipping 21 matching lines...) Expand all
190 (last_begin_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() / 208 (last_begin_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() /
191 1000.0L); 209 1000.0L);
192 timestamps_state->SetDouble( 210 timestamps_state->SetDouble(
193 "6_deadline", 211 "6_deadline",
194 (last_begin_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / 212 (last_begin_frame_args_.deadline - base::TimeTicks()).InMicroseconds() /
195 1000.0L); 213 1000.0L);
196 state->Set("major_timestamps_in_ms", timestamps_state.release()); 214 state->Set("major_timestamps_in_ms", timestamps_state.release());
197 215
198 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue); 216 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue);
199 minor_state->SetInteger("commit_count", commit_count_); 217 minor_state->SetInteger("commit_count", commit_count_);
200 minor_state->SetInteger("current_frame_number", current_frame_number_); 218 minor_state->SetInteger("begin_frame_count_", begin_frame_count_);
219
220 minor_state->SetInteger("last_begin_frame_count_swap_performed_",
221 last_begin_frame_count_swap_performed_);
201 minor_state->SetInteger( 222 minor_state->SetInteger(
202 "last_frame_number_where_begin_frame_sent_to_main_thread", 223 "last_begin_frame_count_begin_frame_sent_to_main_thread_",
203 last_frame_number_where_begin_frame_sent_to_main_thread_); 224 last_begin_frame_count_begin_frame_sent_to_main_thread_);
204 minor_state->SetInteger("last_frame_number_swap_performed_",
205 last_frame_number_swap_performed_);
206 minor_state->SetInteger( 225 minor_state->SetInteger(
207 "last_frame_number_where_update_visible_tiles_was_called", 226 "last_begin_frame_count_update_visible_tiles_was_called_",
208 last_frame_number_where_update_visible_tiles_was_called_); 227 last_begin_frame_count_update_visible_tiles_was_called_);
209 minor_state->SetInteger("consecutive_failed_draws", 228
229 minor_state->SetInteger("consecutive_failed_draws_",
210 consecutive_failed_draws_); 230 consecutive_failed_draws_);
211 minor_state->SetBoolean("needs_redraw", needs_redraw_); 231 minor_state->SetBoolean("needs_redraw", needs_redraw_);
212 minor_state->SetBoolean("swap_used_incomplete_tile", 232 minor_state->SetBoolean("swap_used_incomplete_tile",
213 swap_used_incomplete_tile_); 233 swap_used_incomplete_tile_);
214 minor_state->SetBoolean("needs_commit", needs_commit_); 234 minor_state->SetBoolean("needs_commit", needs_commit_);
215 minor_state->SetBoolean("main_thread_needs_layer_textures", 235 minor_state->SetBoolean("main_thread_needs_layer_textures",
216 main_thread_needs_layer_textures_); 236 main_thread_needs_layer_textures_);
217 minor_state->SetBoolean("inside_begin_frame", inside_begin_frame_);
218 minor_state->SetBoolean("visible", visible_); 237 minor_state->SetBoolean("visible", visible_);
219 minor_state->SetBoolean("can_start", can_start_); 238 minor_state->SetBoolean("can_start", can_start_);
220 minor_state->SetBoolean("can_draw", can_draw_); 239 minor_state->SetBoolean("can_draw", can_draw_);
221 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); 240 minor_state->SetBoolean("has_pending_tree", has_pending_tree_);
222 minor_state->SetBoolean("pending_tree_is_ready_for_activation_", 241 minor_state->SetBoolean("pending_tree_is_ready_for_activation_",
223 pending_tree_is_ready_for_activation_); 242 pending_tree_is_ready_for_activation_);
224 minor_state->SetBoolean("active_tree_needs_first_draw_", 243 minor_state->SetBoolean("active_tree_needs_first_draw_",
225 active_tree_needs_first_draw_); 244 active_tree_needs_first_draw_);
226 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_); 245 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_);
227 minor_state->SetBoolean("did_create_and_initialize_first_output_surface", 246 minor_state->SetBoolean("did_create_and_initialize_first_output_surface",
228 did_create_and_initialize_first_output_surface_); 247 did_create_and_initialize_first_output_surface_);
229 state->Set("minor_state", minor_state.release()); 248 state->Set("minor_state", minor_state.release());
230 249
231 return state.PassAs<base::Value>(); 250 return state.PassAs<base::Value>();
232 } 251 }
233 252
234 bool SchedulerStateMachine::HasDrawnAndSwappedThisFrame() const { 253 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const {
235 return current_frame_number_ == last_frame_number_swap_performed_; 254 return begin_frame_count_ ==
255 last_begin_frame_count_begin_frame_sent_to_main_thread_;
236 } 256 }
237 257
238 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { 258 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const {
239 return current_frame_number_ == 259 return begin_frame_count_ ==
240 last_frame_number_where_update_visible_tiles_was_called_; 260 last_begin_frame_count_update_visible_tiles_was_called_;
241 } 261 }
242 262
243 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const { 263 bool SchedulerStateMachine::HasSwappedThisFrame() const {
244 return current_frame_number_ == 264 return begin_frame_count_ == last_begin_frame_count_swap_performed_;
245 last_frame_number_where_begin_frame_sent_to_main_thread_;
246 } 265 }
247 266
248 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { 267 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
249 // These are all the cases where we normally cannot or do not want to draw 268 // These are all the cases where we normally cannot or do not want to draw
250 // but, if needs_redraw_ is true and we do not draw to make forward progress, 269 // but, if needs_redraw_ is true and we do not draw to make forward progress,
251 // we might deadlock with the main thread. 270 // we might deadlock with the main thread.
252 // This should be a superset of PendingActivationsShouldBeForced() since 271 // This should be a superset of PendingActivationsShouldBeForced() since
253 // activation of the pending tree is blocked by drawing of the active tree and 272 // activation of the pending tree is blocked by drawing of the active tree and
254 // the main thread might be blocked on activation of the most recent commit. 273 // the main thread might be blocked on activation of the most recent commit.
255 if (PendingActivationsShouldBeForced()) 274 if (PendingActivationsShouldBeForced())
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 } 337 }
319 338
320 // If we need to abort draws, we should do so ASAP since the draw could 339 // If we need to abort draws, we should do so ASAP since the draw could
321 // be blocking other important actions (like output surface initialization), 340 // be blocking other important actions (like output surface initialization),
322 // from occuring. If we are waiting for the first draw, then perfom the 341 // from occuring. If we are waiting for the first draw, then perfom the
323 // aborted draw to keep things moving. If we are not waiting for the first 342 // aborted draw to keep things moving. If we are not waiting for the first
324 // draw however, we don't want to abort for no reason. 343 // draw however, we don't want to abort for no reason.
325 if (PendingDrawsShouldBeAborted()) 344 if (PendingDrawsShouldBeAborted())
326 return active_tree_needs_first_draw_; 345 return active_tree_needs_first_draw_;
327 346
328 // After this line, we only want to draw once per frame. 347 // After this line, we only want to swap once per frame.
329 if (HasDrawnAndSwappedThisFrame()) 348 if (HasSwappedThisFrame())
330 return false; 349 return false;
331 350
332 // We currently only draw within the BeginFrame. 351 // Except for the cases above, do not draw outside of the BeginFrame deadline.
333 if (!inside_begin_frame_) 352 if (begin_frame_state_ != BEGIN_FRAME_STATE_INSIDE_DEADLINE)
334 return false; 353 return false;
335 354
336 // Only handle forced redraws due to timeouts on the regular deadline. 355 // Only handle forced redraws due to timeouts on the regular deadline.
337 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) { 356 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) {
338 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); 357 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
339 return true; 358 return true;
340 } 359 }
341 360
342 return needs_redraw_; 361 return needs_redraw_;
343 } 362 }
(...skipping 29 matching lines...) Expand all
373 bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const { 392 bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const {
374 if (!settings_.impl_side_painting) 393 if (!settings_.impl_side_painting)
375 return false; 394 return false;
376 if (HasUpdatedVisibleTilesThisFrame()) 395 if (HasUpdatedVisibleTilesThisFrame())
377 return false; 396 return false;
378 397
379 // There's no reason to check for tiles if we don't have an output surface. 398 // There's no reason to check for tiles if we don't have an output surface.
380 if (!HasInitializedOutputSurface()) 399 if (!HasInitializedOutputSurface())
381 return false; 400 return false;
382 401
383 // We always want to update the most recent visible tiles before drawing 402 // We should not check for visible tiles until we've entered the deadline so
384 // so we draw with fewer missing tiles. 403 // we check as late possible and give the tiles more time to initialize.
385 if (ShouldDraw()) 404 if (begin_frame_state_ != BEGIN_FRAME_STATE_INSIDE_DEADLINE)
386 return true; 405 return false;
387 406
388 // If the last swap drew with checkerboard or missing tiles, we should 407 // If the last swap drew with checkerboard or missing tiles, we should
389 // poll for any new visible tiles so we can be notified to draw again 408 // poll for any new visible tiles so we can be notified to draw again
390 // when there are. 409 // when there are.
391 if (swap_used_incomplete_tile_) 410 if (swap_used_incomplete_tile_)
392 return true; 411 return true;
393 412
394 return false; 413 return false;
395 } 414 }
396 415
(...skipping 10 matching lines...) Expand all
407 return false; 426 return false;
408 427
409 // We want to handle readback commits immediately to unblock the main thread. 428 // We want to handle readback commits immediately to unblock the main thread.
410 // Note: This BeginFrame will correspond to the replacement commit that comes 429 // Note: This BeginFrame will correspond to the replacement commit that comes
411 // after the readback commit itself, so we only send the BeginFrame if a 430 // after the readback commit itself, so we only send the BeginFrame if a
412 // commit isn't already pending behind the readback. 431 // commit isn't already pending behind the readback.
413 if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME) 432 if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME)
414 return !CommitPending(); 433 return !CommitPending();
415 434
416 // We do not need commits if we are not visible, unless there's a 435 // We do not need commits if we are not visible, unless there's a
417 // request for a forced commit. 436 // request for a readback.
418 if (!visible_) 437 if (!visible_)
419 return false; 438 return false;
420 439
440 // We shouldn't normally accept commits if there isn't an OutputSurface.
441 if (!HasInitializedOutputSurface())
442 return false;
443
421 // We want to start the first commit after we get a new output surface ASAP. 444 // We want to start the first commit after we get a new output surface ASAP.
422 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) 445 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT)
423 return true; 446 return true;
424 447
448 // We should not send the BeginFrame to the main thread while we are in
449 // BEGIN_FRAME_STATE_IDLE since we might have new user input coming in soon.
450 // TODO(brianderson): Also allow sending BeginFrame to main thread while idle
451 // when the main thread isn't consuming user input.
452 if (begin_frame_state_ == BEGIN_FRAME_STATE_IDLE)
453 return false;
454
425 // We need a new commit for the forced redraw. This honors the 455 // We need a new commit for the forced redraw. This honors the
426 // single commit per interval because the result will be swapped to screen. 456 // single commit per interval because the result will be swapped to screen.
427 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) 457 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
428 return true; 458 return true;
429 459
430 // After this point, we only start a commit once per frame. 460 // After this point, we only start a commit once per frame.
431 if (HasSentBeginFrameToMainThreadThisFrame()) 461 if (HasSentBeginFrameToMainThreadThisFrame())
432 return false; 462 return false;
433 463
434 // We shouldn't normally accept commits if there isn't an OutputSurface.
435 if (!HasInitializedOutputSurface())
436 return false;
437
438 return true; 464 return true;
439 } 465 }
440 466
441 bool SchedulerStateMachine::ShouldCommit() const { 467 bool SchedulerStateMachine::ShouldCommit() const {
442 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; 468 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT;
443 } 469 }
444 470
445 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 471 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
446 if (ShouldAcquireLayerTexturesForMainThread()) 472 if (ShouldAcquireLayerTexturesForMainThread())
447 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; 473 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD;
(...skipping 26 matching lines...) Expand all
474 DCHECK(!(forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW && 500 DCHECK(!(forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW &&
475 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK)); 501 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK));
476 } 502 }
477 503
478 void SchedulerStateMachine::UpdateState(Action action) { 504 void SchedulerStateMachine::UpdateState(Action action) {
479 switch (action) { 505 switch (action) {
480 case ACTION_NONE: 506 case ACTION_NONE:
481 return; 507 return;
482 508
483 case ACTION_UPDATE_VISIBLE_TILES: 509 case ACTION_UPDATE_VISIBLE_TILES:
484 last_frame_number_where_update_visible_tiles_was_called_ = 510 last_begin_frame_count_update_visible_tiles_was_called_ =
485 current_frame_number_; 511 begin_frame_count_;
486 return; 512 return;
487 513
488 case ACTION_ACTIVATE_PENDING_TREE: 514 case ACTION_ACTIVATE_PENDING_TREE:
489 UpdateStateOnActivation(); 515 UpdateStateOnActivation();
490 return; 516 return;
491 517
492 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: 518 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:
493 DCHECK(!has_pending_tree_); 519 DCHECK(!has_pending_tree_);
494 DCHECK(visible_ || readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME); 520 DCHECK(visible_ || readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME);
495 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; 521 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS;
496 needs_commit_ = false; 522 needs_commit_ = false;
497 if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME) 523 if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME)
498 readback_state_ = READBACK_STATE_WAITING_FOR_COMMIT; 524 readback_state_ = READBACK_STATE_WAITING_FOR_COMMIT;
499 last_frame_number_where_begin_frame_sent_to_main_thread_ = 525 last_begin_frame_count_begin_frame_sent_to_main_thread_ =
500 current_frame_number_; 526 begin_frame_count_;
501 return; 527 return;
502 528
503 case ACTION_COMMIT: { 529 case ACTION_COMMIT: {
504 bool commit_was_aborted = false; 530 bool commit_was_aborted = false;
505 UpdateStateOnCommit(commit_was_aborted); 531 UpdateStateOnCommit(commit_was_aborted);
506 return; 532 return;
507 } 533 }
508 534
509 case ACTION_DRAW_AND_SWAP_FORCED: 535 case ACTION_DRAW_AND_SWAP_FORCED:
510 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { 536 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 (!commit_was_aborted || 629 (!commit_was_aborted ||
604 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK || 630 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK ||
605 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) { 631 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) {
606 needs_redraw_ = true; 632 needs_redraw_ = true;
607 active_tree_needs_first_draw_ = true; 633 active_tree_needs_first_draw_ = true;
608 } 634 }
609 635
610 // This post-commit work is common to both completed and aborted commits. 636 // This post-commit work is common to both completed and aborted commits.
611 pending_tree_is_ready_for_activation_ = false; 637 pending_tree_is_ready_for_activation_ = false;
612 638
613 if (draw_if_possible_failed_) 639 if (draw_if_possible_failed_) {
614 last_frame_number_swap_performed_ = -1; 640 last_begin_frame_count_swap_performed_ = -1;
641 }
615 642
616 // If we are planing to draw with the new commit, lock the layer textures for 643 // If we are planing to draw with the new commit, lock the layer textures for
617 // use on the impl thread. Otherwise, leave them unlocked. 644 // use on the impl thread. Otherwise, leave them unlocked.
618 if (has_pending_tree_ || needs_redraw_) 645 if (has_pending_tree_ || needs_redraw_)
619 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD; 646 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD;
620 else 647 else
621 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; 648 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED;
622 } 649 }
623 650
624 void SchedulerStateMachine::UpdateStateOnActivation() { 651 void SchedulerStateMachine::UpdateStateOnActivation() {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 } 694 }
668 695
669 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD) 696 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD)
670 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; 697 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED;
671 698
672 needs_redraw_ = false; 699 needs_redraw_ = false;
673 draw_if_possible_failed_ = false; 700 draw_if_possible_failed_ = false;
674 active_tree_needs_first_draw_ = false; 701 active_tree_needs_first_draw_ = false;
675 702
676 if (did_swap) 703 if (did_swap)
677 last_frame_number_swap_performed_ = current_frame_number_; 704 last_begin_frame_count_swap_performed_ = begin_frame_count_;
678 } 705 }
679 706
680 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { 707 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() {
681 DCHECK(!main_thread_needs_layer_textures_); 708 DCHECK(!main_thread_needs_layer_textures_);
682 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); 709 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD);
683 main_thread_needs_layer_textures_ = true; 710 main_thread_needs_layer_textures_ = true;
684 } 711 }
685 712
713 bool SchedulerStateMachine::BeginFrameNeededByImplThread() const {
714 return BeginFrameNeededToDrawByImplThread() ||
715 ProactiveBeginFrameWantedByImplThread();
716 }
717
686 // These are the cases where we definitely (or almost definitely) have a 718 // These are the cases where we definitely (or almost definitely) have a
687 // new frame to draw and can draw. 719 // new frame to draw and can draw.
688 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { 720 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const {
689 // The output surface is the provider of BeginFrames for the impl thread, 721 // The output surface is the provider of BeginFrames for the impl thread,
690 // so we are not going to get them even if we ask for them. 722 // so we are not going to get them even if we ask for them.
691 if (!HasInitializedOutputSurface()) 723 if (!HasInitializedOutputSurface())
692 return false; 724 return false;
693 725
694 // If we can't draw, don't tick until we are notified that we can draw again. 726 // If we can't draw, don't tick until we are notified that we can draw again.
695 if (!can_draw_) 727 if (!can_draw_)
(...skipping 14 matching lines...) Expand all
710 if (swap_used_incomplete_tile_) 742 if (swap_used_incomplete_tile_)
711 return true; 743 return true;
712 744
713 return needs_redraw_; 745 return needs_redraw_;
714 } 746 }
715 747
716 // These are cases where we are very likely to draw soon, but might not 748 // These are cases where we are very likely to draw soon, but might not
717 // actually have a new frame to draw when we receive the next BeginFrame. 749 // actually have a new frame to draw when we receive the next BeginFrame.
718 // Proactively requesting the BeginFrame helps hide the round trip latency of 750 // Proactively requesting the BeginFrame helps hide the round trip latency of
719 // the SetNeedsBeginFrame request that has to go to the Browser. 751 // the SetNeedsBeginFrame request that has to go to the Browser.
720 // However, this is bad for the synchronous compositor because we have to
721 // draw when we get the BeginFrame and could end up drawing many duplicate
722 // frames.
723 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const { 752 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const {
724 // The output surface is the provider of BeginFrames for the impl thread, 753 // The output surface is the provider of BeginFrames for the impl thread,
725 // so we are not going to get them even if we ask for them. 754 // so we are not going to get them even if we ask for them.
726 if (!HasInitializedOutputSurface()) 755 if (!HasInitializedOutputSurface())
727 return false; 756 return false;
728 757
758 // Proactive BeginFrames are bad for the synchronous compositor because we
759 // have to draw when we get the BeginFrame and could end up drawing many
760 // duplicate frames if our new frame isn't ready in time.
761 if (settings_.using_synchronous_renderer_compositor)
762 return false;
763
764 // Do not be proactive if vsync is off.
765 if (!settings_.throttle_frame_production)
766 return false;
767
729 // Do not be proactive when invisible. 768 // Do not be proactive when invisible.
730 if (!visible_) 769 if (!visible_)
731 return false; 770 return false;
732 771
733 // We should proactively request a BeginFrame if a commit is pending 772 // We should proactively request a BeginFrame if a commit is pending
734 // because we will want to draw if the commit completes quickly. 773 // because we will want to draw if the commit completes quickly.
735 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) 774 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE)
736 return true; 775 return true;
737 776
738 // If the pending tree activates quickly, we'll want a BeginFrame soon 777 // If the pending tree activates quickly, we'll want a BeginFrame soon
739 // to draw the new active tree. 778 // to draw the new active tree.
740 if (has_pending_tree_) 779 if (has_pending_tree_)
741 return true; 780 return true;
742 781
743 return false; 782 return false;
744 } 783 }
745 784
746 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { 785 void SchedulerStateMachine::OnBeginFrame(const BeginFrameArgs& args) {
747 current_frame_number_++; 786 begin_frame_count_++;
748 inside_begin_frame_ = true;
749 last_begin_frame_args_ = args; 787 last_begin_frame_args_ = args;
788 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_IDLE)
789 << *AsValue();
790 begin_frame_state_ = BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME;
750 } 791 }
751 792
752 void SchedulerStateMachine::DidLeaveBeginFrame() { 793 void SchedulerStateMachine::OnBeginFrameDeadlinePending() {
enne (OOO) 2013/09/11 22:30:47 These functions make things a lot more clear!
753 inside_begin_frame_ = false; 794 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME)
795 << *AsValue();
796 begin_frame_state_ = BEGIN_FRAME_STATE_DEADLINE_PENDING;
797 }
798
799 void SchedulerStateMachine::OnBeginFrameDeadline() {
800 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_DEADLINE_PENDING)
801 << *AsValue();
802 begin_frame_state_ = BEGIN_FRAME_STATE_INSIDE_DEADLINE;
803 }
804
805 void SchedulerStateMachine::OnBeginFrameIdle() {
806 if (HasInitializedOutputSurface()) {
807 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_INSIDE_DEADLINE)
808 << *AsValue();
809 }
810 begin_frame_state_ = BEGIN_FRAME_STATE_IDLE;
811 }
812
813 bool SchedulerStateMachine::ShouldTriggerBeginFrameDeadlineEarly() const {
814 // TODO(brianderson): This should take into account multiple commit sources.
815 return begin_frame_state_ == BEGIN_FRAME_STATE_DEADLINE_PENDING &&
816 active_tree_needs_first_draw_;
817 }
818
819 bool SchedulerStateMachine::InsideBeginFrame() const {
enne (OOO) 2013/09/11 22:30:47 What does "inside begin frame" mean here if this f
brianderson 2013/09/12 00:12:34 I'll need to fix the naming. "Inside BeginFrame" i
820 return begin_frame_state_ == BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME ||
821 begin_frame_state_ == BEGIN_FRAME_STATE_DEADLINE_PENDING;
754 } 822 }
755 823
756 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 824 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
757 825
826 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }
827
758 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 828 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
759 829
760 void SchedulerStateMachine::SetSwapUsedIncompleteTile( 830 void SchedulerStateMachine::SetSwapUsedIncompleteTile(
761 bool used_incomplete_tile) { 831 bool used_incomplete_tile) {
762 swap_used_incomplete_tile_ = used_incomplete_tile; 832 swap_used_incomplete_tile_ = used_incomplete_tile;
763 } 833 }
764 834
765 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) { 835 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) {
766 draw_if_possible_failed_ = !success; 836 draw_if_possible_failed_ = !success;
767 if (draw_if_possible_failed_) { 837 if (draw_if_possible_failed_) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 SetNeedsCommit(); 890 SetNeedsCommit();
821 } 891 }
822 } 892 }
823 893
824 void SchedulerStateMachine::DidLoseOutputSurface() { 894 void SchedulerStateMachine::DidLoseOutputSurface() {
825 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 895 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
826 output_surface_state_ == OUTPUT_SURFACE_CREATING) 896 output_surface_state_ == OUTPUT_SURFACE_CREATING)
827 return; 897 return;
828 output_surface_state_ = OUTPUT_SURFACE_LOST; 898 output_surface_state_ = OUTPUT_SURFACE_LOST;
829 needs_redraw_ = false; 899 needs_redraw_ = false;
900 begin_frame_state_ = BEGIN_FRAME_STATE_IDLE;
830 } 901 }
831 902
832 void SchedulerStateMachine::NotifyReadyToActivate() { 903 void SchedulerStateMachine::NotifyReadyToActivate() {
833 if (has_pending_tree_) 904 if (has_pending_tree_)
834 pending_tree_is_ready_for_activation_ = true; 905 pending_tree_is_ready_for_activation_ = true;
835 } 906 }
836 907
837 void SchedulerStateMachine::SetCanDraw(bool can) { can_draw_ = can; }
838
839 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { 908 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
840 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); 909 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING);
841 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; 910 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT;
842 911
843 if (did_create_and_initialize_first_output_surface_) { 912 if (did_create_and_initialize_first_output_surface_) {
844 // TODO(boliu): See if we can remove this when impl-side painting is always 913 // TODO(boliu): See if we can remove this when impl-side painting is always
845 // on. Does anything on the main thread need to update after recreate? 914 // on. Does anything on the main thread need to update after recreate?
846 needs_commit_ = true; 915 needs_commit_ = true;
847 } 916 }
848 did_create_and_initialize_first_output_surface_ = true; 917 did_create_and_initialize_first_output_surface_ = true;
849 } 918 }
850 919
851 bool SchedulerStateMachine::HasInitializedOutputSurface() const { 920 bool SchedulerStateMachine::HasInitializedOutputSurface() const {
852 switch (output_surface_state_) { 921 switch (output_surface_state_) {
853 case OUTPUT_SURFACE_LOST: 922 case OUTPUT_SURFACE_LOST:
854 case OUTPUT_SURFACE_CREATING: 923 case OUTPUT_SURFACE_CREATING:
855 return false; 924 return false;
856 925
857 case OUTPUT_SURFACE_ACTIVE: 926 case OUTPUT_SURFACE_ACTIVE:
858 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 927 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
859 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 928 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
860 return true; 929 return true;
861 } 930 }
862 NOTREACHED(); 931 NOTREACHED();
863 return false; 932 return false;
864 } 933 }
865 934
866 } // namespace cc 935 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698