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

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: disable by default everywhere 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_INSIDE_BEGIN_FRAME:
67 return "BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME";
68 case BEGIN_FRAME_STATE_DEADLINE_PENDING:
69 return "BEGIN_FRAME_STATE_DEADLINE_PENDING";
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 possible and give the tiles more time to initialize.
danakj 2013/09/17 20:26:19 as late as possible
brianderson 2013/09/17 21:08:24 Done.
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
446 // We shouldn't normally accept commits if there isn't an OutputSurface.
danakj 2013/09/17 20:26:19 Only if there's a readback? "shouldn't normally" i
brianderson 2013/09/17 21:08:24 Only during readback, yes. I should move this to
447 if (!HasInitializedOutputSurface())
448 return false;
449
426 // We want to start the first commit after we get a new output surface ASAP. 450 // 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) 451 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT)
428 return true; 452 return true;
429 453
454 // We should not send the BeginFrame to the main thread while we are in
danakj 2013/09/17 20:26:19 Why is this above the forced redraw return true? I
brianderson 2013/09/17 21:08:24 There is a input latency vs quickness to first fra
455 // BEGIN_FRAME_STATE_IDLE since we might have new user input coming in soon.
456 // However, if we are not expecting a BeginFrame to take us out of idle,
457 // we should not early out here to avoid blocking commits forever.
458 // TODO(brianderson): Also allow sending BeginFrame to main thread while idle
459 // when the main thread isn't consuming user input.
460 if (begin_frame_state_ == BEGIN_FRAME_STATE_IDLE &&
461 BeginFrameNeededByImplThread())
462 return false;
463
430 // We need a new commit for the forced redraw. This honors the 464 // 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. 465 // single commit per interval because the result will be swapped to screen.
432 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) 466 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
433 return true; 467 return true;
434 468
435 // After this point, we only start a commit once per frame. 469 // After this point, we only start a commit once per frame.
436 if (HasSentBeginFrameToMainThreadThisFrame()) 470 if (HasSentBeginFrameToMainThreadThisFrame())
437 return false; 471 return false;
438 472
439 // We shouldn't normally accept commits if there isn't an OutputSurface.
440 if (!HasInitializedOutputSurface())
441 return false;
442
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 if (settings_.using_synchronous_renderer_compositor)
746 return BeginFrameNeededToDrawByImplThread();
747
748 return BeginFrameNeededToDrawByImplThread() ||
749 ProactiveBeginFrameWantedByImplThread();
750 }
751
752 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
753 return !BeginFrameNeededByImplThread() &&
danakj 2013/09/17 20:26:19 This is just to deal with synchronous compositor r
brianderson 2013/09/17 21:08:24 Yes. I will make it explicit.
754 ProactiveBeginFrameWantedByImplThread();
755 }
756
710 // These are the cases where we definitely (or almost definitely) have a 757 // These are the cases where we definitely (or almost definitely) have a
711 // new frame to draw and can draw. 758 // new frame to draw and can draw.
712 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { 759 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const {
713 // The output surface is the provider of BeginFrames for the impl thread, 760 // 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. 761 // so we are not going to get them even if we ask for them.
715 if (!HasInitializedOutputSurface()) 762 if (!HasInitializedOutputSurface())
716 return false; 763 return false;
717 764
718 // If we can't draw, don't tick until we are notified that we can draw again. 765 // If we can't draw, don't tick until we are notified that we can draw again.
719 if (!can_draw_) 766 if (!can_draw_)
(...skipping 14 matching lines...) Expand all
734 if (swap_used_incomplete_tile_) 781 if (swap_used_incomplete_tile_)
735 return true; 782 return true;
736 783
737 return needs_redraw_; 784 return needs_redraw_;
738 } 785 }
739 786
740 // These are cases where we are very likely to draw soon, but might not 787 // 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. 788 // 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 789 // Proactively requesting the BeginFrame helps hide the round trip latency of
743 // the SetNeedsBeginFrame request that has to go to the Browser. 790 // 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 { 791 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const {
748 // The output surface is the provider of BeginFrames for the impl thread, 792 // 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. 793 // so we are not going to get them even if we ask for them.
750 if (!HasInitializedOutputSurface()) 794 if (!HasInitializedOutputSurface())
751 return false; 795 return false;
752 796
797 // Do not be proactive if vsync is off.
798 if (!settings_.throttle_frame_production)
799 return false;
800
753 // Do not be proactive when invisible. 801 // Do not be proactive when invisible.
754 if (!visible_) 802 if (!visible_)
755 return false; 803 return false;
756 804
757 // We should proactively request a BeginFrame if a commit is pending 805 // We should proactively request a BeginFrame if a commit is pending
758 // because we will want to draw if the commit completes quickly. 806 // because we will want to draw if the commit completes quickly.
759 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) 807 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE)
760 return true; 808 return true;
761 809
762 // If the pending tree activates quickly, we'll want a BeginFrame soon 810 // If the pending tree activates quickly, we'll want a BeginFrame soon
763 // to draw the new active tree. 811 // to draw the new active tree.
764 if (has_pending_tree_) 812 if (has_pending_tree_)
765 return true; 813 return true;
766 814
767 // Changing priorities may allow us to activate (given the new priorities), 815 // Changing priorities may allow us to activate (given the new priorities),
768 // which may result in a new frame. 816 // which may result in a new frame.
769 if (needs_manage_tiles_) 817 if (needs_manage_tiles_)
770 return true; 818 return true;
771 819
772 // If we just swapped, it's likely that we are going to produce another 820 // 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 821 // frame soon. This helps avoid negative glitches in our SetNeedsBeginFrame
774 // requests, which may propagate to the BeginFrame provider and get sampled 822 // requests, which may propagate to the BeginFrame provider and get sampled
775 // at an inopportune time, delaying the next BeginFrame. 823 // at an inopportune time, delaying the next BeginFrame.
776 if (last_frame_number_swap_performed_ == current_frame_number_) 824 if (last_frame_number_swap_performed_ == current_frame_number_)
777 return true; 825 return true;
778 826
779 return false; 827 return false;
780 } 828 }
781 829
782 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { 830 void SchedulerStateMachine::OnBeginFrame(const BeginFrameArgs& args) {
783 current_frame_number_++; 831 current_frame_number_++;
784 inside_begin_frame_ = true;
785 last_begin_frame_args_ = args; 832 last_begin_frame_args_ = args;
833 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_IDLE)
834 << *AsValue();
835 begin_frame_state_ = BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME;
786 } 836 }
787 837
788 void SchedulerStateMachine::DidLeaveBeginFrame() { 838 void SchedulerStateMachine::OnBeginFrameDeadlinePending() {
789 inside_begin_frame_ = false; 839 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME)
840 << *AsValue();
841 begin_frame_state_ = BEGIN_FRAME_STATE_DEADLINE_PENDING;
842 }
843
844 void SchedulerStateMachine::OnBeginFrameDeadline() {
845 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_DEADLINE_PENDING)
846 << *AsValue();
847 begin_frame_state_ = BEGIN_FRAME_STATE_INSIDE_DEADLINE;
848 }
849
850 void SchedulerStateMachine::OnBeginFrameIdle() {
851 if (HasInitializedOutputSurface()) {
852 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_INSIDE_DEADLINE)
853 << *AsValue();
854 }
855 begin_frame_state_ = BEGIN_FRAME_STATE_IDLE;
856 }
857
858 bool SchedulerStateMachine::ShouldTriggerBeginFrameDeadlineEarly() const {
859 // TODO(brianderson): This should take into account multiple commit sources.
860 return begin_frame_state_ == BEGIN_FRAME_STATE_DEADLINE_PENDING &&
861 active_tree_needs_first_draw_;
790 } 862 }
791 863
792 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { 864 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() {
793 current_frame_number_++; 865 current_frame_number_++;
794 inside_poll_for_anticipated_draw_triggers_ = true; 866 inside_poll_for_anticipated_draw_triggers_ = true;
795 } 867 }
796 868
797 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() { 869 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() {
798 inside_poll_for_anticipated_draw_triggers_ = false; 870 inside_poll_for_anticipated_draw_triggers_ = false;
799 } 871 }
800 872
801 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 873 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
802 874
875 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }
876
803 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 877 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
804 878
805 void SchedulerStateMachine::SetNeedsManageTiles() { 879 void SchedulerStateMachine::SetNeedsManageTiles() {
806 needs_manage_tiles_ = true; 880 needs_manage_tiles_ = true;
807 } 881 }
808 882
809 void SchedulerStateMachine::SetSwapUsedIncompleteTile( 883 void SchedulerStateMachine::SetSwapUsedIncompleteTile(
810 bool used_incomplete_tile) { 884 bool used_incomplete_tile) {
811 swap_used_incomplete_tile_ = used_incomplete_tile; 885 swap_used_incomplete_tile_ = used_incomplete_tile;
812 } 886 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 SetNeedsCommit(); 943 SetNeedsCommit();
870 } 944 }
871 } 945 }
872 946
873 void SchedulerStateMachine::DidLoseOutputSurface() { 947 void SchedulerStateMachine::DidLoseOutputSurface() {
874 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 948 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
875 output_surface_state_ == OUTPUT_SURFACE_CREATING) 949 output_surface_state_ == OUTPUT_SURFACE_CREATING)
876 return; 950 return;
877 output_surface_state_ = OUTPUT_SURFACE_LOST; 951 output_surface_state_ = OUTPUT_SURFACE_LOST;
878 needs_redraw_ = false; 952 needs_redraw_ = false;
953 begin_frame_state_ = BEGIN_FRAME_STATE_IDLE;
879 } 954 }
880 955
881 void SchedulerStateMachine::NotifyReadyToActivate() { 956 void SchedulerStateMachine::NotifyReadyToActivate() {
882 if (has_pending_tree_) 957 if (has_pending_tree_)
883 pending_tree_is_ready_for_activation_ = true; 958 pending_tree_is_ready_for_activation_ = true;
884 } 959 }
885 960
886 void SchedulerStateMachine::SetCanDraw(bool can) { can_draw_ = can; }
887
888 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { 961 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
889 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); 962 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING);
890 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; 963 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT;
891 964
892 if (did_create_and_initialize_first_output_surface_) { 965 if (did_create_and_initialize_first_output_surface_) {
893 // TODO(boliu): See if we can remove this when impl-side painting is always 966 // 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? 967 // on. Does anything on the main thread need to update after recreate?
895 needs_commit_ = true; 968 needs_commit_ = true;
896 } 969 }
897 did_create_and_initialize_first_output_surface_ = true; 970 did_create_and_initialize_first_output_surface_ = true;
898 } 971 }
899 972
900 bool SchedulerStateMachine::HasInitializedOutputSurface() const { 973 bool SchedulerStateMachine::HasInitializedOutputSurface() const {
901 switch (output_surface_state_) { 974 switch (output_surface_state_) {
902 case OUTPUT_SURFACE_LOST: 975 case OUTPUT_SURFACE_LOST:
903 case OUTPUT_SURFACE_CREATING: 976 case OUTPUT_SURFACE_CREATING:
904 return false; 977 return false;
905 978
906 case OUTPUT_SURFACE_ACTIVE: 979 case OUTPUT_SURFACE_ACTIVE:
907 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 980 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
908 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 981 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
909 return true; 982 return true;
910 } 983 }
911 NOTREACHED(); 984 NOTREACHED();
912 return false; 985 return false;
913 } 986 }
914 987
915 } // namespace cc 988 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698