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

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: address dana's commetns 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 current_frame_number_(0),
23 last_frame_number_where_begin_frame_sent_to_main_thread_(-1),
24 last_frame_number_swap_performed_(-1), 24 last_frame_number_swap_performed_(-1),
25 last_frame_number_where_update_visible_tiles_was_called_(-1), 25 last_frame_number_begin_frame_sent_to_main_thread_(-1),
26 last_frame_number_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 needs_manage_tiles_(false), 29 needs_manage_tiles_(false),
29 swap_used_incomplete_tile_(false), 30 swap_used_incomplete_tile_(false),
30 needs_commit_(false), 31 needs_commit_(false),
31 main_thread_needs_layer_textures_(false), 32 main_thread_needs_layer_textures_(false),
32 inside_begin_frame_(false),
33 inside_poll_for_anticipated_draw_triggers_(false), 33 inside_poll_for_anticipated_draw_triggers_(false),
34 visible_(false), 34 visible_(false),
35 can_start_(false), 35 can_start_(false),
36 can_draw_(false), 36 can_draw_(false),
37 has_pending_tree_(false), 37 has_pending_tree_(false),
38 pending_tree_is_ready_for_activation_(false), 38 pending_tree_is_ready_for_activation_(false),
39 active_tree_needs_first_draw_(false), 39 active_tree_needs_first_draw_(false),
40 draw_if_possible_failed_(false), 40 draw_if_possible_failed_(false),
41 did_create_and_initialize_first_output_surface_(false) {} 41 did_create_and_initialize_first_output_surface_(false) {}
42 42
43 const char* SchedulerStateMachine::OutputSurfaceStateToString( 43 const char* SchedulerStateMachine::OutputSurfaceStateToString(
44 OutputSurfaceState state) { 44 OutputSurfaceState state) {
45 switch (state) { 45 switch (state) {
46 case OUTPUT_SURFACE_ACTIVE: 46 case OUTPUT_SURFACE_ACTIVE:
47 return "OUTPUT_SURFACE_ACTIVE"; 47 return "OUTPUT_SURFACE_ACTIVE";
48 case OUTPUT_SURFACE_LOST: 48 case OUTPUT_SURFACE_LOST:
49 return "OUTPUT_SURFACE_LOST"; 49 return "OUTPUT_SURFACE_LOST";
50 case OUTPUT_SURFACE_CREATING: 50 case OUTPUT_SURFACE_CREATING:
51 return "OUTPUT_SURFACE_CREATING"; 51 return "OUTPUT_SURFACE_CREATING";
52 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 52 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
53 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT"; 53 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT";
54 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 54 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
55 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION"; 55 return "OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION";
56 } 56 }
57 NOTREACHED(); 57 NOTREACHED();
58 return "???"; 58 return "???";
59 } 59 }
60 60
61 const char* SchedulerStateMachine::BeginFrameStateToString(
62 BeginFrameState state) {
63 switch (state) {
64 case BEGIN_FRAME_STATE_IDLE:
65 return "BEGIN_FRAME_STATE_IDLE";
66 case BEGIN_FRAME_STATE_BEGIN_FRAME_STARTING:
67 return "BEGIN_FRAME_STATE_BEGIN_FRAME_STARTING";
68 case BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME:
69 return "BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME";
70 case BEGIN_FRAME_STATE_INSIDE_DEADLINE:
71 return "BEGIN_FRAME_STATE_INSIDE_DEADLINE";
72 }
73 NOTREACHED();
74 return "???";
75 }
76
61 const char* SchedulerStateMachine::CommitStateToString(CommitState state) { 77 const char* SchedulerStateMachine::CommitStateToString(CommitState state) {
62 switch (state) { 78 switch (state) {
63 case COMMIT_STATE_IDLE: 79 case COMMIT_STATE_IDLE:
64 return "COMMIT_STATE_IDLE"; 80 return "COMMIT_STATE_IDLE";
65 case COMMIT_STATE_FRAME_IN_PROGRESS: 81 case COMMIT_STATE_FRAME_IN_PROGRESS:
66 return "COMMIT_STATE_FRAME_IN_PROGRESS"; 82 return "COMMIT_STATE_FRAME_IN_PROGRESS";
67 case COMMIT_STATE_READY_TO_COMMIT: 83 case COMMIT_STATE_READY_TO_COMMIT:
68 return "COMMIT_STATE_READY_TO_COMMIT"; 84 return "COMMIT_STATE_READY_TO_COMMIT";
69 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: 85 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW:
70 return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW"; 86 return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW";
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 } 169 }
154 NOTREACHED(); 170 NOTREACHED();
155 return "???"; 171 return "???";
156 } 172 }
157 173
158 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { 174 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const {
159 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); 175 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
160 176
161 scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue); 177 scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue);
162 major_state->SetString("next_action", ActionToString(NextAction())); 178 major_state->SetString("next_action", ActionToString(NextAction()));
179 major_state->SetString("begin_frame_state",
180 BeginFrameStateToString(begin_frame_state_));
163 major_state->SetString("commit_state", CommitStateToString(commit_state_)); 181 major_state->SetString("commit_state", CommitStateToString(commit_state_));
164 major_state->SetString("texture_state_", 182 major_state->SetString("texture_state_",
165 TextureStateToString(texture_state_)); 183 TextureStateToString(texture_state_));
166 major_state->SetString("output_surface_state_", 184 major_state->SetString("output_surface_state_",
167 OutputSurfaceStateToString(output_surface_state_)); 185 OutputSurfaceStateToString(output_surface_state_));
168 major_state->SetString( 186 major_state->SetString(
169 "forced_redraw_state", 187 "forced_redraw_state",
170 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); 188 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_));
171 major_state->SetString("readback_state", 189 major_state->SetString("readback_state",
172 SynchronousReadbackStateToString(readback_state_)); 190 SynchronousReadbackStateToString(readback_state_));
(...skipping 22 matching lines...) Expand all
195 1000.0L); 213 1000.0L);
196 timestamps_state->SetDouble( 214 timestamps_state->SetDouble(
197 "6_deadline", 215 "6_deadline",
198 (last_begin_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / 216 (last_begin_frame_args_.deadline - base::TimeTicks()).InMicroseconds() /
199 1000.0L); 217 1000.0L);
200 state->Set("major_timestamps_in_ms", timestamps_state.release()); 218 state->Set("major_timestamps_in_ms", timestamps_state.release());
201 219
202 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue); 220 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue);
203 minor_state->SetInteger("commit_count", commit_count_); 221 minor_state->SetInteger("commit_count", commit_count_);
204 minor_state->SetInteger("current_frame_number", current_frame_number_); 222 minor_state->SetInteger("current_frame_number", current_frame_number_);
205 minor_state->SetInteger( 223
206 "last_frame_number_where_begin_frame_sent_to_main_thread", 224 minor_state->SetInteger("last_frame_number_swap_performed",
207 last_frame_number_where_begin_frame_sent_to_main_thread_);
208 minor_state->SetInteger("last_frame_number_swap_performed_",
209 last_frame_number_swap_performed_); 225 last_frame_number_swap_performed_);
210 minor_state->SetInteger( 226 minor_state->SetInteger(
211 "last_frame_number_where_update_visible_tiles_was_called", 227 "last_frame_number_begin_frame_sent_to_main_thread",
212 last_frame_number_where_update_visible_tiles_was_called_); 228 last_frame_number_begin_frame_sent_to_main_thread_);
229 minor_state->SetInteger(
230 "last_frame_number_update_visible_tiles_was_called",
231 last_frame_number_update_visible_tiles_was_called_);
232
213 minor_state->SetInteger("consecutive_failed_draws", 233 minor_state->SetInteger("consecutive_failed_draws",
214 consecutive_failed_draws_); 234 consecutive_failed_draws_);
215 minor_state->SetBoolean("needs_redraw", needs_redraw_); 235 minor_state->SetBoolean("needs_redraw", needs_redraw_);
216 minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); 236 minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_);
217 minor_state->SetBoolean("swap_used_incomplete_tile", 237 minor_state->SetBoolean("swap_used_incomplete_tile",
218 swap_used_incomplete_tile_); 238 swap_used_incomplete_tile_);
219 minor_state->SetBoolean("needs_commit", needs_commit_); 239 minor_state->SetBoolean("needs_commit", needs_commit_);
220 minor_state->SetBoolean("main_thread_needs_layer_textures", 240 minor_state->SetBoolean("main_thread_needs_layer_textures",
221 main_thread_needs_layer_textures_); 241 main_thread_needs_layer_textures_);
222 minor_state->SetBoolean("inside_begin_frame", inside_begin_frame_);
223 minor_state->SetBoolean("visible", visible_); 242 minor_state->SetBoolean("visible", visible_);
224 minor_state->SetBoolean("can_start", can_start_); 243 minor_state->SetBoolean("can_start", can_start_);
225 minor_state->SetBoolean("can_draw", can_draw_); 244 minor_state->SetBoolean("can_draw", can_draw_);
226 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); 245 minor_state->SetBoolean("has_pending_tree", has_pending_tree_);
227 minor_state->SetBoolean("pending_tree_is_ready_for_activation_", 246 minor_state->SetBoolean("pending_tree_is_ready_for_activation",
228 pending_tree_is_ready_for_activation_); 247 pending_tree_is_ready_for_activation_);
229 minor_state->SetBoolean("active_tree_needs_first_draw_", 248 minor_state->SetBoolean("active_tree_needs_first_draw",
230 active_tree_needs_first_draw_); 249 active_tree_needs_first_draw_);
231 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_); 250 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_);
232 minor_state->SetBoolean("did_create_and_initialize_first_output_surface", 251 minor_state->SetBoolean("did_create_and_initialize_first_output_surface",
233 did_create_and_initialize_first_output_surface_); 252 did_create_and_initialize_first_output_surface_);
234 state->Set("minor_state", minor_state.release()); 253 state->Set("minor_state", minor_state.release());
235 254
236 return state.PassAs<base::Value>(); 255 return state.PassAs<base::Value>();
237 } 256 }
238 257
239 bool SchedulerStateMachine::HasDrawnAndSwappedThisFrame() const { 258 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const {
240 return current_frame_number_ == last_frame_number_swap_performed_; 259 return current_frame_number_ ==
260 last_frame_number_begin_frame_sent_to_main_thread_;
241 } 261 }
242 262
243 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { 263 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const {
244 return current_frame_number_ == 264 return current_frame_number_ ==
245 last_frame_number_where_update_visible_tiles_was_called_; 265 last_frame_number_update_visible_tiles_was_called_;
246 } 266 }
247 267
248 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const { 268 bool SchedulerStateMachine::HasSwappedThisFrame() const {
249 return current_frame_number_ == 269 return current_frame_number_ == last_frame_number_swap_performed_;
250 last_frame_number_where_begin_frame_sent_to_main_thread_;
251 } 270 }
252 271
253 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { 272 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
254 // These are all the cases where we normally cannot or do not want to draw 273 // These are all the cases where we normally cannot or do not want to draw
255 // but, if needs_redraw_ is true and we do not draw to make forward progress, 274 // but, if needs_redraw_ is true and we do not draw to make forward progress,
256 // we might deadlock with the main thread. 275 // we might deadlock with the main thread.
257 // This should be a superset of PendingActivationsShouldBeForced() since 276 // This should be a superset of PendingActivationsShouldBeForced() since
258 // activation of the pending tree is blocked by drawing of the active tree and 277 // activation of the pending tree is blocked by drawing of the active tree and
259 // the main thread might be blocked on activation of the most recent commit. 278 // the main thread might be blocked on activation of the most recent commit.
260 if (PendingActivationsShouldBeForced()) 279 if (PendingActivationsShouldBeForced())
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 } 342 }
324 343
325 // If we need to abort draws, we should do so ASAP since the draw could 344 // If we need to abort draws, we should do so ASAP since the draw could
326 // be blocking other important actions (like output surface initialization), 345 // be blocking other important actions (like output surface initialization),
327 // from occuring. If we are waiting for the first draw, then perfom the 346 // from occuring. If we are waiting for the first draw, then perfom the
328 // aborted draw to keep things moving. If we are not waiting for the first 347 // aborted draw to keep things moving. If we are not waiting for the first
329 // draw however, we don't want to abort for no reason. 348 // draw however, we don't want to abort for no reason.
330 if (PendingDrawsShouldBeAborted()) 349 if (PendingDrawsShouldBeAborted())
331 return active_tree_needs_first_draw_; 350 return active_tree_needs_first_draw_;
332 351
333 // After this line, we only want to draw once per frame. 352 // After this line, we only want to swap once per frame.
334 if (HasDrawnAndSwappedThisFrame()) 353 if (HasSwappedThisFrame())
335 return false; 354 return false;
336 355
337 // We currently only draw within the BeginFrame. 356 // Except for the cases above, do not draw outside of the BeginFrame deadline.
338 if (!inside_begin_frame_) 357 if (begin_frame_state_ != BEGIN_FRAME_STATE_INSIDE_DEADLINE)
339 return false; 358 return false;
340 359
341 // Only handle forced redraws due to timeouts on the regular deadline. 360 // Only handle forced redraws due to timeouts on the regular deadline.
342 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) { 361 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) {
343 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); 362 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
344 return true; 363 return true;
345 } 364 }
346 365
347 return needs_redraw_; 366 return needs_redraw_;
348 } 367 }
(...skipping 29 matching lines...) Expand all
378 bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const { 397 bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const {
379 if (!settings_.impl_side_painting) 398 if (!settings_.impl_side_painting)
380 return false; 399 return false;
381 if (HasUpdatedVisibleTilesThisFrame()) 400 if (HasUpdatedVisibleTilesThisFrame())
382 return false; 401 return false;
383 402
384 // There's no reason to check for tiles if we don't have an output surface. 403 // There's no reason to check for tiles if we don't have an output surface.
385 if (!HasInitializedOutputSurface()) 404 if (!HasInitializedOutputSurface())
386 return false; 405 return false;
387 406
388 // We always want to update the most recent visible tiles before drawing 407 // We should not check for visible tiles until we've entered the deadline so
389 // so we draw with fewer missing tiles. 408 // we check as late as possible and give the tiles more time to initialize.
390 if (ShouldDraw()) 409 if (begin_frame_state_ != BEGIN_FRAME_STATE_INSIDE_DEADLINE)
391 return true; 410 return false;
392 411
393 // If the last swap drew with checkerboard or missing tiles, we should 412 // If the last swap drew with checkerboard or missing tiles, we should
394 // poll for any new visible tiles so we can be notified to draw again 413 // poll for any new visible tiles so we can be notified to draw again
395 // when there are. 414 // when there are.
396 if (swap_used_incomplete_tile_) 415 if (swap_used_incomplete_tile_)
397 return true; 416 return true;
398 417
399 return false; 418 return false;
400 } 419 }
401 420
402 bool SchedulerStateMachine::ShouldSendBeginFrameToMainThread() const { 421 bool SchedulerStateMachine::ShouldSendBeginFrameToMainThread() const {
403 if (!needs_commit_) 422 if (!needs_commit_)
404 return false; 423 return false;
405 424
406 // Only send BeginFrame to the main thread when idle. 425 // Only send BeginFrame to the main thread when there isn't another commit
426 // pending already.
407 if (commit_state_ != COMMIT_STATE_IDLE) 427 if (commit_state_ != COMMIT_STATE_IDLE)
408 return false; 428 return false;
409 429
410 // We can't accept a commit if we have a pending tree. 430 // We can't accept a commit if we have a pending tree.
411 if (has_pending_tree_) 431 if (has_pending_tree_)
412 return false; 432 return false;
413 433
414 // We want to handle readback commits immediately to unblock the main thread. 434 // We want to handle readback commits immediately to unblock the main thread.
415 // Note: This BeginFrame will correspond to the replacement commit that comes 435 // Note: This BeginFrame will correspond to the replacement commit that comes
416 // after the readback commit itself, so we only send the BeginFrame if a 436 // after the readback commit itself, so we only send the BeginFrame if a
417 // commit isn't already pending behind the readback. 437 // commit isn't already pending behind the readback.
418 if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME) 438 if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME)
419 return !CommitPending(); 439 return !CommitPending();
420 440
421 // We do not need commits if we are not visible, unless there's a 441 // We do not need commits if we are not visible, unless there's a
422 // request for a forced commit. 442 // request for a readback.
423 if (!visible_) 443 if (!visible_)
424 return false; 444 return false;
425 445
426 // We want to start the first commit after we get a new output surface ASAP. 446 // We want to start the first commit after we get a new output surface ASAP.
427 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) 447 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT)
428 return true; 448 return true;
429 449
450 // We should not send the BeginFrame to the main thread while we are in
451 // BEGIN_FRAME_STATE_IDLE since we might have new user input coming in soon.
452 // However, if we are not expecting a BeginFrame to take us out of idle,
453 // we should not early out here to avoid blocking commits forever.
454 // TODO(brianderson): Also allow sending BeginFrame to main thread while idle
455 // when the main thread isn't consuming user input.
456 if (begin_frame_state_ == BEGIN_FRAME_STATE_IDLE &&
brianderson 2013/09/18 00:14:39 In browser tests, is there a way to know when a wi
457 BeginFrameNeededByImplThread())
458 return false;
459
430 // We need a new commit for the forced redraw. This honors the 460 // We need a new commit for the forced redraw. This honors the
431 // single commit per interval because the result will be swapped to screen. 461 // single commit per interval because the result will be swapped to screen.
432 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) 462 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
433 return true; 463 return true;
434 464
435 // After this point, we only start a commit once per frame. 465 // After this point, we only start a commit once per frame.
436 if (HasSentBeginFrameToMainThreadThisFrame()) 466 if (HasSentBeginFrameToMainThreadThisFrame())
437 return false; 467 return false;
438 468
439 // We shouldn't normally accept commits if there isn't an OutputSurface. 469 // We shouldn't normally accept commits if there isn't an OutputSurface.
440 if (!HasInitializedOutputSurface()) 470 if (!HasInitializedOutputSurface())
441 return false; 471 return false;
442 472
443 return true; 473 return true;
444 } 474 }
445 475
446 bool SchedulerStateMachine::ShouldCommit() const { 476 bool SchedulerStateMachine::ShouldCommit() const {
447 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; 477 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT;
448 } 478 }
449 479
450 bool SchedulerStateMachine::ShouldManageTiles() const { 480 bool SchedulerStateMachine::ShouldManageTiles() const {
451 // Limiting to once per-frame is not enough, since we only want to 481 // Limiting to once per-frame is not enough, since we only want to
452 // manage tiles _after_ draws. Polling for draw triggers and 482 // manage tiles _after_ draws. Polling for draw triggers and
453 // begin-frame are mutually exclusive, so we limit to these two cases. 483 // begin-frame are mutually exclusive, so we limit to these two cases.
454 if (!inside_begin_frame_ && !inside_poll_for_anticipated_draw_triggers_) 484 if (begin_frame_state_ != BEGIN_FRAME_STATE_INSIDE_DEADLINE &&
485 !inside_poll_for_anticipated_draw_triggers_)
455 return false; 486 return false;
456 return needs_manage_tiles_; 487 return needs_manage_tiles_;
457 } 488 }
458 489
459 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 490 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
460 if (ShouldAcquireLayerTexturesForMainThread()) 491 if (ShouldAcquireLayerTexturesForMainThread())
461 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; 492 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD;
462 if (ShouldUpdateVisibleTiles()) 493 if (ShouldUpdateVisibleTiles())
463 return ACTION_UPDATE_VISIBLE_TILES; 494 return ACTION_UPDATE_VISIBLE_TILES;
464 if (ShouldActivatePendingTree()) 495 if (ShouldActivatePendingTree())
(...skipping 25 matching lines...) Expand all
490 DCHECK(!(forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW && 521 DCHECK(!(forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW &&
491 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK)); 522 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK));
492 } 523 }
493 524
494 void SchedulerStateMachine::UpdateState(Action action) { 525 void SchedulerStateMachine::UpdateState(Action action) {
495 switch (action) { 526 switch (action) {
496 case ACTION_NONE: 527 case ACTION_NONE:
497 return; 528 return;
498 529
499 case ACTION_UPDATE_VISIBLE_TILES: 530 case ACTION_UPDATE_VISIBLE_TILES:
500 last_frame_number_where_update_visible_tiles_was_called_ = 531 last_frame_number_update_visible_tiles_was_called_ =
501 current_frame_number_; 532 current_frame_number_;
502 return; 533 return;
503 534
504 case ACTION_ACTIVATE_PENDING_TREE: 535 case ACTION_ACTIVATE_PENDING_TREE:
505 UpdateStateOnActivation(); 536 UpdateStateOnActivation();
506 return; 537 return;
507 538
508 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: 539 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:
509 DCHECK(!has_pending_tree_); 540 DCHECK(!has_pending_tree_);
510 DCHECK(visible_ || readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME); 541 DCHECK(visible_ || readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME);
511 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; 542 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS;
512 needs_commit_ = false; 543 needs_commit_ = false;
513 if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME) 544 if (readback_state_ == READBACK_STATE_NEEDS_BEGIN_FRAME)
514 readback_state_ = READBACK_STATE_WAITING_FOR_COMMIT; 545 readback_state_ = READBACK_STATE_WAITING_FOR_COMMIT;
515 last_frame_number_where_begin_frame_sent_to_main_thread_ = 546 last_frame_number_begin_frame_sent_to_main_thread_ =
516 current_frame_number_; 547 current_frame_number_;
517 return; 548 return;
518 549
519 case ACTION_COMMIT: { 550 case ACTION_COMMIT: {
520 bool commit_was_aborted = false; 551 bool commit_was_aborted = false;
521 UpdateStateOnCommit(commit_was_aborted); 552 UpdateStateOnCommit(commit_was_aborted);
522 return; 553 return;
523 } 554 }
524 555
525 case ACTION_DRAW_AND_SWAP_FORCED: 556 case ACTION_DRAW_AND_SWAP_FORCED:
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 void SchedulerStateMachine::UpdateStateOnManageTiles() { 731 void SchedulerStateMachine::UpdateStateOnManageTiles() {
701 needs_manage_tiles_ = false; 732 needs_manage_tiles_ = false;
702 } 733 }
703 734
704 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { 735 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() {
705 DCHECK(!main_thread_needs_layer_textures_); 736 DCHECK(!main_thread_needs_layer_textures_);
706 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); 737 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD);
707 main_thread_needs_layer_textures_ = true; 738 main_thread_needs_layer_textures_ = true;
708 } 739 }
709 740
741 bool SchedulerStateMachine::BeginFrameNeededByImplThread() const {
742 // Proactive BeginFrames are bad for the synchronous compositor because we
743 // have to draw when we get the BeginFrame and could end up drawing many
744 // duplicate frames if our new frame isn't ready in time.
745 // To poll for state with the synchronous compositor without having to draw,
746 // we rely on ShouldPollForAnticipatedDrawTriggers instead.
747 if (settings_.using_synchronous_renderer_compositor)
748 return BeginFrameNeededToDrawByImplThread();
749
750 return BeginFrameNeededToDrawByImplThread() ||
751 ProactiveBeginFrameWantedByImplThread();
752 }
753
754 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
755 // ShouldPollForAnticipatedDrawTriggers is what we use in place of
756 // ProactiveBeginFrameWantedByImplThread when we are using the synchronous
757 // compositor.
758 if (settings_.using_synchronous_renderer_compositor) {
759 return !BeginFrameNeededToDrawByImplThread() &&
760 ProactiveBeginFrameWantedByImplThread();
761 }
762
763 // Non synchronous compositors should rely on
764 // ProactiveBeginFrameWantedByImplThread to poll for state instead.
765 return false;
766 }
767
710 // These are the cases where we definitely (or almost definitely) have a 768 // These are the cases where we definitely (or almost definitely) have a
711 // new frame to draw and can draw. 769 // new frame to draw and can draw.
712 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { 770 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const {
713 // The output surface is the provider of BeginFrames for the impl thread, 771 // The output surface is the provider of BeginFrames for the impl thread,
714 // so we are not going to get them even if we ask for them. 772 // so we are not going to get them even if we ask for them.
715 if (!HasInitializedOutputSurface()) 773 if (!HasInitializedOutputSurface())
716 return false; 774 return false;
717 775
718 // If we can't draw, don't tick until we are notified that we can draw again. 776 // If we can't draw, don't tick until we are notified that we can draw again.
719 if (!can_draw_) 777 if (!can_draw_)
(...skipping 14 matching lines...) Expand all
734 if (swap_used_incomplete_tile_) 792 if (swap_used_incomplete_tile_)
735 return true; 793 return true;
736 794
737 return needs_redraw_; 795 return needs_redraw_;
738 } 796 }
739 797
740 // These are cases where we are very likely to draw soon, but might not 798 // These are cases where we are very likely to draw soon, but might not
741 // actually have a new frame to draw when we receive the next BeginFrame. 799 // actually have a new frame to draw when we receive the next BeginFrame.
742 // Proactively requesting the BeginFrame helps hide the round trip latency of 800 // Proactively requesting the BeginFrame helps hide the round trip latency of
743 // the SetNeedsBeginFrame request that has to go to the Browser. 801 // the SetNeedsBeginFrame request that has to go to the Browser.
744 // However, this is bad for the synchronous compositor because we have to
745 // draw when we get the BeginFrame and could end up drawing many duplicate
746 // frames.
747 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const { 802 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const {
748 // The output surface is the provider of BeginFrames for the impl thread, 803 // The output surface is the provider of BeginFrames for the impl thread,
749 // so we are not going to get them even if we ask for them. 804 // so we are not going to get them even if we ask for them.
750 if (!HasInitializedOutputSurface()) 805 if (!HasInitializedOutputSurface())
751 return false; 806 return false;
752 807
808 // Do not be proactive if vsync is off.
809 if (!settings_.throttle_frame_production)
810 return false;
811
753 // Do not be proactive when invisible. 812 // Do not be proactive when invisible.
754 if (!visible_) 813 if (!visible_)
755 return false; 814 return false;
756 815
757 // We should proactively request a BeginFrame if a commit is pending 816 // We should proactively request a BeginFrame if a commit is pending
758 // because we will want to draw if the commit completes quickly. 817 // because we will want to draw if the commit completes quickly.
759 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) 818 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE)
760 return true; 819 return true;
761 820
762 // If the pending tree activates quickly, we'll want a BeginFrame soon 821 // If the pending tree activates quickly, we'll want a BeginFrame soon
763 // to draw the new active tree. 822 // to draw the new active tree.
764 if (has_pending_tree_) 823 if (has_pending_tree_)
765 return true; 824 return true;
766 825
767 // Changing priorities may allow us to activate (given the new priorities), 826 // Changing priorities may allow us to activate (given the new priorities),
768 // which may result in a new frame. 827 // which may result in a new frame.
769 if (needs_manage_tiles_) 828 if (needs_manage_tiles_)
770 return true; 829 return true;
771 830
772 // If we just swapped, it's likely that we are going to produce another 831 // If we just swapped, it's likely that we are going to produce another
773 // frame soon. This helps avoid negative glitches in our SetNeedsBeginFrame 832 // frame soon. This helps avoid negative glitches in our SetNeedsBeginFrame
774 // requests, which may propagate to the BeginFrame provider and get sampled 833 // requests, which may propagate to the BeginFrame provider and get sampled
775 // at an inopportune time, delaying the next BeginFrame. 834 // at an inopportune time, delaying the next BeginFrame.
776 if (last_frame_number_swap_performed_ == current_frame_number_) 835 if (last_frame_number_swap_performed_ == current_frame_number_)
777 return true; 836 return true;
778 837
779 return false; 838 return false;
780 } 839 }
781 840
782 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { 841 void SchedulerStateMachine::OnBeginFrame(const BeginFrameArgs& args) {
783 current_frame_number_++; 842 current_frame_number_++;
784 inside_begin_frame_ = true;
785 last_begin_frame_args_ = args; 843 last_begin_frame_args_ = args;
844 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_IDLE)
845 << *AsValue();
846 begin_frame_state_ = BEGIN_FRAME_STATE_BEGIN_FRAME_STARTING;
786 } 847 }
787 848
788 void SchedulerStateMachine::DidLeaveBeginFrame() { 849 void SchedulerStateMachine::OnBeginFrameDeadlinePending() {
789 inside_begin_frame_ = false; 850 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_BEGIN_FRAME_STARTING)
851 << *AsValue();
852 begin_frame_state_ = BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME;
853 }
854
855 void SchedulerStateMachine::OnBeginFrameDeadline() {
856 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME)
857 << *AsValue();
858 begin_frame_state_ = BEGIN_FRAME_STATE_INSIDE_DEADLINE;
859 }
860
861 void SchedulerStateMachine::OnBeginFrameIdle() {
862 if (HasInitializedOutputSurface()) {
863 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_INSIDE_DEADLINE)
864 << *AsValue();
865 }
866 begin_frame_state_ = BEGIN_FRAME_STATE_IDLE;
867 }
868
869 bool SchedulerStateMachine::ShouldTriggerBeginFrameDeadlineEarly() const {
870 // If we are in the middle of the readback, we won't swap, so there is
871 // no reason to trigger the deadline early.
872 if (readback_state_ != READBACK_STATE_IDLE)
873 return false;
874
875 // TODO(brianderson): This should take into account multiple commit sources.
876 return begin_frame_state_ == BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME &&
877 active_tree_needs_first_draw_;
790 } 878 }
791 879
792 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { 880 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() {
793 current_frame_number_++; 881 current_frame_number_++;
794 inside_poll_for_anticipated_draw_triggers_ = true; 882 inside_poll_for_anticipated_draw_triggers_ = true;
795 } 883 }
796 884
797 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() { 885 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() {
798 inside_poll_for_anticipated_draw_triggers_ = false; 886 inside_poll_for_anticipated_draw_triggers_ = false;
799 } 887 }
800 888
801 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 889 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
802 890
891 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }
892
803 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 893 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
804 894
805 void SchedulerStateMachine::SetNeedsManageTiles() { 895 void SchedulerStateMachine::SetNeedsManageTiles() {
806 needs_manage_tiles_ = true; 896 needs_manage_tiles_ = true;
807 } 897 }
808 898
809 void SchedulerStateMachine::SetSwapUsedIncompleteTile( 899 void SchedulerStateMachine::SetSwapUsedIncompleteTile(
810 bool used_incomplete_tile) { 900 bool used_incomplete_tile) {
811 swap_used_incomplete_tile_ = used_incomplete_tile; 901 swap_used_incomplete_tile_ = used_incomplete_tile;
812 } 902 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 SetNeedsCommit(); 959 SetNeedsCommit();
870 } 960 }
871 } 961 }
872 962
873 void SchedulerStateMachine::DidLoseOutputSurface() { 963 void SchedulerStateMachine::DidLoseOutputSurface() {
874 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 964 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
875 output_surface_state_ == OUTPUT_SURFACE_CREATING) 965 output_surface_state_ == OUTPUT_SURFACE_CREATING)
876 return; 966 return;
877 output_surface_state_ = OUTPUT_SURFACE_LOST; 967 output_surface_state_ = OUTPUT_SURFACE_LOST;
878 needs_redraw_ = false; 968 needs_redraw_ = false;
969 begin_frame_state_ = BEGIN_FRAME_STATE_IDLE;
879 } 970 }
880 971
881 void SchedulerStateMachine::NotifyReadyToActivate() { 972 void SchedulerStateMachine::NotifyReadyToActivate() {
882 if (has_pending_tree_) 973 if (has_pending_tree_)
883 pending_tree_is_ready_for_activation_ = true; 974 pending_tree_is_ready_for_activation_ = true;
884 } 975 }
885 976
886 void SchedulerStateMachine::SetCanDraw(bool can) { can_draw_ = can; }
887
888 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { 977 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
889 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); 978 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING);
890 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; 979 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT;
891 980
892 if (did_create_and_initialize_first_output_surface_) { 981 if (did_create_and_initialize_first_output_surface_) {
893 // TODO(boliu): See if we can remove this when impl-side painting is always 982 // TODO(boliu): See if we can remove this when impl-side painting is always
894 // on. Does anything on the main thread need to update after recreate? 983 // on. Does anything on the main thread need to update after recreate?
895 needs_commit_ = true; 984 needs_commit_ = true;
896 } 985 }
897 did_create_and_initialize_first_output_surface_ = true; 986 did_create_and_initialize_first_output_surface_ = true;
898 } 987 }
899 988
900 bool SchedulerStateMachine::HasInitializedOutputSurface() const { 989 bool SchedulerStateMachine::HasInitializedOutputSurface() const {
901 switch (output_surface_state_) { 990 switch (output_surface_state_) {
902 case OUTPUT_SURFACE_LOST: 991 case OUTPUT_SURFACE_LOST:
903 case OUTPUT_SURFACE_CREATING: 992 case OUTPUT_SURFACE_CREATING:
904 return false; 993 return false;
905 994
906 case OUTPUT_SURFACE_ACTIVE: 995 case OUTPUT_SURFACE_ACTIVE:
907 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 996 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
908 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 997 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
909 return true; 998 return true;
910 } 999 }
911 NOTREACHED(); 1000 NOTREACHED();
912 return false; 1001 return false;
913 } 1002 }
914 1003
915 } // namespace cc 1004 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler_state_machine.h ('k') | cc/scheduler/scheduler_state_machine_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698