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

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

Issue 1028333002: Chromium -> Mojo roll. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 9 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/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
11 #include "base/trace_event/trace_event_argument.h" 11 #include "base/trace_event/trace_event_argument.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "ui/gfx/frame_time.h" 13 #include "ui/gfx/frame_time.h"
14 14
15 namespace cc { 15 namespace cc {
16 16
17 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) 17 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
18 : settings_(settings), 18 : settings_(settings),
19 output_surface_state_(OUTPUT_SURFACE_LOST), 19 output_surface_state_(OUTPUT_SURFACE_LOST),
20 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), 20 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE),
21 commit_state_(COMMIT_STATE_IDLE), 21 commit_state_(COMMIT_STATE_IDLE),
22 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), 22 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE),
23 commit_count_(0), 23 commit_count_(0),
24 current_frame_number_(0), 24 current_frame_number_(0),
25 last_frame_number_animate_performed_(-1), 25 last_frame_number_animate_performed_(-1),
26 last_frame_number_swap_performed_(-1), 26 last_frame_number_swap_performed_(-1),
27 last_frame_number_swap_requested_(-1), 27 last_frame_number_swap_requested_(-1),
28 last_frame_number_begin_main_frame_sent_(-1), 28 last_frame_number_begin_main_frame_sent_(-1),
29 animate_funnel_(false),
30 perform_swap_funnel_(false),
31 request_swap_funnel_(false),
32 send_begin_main_frame_funnel_(false),
29 prepare_tiles_funnel_(0), 33 prepare_tiles_funnel_(0),
30 consecutive_checkerboard_animations_(0), 34 consecutive_checkerboard_animations_(0),
31 max_pending_swaps_(1), 35 max_pending_swaps_(1),
32 pending_swaps_(0), 36 pending_swaps_(0),
33 needs_redraw_(false), 37 needs_redraw_(false),
34 needs_animate_(false), 38 needs_animate_(false),
35 needs_prepare_tiles_(false), 39 needs_prepare_tiles_(false),
36 needs_commit_(false), 40 needs_commit_(false),
37 inside_poll_for_anticipated_draw_triggers_(false), 41 inside_poll_for_anticipated_draw_triggers_(false),
38 visible_(false), 42 visible_(false),
39 can_start_(false), 43 can_start_(false),
40 can_draw_(false), 44 can_draw_(false),
41 has_pending_tree_(false), 45 has_pending_tree_(false),
42 pending_tree_is_ready_for_activation_(false), 46 pending_tree_is_ready_for_activation_(false),
43 active_tree_needs_first_draw_(false), 47 active_tree_needs_first_draw_(false),
44 did_commit_after_animating_(false),
45 did_create_and_initialize_first_output_surface_(false), 48 did_create_and_initialize_first_output_surface_(false),
46 impl_latency_takes_priority_(false), 49 impl_latency_takes_priority_(false),
47 skip_next_begin_main_frame_to_reduce_latency_(false), 50 skip_next_begin_main_frame_to_reduce_latency_(false),
48 skip_begin_main_frame_to_reduce_latency_(false), 51 skip_begin_main_frame_to_reduce_latency_(false),
49 continuous_painting_(false), 52 continuous_painting_(false),
50 children_need_begin_frames_(false), 53 children_need_begin_frames_(false),
51 defer_commits_(false) { 54 defer_commits_(false),
55 last_commit_had_no_updates_(false) {
52 } 56 }
53 57
54 const char* SchedulerStateMachine::OutputSurfaceStateToString( 58 const char* SchedulerStateMachine::OutputSurfaceStateToString(
55 OutputSurfaceState state) { 59 OutputSurfaceState state) {
56 switch (state) { 60 switch (state) {
57 case OUTPUT_SURFACE_ACTIVE: 61 case OUTPUT_SURFACE_ACTIVE:
58 return "OUTPUT_SURFACE_ACTIVE"; 62 return "OUTPUT_SURFACE_ACTIVE";
59 case OUTPUT_SURFACE_LOST: 63 case OUTPUT_SURFACE_LOST:
60 return "OUTPUT_SURFACE_LOST"; 64 return "OUTPUT_SURFACE_LOST";
61 case OUTPUT_SURFACE_CREATING: 65 case OUTPUT_SURFACE_CREATING:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 return "ACTION_PREPARE_TILES"; 148 return "ACTION_PREPARE_TILES";
145 } 149 }
146 NOTREACHED(); 150 NOTREACHED();
147 return "???"; 151 return "???";
148 } 152 }
149 153
150 scoped_refptr<base::trace_event::ConvertableToTraceFormat> 154 scoped_refptr<base::trace_event::ConvertableToTraceFormat>
151 SchedulerStateMachine::AsValue() const { 155 SchedulerStateMachine::AsValue() const {
152 scoped_refptr<base::trace_event::TracedValue> state = 156 scoped_refptr<base::trace_event::TracedValue> state =
153 new base::trace_event::TracedValue(); 157 new base::trace_event::TracedValue();
154 AsValueInto(state.get(), gfx::FrameTime::Now()); 158 AsValueInto(state.get());
155 return state; 159 return state;
156 } 160 }
157 161
158 void SchedulerStateMachine::AsValueInto(base::trace_event::TracedValue* state, 162 void SchedulerStateMachine::AsValueInto(
159 base::TimeTicks now) const { 163 base::trace_event::TracedValue* state) const {
160 state->BeginDictionary("major_state"); 164 state->BeginDictionary("major_state");
161 state->SetString("next_action", ActionToString(NextAction())); 165 state->SetString("next_action", ActionToString(NextAction()));
162 state->SetString("begin_impl_frame_state", 166 state->SetString("begin_impl_frame_state",
163 BeginImplFrameStateToString(begin_impl_frame_state_)); 167 BeginImplFrameStateToString(begin_impl_frame_state_));
164 state->SetString("commit_state", CommitStateToString(commit_state_)); 168 state->SetString("commit_state", CommitStateToString(commit_state_));
165 state->SetString("output_surface_state_", 169 state->SetString("output_surface_state_",
166 OutputSurfaceStateToString(output_surface_state_)); 170 OutputSurfaceStateToString(output_surface_state_));
167 state->SetString("forced_redraw_state", 171 state->SetString("forced_redraw_state",
168 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); 172 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_));
169 state->EndDictionary(); 173 state->EndDictionary();
170 174
171 state->BeginDictionary("major_timestamps_in_ms");
172 state->SetDouble("0_interval",
173 begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L);
174 state->SetDouble(
175 "1_now_to_deadline",
176 (begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L);
177 state->SetDouble(
178 "2_frame_time_to_now",
179 (now - begin_impl_frame_args_.frame_time).InMicroseconds() / 1000.0L);
180 state->SetDouble("3_frame_time_to_deadline",
181 (begin_impl_frame_args_.deadline -
182 begin_impl_frame_args_.frame_time).InMicroseconds() /
183 1000.0L);
184 state->SetDouble("4_now",
185 (now - base::TimeTicks()).InMicroseconds() / 1000.0L);
186 state->SetDouble(
187 "5_frame_time",
188 (begin_impl_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() /
189 1000.0L);
190 state->SetDouble(
191 "6_deadline",
192 (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() /
193 1000.0L);
194 state->EndDictionary();
195
196 state->BeginDictionary("minor_state"); 175 state->BeginDictionary("minor_state");
197 state->SetInteger("commit_count", commit_count_); 176 state->SetInteger("commit_count", commit_count_);
198 state->SetInteger("current_frame_number", current_frame_number_); 177 state->SetInteger("current_frame_number", current_frame_number_);
199
200 state->SetInteger("last_frame_number_animate_performed", 178 state->SetInteger("last_frame_number_animate_performed",
201 last_frame_number_animate_performed_); 179 last_frame_number_animate_performed_);
202 state->SetInteger("last_frame_number_swap_performed", 180 state->SetInteger("last_frame_number_swap_performed",
203 last_frame_number_swap_performed_); 181 last_frame_number_swap_performed_);
204 state->SetInteger("last_frame_number_swap_requested", 182 state->SetInteger("last_frame_number_swap_requested",
205 last_frame_number_swap_requested_); 183 last_frame_number_swap_requested_);
206 state->SetInteger("last_frame_number_begin_main_frame_sent", 184 state->SetInteger("last_frame_number_begin_main_frame_sent",
207 last_frame_number_begin_main_frame_sent_); 185 last_frame_number_begin_main_frame_sent_);
208 186 state->SetBoolean("funnel: animate_funnel", animate_funnel_);
209 state->SetInteger("prepare_tiles_funnel", prepare_tiles_funnel_); 187 state->SetBoolean("funnel: perform_swap_funnel", perform_swap_funnel_);
188 state->SetBoolean("funnel: request_swap_funnel", request_swap_funnel_);
189 state->SetBoolean("funnel: send_begin_main_frame_funnel",
190 send_begin_main_frame_funnel_);
191 state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_);
210 state->SetInteger("consecutive_checkerboard_animations", 192 state->SetInteger("consecutive_checkerboard_animations",
211 consecutive_checkerboard_animations_); 193 consecutive_checkerboard_animations_);
212 state->SetInteger("max_pending_swaps_", max_pending_swaps_); 194 state->SetInteger("max_pending_swaps_", max_pending_swaps_);
213 state->SetInteger("pending_swaps_", pending_swaps_); 195 state->SetInteger("pending_swaps_", pending_swaps_);
214 state->SetBoolean("needs_redraw", needs_redraw_); 196 state->SetBoolean("needs_redraw", needs_redraw_);
215 state->SetBoolean("needs_animate_", needs_animate_); 197 state->SetBoolean("needs_animate_", needs_animate_);
216 state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_); 198 state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_);
217 state->SetBoolean("needs_commit", needs_commit_); 199 state->SetBoolean("needs_commit", needs_commit_);
218 state->SetBoolean("visible", visible_); 200 state->SetBoolean("visible", visible_);
219 state->SetBoolean("can_start", can_start_); 201 state->SetBoolean("can_start", can_start_);
220 state->SetBoolean("can_draw", can_draw_); 202 state->SetBoolean("can_draw", can_draw_);
221 state->SetBoolean("has_pending_tree", has_pending_tree_); 203 state->SetBoolean("has_pending_tree", has_pending_tree_);
222 state->SetBoolean("pending_tree_is_ready_for_activation", 204 state->SetBoolean("pending_tree_is_ready_for_activation",
223 pending_tree_is_ready_for_activation_); 205 pending_tree_is_ready_for_activation_);
224 state->SetBoolean("active_tree_needs_first_draw", 206 state->SetBoolean("active_tree_needs_first_draw",
225 active_tree_needs_first_draw_); 207 active_tree_needs_first_draw_);
226 state->SetBoolean("did_commit_after_animating", did_commit_after_animating_);
227 state->SetBoolean("did_create_and_initialize_first_output_surface", 208 state->SetBoolean("did_create_and_initialize_first_output_surface",
228 did_create_and_initialize_first_output_surface_); 209 did_create_and_initialize_first_output_surface_);
229 state->SetBoolean("impl_latency_takes_priority", 210 state->SetBoolean("impl_latency_takes_priority",
230 impl_latency_takes_priority_); 211 impl_latency_takes_priority_);
231 state->SetBoolean("main_thread_is_in_high_latency_mode", 212 state->SetBoolean("main_thread_is_in_high_latency_mode",
232 MainThreadIsInHighLatencyMode()); 213 MainThreadIsInHighLatencyMode());
233 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", 214 state->SetBoolean("skip_begin_main_frame_to_reduce_latency",
234 skip_begin_main_frame_to_reduce_latency_); 215 skip_begin_main_frame_to_reduce_latency_);
235 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", 216 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
236 skip_next_begin_main_frame_to_reduce_latency_); 217 skip_next_begin_main_frame_to_reduce_latency_);
237 state->SetBoolean("continuous_painting", continuous_painting_); 218 state->SetBoolean("continuous_painting", continuous_painting_);
238 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); 219 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_);
239 state->SetBoolean("defer_commits", defer_commits_); 220 state->SetBoolean("defer_commits", defer_commits_);
240 state->EndDictionary(); 221 state->EndDictionary();
241 } 222 }
242 223
243 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { 224 void SchedulerStateMachine::AdvanceCurrentFrameNumber() {
244 current_frame_number_++; 225 current_frame_number_++;
245 226
227 animate_funnel_ = false;
228 perform_swap_funnel_ = false;
229 request_swap_funnel_ = false;
230 send_begin_main_frame_funnel_ = false;
231
246 // "Drain" the PrepareTiles funnel. 232 // "Drain" the PrepareTiles funnel.
247 if (prepare_tiles_funnel_ > 0) 233 if (prepare_tiles_funnel_ > 0)
248 prepare_tiles_funnel_--; 234 prepare_tiles_funnel_--;
249 235
250 skip_begin_main_frame_to_reduce_latency_ = 236 skip_begin_main_frame_to_reduce_latency_ =
251 skip_next_begin_main_frame_to_reduce_latency_; 237 skip_next_begin_main_frame_to_reduce_latency_;
252 skip_next_begin_main_frame_to_reduce_latency_ = false; 238 skip_next_begin_main_frame_to_reduce_latency_ = false;
253 } 239 }
254 240
255 bool SchedulerStateMachine::HasAnimatedThisFrame() const {
256 return last_frame_number_animate_performed_ == current_frame_number_;
257 }
258
259 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const {
260 return current_frame_number_ ==
261 last_frame_number_begin_main_frame_sent_;
262 }
263
264 bool SchedulerStateMachine::HasSwappedThisFrame() const {
265 return current_frame_number_ == last_frame_number_swap_performed_;
266 }
267
268 bool SchedulerStateMachine::HasRequestedSwapThisFrame() const {
269 return current_frame_number_ == last_frame_number_swap_requested_;
270 }
271
272 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { 241 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
273 // These are all the cases where we normally cannot or do not want to draw 242 // These are all the cases where we normally cannot or do not want to draw
274 // but, if needs_redraw_ is true and we do not draw to make forward progress, 243 // but, if needs_redraw_ is true and we do not draw to make forward progress,
275 // we might deadlock with the main thread. 244 // we might deadlock with the main thread.
276 // This should be a superset of PendingActivationsShouldBeForced() since 245 // This should be a superset of PendingActivationsShouldBeForced() since
277 // activation of the pending tree is blocked by drawing of the active tree and 246 // activation of the pending tree is blocked by drawing of the active tree and
278 // the main thread might be blocked on activation of the most recent commit. 247 // the main thread might be blocked on activation of the most recent commit.
279 if (PendingActivationsShouldBeForced()) 248 if (PendingActivationsShouldBeForced())
280 return true; 249 return true;
281 250
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 303
335 bool SchedulerStateMachine::ShouldDraw() const { 304 bool SchedulerStateMachine::ShouldDraw() const {
336 // If we need to abort draws, we should do so ASAP since the draw could 305 // If we need to abort draws, we should do so ASAP since the draw could
337 // be blocking other important actions (like output surface initialization), 306 // be blocking other important actions (like output surface initialization),
338 // from occuring. If we are waiting for the first draw, then perfom the 307 // from occuring. If we are waiting for the first draw, then perfom the
339 // aborted draw to keep things moving. If we are not waiting for the first 308 // aborted draw to keep things moving. If we are not waiting for the first
340 // draw however, we don't want to abort for no reason. 309 // draw however, we don't want to abort for no reason.
341 if (PendingDrawsShouldBeAborted()) 310 if (PendingDrawsShouldBeAborted())
342 return active_tree_needs_first_draw_; 311 return active_tree_needs_first_draw_;
343 312
313 // Do not draw too many times in a single frame. It's okay that we don't check
314 // this before checking for aborted draws because aborted draws do not request
315 // a swap.
316 if (request_swap_funnel_)
317 return false;
318
344 // Don't draw if we are waiting on the first commit after a surface. 319 // Don't draw if we are waiting on the first commit after a surface.
345 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) 320 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE)
346 return false; 321 return false;
347 322
348 // If a commit has occurred after the animate call, we need to call animate
349 // again before we should draw.
350 if (did_commit_after_animating_)
351 return false;
352
353 // After this line, we only want to send a swap request once per frame.
354 if (HasRequestedSwapThisFrame())
355 return false;
356
357 // Do not queue too many swaps. 323 // Do not queue too many swaps.
358 if (pending_swaps_ >= max_pending_swaps_) 324 if (pending_swaps_ >= max_pending_swaps_)
359 return false; 325 return false;
360 326
361 // Except for the cases above, do not draw outside of the BeginImplFrame 327 // Except for the cases above, do not draw outside of the BeginImplFrame
362 // deadline. 328 // deadline.
363 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 329 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
364 return false; 330 return false;
365 331
366 // Only handle forced redraws due to timeouts on the regular deadline. 332 // Only handle forced redraws due to timeouts on the regular deadline.
(...skipping 16 matching lines...) Expand all
383 349
384 // If we want to force activation, do so ASAP. 350 // If we want to force activation, do so ASAP.
385 if (PendingActivationsShouldBeForced()) 351 if (PendingActivationsShouldBeForced())
386 return true; 352 return true;
387 353
388 // At this point, only activate if we are ready to activate. 354 // At this point, only activate if we are ready to activate.
389 return pending_tree_is_ready_for_activation_; 355 return pending_tree_is_ready_for_activation_;
390 } 356 }
391 357
392 bool SchedulerStateMachine::ShouldAnimate() const { 358 bool SchedulerStateMachine::ShouldAnimate() const {
359 // Do not animate too many times in a single frame.
360 if (animate_funnel_)
361 return false;
362
393 // Don't animate if we are waiting on the first commit after a surface. 363 // Don't animate if we are waiting on the first commit after a surface.
394 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) 364 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE)
395 return false; 365 return false;
396 366
397 // If a commit occurred after our last call, we need to do animation again.
398 if (HasAnimatedThisFrame() && !did_commit_after_animating_)
399 return false;
400
401 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING && 367 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING &&
402 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 368 begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
403 return false; 369 return false;
404 370
405 return needs_redraw_ || needs_animate_; 371 return needs_redraw_ || needs_animate_;
406 } 372 }
407 373
408 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { 374 bool SchedulerStateMachine::CouldSendBeginMainFrame() const {
375 // Do not send begin main frame too many times in a single frame.
376 if (send_begin_main_frame_funnel_)
377 return false;
378
409 if (!needs_commit_) 379 if (!needs_commit_)
410 return false; 380 return false;
411 381
412 // We can not perform commits if we are not visible. 382 // We can not perform commits if we are not visible.
413 if (!visible_) 383 if (!visible_)
414 return false; 384 return false;
415 385
416 // Do not make a new commits when it is deferred. 386 // Do not make a new commits when it is deferred.
417 if (defer_commits_) 387 if (defer_commits_)
418 return false; 388 return false;
(...skipping 23 matching lines...) Expand all
442 // thread isn't consuming user input. 412 // thread isn't consuming user input.
443 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE && 413 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE &&
444 BeginFrameNeeded()) 414 BeginFrameNeeded())
445 return false; 415 return false;
446 416
447 // We need a new commit for the forced redraw. This honors the 417 // We need a new commit for the forced redraw. This honors the
448 // single commit per interval because the result will be swapped to screen. 418 // single commit per interval because the result will be swapped to screen.
449 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) 419 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
450 return true; 420 return true;
451 421
452 // After this point, we only start a commit once per frame.
453 if (HasSentBeginMainFrameThisFrame())
454 return false;
455
456 // We shouldn't normally accept commits if there isn't an OutputSurface. 422 // We shouldn't normally accept commits if there isn't an OutputSurface.
457 if (!HasInitializedOutputSurface()) 423 if (!HasInitializedOutputSurface())
458 return false; 424 return false;
459 425
460 // SwapAck throttle the BeginMainFrames unless we just swapped. 426 // SwapAck throttle the BeginMainFrames unless we just swapped.
461 // TODO(brianderson): Remove this restriction to improve throughput. 427 // TODO(brianderson): Remove this restriction to improve throughput.
462 bool just_swapped_in_deadline = 428 bool just_swapped_in_deadline =
463 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && 429 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
464 HasSwappedThisFrame(); 430 perform_swap_funnel_;
465 if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline) 431 if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline)
466 return false; 432 return false;
467 433
468 if (skip_begin_main_frame_to_reduce_latency_) 434 if (skip_begin_main_frame_to_reduce_latency_)
469 return false; 435 return false;
470 436
471 return true; 437 return true;
472 } 438 }
473 439
474 bool SchedulerStateMachine::ShouldCommit() const { 440 bool SchedulerStateMachine::ShouldCommit() const {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 void SchedulerStateMachine::UpdateState(Action action) { 497 void SchedulerStateMachine::UpdateState(Action action) {
532 switch (action) { 498 switch (action) {
533 case ACTION_NONE: 499 case ACTION_NONE:
534 return; 500 return;
535 501
536 case ACTION_ACTIVATE_SYNC_TREE: 502 case ACTION_ACTIVATE_SYNC_TREE:
537 UpdateStateOnActivation(); 503 UpdateStateOnActivation();
538 return; 504 return;
539 505
540 case ACTION_ANIMATE: 506 case ACTION_ANIMATE:
507 DCHECK(!animate_funnel_);
541 last_frame_number_animate_performed_ = current_frame_number_; 508 last_frame_number_animate_performed_ = current_frame_number_;
509 animate_funnel_ = true;
542 needs_animate_ = false; 510 needs_animate_ = false;
543 did_commit_after_animating_ = false;
544 // TODO(skyostil): Instead of assuming this, require the client to tell 511 // TODO(skyostil): Instead of assuming this, require the client to tell
545 // us. 512 // us.
546 SetNeedsRedraw(); 513 SetNeedsRedraw();
547 return; 514 return;
548 515
549 case ACTION_SEND_BEGIN_MAIN_FRAME: 516 case ACTION_SEND_BEGIN_MAIN_FRAME:
550 DCHECK(!has_pending_tree_ || 517 DCHECK(!has_pending_tree_ ||
551 settings_.main_frame_before_activation_enabled); 518 settings_.main_frame_before_activation_enabled);
552 DCHECK(visible_); 519 DCHECK(visible_);
520 DCHECK(!send_begin_main_frame_funnel_);
553 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT; 521 commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT;
554 needs_commit_ = false; 522 needs_commit_ = false;
523 send_begin_main_frame_funnel_ = true;
555 last_frame_number_begin_main_frame_sent_ = 524 last_frame_number_begin_main_frame_sent_ =
556 current_frame_number_; 525 current_frame_number_;
557 return; 526 return;
558 527
559 case ACTION_COMMIT: { 528 case ACTION_COMMIT: {
560 bool commit_has_no_updates = false; 529 bool commit_has_no_updates = false;
561 UpdateStateOnCommit(commit_has_no_updates); 530 UpdateStateOnCommit(commit_has_no_updates);
562 return; 531 return;
563 } 532 }
564 533
(...skipping 24 matching lines...) Expand all
589 558
590 case ACTION_PREPARE_TILES: 559 case ACTION_PREPARE_TILES:
591 UpdateStateOnPrepareTiles(); 560 UpdateStateOnPrepareTiles();
592 return; 561 return;
593 } 562 }
594 } 563 }
595 564
596 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) { 565 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) {
597 commit_count_++; 566 commit_count_++;
598 567
599 if (!commit_has_no_updates && HasAnimatedThisFrame()) 568 if (!commit_has_no_updates)
600 did_commit_after_animating_ = true; 569 animate_funnel_ = false;
601 570
602 if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) { 571 if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) {
603 commit_state_ = COMMIT_STATE_IDLE; 572 commit_state_ = COMMIT_STATE_IDLE;
604 } else if (settings_.impl_side_painting) { 573 } else if (settings_.impl_side_painting) {
605 commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION; 574 commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION;
606 } else { 575 } else {
607 commit_state_ = settings_.main_thread_should_always_be_low_latency 576 commit_state_ = settings_.main_thread_should_always_be_low_latency
608 ? COMMIT_STATE_WAITING_FOR_DRAW 577 ? COMMIT_STATE_WAITING_FOR_DRAW
609 : COMMIT_STATE_IDLE; 578 : COMMIT_STATE_IDLE;
610 } 579 }
(...skipping 27 matching lines...) Expand all
638 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) { 607 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) {
639 needs_redraw_ = true; 608 needs_redraw_ = true;
640 active_tree_needs_first_draw_ = true; 609 active_tree_needs_first_draw_ = true;
641 } 610 }
642 611
643 // This post-commit work is common to both completed and aborted commits. 612 // This post-commit work is common to both completed and aborted commits.
644 pending_tree_is_ready_for_activation_ = false; 613 pending_tree_is_ready_for_activation_ = false;
645 614
646 if (continuous_painting_) 615 if (continuous_painting_)
647 needs_commit_ = true; 616 needs_commit_ = true;
617 last_commit_had_no_updates_ = commit_has_no_updates;
648 } 618 }
649 619
650 void SchedulerStateMachine::UpdateStateOnActivation() { 620 void SchedulerStateMachine::UpdateStateOnActivation() {
651 if (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION) { 621 if (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION) {
652 commit_state_ = settings_.main_thread_should_always_be_low_latency 622 commit_state_ = settings_.main_thread_should_always_be_low_latency
653 ? COMMIT_STATE_WAITING_FOR_DRAW 623 ? COMMIT_STATE_WAITING_FOR_DRAW
654 : COMMIT_STATE_IDLE; 624 : COMMIT_STATE_IDLE;
655 } 625 }
656 626
657 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) 627 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
(...skipping 11 matching lines...) Expand all
669 void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) { 639 void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) {
670 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 640 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
671 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; 641 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
672 642
673 if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW) 643 if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW)
674 commit_state_ = COMMIT_STATE_IDLE; 644 commit_state_ = COMMIT_STATE_IDLE;
675 645
676 needs_redraw_ = false; 646 needs_redraw_ = false;
677 active_tree_needs_first_draw_ = false; 647 active_tree_needs_first_draw_ = false;
678 648
679 if (did_request_swap) 649 if (did_request_swap) {
650 DCHECK(!request_swap_funnel_);
651 request_swap_funnel_ = true;
680 last_frame_number_swap_requested_ = current_frame_number_; 652 last_frame_number_swap_requested_ = current_frame_number_;
653 }
681 } 654 }
682 655
683 void SchedulerStateMachine::UpdateStateOnPrepareTiles() { 656 void SchedulerStateMachine::UpdateStateOnPrepareTiles() {
684 needs_prepare_tiles_ = false; 657 needs_prepare_tiles_ = false;
685 } 658 }
686 659
687 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { 660 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() {
688 TRACE_EVENT_INSTANT0("cc", 661 TRACE_EVENT_INSTANT0("cc",
689 "Scheduler: SkipNextBeginMainFrameToReduceLatency", 662 "Scheduler: SkipNextBeginMainFrameToReduceLatency",
690 TRACE_EVENT_SCOPE_THREAD); 663 TRACE_EVENT_SCOPE_THREAD);
(...skipping 22 matching lines...) Expand all
713 // Proactive BeginFrames are bad for the synchronous compositor because we 686 // Proactive BeginFrames are bad for the synchronous compositor because we
714 // have to draw when we get the BeginFrame and could end up drawing many 687 // have to draw when we get the BeginFrame and could end up drawing many
715 // duplicate frames if our new frame isn't ready in time. 688 // duplicate frames if our new frame isn't ready in time.
716 // To poll for state with the synchronous compositor without having to draw, 689 // To poll for state with the synchronous compositor without having to draw,
717 // we rely on ShouldPollForAnticipatedDrawTriggers instead. 690 // we rely on ShouldPollForAnticipatedDrawTriggers instead.
718 // Synchronous compositor doesn't have a browser. 691 // Synchronous compositor doesn't have a browser.
719 DCHECK(!children_need_begin_frames_); 692 DCHECK(!children_need_begin_frames_);
720 return BeginFrameNeededToAnimateOrDraw(); 693 return BeginFrameNeededToAnimateOrDraw();
721 } 694 }
722 695
723 bool SchedulerStateMachine::ShouldSetNeedsBeginFrames(
724 bool frame_source_needs_begin_frames) const {
725 bool needs_begin_frame = BeginFrameNeeded();
726
727 // Never call SetNeedsBeginFrames if the frame source has the right value.
728 if (needs_begin_frame == frame_source_needs_begin_frames)
729 return false;
730
731 // Always request the BeginFrame immediately if it's needed.
732 if (needs_begin_frame)
733 return true;
734
735 // Stop requesting BeginFrames after a deadline.
736 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
737 return true;
738
739 // Stop requesting BeginFrames immediately when output surface is lost.
740 if (!HasInitializedOutputSurface())
741 return true;
742
743 return false;
744 }
745
746 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const { 696 bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
747 // ShouldPollForAnticipatedDrawTriggers is what we use in place of 697 // ShouldPollForAnticipatedDrawTriggers is what we use in place of
748 // ProactiveBeginFrameWanted when we are using the synchronous 698 // ProactiveBeginFrameWanted when we are using the synchronous
749 // compositor. 699 // compositor.
750 if (!SupportsProactiveBeginFrame()) { 700 if (!SupportsProactiveBeginFrame()) {
751 return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted(); 701 return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted();
752 } 702 }
753 703
754 // Non synchronous compositors should rely on 704 // Non synchronous compositors should rely on
755 // ProactiveBeginFrameWanted to poll for state instead. 705 // ProactiveBeginFrameWanted to poll for state instead.
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 // Changing priorities may allow us to activate (given the new priorities), 758 // Changing priorities may allow us to activate (given the new priorities),
809 // which may result in a new frame. 759 // which may result in a new frame.
810 if (needs_prepare_tiles_) 760 if (needs_prepare_tiles_)
811 return true; 761 return true;
812 762
813 // If we just sent a swap request, it's likely that we are going to produce 763 // If we just sent a swap request, it's likely that we are going to produce
814 // another frame soon. This helps avoid negative glitches in our 764 // another frame soon. This helps avoid negative glitches in our
815 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame 765 // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame
816 // provider and get sampled at an inopportune time, delaying the next 766 // provider and get sampled at an inopportune time, delaying the next
817 // BeginImplFrame. 767 // BeginImplFrame.
818 if (HasRequestedSwapThisFrame()) 768 if (request_swap_funnel_)
769 return true;
770
771 // If the last commit was aborted because of early out (no updates), we should
772 // still want a begin frame in case there is a commit coming again.
773 if (last_commit_had_no_updates_)
819 return true; 774 return true;
820 775
821 return false; 776 return false;
822 } 777 }
823 778
824 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { 779 void SchedulerStateMachine::OnBeginImplFrame() {
825 AdvanceCurrentFrameNumber(); 780 AdvanceCurrentFrameNumber();
826 begin_impl_frame_args_ = args;
827 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) 781 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE)
828 << AsValue()->ToString(); 782 << AsValue()->ToString();
829 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; 783 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING;
784 last_commit_had_no_updates_ = false;
830 } 785 }
831 786
832 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { 787 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() {
833 DCHECK_EQ(begin_impl_frame_state_, 788 DCHECK_EQ(begin_impl_frame_state_,
834 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) 789 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING)
835 << AsValue()->ToString(); 790 << AsValue()->ToString();
836 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; 791 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
837 } 792 }
838 793
839 void SchedulerStateMachine::OnBeginImplFrameDeadline() { 794 void SchedulerStateMachine::OnBeginImplFrameDeadline() {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 } 858 }
904 859
905 bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const { 860 bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const {
906 // If a commit is pending before the previous commit has been drawn, we 861 // If a commit is pending before the previous commit has been drawn, we
907 // are definitely in a high latency mode. 862 // are definitely in a high latency mode.
908 if (CommitPending() && (active_tree_needs_first_draw_ || has_pending_tree_)) 863 if (CommitPending() && (active_tree_needs_first_draw_ || has_pending_tree_))
909 return true; 864 return true;
910 865
911 // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main 866 // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main
912 // thread is in a low latency mode. 867 // thread is in a low latency mode.
913 if (HasSentBeginMainFrameThisFrame() && 868 if (send_begin_main_frame_funnel_ &&
914 (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING || 869 (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING ||
915 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)) 870 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME))
916 return false; 871 return false;
917 872
918 // If there's a commit in progress it must either be from the previous frame 873 // If there's a commit in progress it must either be from the previous frame
919 // or it started after the impl thread's deadline. In either case the main 874 // or it started after the impl thread's deadline. In either case the main
920 // thread is in high latency mode. 875 // thread is in high latency mode.
921 if (CommitPending()) 876 if (CommitPending())
922 return true; 877 return true;
923 878
924 // Similarly, if there's a pending tree the main thread is in high latency 879 // Similarly, if there's a pending tree the main thread is in high latency
925 // mode, because either 880 // mode, because either
926 // it's from the previous frame 881 // it's from the previous frame
927 // or 882 // or
928 // we're currently drawing the active tree and the pending tree will thus 883 // we're currently drawing the active tree and the pending tree will thus
929 // only be drawn in the next frame. 884 // only be drawn in the next frame.
930 if (has_pending_tree_) 885 if (has_pending_tree_)
931 return true; 886 return true;
932 887
933 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) { 888 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) {
934 // Even if there's a new active tree to draw at the deadline or we've just 889 // Even if there's a new active tree to draw at the deadline or we've just
935 // swapped it, it may have been triggered by a previous BeginImplFrame, in 890 // swapped it, it may have been triggered by a previous BeginImplFrame, in
936 // which case the main thread is in a high latency mode. 891 // which case the main thread is in a high latency mode.
937 return (active_tree_needs_first_draw_ || HasSwappedThisFrame()) && 892 return (active_tree_needs_first_draw_ || perform_swap_funnel_) &&
938 !HasSentBeginMainFrameThisFrame(); 893 !send_begin_main_frame_funnel_;
939 } 894 }
940 895
941 // If the active tree needs its first draw in any other state, we know the 896 // If the active tree needs its first draw in any other state, we know the
942 // main thread is in a high latency mode. 897 // main thread is in a high latency mode.
943 return active_tree_needs_first_draw_; 898 return active_tree_needs_first_draw_;
944 } 899 }
945 900
946 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { 901 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() {
947 AdvanceCurrentFrameNumber(); 902 AdvanceCurrentFrameNumber();
948 inside_poll_for_anticipated_draw_triggers_ = true; 903 inside_poll_for_anticipated_draw_triggers_ = true;
(...skipping 20 matching lines...) Expand all
969 } 924 }
970 } 925 }
971 926
972 void SchedulerStateMachine::SetMaxSwapsPending(int max) { 927 void SchedulerStateMachine::SetMaxSwapsPending(int max) {
973 max_pending_swaps_ = max; 928 max_pending_swaps_ = max;
974 } 929 }
975 930
976 void SchedulerStateMachine::DidSwapBuffers() { 931 void SchedulerStateMachine::DidSwapBuffers() {
977 pending_swaps_++; 932 pending_swaps_++;
978 DCHECK_LE(pending_swaps_, max_pending_swaps_); 933 DCHECK_LE(pending_swaps_, max_pending_swaps_);
934 DCHECK(!perform_swap_funnel_);
979 935
936 perform_swap_funnel_ = true;
980 last_frame_number_swap_performed_ = current_frame_number_; 937 last_frame_number_swap_performed_ = current_frame_number_;
981 } 938 }
982 939
983 void SchedulerStateMachine::DidSwapBuffersComplete() { 940 void SchedulerStateMachine::DidSwapBuffersComplete() {
984 DCHECK_GT(pending_swaps_, 0); 941 DCHECK_GT(pending_swaps_, 0);
985 pending_swaps_--; 942 pending_swaps_--;
986 } 943 }
987 944
988 void SchedulerStateMachine::SetImplLatencyTakesPriority( 945 void SchedulerStateMachine::SetImplLatencyTakesPriority(
989 bool impl_latency_takes_priority) { 946 bool impl_latency_takes_priority) {
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1123 static_cast<int>(begin_impl_frame_state_), 1080 static_cast<int>(begin_impl_frame_state_),
1124 static_cast<int>(commit_state_), 1081 static_cast<int>(commit_state_),
1125 has_pending_tree_ ? 'T' : 'F', 1082 has_pending_tree_ ? 'T' : 'F',
1126 pending_tree_is_ready_for_activation_ ? 'T' : 'F', 1083 pending_tree_is_ready_for_activation_ ? 'T' : 'F',
1127 active_tree_needs_first_draw_ ? 'T' : 'F', 1084 active_tree_needs_first_draw_ ? 'T' : 'F',
1128 max_pending_swaps_, 1085 max_pending_swaps_,
1129 pending_swaps_); 1086 pending_swaps_);
1130 } 1087 }
1131 1088
1132 } // namespace cc 1089 } // 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