OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "cc/scheduler/scheduler_state_machine.h" | |
6 | |
7 #include "base/trace_event/trace_event.h" | |
8 #include "cc/scheduler/scheduler.h" | |
9 #include "cc/test/begin_frame_args_test.h" | |
10 #include "testing/gtest/include/gtest/gtest.h" | |
11 | |
12 // Macro to compare two enum values and get nice output. | |
13 // Without: | |
14 // Value of: actual() Actual: 7 | |
15 // Expected: expected() Which is: 0 | |
16 // With: | |
17 // Value of: actual() Actual: "ACTION_ANIMATE" | |
18 // Expected: expected() Which is: "ACTION_NONE" | |
19 #define EXPECT_ENUM_EQ(enum_tostring, expected, actual) \ | |
20 EXPECT_STREQ(SchedulerStateMachine::enum_tostring(expected), \ | |
21 SchedulerStateMachine::enum_tostring(actual)) | |
22 | |
23 #define EXPECT_IMPL_FRAME_STATE(expected) \ | |
24 EXPECT_ENUM_EQ(BeginImplFrameStateToString, expected, \ | |
25 state.begin_impl_frame_state()) \ | |
26 << state.AsValue()->ToString() | |
27 | |
28 #define EXPECT_COMMIT_STATE(expected) \ | |
29 EXPECT_ENUM_EQ(CommitStateToString, expected, state.CommitState()) | |
30 | |
31 #define EXPECT_ACTION(expected) \ | |
32 EXPECT_ENUM_EQ(ActionToString, expected, state.NextAction()) \ | |
33 << state.AsValue()->ToString() | |
34 | |
35 #define EXPECT_ACTION_UPDATE_STATE(action) \ | |
36 EXPECT_ACTION(action); \ | |
37 if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \ | |
38 action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \ | |
39 EXPECT_IMPL_FRAME_STATE( \ | |
40 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); \ | |
41 } \ | |
42 state.UpdateState(action); \ | |
43 if (action == SchedulerStateMachine::ACTION_NONE) { \ | |
44 if (state.begin_impl_frame_state() == \ | |
45 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \ | |
46 state.OnBeginImplFrameDeadlinePending(); \ | |
47 if (state.begin_impl_frame_state() == \ | |
48 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \ | |
49 state.OnBeginImplFrameIdle(); \ | |
50 } | |
51 | |
52 #define SET_UP_STATE(state) \ | |
53 state.SetCanStart(); \ | |
54 state.UpdateState(state.NextAction()); \ | |
55 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); \ | |
56 state.SetVisible(true); \ | |
57 state.SetCanDraw(true); | |
58 | |
59 namespace cc { | |
60 | |
61 namespace { | |
62 | |
63 const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states[] = | |
64 {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE, | |
65 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING, | |
66 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME, | |
67 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, }; | |
68 | |
69 const SchedulerStateMachine::CommitState all_commit_states[] = { | |
70 SchedulerStateMachine::COMMIT_STATE_IDLE, | |
71 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT, | |
72 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED, | |
73 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, | |
74 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION, | |
75 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW}; | |
76 | |
77 // Exposes the protected state fields of the SchedulerStateMachine for testing | |
78 class StateMachine : public SchedulerStateMachine { | |
79 public: | |
80 explicit StateMachine(const SchedulerSettings& scheduler_settings) | |
81 : SchedulerStateMachine(scheduler_settings) {} | |
82 | |
83 void CreateAndInitializeOutputSurfaceWithActivatedCommit() { | |
84 DidCreateAndInitializeOutputSurface(); | |
85 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; | |
86 } | |
87 | |
88 void SetCommitState(CommitState cs) { commit_state_ = cs; } | |
89 CommitState CommitState() const { return commit_state_; } | |
90 | |
91 ForcedRedrawOnTimeoutState ForcedRedrawState() const { | |
92 return forced_redraw_state_; | |
93 } | |
94 | |
95 void SetBeginImplFrameState(BeginImplFrameState bifs) { | |
96 begin_impl_frame_state_ = bifs; | |
97 } | |
98 | |
99 BeginImplFrameState begin_impl_frame_state() const { | |
100 return begin_impl_frame_state_; | |
101 } | |
102 | |
103 OutputSurfaceState output_surface_state() const { | |
104 return output_surface_state_; | |
105 } | |
106 | |
107 bool NeedsCommit() const { return needs_commit_; } | |
108 | |
109 void SetNeedsRedraw(bool b) { needs_redraw_ = b; } | |
110 | |
111 void SetNeedsForcedRedrawForTimeout(bool b) { | |
112 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT; | |
113 active_tree_needs_first_draw_ = true; | |
114 } | |
115 bool NeedsForcedRedrawForTimeout() const { | |
116 return forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE; | |
117 } | |
118 | |
119 void SetActiveTreeNeedsFirstDraw(bool needs_first_draw) { | |
120 active_tree_needs_first_draw_ = needs_first_draw; | |
121 } | |
122 | |
123 bool CanDraw() const { return can_draw_; } | |
124 bool Visible() const { return visible_; } | |
125 | |
126 bool PendingActivationsShouldBeForced() const { | |
127 return SchedulerStateMachine::PendingActivationsShouldBeForced(); | |
128 } | |
129 | |
130 void SetHasPendingTree(bool has_pending_tree) { | |
131 has_pending_tree_ = has_pending_tree; | |
132 } | |
133 | |
134 using SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately; | |
135 using SchedulerStateMachine::ProactiveBeginFrameWanted; | |
136 using SchedulerStateMachine::UpdateStateOnCommit; | |
137 }; | |
138 | |
139 TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) { | |
140 SchedulerSettings default_scheduler_settings; | |
141 | |
142 // If no commit needed, do nothing. | |
143 { | |
144 StateMachine state(default_scheduler_settings); | |
145 state.SetCanStart(); | |
146 EXPECT_ACTION_UPDATE_STATE( | |
147 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION) | |
148 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
149 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
150 state.SetNeedsRedraw(false); | |
151 state.SetVisible(true); | |
152 | |
153 EXPECT_FALSE(state.BeginFrameNeeded()); | |
154 | |
155 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
156 EXPECT_FALSE(state.BeginFrameNeeded()); | |
157 state.OnBeginImplFrame(); | |
158 | |
159 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
160 state.OnBeginImplFrameDeadline(); | |
161 } | |
162 | |
163 // If commit requested but can_start is still false, do nothing. | |
164 { | |
165 StateMachine state(default_scheduler_settings); | |
166 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
167 state.SetNeedsRedraw(false); | |
168 state.SetVisible(true); | |
169 state.SetNeedsCommit(); | |
170 | |
171 EXPECT_FALSE(state.BeginFrameNeeded()); | |
172 | |
173 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
174 EXPECT_FALSE(state.BeginFrameNeeded()); | |
175 state.OnBeginImplFrame(); | |
176 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
177 state.OnBeginImplFrameDeadline(); | |
178 } | |
179 | |
180 // If commit requested, begin a main frame. | |
181 { | |
182 StateMachine state(default_scheduler_settings); | |
183 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
184 state.SetCanStart(); | |
185 state.UpdateState(state.NextAction()); | |
186 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
187 state.SetNeedsRedraw(false); | |
188 state.SetVisible(true); | |
189 state.SetNeedsCommit(); | |
190 | |
191 EXPECT_TRUE(state.BeginFrameNeeded()); | |
192 | |
193 state.OnBeginImplFrame(); | |
194 EXPECT_ACTION_UPDATE_STATE( | |
195 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
196 } | |
197 | |
198 // Begin the frame, make sure needs_commit and commit_state update correctly. | |
199 { | |
200 StateMachine state(default_scheduler_settings); | |
201 state.SetCanStart(); | |
202 state.UpdateState(state.NextAction()); | |
203 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
204 state.SetVisible(true); | |
205 state.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
206 EXPECT_COMMIT_STATE( | |
207 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
208 EXPECT_FALSE(state.NeedsCommit()); | |
209 } | |
210 } | |
211 | |
212 // Explicitly test main_frame_before_activation_enabled = true | |
213 TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) { | |
214 SchedulerSettings scheduler_settings; | |
215 scheduler_settings.impl_side_painting = true; | |
216 scheduler_settings.main_frame_before_activation_enabled = true; | |
217 StateMachine state(scheduler_settings); | |
218 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
219 SET_UP_STATE(state) | |
220 state.SetNeedsRedraw(false); | |
221 state.SetNeedsCommit(); | |
222 | |
223 EXPECT_TRUE(state.BeginFrameNeeded()); | |
224 | |
225 // Commit to the pending tree. | |
226 state.OnBeginImplFrame(); | |
227 EXPECT_ACTION_UPDATE_STATE( | |
228 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
229 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
230 | |
231 state.NotifyBeginMainFrameStarted(); | |
232 state.NotifyReadyToCommit(); | |
233 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
234 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
235 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
236 | |
237 state.OnBeginImplFrameDeadline(); | |
238 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
239 | |
240 // Verify that the next commit starts while there is still a pending tree. | |
241 state.SetNeedsCommit(); | |
242 state.OnBeginImplFrame(); | |
243 EXPECT_ACTION_UPDATE_STATE( | |
244 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
245 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
246 | |
247 // Verify the pending commit doesn't overwrite the pending | |
248 // tree until the pending tree has been activated. | |
249 state.NotifyBeginMainFrameStarted(); | |
250 state.NotifyReadyToCommit(); | |
251 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
252 | |
253 // Verify NotifyReadyToActivate unblocks activation, draw, and | |
254 // commit in that order. | |
255 state.NotifyReadyToActivate(); | |
256 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); | |
257 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
258 | |
259 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately()); | |
260 state.OnBeginImplFrameDeadline(); | |
261 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
262 EXPECT_ACTION_UPDATE_STATE( | |
263 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
264 state.DidSwapBuffers(); | |
265 state.DidSwapBuffersComplete(); | |
266 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
267 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
268 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
269 } | |
270 | |
271 TEST(SchedulerStateMachineTest, | |
272 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain) { | |
273 SchedulerSettings default_scheduler_settings; | |
274 StateMachine state(default_scheduler_settings); | |
275 SET_UP_STATE(state) | |
276 state.SetNeedsRedraw(true); | |
277 EXPECT_TRUE(state.RedrawPending()); | |
278 EXPECT_TRUE(state.BeginFrameNeeded()); | |
279 state.OnBeginImplFrame(); | |
280 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
281 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
282 state.OnBeginImplFrameDeadline(); | |
283 | |
284 // We're drawing now. | |
285 EXPECT_ACTION_UPDATE_STATE( | |
286 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
287 state.DidSwapBuffers(); | |
288 state.DidSwapBuffersComplete(); | |
289 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
290 | |
291 EXPECT_FALSE(state.RedrawPending()); | |
292 EXPECT_FALSE(state.CommitPending()); | |
293 | |
294 // Failing the draw makes us require a commit. | |
295 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); | |
296 state.OnBeginImplFrame(); | |
297 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
298 EXPECT_ACTION_UPDATE_STATE( | |
299 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
300 EXPECT_TRUE(state.RedrawPending()); | |
301 EXPECT_TRUE(state.CommitPending()); | |
302 } | |
303 | |
304 TEST(SchedulerStateMachineTest, TestFailedDrawForMissingHighResNeedsCommit) { | |
305 SchedulerSettings default_scheduler_settings; | |
306 StateMachine state(default_scheduler_settings); | |
307 SET_UP_STATE(state) | |
308 state.SetNeedsRedraw(true); | |
309 EXPECT_TRUE(state.RedrawPending()); | |
310 EXPECT_TRUE(state.BeginFrameNeeded()); | |
311 | |
312 state.OnBeginImplFrame(); | |
313 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
314 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
315 state.OnBeginImplFrameDeadline(); | |
316 EXPECT_ACTION_UPDATE_STATE( | |
317 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
318 state.DidSwapBuffers(); | |
319 state.DidSwapBuffersComplete(); | |
320 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
321 EXPECT_FALSE(state.RedrawPending()); | |
322 EXPECT_FALSE(state.CommitPending()); | |
323 | |
324 // Missing high res content requires a commit (but not a redraw) | |
325 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT); | |
326 state.OnBeginImplFrame(); | |
327 EXPECT_ACTION_UPDATE_STATE( | |
328 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
329 EXPECT_FALSE(state.RedrawPending()); | |
330 EXPECT_TRUE(state.CommitPending()); | |
331 } | |
332 | |
333 TEST(SchedulerStateMachineTest, | |
334 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw) { | |
335 SchedulerSettings default_scheduler_settings; | |
336 StateMachine state(default_scheduler_settings); | |
337 SET_UP_STATE(state) | |
338 state.SetNeedsRedraw(true); | |
339 EXPECT_TRUE(state.RedrawPending()); | |
340 EXPECT_TRUE(state.BeginFrameNeeded()); | |
341 state.OnBeginImplFrame(); | |
342 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
343 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
344 state.OnBeginImplFrameDeadline(); | |
345 | |
346 // We're drawing now. | |
347 EXPECT_ACTION_UPDATE_STATE( | |
348 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
349 state.DidSwapBuffers(); | |
350 state.DidSwapBuffersComplete(); | |
351 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
352 EXPECT_FALSE(state.RedrawPending()); | |
353 EXPECT_FALSE(state.CommitPending()); | |
354 | |
355 // While still in the same BeginMainFrame callback on the main thread, | |
356 // set needs redraw again. This should not redraw. | |
357 state.SetNeedsRedraw(true); | |
358 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
359 | |
360 // Failing the draw for animation checkerboards makes us require a commit. | |
361 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); | |
362 state.OnBeginImplFrame(); | |
363 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
364 EXPECT_ACTION_UPDATE_STATE( | |
365 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
366 EXPECT_TRUE(state.RedrawPending()); | |
367 } | |
368 | |
369 TEST(SchedulerStateMachineTest, | |
370 TestFailedDrawsEventuallyForceDrawAfterNextCommit) { | |
371 SchedulerSettings scheduler_settings; | |
372 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = 1; | |
373 StateMachine state(scheduler_settings); | |
374 SET_UP_STATE(state) | |
375 | |
376 // Start a commit. | |
377 state.SetNeedsCommit(); | |
378 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
379 state.OnBeginImplFrame(); | |
380 EXPECT_ACTION_UPDATE_STATE( | |
381 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
382 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
383 EXPECT_TRUE(state.CommitPending()); | |
384 | |
385 // Then initiate a draw. | |
386 state.SetNeedsRedraw(true); | |
387 state.OnBeginImplFrameDeadline(); | |
388 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
389 EXPECT_ACTION_UPDATE_STATE( | |
390 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
391 | |
392 // Fail the draw. | |
393 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); | |
394 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
395 EXPECT_TRUE(state.BeginFrameNeeded()); | |
396 EXPECT_TRUE(state.RedrawPending()); | |
397 // But the commit is ongoing. | |
398 EXPECT_TRUE(state.CommitPending()); | |
399 | |
400 // Finish the commit. Note, we should not yet be forcing a draw, but should | |
401 // continue the commit as usual. | |
402 state.NotifyBeginMainFrameStarted(); | |
403 state.NotifyReadyToCommit(); | |
404 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
405 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
406 EXPECT_TRUE(state.RedrawPending()); | |
407 | |
408 // The redraw should be forced at the end of the next BeginImplFrame. | |
409 state.OnBeginImplFrame(); | |
410 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
411 EXPECT_ACTION_UPDATE_STATE( | |
412 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
413 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
414 state.OnBeginImplFrameDeadline(); | |
415 EXPECT_ACTION_UPDATE_STATE( | |
416 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED); | |
417 state.DidSwapBuffers(); | |
418 state.DidSwapBuffersComplete(); | |
419 } | |
420 | |
421 TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) { | |
422 SchedulerSettings scheduler_settings; | |
423 int draw_limit = 1; | |
424 scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = | |
425 draw_limit; | |
426 scheduler_settings.impl_side_painting = true; | |
427 StateMachine state(scheduler_settings); | |
428 SET_UP_STATE(state) | |
429 | |
430 // Start a commit. | |
431 state.SetNeedsCommit(); | |
432 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
433 state.OnBeginImplFrame(); | |
434 EXPECT_ACTION_UPDATE_STATE( | |
435 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
436 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
437 EXPECT_TRUE(state.CommitPending()); | |
438 | |
439 // Then initiate a draw. | |
440 state.SetNeedsRedraw(true); | |
441 state.OnBeginImplFrameDeadline(); | |
442 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
443 EXPECT_ACTION_UPDATE_STATE( | |
444 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
445 | |
446 // Fail the draw enough times to force a redraw, | |
447 // then once more for good measure. | |
448 for (int i = 0; i < draw_limit + 1; ++i) | |
449 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); | |
450 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
451 EXPECT_TRUE(state.BeginFrameNeeded()); | |
452 EXPECT_TRUE(state.RedrawPending()); | |
453 // But the commit is ongoing. | |
454 EXPECT_TRUE(state.CommitPending()); | |
455 EXPECT_TRUE(state.ForcedRedrawState() == | |
456 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT); | |
457 | |
458 state.NotifyBeginMainFrameStarted(); | |
459 state.NotifyReadyToCommit(); | |
460 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
461 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
462 EXPECT_TRUE(state.RedrawPending()); | |
463 EXPECT_FALSE(state.CommitPending()); | |
464 | |
465 // Now force redraw should be in waiting for activation | |
466 EXPECT_TRUE(state.ForcedRedrawState() == | |
467 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION); | |
468 | |
469 // After failing additional draws, we should still be in a forced | |
470 // redraw, but not back in WAITING_FOR_COMMIT. | |
471 for (int i = 0; i < draw_limit + 1; ++i) | |
472 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); | |
473 EXPECT_TRUE(state.RedrawPending()); | |
474 EXPECT_TRUE(state.ForcedRedrawState() == | |
475 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION); | |
476 } | |
477 | |
478 TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) { | |
479 SchedulerSettings default_scheduler_settings; | |
480 StateMachine state(default_scheduler_settings); | |
481 SET_UP_STATE(state) | |
482 | |
483 // Start a draw. | |
484 state.SetNeedsRedraw(true); | |
485 EXPECT_TRUE(state.BeginFrameNeeded()); | |
486 state.OnBeginImplFrame(); | |
487 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
488 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
489 state.OnBeginImplFrameDeadline(); | |
490 EXPECT_TRUE(state.RedrawPending()); | |
491 EXPECT_ACTION_UPDATE_STATE( | |
492 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
493 | |
494 // Failing the draw for animation checkerboards makes us require a commit. | |
495 state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); | |
496 EXPECT_ACTION_UPDATE_STATE( | |
497 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
498 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
499 EXPECT_TRUE(state.RedrawPending()); | |
500 | |
501 // We should not be trying to draw again now, but we have a commit pending. | |
502 EXPECT_TRUE(state.BeginFrameNeeded()); | |
503 state.OnBeginImplFrame(); | |
504 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
505 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
506 | |
507 // We should try to draw again at the end of the next BeginImplFrame on | |
508 // the impl thread. | |
509 state.OnBeginImplFrameDeadline(); | |
510 EXPECT_ACTION_UPDATE_STATE( | |
511 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
512 state.DidSwapBuffers(); | |
513 state.DidSwapBuffersComplete(); | |
514 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
515 } | |
516 | |
517 TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) { | |
518 SchedulerSettings default_scheduler_settings; | |
519 StateMachine state(default_scheduler_settings); | |
520 SET_UP_STATE(state) | |
521 state.SetNeedsRedraw(true); | |
522 | |
523 // Draw the first frame. | |
524 EXPECT_TRUE(state.BeginFrameNeeded()); | |
525 state.OnBeginImplFrame(); | |
526 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
527 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
528 | |
529 state.OnBeginImplFrameDeadline(); | |
530 EXPECT_ACTION_UPDATE_STATE( | |
531 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
532 state.DidSwapBuffers(); | |
533 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS); | |
534 state.DidSwapBuffersComplete(); | |
535 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
536 | |
537 // Before the next BeginImplFrame, set needs redraw again. | |
538 // This should not redraw until the next BeginImplFrame. | |
539 state.SetNeedsRedraw(true); | |
540 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
541 | |
542 // Move to another frame. This should now draw. | |
543 EXPECT_TRUE(state.BeginFrameNeeded()); | |
544 state.OnBeginImplFrame(); | |
545 | |
546 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
547 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
548 | |
549 state.OnBeginImplFrameDeadline(); | |
550 EXPECT_ACTION_UPDATE_STATE( | |
551 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
552 state.DidSwapBuffers(); | |
553 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS); | |
554 state.DidSwapBuffersComplete(); | |
555 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
556 | |
557 // We just swapped, so we should proactively request another BeginImplFrame. | |
558 EXPECT_TRUE(state.BeginFrameNeeded()); | |
559 } | |
560 | |
561 TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) { | |
562 SchedulerSettings default_scheduler_settings; | |
563 | |
564 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline | |
565 // but not visible, don't draw. | |
566 size_t num_commit_states = | |
567 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState); | |
568 size_t num_begin_impl_frame_states = | |
569 sizeof(all_begin_impl_frame_states) / | |
570 sizeof(SchedulerStateMachine::BeginImplFrameState); | |
571 for (size_t i = 0; i < num_commit_states; ++i) { | |
572 for (size_t j = 0; j < num_begin_impl_frame_states; ++j) { | |
573 StateMachine state(default_scheduler_settings); | |
574 state.SetCanStart(); | |
575 state.UpdateState(state.NextAction()); | |
576 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
577 state.SetCommitState(all_commit_states[i]); | |
578 state.SetBeginImplFrameState(all_begin_impl_frame_states[j]); | |
579 bool visible = | |
580 (all_begin_impl_frame_states[j] != | |
581 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); | |
582 state.SetVisible(visible); | |
583 | |
584 // Case 1: needs_commit=false | |
585 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE, | |
586 state.NextAction()); | |
587 | |
588 // Case 2: needs_commit=true | |
589 state.SetNeedsCommit(); | |
590 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE, | |
591 state.NextAction()) | |
592 << state.AsValue()->ToString(); | |
593 } | |
594 } | |
595 | |
596 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw | |
597 // except if we're ready to commit, in which case we expect a commit first. | |
598 for (size_t i = 0; i < num_commit_states; ++i) { | |
599 StateMachine state(default_scheduler_settings); | |
600 state.SetCanStart(); | |
601 state.UpdateState(state.NextAction()); | |
602 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
603 state.SetCanDraw(true); | |
604 state.SetCommitState(all_commit_states[i]); | |
605 state.SetBeginImplFrameState( | |
606 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); | |
607 | |
608 state.SetNeedsRedraw(true); | |
609 state.SetVisible(true); | |
610 | |
611 SchedulerStateMachine::Action expected_action; | |
612 if (all_commit_states[i] == | |
613 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT) { | |
614 expected_action = SchedulerStateMachine::ACTION_COMMIT; | |
615 } else { | |
616 expected_action = SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE; | |
617 EXPECT_ACTION(SchedulerStateMachine::ACTION_ANIMATE); | |
618 state.UpdateState(state.NextAction()); | |
619 } | |
620 | |
621 // Case 1: needs_commit=false. | |
622 EXPECT_ACTION(expected_action); | |
623 | |
624 // Case 2: needs_commit=true. | |
625 state.SetNeedsCommit(); | |
626 EXPECT_ACTION(expected_action); | |
627 } | |
628 } | |
629 | |
630 TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible) { | |
631 SchedulerSettings default_scheduler_settings; | |
632 | |
633 size_t num_commit_states = | |
634 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState); | |
635 for (size_t i = 0; i < num_commit_states; ++i) { | |
636 // There shouldn't be any drawing regardless of BeginImplFrame. | |
637 for (size_t j = 0; j < 2; ++j) { | |
638 StateMachine state(default_scheduler_settings); | |
639 state.SetCanStart(); | |
640 state.UpdateState(state.NextAction()); | |
641 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
642 state.SetCommitState(all_commit_states[i]); | |
643 state.SetVisible(false); | |
644 state.SetNeedsRedraw(true); | |
645 if (j == 1) { | |
646 state.SetBeginImplFrameState( | |
647 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); | |
648 } | |
649 | |
650 // Case 1: needs_commit=false. | |
651 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE, | |
652 state.NextAction()); | |
653 | |
654 // Case 2: needs_commit=true. | |
655 state.SetNeedsCommit(); | |
656 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE, | |
657 state.NextAction()) | |
658 << state.AsValue()->ToString(); | |
659 } | |
660 } | |
661 } | |
662 | |
663 TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) { | |
664 SchedulerSettings default_scheduler_settings; | |
665 | |
666 size_t num_commit_states = | |
667 sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState); | |
668 for (size_t i = 0; i < num_commit_states; ++i) { | |
669 // There shouldn't be any drawing regardless of BeginImplFrame. | |
670 for (size_t j = 0; j < 2; ++j) { | |
671 StateMachine state(default_scheduler_settings); | |
672 state.SetCanStart(); | |
673 state.UpdateState(state.NextAction()); | |
674 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
675 state.SetCommitState(all_commit_states[i]); | |
676 state.SetVisible(false); | |
677 state.SetNeedsRedraw(true); | |
678 if (j == 1) | |
679 state.OnBeginImplFrame(); | |
680 | |
681 state.SetCanDraw(false); | |
682 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE, | |
683 state.NextAction()); | |
684 } | |
685 } | |
686 } | |
687 | |
688 TEST(SchedulerStateMachineTest, | |
689 TestCanRedrawWithWaitingForFirstDrawMakesProgress) { | |
690 SchedulerSettings default_scheduler_settings; | |
691 StateMachine state(default_scheduler_settings); | |
692 state.SetCanStart(); | |
693 state.UpdateState(state.NextAction()); | |
694 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
695 | |
696 state.SetActiveTreeNeedsFirstDraw(true); | |
697 state.SetNeedsCommit(); | |
698 state.SetNeedsRedraw(true); | |
699 state.SetVisible(true); | |
700 state.SetCanDraw(false); | |
701 state.OnBeginImplFrame(); | |
702 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
703 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); | |
704 EXPECT_ACTION_UPDATE_STATE( | |
705 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
706 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
707 state.NotifyBeginMainFrameStarted(); | |
708 state.NotifyReadyToCommit(); | |
709 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
710 state.OnBeginImplFrameDeadline(); | |
711 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
712 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); | |
713 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
714 } | |
715 | |
716 TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost) { | |
717 SchedulerSettings scheduler_settings; | |
718 StateMachine state(scheduler_settings); | |
719 SET_UP_STATE(state) | |
720 state.SetNeedsCommit(); | |
721 | |
722 EXPECT_TRUE(state.BeginFrameNeeded()); | |
723 | |
724 // Begin the frame. | |
725 state.OnBeginImplFrame(); | |
726 EXPECT_ACTION_UPDATE_STATE( | |
727 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
728 EXPECT_COMMIT_STATE( | |
729 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
730 | |
731 // Now, while the frame is in progress, set another commit. | |
732 state.SetNeedsCommit(); | |
733 EXPECT_TRUE(state.NeedsCommit()); | |
734 | |
735 // Let the frame finish. | |
736 state.NotifyBeginMainFrameStarted(); | |
737 state.NotifyReadyToCommit(); | |
738 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT); | |
739 | |
740 // Expect to commit regardless of BeginImplFrame state. | |
741 EXPECT_IMPL_FRAME_STATE( | |
742 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING); | |
743 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT); | |
744 | |
745 state.OnBeginImplFrameDeadlinePending(); | |
746 EXPECT_IMPL_FRAME_STATE( | |
747 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME); | |
748 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT); | |
749 | |
750 state.OnBeginImplFrameDeadline(); | |
751 EXPECT_IMPL_FRAME_STATE( | |
752 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); | |
753 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT); | |
754 | |
755 state.OnBeginImplFrameIdle(); | |
756 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | |
757 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT); | |
758 | |
759 state.OnBeginImplFrame(); | |
760 EXPECT_IMPL_FRAME_STATE( | |
761 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING); | |
762 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT); | |
763 | |
764 // Finish the commit, then make sure we start the next commit immediately | |
765 // and draw on the next BeginImplFrame. | |
766 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
767 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
768 EXPECT_ACTION_UPDATE_STATE( | |
769 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
770 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
771 | |
772 state.OnBeginImplFrameDeadline(); | |
773 | |
774 EXPECT_TRUE(state.active_tree_needs_first_draw()); | |
775 EXPECT_ACTION_UPDATE_STATE( | |
776 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
777 state.DidSwapBuffers(); | |
778 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS); | |
779 state.DidSwapBuffersComplete(); | |
780 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
781 } | |
782 | |
783 TEST(SchedulerStateMachineTest, TestFullCycle) { | |
784 SchedulerSettings default_scheduler_settings; | |
785 StateMachine state(default_scheduler_settings); | |
786 SET_UP_STATE(state) | |
787 | |
788 // Start clean and set commit. | |
789 state.SetNeedsCommit(); | |
790 | |
791 // Begin the frame. | |
792 state.OnBeginImplFrame(); | |
793 EXPECT_ACTION_UPDATE_STATE( | |
794 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
795 EXPECT_COMMIT_STATE( | |
796 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
797 EXPECT_FALSE(state.NeedsCommit()); | |
798 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
799 | |
800 // Tell the scheduler the frame finished. | |
801 state.NotifyBeginMainFrameStarted(); | |
802 state.NotifyReadyToCommit(); | |
803 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT); | |
804 | |
805 // Commit. | |
806 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
807 EXPECT_TRUE(state.active_tree_needs_first_draw()); | |
808 EXPECT_TRUE(state.needs_redraw()); | |
809 | |
810 // Expect to do nothing until BeginImplFrame deadline | |
811 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
812 | |
813 // At BeginImplFrame deadline, draw. | |
814 state.OnBeginImplFrameDeadline(); | |
815 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
816 EXPECT_ACTION_UPDATE_STATE( | |
817 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
818 state.DidSwapBuffers(); | |
819 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS); | |
820 state.DidSwapBuffersComplete(); | |
821 | |
822 // Should be synchronized, no draw needed, no action needed. | |
823 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
824 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
825 EXPECT_FALSE(state.needs_redraw()); | |
826 } | |
827 | |
828 TEST(SchedulerStateMachineTest, TestFullCycleWithMainThreadLowLatencyMode) { | |
829 SchedulerSettings scheduler_settings; | |
830 scheduler_settings.main_thread_should_always_be_low_latency = true; | |
831 StateMachine state(scheduler_settings); | |
832 SET_UP_STATE(state) | |
833 | |
834 // Start clean and set commit. | |
835 state.SetNeedsCommit(); | |
836 | |
837 // Begin the frame. | |
838 state.OnBeginImplFrame(); | |
839 EXPECT_ACTION_UPDATE_STATE( | |
840 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
841 EXPECT_COMMIT_STATE( | |
842 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
843 EXPECT_FALSE(state.NeedsCommit()); | |
844 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
845 | |
846 // Tell the scheduler the frame finished. | |
847 state.NotifyBeginMainFrameStarted(); | |
848 state.NotifyReadyToCommit(); | |
849 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT); | |
850 | |
851 // Commit. | |
852 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
853 EXPECT_TRUE(state.active_tree_needs_first_draw()); | |
854 EXPECT_TRUE(state.needs_redraw()); | |
855 | |
856 // Now commit should wait for draw. | |
857 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW); | |
858 | |
859 // Swap throttled. Do not draw. | |
860 state.DidSwapBuffers(); | |
861 state.OnBeginImplFrameDeadline(); | |
862 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
863 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
864 state.DidSwapBuffersComplete(); | |
865 | |
866 // Haven't draw since last commit, do not begin new main frame. | |
867 state.SetNeedsCommit(); | |
868 state.OnBeginImplFrame(); | |
869 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
870 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
871 | |
872 // At BeginImplFrame deadline, draw. | |
873 state.OnBeginImplFrameDeadline(); | |
874 EXPECT_ACTION_UPDATE_STATE( | |
875 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
876 state.DidSwapBuffers(); | |
877 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS); | |
878 state.DidSwapBuffersComplete(); | |
879 | |
880 // Now will be able to start main frame. | |
881 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
882 EXPECT_FALSE(state.needs_redraw()); | |
883 EXPECT_ACTION_UPDATE_STATE( | |
884 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
885 } | |
886 | |
887 TEST(SchedulerStateMachineTest, | |
888 TestFullCycleWithMainThreadLowLatencyMode_ImplSidePaint) { | |
889 SchedulerSettings scheduler_settings; | |
890 scheduler_settings.main_thread_should_always_be_low_latency = true; | |
891 scheduler_settings.impl_side_painting = true; | |
892 StateMachine state(scheduler_settings); | |
893 SET_UP_STATE(state) | |
894 | |
895 // Start clean and set commit. | |
896 state.SetNeedsCommit(); | |
897 | |
898 // Begin the frame. | |
899 state.OnBeginImplFrame(); | |
900 EXPECT_ACTION_UPDATE_STATE( | |
901 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
902 EXPECT_COMMIT_STATE( | |
903 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
904 EXPECT_FALSE(state.NeedsCommit()); | |
905 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
906 | |
907 // Tell the scheduler the frame finished. | |
908 state.NotifyBeginMainFrameStarted(); | |
909 state.NotifyReadyToCommit(); | |
910 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT); | |
911 | |
912 // Commit. | |
913 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
914 | |
915 // Now commit should wait for activation. | |
916 EXPECT_COMMIT_STATE( | |
917 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION); | |
918 | |
919 // No activation yet, so this commit is not drawn yet. Force to draw this | |
920 // frame, and still block BeginMainFrame. | |
921 state.SetNeedsRedraw(true); | |
922 state.SetNeedsCommit(); | |
923 state.OnBeginImplFrameDeadline(); | |
924 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
925 EXPECT_ACTION_UPDATE_STATE( | |
926 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
927 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
928 | |
929 // Cannot BeginMainFrame yet since last commit is not yet activated and drawn. | |
930 state.OnBeginImplFrame(); | |
931 EXPECT_COMMIT_STATE( | |
932 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION); | |
933 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
934 | |
935 // Now activate sync tree. | |
936 state.NotifyReadyToActivate(); | |
937 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); | |
938 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
939 EXPECT_TRUE(state.active_tree_needs_first_draw()); | |
940 EXPECT_TRUE(state.needs_redraw()); | |
941 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW); | |
942 | |
943 // Swap throttled. Do not draw. | |
944 state.DidSwapBuffers(); | |
945 state.OnBeginImplFrameDeadline(); | |
946 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
947 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
948 state.DidSwapBuffersComplete(); | |
949 | |
950 // Haven't draw since last commit, do not begin new main frame. | |
951 state.OnBeginImplFrame(); | |
952 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
953 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
954 | |
955 // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame. | |
956 state.OnBeginImplFrameDeadline(); | |
957 EXPECT_ACTION_UPDATE_STATE( | |
958 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
959 state.DidSwapBuffers(); | |
960 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS); | |
961 state.DidSwapBuffersComplete(); | |
962 | |
963 // Now will be able to start main frame. | |
964 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
965 EXPECT_FALSE(state.needs_redraw()); | |
966 EXPECT_ACTION_UPDATE_STATE( | |
967 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
968 } | |
969 | |
970 TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) { | |
971 SchedulerSettings default_scheduler_settings; | |
972 StateMachine state(default_scheduler_settings); | |
973 SET_UP_STATE(state) | |
974 | |
975 // Start clean and set commit. | |
976 state.SetNeedsCommit(); | |
977 | |
978 // Begin the frame. | |
979 state.OnBeginImplFrame(); | |
980 EXPECT_ACTION_UPDATE_STATE( | |
981 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
982 EXPECT_COMMIT_STATE( | |
983 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
984 EXPECT_FALSE(state.NeedsCommit()); | |
985 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
986 | |
987 // Request another commit while the commit is in flight. | |
988 state.SetNeedsCommit(); | |
989 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
990 | |
991 // Tell the scheduler the frame finished. | |
992 state.NotifyBeginMainFrameStarted(); | |
993 state.NotifyReadyToCommit(); | |
994 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT); | |
995 | |
996 // First commit. | |
997 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
998 EXPECT_TRUE(state.active_tree_needs_first_draw()); | |
999 EXPECT_TRUE(state.needs_redraw()); | |
1000 | |
1001 // Expect to do nothing until BeginImplFrame deadline. | |
1002 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1003 | |
1004 // At BeginImplFrame deadline, draw. | |
1005 state.OnBeginImplFrameDeadline(); | |
1006 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1007 EXPECT_ACTION_UPDATE_STATE( | |
1008 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1009 state.DidSwapBuffers(); | |
1010 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS); | |
1011 state.DidSwapBuffersComplete(); | |
1012 | |
1013 // Should be synchronized, no draw needed, no action needed. | |
1014 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1015 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
1016 EXPECT_FALSE(state.needs_redraw()); | |
1017 | |
1018 // Next BeginImplFrame should initiate second commit. | |
1019 state.OnBeginImplFrame(); | |
1020 EXPECT_ACTION_UPDATE_STATE( | |
1021 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1022 } | |
1023 | |
1024 TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) { | |
1025 SchedulerSettings default_scheduler_settings; | |
1026 StateMachine state(default_scheduler_settings); | |
1027 state.SetCanStart(); | |
1028 state.UpdateState(state.NextAction()); | |
1029 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
1030 state.SetNeedsCommit(); | |
1031 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1032 } | |
1033 | |
1034 // See ThreadProxy::BeginMainFrame "EarlyOut_NotVisible" / | |
1035 // "EarlyOut_OutputSurfaceLost" cases. | |
1036 TEST(SchedulerStateMachineTest, TestAbortBeginMainFrameBecauseInvisible) { | |
1037 SchedulerSettings default_scheduler_settings; | |
1038 StateMachine state(default_scheduler_settings); | |
1039 SET_UP_STATE(state) | |
1040 | |
1041 // Start clean and set commit. | |
1042 state.SetNeedsCommit(); | |
1043 | |
1044 // Begin the frame while visible. | |
1045 state.OnBeginImplFrame(); | |
1046 EXPECT_ACTION_UPDATE_STATE( | |
1047 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1048 EXPECT_COMMIT_STATE( | |
1049 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
1050 EXPECT_FALSE(state.NeedsCommit()); | |
1051 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1052 | |
1053 // Become invisible and abort BeginMainFrame. | |
1054 state.SetVisible(false); | |
1055 state.BeginMainFrameAborted(CommitEarlyOutReason::ABORTED_NOT_VISIBLE); | |
1056 | |
1057 // NeedsCommit should now be true again because we never actually did a | |
1058 // commit. | |
1059 EXPECT_TRUE(state.NeedsCommit()); | |
1060 | |
1061 // We should now be back in the idle state as if we never started the frame. | |
1062 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
1063 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1064 | |
1065 // We shouldn't do anything on the BeginImplFrame deadline. | |
1066 state.OnBeginImplFrameDeadline(); | |
1067 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1068 | |
1069 // Become visible again. | |
1070 state.SetVisible(true); | |
1071 | |
1072 // Although we have aborted on this frame and haven't cancelled the commit | |
1073 // (i.e. need another), don't send another BeginMainFrame yet. | |
1074 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
1075 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1076 EXPECT_TRUE(state.NeedsCommit()); | |
1077 | |
1078 // Start a new frame. | |
1079 state.OnBeginImplFrame(); | |
1080 EXPECT_ACTION_UPDATE_STATE( | |
1081 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1082 | |
1083 // We should be starting the commit now. | |
1084 EXPECT_COMMIT_STATE( | |
1085 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
1086 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1087 } | |
1088 | |
1089 // See ThreadProxy::BeginMainFrame "EarlyOut_NoUpdates" case. | |
1090 TEST(SchedulerStateMachineTest, TestAbortBeginMainFrameBecauseCommitNotNeeded) { | |
1091 SchedulerSettings default_scheduler_settings; | |
1092 StateMachine state(default_scheduler_settings); | |
1093 state.SetCanStart(); | |
1094 state.UpdateState(state.NextAction()); | |
1095 state.DidCreateAndInitializeOutputSurface(); | |
1096 state.SetVisible(true); | |
1097 state.SetCanDraw(true); | |
1098 | |
1099 // Get into a begin frame / commit state. | |
1100 state.SetNeedsCommit(); | |
1101 state.OnBeginImplFrame(); | |
1102 EXPECT_ACTION_UPDATE_STATE( | |
1103 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1104 EXPECT_COMMIT_STATE( | |
1105 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
1106 EXPECT_FALSE(state.NeedsCommit()); | |
1107 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1108 | |
1109 // Abort the commit, true means that the BeginMainFrame was sent but there | |
1110 // was no work to do on the main thread. | |
1111 state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES); | |
1112 | |
1113 // NeedsCommit should now be false because the commit was actually handled. | |
1114 EXPECT_FALSE(state.NeedsCommit()); | |
1115 | |
1116 // Even though the commit was aborted, we still expect to draw the new frame. | |
1117 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1118 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1119 state.OnBeginImplFrameDeadline(); | |
1120 EXPECT_ACTION_UPDATE_STATE( | |
1121 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1122 state.DidSwapBuffers(); | |
1123 state.DidSwapBuffersComplete(); | |
1124 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1125 | |
1126 // Verify another commit doesn't start on another frame either. | |
1127 EXPECT_FALSE(state.NeedsCommit()); | |
1128 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
1129 | |
1130 state.OnBeginImplFrame(); | |
1131 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1132 state.OnBeginImplFrameDeadline(); | |
1133 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1134 | |
1135 // Verify another commit can start if requested, though. | |
1136 state.SetNeedsCommit(); | |
1137 EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE); | |
1138 state.OnBeginImplFrame(); | |
1139 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1140 } | |
1141 | |
1142 TEST(SchedulerStateMachineTest, TestFirstContextCreation) { | |
1143 SchedulerSettings default_scheduler_settings; | |
1144 StateMachine state(default_scheduler_settings); | |
1145 state.SetCanStart(); | |
1146 state.SetVisible(true); | |
1147 state.SetCanDraw(true); | |
1148 | |
1149 EXPECT_ACTION_UPDATE_STATE( | |
1150 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION); | |
1151 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
1152 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1153 | |
1154 // Check that the first init does not SetNeedsCommit. | |
1155 state.OnBeginImplFrame(); | |
1156 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1157 state.OnBeginImplFrameDeadline(); | |
1158 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1159 | |
1160 // Check that a needs commit initiates a BeginMainFrame. | |
1161 state.SetNeedsCommit(); | |
1162 state.OnBeginImplFrame(); | |
1163 EXPECT_ACTION_UPDATE_STATE( | |
1164 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1165 } | |
1166 | |
1167 TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) { | |
1168 SchedulerSettings default_scheduler_settings; | |
1169 StateMachine state(default_scheduler_settings); | |
1170 SET_UP_STATE(state) | |
1171 | |
1172 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, | |
1173 state.NextAction()); | |
1174 state.DidLoseOutputSurface(); | |
1175 | |
1176 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION); | |
1177 state.UpdateState(state.NextAction()); | |
1178 | |
1179 // Once context recreation begins, nothing should happen. | |
1180 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1181 | |
1182 // Recreate the context. | |
1183 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
1184 | |
1185 // When the context is recreated, we should begin a commit. | |
1186 state.OnBeginImplFrame(); | |
1187 EXPECT_ACTION_UPDATE_STATE( | |
1188 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1189 } | |
1190 | |
1191 TEST(SchedulerStateMachineTest, | |
1192 TestContextLostWhenIdleAndCommitRequestedWhileRecreating) { | |
1193 SchedulerSettings default_scheduler_settings; | |
1194 // We use impl side painting because it's the more complicated version. | |
1195 default_scheduler_settings.impl_side_painting = true; | |
1196 StateMachine state(default_scheduler_settings); | |
1197 SET_UP_STATE(state) | |
1198 | |
1199 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION, | |
1200 state.NextAction()); | |
1201 state.DidLoseOutputSurface(); | |
1202 EXPECT_EQ(state.output_surface_state(), | |
1203 SchedulerStateMachine::OUTPUT_SURFACE_LOST); | |
1204 | |
1205 EXPECT_ACTION_UPDATE_STATE( | |
1206 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION); | |
1207 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1208 | |
1209 // Once context recreation begins, nothing should happen. | |
1210 state.OnBeginImplFrame(); | |
1211 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1212 state.OnBeginImplFrameDeadline(); | |
1213 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1214 | |
1215 // While context is recreating, commits shouldn't begin. | |
1216 state.SetNeedsCommit(); | |
1217 state.OnBeginImplFrame(); | |
1218 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1219 state.OnBeginImplFrameDeadline(); | |
1220 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1221 | |
1222 // Recreate the context | |
1223 state.DidCreateAndInitializeOutputSurface(); | |
1224 EXPECT_EQ(state.output_surface_state(), | |
1225 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT); | |
1226 EXPECT_FALSE(state.RedrawPending()); | |
1227 | |
1228 // When the context is recreated, we wait until the next BeginImplFrame | |
1229 // before starting. | |
1230 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1231 | |
1232 // When the BeginFrame comes in we should begin a commit | |
1233 state.OnBeginImplFrame(); | |
1234 EXPECT_ACTION_UPDATE_STATE( | |
1235 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1236 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1237 EXPECT_COMMIT_STATE( | |
1238 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
1239 | |
1240 // Until that commit finishes, we shouldn't be drawing or animate. | |
1241 state.OnBeginImplFrameDeadline(); | |
1242 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1243 | |
1244 // Finish the commit, which should make the surface active. | |
1245 state.NotifyBeginMainFrameStarted(); | |
1246 state.NotifyReadyToCommit(); | |
1247 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
1248 EXPECT_EQ(state.output_surface_state(), | |
1249 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION); | |
1250 state.NotifyReadyToActivate(); | |
1251 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); | |
1252 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1253 EXPECT_EQ(state.output_surface_state(), | |
1254 SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE); | |
1255 | |
1256 // Finishing the first commit after initializing an output surface should | |
1257 // automatically cause a redraw. | |
1258 EXPECT_TRUE(state.RedrawPending()); | |
1259 state.OnBeginImplFrame(); | |
1260 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1261 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1262 state.OnBeginImplFrameDeadline(); | |
1263 EXPECT_ACTION_UPDATE_STATE( | |
1264 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1265 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1266 EXPECT_FALSE(state.RedrawPending()); | |
1267 | |
1268 // Next frame as no work to do. | |
1269 state.OnBeginImplFrame(); | |
1270 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1271 state.OnBeginImplFrameDeadline(); | |
1272 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1273 | |
1274 // Once the context is recreated, whether we draw should be based on | |
1275 // SetCanDraw if waiting on first draw after activate. | |
1276 state.SetNeedsRedraw(true); | |
1277 state.OnBeginImplFrame(); | |
1278 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1279 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1280 state.OnBeginImplFrameDeadline(); | |
1281 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1282 state.SetCanDraw(false); | |
1283 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1284 state.SetCanDraw(true); | |
1285 EXPECT_ACTION_UPDATE_STATE( | |
1286 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1287 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1288 | |
1289 // Once the context is recreated, whether we draw should be based on | |
1290 // SetCanDraw if waiting on first draw after activate. | |
1291 state.SetNeedsRedraw(true); | |
1292 state.SetNeedsCommit(); | |
1293 state.OnBeginImplFrame(); | |
1294 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1295 EXPECT_ACTION_UPDATE_STATE( | |
1296 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1297 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1298 // Activate so we need the first draw | |
1299 state.NotifyBeginMainFrameStarted(); | |
1300 state.NotifyReadyToCommit(); | |
1301 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
1302 state.NotifyReadyToActivate(); | |
1303 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); | |
1304 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1305 EXPECT_TRUE(state.active_tree_needs_first_draw()); | |
1306 EXPECT_TRUE(state.needs_redraw()); | |
1307 | |
1308 state.OnBeginImplFrameDeadline(); | |
1309 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1310 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1311 state.SetCanDraw(false); | |
1312 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); | |
1313 state.SetCanDraw(true); | |
1314 EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1315 } | |
1316 | |
1317 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) { | |
1318 SchedulerSettings scheduler_settings; | |
1319 StateMachine state(scheduler_settings); | |
1320 SET_UP_STATE(state) | |
1321 | |
1322 // Get a commit in flight. | |
1323 state.SetNeedsCommit(); | |
1324 | |
1325 // Set damage and expect a draw. | |
1326 state.SetNeedsRedraw(true); | |
1327 state.OnBeginImplFrame(); | |
1328 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1329 EXPECT_ACTION_UPDATE_STATE( | |
1330 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1331 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1332 state.OnBeginImplFrameDeadline(); | |
1333 EXPECT_ACTION_UPDATE_STATE( | |
1334 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1335 state.DidSwapBuffers(); | |
1336 state.DidSwapBuffersComplete(); | |
1337 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1338 | |
1339 // Cause a lost context while the BeginMainFrame is in flight. | |
1340 state.DidLoseOutputSurface(); | |
1341 | |
1342 // Ask for another draw. Expect nothing happens. | |
1343 state.SetNeedsRedraw(true); | |
1344 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1345 | |
1346 // Finish the frame, and commit. | |
1347 state.NotifyBeginMainFrameStarted(); | |
1348 state.NotifyReadyToCommit(); | |
1349 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
1350 | |
1351 // We will abort the draw when the output surface is lost if we are | |
1352 // waiting for the first draw to unblock the main thread. | |
1353 EXPECT_TRUE(state.active_tree_needs_first_draw()); | |
1354 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); | |
1355 | |
1356 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE | |
1357 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | |
1358 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION); | |
1359 | |
1360 state.OnBeginImplFrame(); | |
1361 EXPECT_IMPL_FRAME_STATE( | |
1362 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING); | |
1363 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1364 | |
1365 state.OnBeginImplFrameDeadlinePending(); | |
1366 EXPECT_IMPL_FRAME_STATE( | |
1367 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME); | |
1368 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1369 | |
1370 state.OnBeginImplFrameDeadline(); | |
1371 EXPECT_IMPL_FRAME_STATE( | |
1372 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); | |
1373 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1374 } | |
1375 | |
1376 TEST(SchedulerStateMachineTest, | |
1377 TestContextLostWhileCommitInProgressAndAnotherCommitRequested) { | |
1378 SchedulerSettings scheduler_settings; | |
1379 StateMachine state(scheduler_settings); | |
1380 SET_UP_STATE(state) | |
1381 | |
1382 // Get a commit in flight. | |
1383 state.SetNeedsCommit(); | |
1384 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1385 | |
1386 // Set damage and expect a draw. | |
1387 state.SetNeedsRedraw(true); | |
1388 state.OnBeginImplFrame(); | |
1389 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1390 EXPECT_ACTION_UPDATE_STATE( | |
1391 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1392 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1393 state.OnBeginImplFrameDeadline(); | |
1394 EXPECT_ACTION_UPDATE_STATE( | |
1395 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1396 state.DidSwapBuffers(); | |
1397 state.DidSwapBuffersComplete(); | |
1398 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1399 | |
1400 // Cause a lost context while the BeginMainFrame is in flight. | |
1401 state.DidLoseOutputSurface(); | |
1402 | |
1403 // Ask for another draw and also set needs commit. Expect nothing happens. | |
1404 state.SetNeedsRedraw(true); | |
1405 state.SetNeedsCommit(); | |
1406 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1407 | |
1408 // Finish the frame, and commit. | |
1409 state.NotifyBeginMainFrameStarted(); | |
1410 state.NotifyReadyToCommit(); | |
1411 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
1412 EXPECT_TRUE(state.active_tree_needs_first_draw()); | |
1413 | |
1414 // Because the output surface is missing, we expect the draw to abort. | |
1415 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); | |
1416 | |
1417 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE | |
1418 EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | |
1419 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION); | |
1420 | |
1421 state.OnBeginImplFrame(); | |
1422 EXPECT_IMPL_FRAME_STATE( | |
1423 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING); | |
1424 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1425 | |
1426 state.OnBeginImplFrameDeadlinePending(); | |
1427 EXPECT_IMPL_FRAME_STATE( | |
1428 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME); | |
1429 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1430 | |
1431 state.OnBeginImplFrameDeadline(); | |
1432 EXPECT_IMPL_FRAME_STATE( | |
1433 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); | |
1434 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1435 | |
1436 state.OnBeginImplFrameIdle(); | |
1437 EXPECT_ACTION_UPDATE_STATE( | |
1438 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION); | |
1439 | |
1440 // After we get a new output surface, the commit flow should start. | |
1441 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
1442 state.OnBeginImplFrame(); | |
1443 EXPECT_ACTION_UPDATE_STATE( | |
1444 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1445 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1446 state.NotifyBeginMainFrameStarted(); | |
1447 state.NotifyReadyToCommit(); | |
1448 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
1449 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1450 state.OnBeginImplFrameDeadline(); | |
1451 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1452 EXPECT_ACTION_UPDATE_STATE( | |
1453 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1454 state.DidSwapBuffers(); | |
1455 state.DidSwapBuffersComplete(); | |
1456 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1457 } | |
1458 | |
1459 TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) { | |
1460 SchedulerSettings default_scheduler_settings; | |
1461 StateMachine state(default_scheduler_settings); | |
1462 SET_UP_STATE(state) | |
1463 | |
1464 state.SetNeedsRedraw(true); | |
1465 | |
1466 // Cause a lost output surface, and restore it. | |
1467 state.DidLoseOutputSurface(); | |
1468 EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION); | |
1469 state.UpdateState(state.NextAction()); | |
1470 state.DidCreateAndInitializeOutputSurface(); | |
1471 | |
1472 EXPECT_FALSE(state.RedrawPending()); | |
1473 state.OnBeginImplFrame(); | |
1474 EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1475 } | |
1476 | |
1477 TEST(SchedulerStateMachineTest, | |
1478 TestPendingActivationsShouldBeForcedAfterLostOutputSurface) { | |
1479 SchedulerSettings settings; | |
1480 settings.impl_side_painting = true; | |
1481 StateMachine state(settings); | |
1482 SET_UP_STATE(state) | |
1483 | |
1484 state.SetCommitState( | |
1485 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
1486 | |
1487 // Cause a lost context. | |
1488 state.DidLoseOutputSurface(); | |
1489 | |
1490 state.NotifyBeginMainFrameStarted(); | |
1491 state.NotifyReadyToCommit(); | |
1492 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
1493 | |
1494 EXPECT_TRUE(state.PendingActivationsShouldBeForced()); | |
1495 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); | |
1496 | |
1497 EXPECT_TRUE(state.PendingDrawsShouldBeAborted()); | |
1498 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); | |
1499 } | |
1500 | |
1501 TEST(SchedulerStateMachineTest, TestNoBeginMainFrameWhenInvisible) { | |
1502 SchedulerSettings default_scheduler_settings; | |
1503 StateMachine state(default_scheduler_settings); | |
1504 state.SetCanStart(); | |
1505 state.UpdateState(state.NextAction()); | |
1506 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
1507 state.SetVisible(false); | |
1508 state.SetNeedsCommit(); | |
1509 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1510 } | |
1511 | |
1512 TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) { | |
1513 SchedulerSettings default_scheduler_settings; | |
1514 StateMachine state(default_scheduler_settings); | |
1515 state.SetCanStart(); | |
1516 state.UpdateState(state.NextAction()); | |
1517 state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); | |
1518 state.SetVisible(false); | |
1519 state.SetCommitState( | |
1520 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | |
1521 state.SetNeedsCommit(); | |
1522 | |
1523 state.NotifyBeginMainFrameStarted(); | |
1524 state.NotifyReadyToCommit(); | |
1525 EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT); | |
1526 state.UpdateState(state.NextAction()); | |
1527 | |
1528 EXPECT_TRUE(state.active_tree_needs_first_draw()); | |
1529 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); | |
1530 } | |
1531 | |
1532 TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) { | |
1533 SchedulerSettings default_scheduler_settings; | |
1534 StateMachine state(default_scheduler_settings); | |
1535 SET_UP_STATE(state) | |
1536 state.SetNeedsCommit(); | |
1537 state.DidLoseOutputSurface(); | |
1538 | |
1539 // When we are visible, we normally want to begin output surface creation | |
1540 // as soon as possible. | |
1541 EXPECT_ACTION_UPDATE_STATE( | |
1542 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION); | |
1543 | |
1544 state.DidCreateAndInitializeOutputSurface(); | |
1545 EXPECT_EQ(state.output_surface_state(), | |
1546 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT); | |
1547 | |
1548 // We should not send a BeginMainFrame when we are invisible, even if we've | |
1549 // lost the output surface and are trying to get the first commit, since the | |
1550 // main thread will just abort anyway. | |
1551 state.SetVisible(false); | |
1552 EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); | |
1553 } | |
1554 | |
1555 TEST(SchedulerStateMachineTest, ReportIfNotDrawing) { | |
1556 SchedulerSettings default_scheduler_settings; | |
1557 StateMachine state(default_scheduler_settings); | |
1558 SET_UP_STATE(state) | |
1559 EXPECT_FALSE(state.PendingDrawsShouldBeAborted()); | |
1560 | |
1561 state.SetCanDraw(false); | |
1562 state.SetVisible(true); | |
1563 EXPECT_TRUE(state.PendingDrawsShouldBeAborted()); | |
1564 | |
1565 state.SetCanDraw(true); | |
1566 state.SetVisible(false); | |
1567 EXPECT_TRUE(state.PendingDrawsShouldBeAborted()); | |
1568 | |
1569 state.SetCanDraw(false); | |
1570 state.SetVisible(false); | |
1571 EXPECT_TRUE(state.PendingDrawsShouldBeAborted()); | |
1572 | |
1573 state.SetCanDraw(true); | |
1574 state.SetVisible(true); | |
1575 EXPECT_FALSE(state.PendingDrawsShouldBeAborted()); | |
1576 } | |
1577 | |
1578 TEST(SchedulerStateMachineTest, | |
1579 TestTriggerDeadlineImmediatelyAfterAbortedCommit) { | |
1580 SchedulerSettings settings; | |
1581 settings.impl_side_painting = true; | |
1582 StateMachine state(settings); | |
1583 SET_UP_STATE(state) | |
1584 | |
1585 // This test mirrors what happens during the first frame of a scroll gesture. | |
1586 // First we get the input event and a BeginFrame. | |
1587 state.OnBeginImplFrame(); | |
1588 | |
1589 // As a response the compositor requests a redraw and a commit to tell the | |
1590 // main thread about the new scroll offset. | |
1591 state.SetNeedsRedraw(true); | |
1592 state.SetNeedsCommit(); | |
1593 | |
1594 // We should start the commit normally. | |
1595 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1596 EXPECT_ACTION_UPDATE_STATE( | |
1597 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1598 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1599 | |
1600 // Since only the scroll offset changed, the main thread will abort the | |
1601 // commit. | |
1602 state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES); | |
1603 | |
1604 // Since the commit was aborted, we should draw right away instead of waiting | |
1605 // for the deadline. | |
1606 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately()); | |
1607 } | |
1608 | |
1609 void FinishPreviousCommitAndDrawWithoutExitingDeadline( | |
1610 StateMachine* state_ptr) { | |
1611 // Gross, but allows us to use macros below. | |
1612 StateMachine& state = *state_ptr; | |
1613 | |
1614 state.NotifyBeginMainFrameStarted(); | |
1615 state.NotifyReadyToCommit(); | |
1616 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
1617 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1618 state.NotifyReadyToActivate(); | |
1619 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); | |
1620 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1621 | |
1622 state.OnBeginImplFrame(); | |
1623 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1624 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1625 | |
1626 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately()); | |
1627 state.OnBeginImplFrameDeadline(); | |
1628 EXPECT_ACTION_UPDATE_STATE( | |
1629 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1630 state.DidSwapBuffers(); | |
1631 } | |
1632 | |
1633 TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) { | |
1634 SchedulerSettings settings; | |
1635 settings.impl_side_painting = true; | |
1636 StateMachine state(settings); | |
1637 SET_UP_STATE(state) | |
1638 | |
1639 // This test ensures that impl-draws are prioritized over main thread updates | |
1640 // in prefer impl latency mode. | |
1641 state.SetNeedsRedraw(true); | |
1642 state.SetNeedsCommit(); | |
1643 state.OnBeginImplFrame(); | |
1644 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1645 EXPECT_ACTION_UPDATE_STATE( | |
1646 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1647 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1648 | |
1649 // Verify the deadline is not triggered early until we enter | |
1650 // prefer impl latency mode. | |
1651 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately()); | |
1652 state.SetImplLatencyTakesPriority(true); | |
1653 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately()); | |
1654 | |
1655 // Trigger the deadline. | |
1656 state.OnBeginImplFrameDeadline(); | |
1657 EXPECT_ACTION_UPDATE_STATE( | |
1658 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1659 state.DidSwapBuffers(); | |
1660 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1661 state.DidSwapBuffersComplete(); | |
1662 | |
1663 // Request a new commit and finish the previous one. | |
1664 state.SetNeedsCommit(); | |
1665 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state); | |
1666 EXPECT_ACTION_UPDATE_STATE( | |
1667 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1668 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1669 state.DidSwapBuffersComplete(); | |
1670 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1671 | |
1672 // Finish the previous commit and draw it. | |
1673 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state); | |
1674 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1675 | |
1676 // Verify we do not send another BeginMainFrame if was are swap throttled | |
1677 // and did not just swap. | |
1678 state.SetNeedsCommit(); | |
1679 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1680 state.OnBeginImplFrame(); | |
1681 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1682 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately()); | |
1683 state.OnBeginImplFrameDeadline(); | |
1684 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1685 } | |
1686 | |
1687 TEST(SchedulerStateMachineTest, | |
1688 TestTriggerDeadlineImmediatelyOnLostOutputSurface) { | |
1689 SchedulerSettings default_scheduler_settings; | |
1690 StateMachine state(default_scheduler_settings); | |
1691 SET_UP_STATE(state) | |
1692 | |
1693 state.SetNeedsCommit(); | |
1694 | |
1695 state.OnBeginImplFrame(); | |
1696 EXPECT_ACTION_UPDATE_STATE( | |
1697 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1698 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1699 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately()); | |
1700 | |
1701 state.DidLoseOutputSurface(); | |
1702 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1703 // The deadline should be triggered immediately when output surface is lost. | |
1704 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately()); | |
1705 } | |
1706 | |
1707 TEST(SchedulerStateMachineTest, TestSetNeedsAnimate) { | |
1708 SchedulerSettings settings; | |
1709 settings.impl_side_painting = true; | |
1710 StateMachine state(settings); | |
1711 SET_UP_STATE(state) | |
1712 | |
1713 // Test requesting an animation that, when run, causes us to draw. | |
1714 state.SetNeedsAnimate(); | |
1715 EXPECT_TRUE(state.BeginFrameNeeded()); | |
1716 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1717 | |
1718 state.OnBeginImplFrame(); | |
1719 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1720 | |
1721 state.OnBeginImplFrameDeadlinePending(); | |
1722 state.OnBeginImplFrameDeadline(); | |
1723 EXPECT_ACTION_UPDATE_STATE( | |
1724 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1725 } | |
1726 | |
1727 TEST(SchedulerStateMachineTest, TestAnimateBeforeCommit) { | |
1728 SchedulerSettings settings; | |
1729 settings.impl_side_painting = true; | |
1730 StateMachine state(settings); | |
1731 SET_UP_STATE(state) | |
1732 | |
1733 // Check that animations are updated before we start a commit. | |
1734 state.SetNeedsAnimate(); | |
1735 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1736 state.SetNeedsCommit(); | |
1737 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1738 EXPECT_TRUE(state.BeginFrameNeeded()); | |
1739 | |
1740 state.OnBeginImplFrame(); | |
1741 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1742 EXPECT_ACTION_UPDATE_STATE( | |
1743 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1744 | |
1745 state.OnBeginImplFrameDeadlinePending(); | |
1746 state.OnBeginImplFrameDeadline(); | |
1747 EXPECT_ACTION_UPDATE_STATE( | |
1748 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1749 } | |
1750 | |
1751 TEST(SchedulerStateMachineTest, TestAnimateAfterCommitBeforeDraw) { | |
1752 SchedulerSettings settings; | |
1753 settings.impl_side_painting = true; | |
1754 StateMachine state(settings); | |
1755 SET_UP_STATE(state) | |
1756 | |
1757 // Check that animations are updated before we start a commit. | |
1758 state.SetNeedsAnimate(); | |
1759 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1760 state.SetNeedsCommit(); | |
1761 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1762 EXPECT_TRUE(state.BeginFrameNeeded()); | |
1763 | |
1764 state.OnBeginImplFrame(); | |
1765 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1766 EXPECT_ACTION_UPDATE_STATE( | |
1767 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1768 | |
1769 state.NotifyBeginMainFrameStarted(); | |
1770 state.NotifyReadyToCommit(); | |
1771 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); | |
1772 | |
1773 state.OnBeginImplFrameDeadlinePending(); | |
1774 state.OnBeginImplFrameDeadline(); | |
1775 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1776 EXPECT_ACTION_UPDATE_STATE( | |
1777 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1778 } | |
1779 | |
1780 TEST(SchedulerStateMachineTest, TestSetNeedsAnimateAfterAnimate) { | |
1781 SchedulerSettings settings; | |
1782 settings.impl_side_painting = true; | |
1783 StateMachine state(settings); | |
1784 SET_UP_STATE(state) | |
1785 | |
1786 // Test requesting an animation after we have already animated during this | |
1787 // frame. | |
1788 state.SetNeedsRedraw(true); | |
1789 EXPECT_TRUE(state.BeginFrameNeeded()); | |
1790 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1791 | |
1792 state.OnBeginImplFrame(); | |
1793 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE); | |
1794 | |
1795 state.SetNeedsAnimate(); | |
1796 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1797 | |
1798 state.OnBeginImplFrameDeadline(); | |
1799 EXPECT_ACTION_UPDATE_STATE( | |
1800 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); | |
1801 } | |
1802 | |
1803 TEST(SchedulerStateMachineTest, TestForwardBeginFramesToChildren) { | |
1804 SchedulerSettings settings; | |
1805 StateMachine state(settings); | |
1806 SET_UP_STATE(state) | |
1807 | |
1808 EXPECT_FALSE(state.BeginFrameNeeded()); | |
1809 state.SetChildrenNeedBeginFrames(true); | |
1810 EXPECT_TRUE(state.BeginFrameNeeded()); | |
1811 } | |
1812 | |
1813 TEST(SchedulerStateMachineTest, TestDeferCommit) { | |
1814 SchedulerSettings settings; | |
1815 StateMachine state(settings); | |
1816 SET_UP_STATE(state) | |
1817 | |
1818 state.SetDeferCommits(true); | |
1819 | |
1820 state.SetNeedsCommit(); | |
1821 EXPECT_TRUE(state.BeginFrameNeeded()); | |
1822 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1823 | |
1824 state.OnBeginImplFrame(); | |
1825 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1826 | |
1827 state.OnBeginImplFrameDeadline(); | |
1828 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); | |
1829 | |
1830 state.SetDeferCommits(false); | |
1831 state.OnBeginImplFrame(); | |
1832 EXPECT_ACTION_UPDATE_STATE( | |
1833 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); | |
1834 } | |
1835 | |
1836 TEST(SchedulerStateMachineTest, EarlyOutCommitWantsProactiveBeginFrame) { | |
1837 SchedulerSettings settings; | |
1838 StateMachine state(settings); | |
1839 SET_UP_STATE(state); | |
1840 | |
1841 EXPECT_FALSE(state.ProactiveBeginFrameWanted()); | |
1842 bool commit_has_no_updates = true; | |
1843 state.UpdateStateOnCommit(commit_has_no_updates); | |
1844 EXPECT_TRUE(state.ProactiveBeginFrameWanted()); | |
1845 state.OnBeginImplFrame(); | |
1846 EXPECT_FALSE(state.ProactiveBeginFrameWanted()); | |
1847 } | |
1848 | |
1849 } // namespace | |
1850 } // namespace cc | |
OLD | NEW |