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.
5 #include "cc/scheduler/scheduler.h"
10 #include "base/logging.h"
11 #include "cc/test/scheduler_test_common.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \
16 EXPECT_EQ(expected_num_actions, client.num_actions_()); \
17 ASSERT_LT(action_index, client.num_actions_()); \
19 EXPECT_STREQ(action, client.Action(action_index)); \
20 for (int i = expected_num_actions; i < client.num_actions_(); ++i) \
21 ADD_FAILURE() << "Unexpected action: " << client.Action(i) << \
22 " with state:\n" << client.StateForAction(action_index); \
25 #define EXPECT_SINGLE_ACTION(action, client) \
26 EXPECT_ACTION(action, client, 0, 1)
31 class FakeSchedulerClient
: public SchedulerClient
{
34 : needs_begin_frame_(false) {
41 draw_will_happen_
= true;
42 swap_will_happen_if_draw_happens_
= true;
46 Scheduler
* CreateScheduler(const SchedulerSettings
& settings
) {
47 scheduler_
= Scheduler::Create(this, settings
);
48 return scheduler_
.get();
51 bool needs_begin_frame() { return needs_begin_frame_
; }
52 int num_draws() const { return num_draws_
; }
53 int num_actions_() const { return static_cast<int>(actions_
.size()); }
54 const char* Action(int i
) const { return actions_
[i
]; }
55 std::string
StateForAction(int i
) const { return states_
[i
]; }
57 bool HasAction(const char* action
) const {
58 for (size_t i
= 0; i
< actions_
.size(); i
++)
59 if (!strcmp(actions_
[i
], action
))
64 void SetDrawWillHappen(bool draw_will_happen
) {
65 draw_will_happen_
= draw_will_happen
;
67 void SetSwapWillHappenIfDrawHappens(bool swap_will_happen_if_draw_happens
) {
68 swap_will_happen_if_draw_happens_
= swap_will_happen_if_draw_happens
;
71 // Scheduler Implementation.
72 virtual void SetNeedsBeginFrameOnImplThread(bool enable
) OVERRIDE
{
73 actions_
.push_back("SetNeedsBeginFrameOnImplThread");
74 states_
.push_back(scheduler_
->StateAsStringForTesting());
75 needs_begin_frame_
= enable
;
77 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE
{
78 actions_
.push_back("ScheduledActionSendBeginFrameToMainThread");
79 states_
.push_back(scheduler_
->StateAsStringForTesting());
81 virtual ScheduledActionDrawAndSwapResult
82 ScheduledActionDrawAndSwapIfPossible() OVERRIDE
{
83 actions_
.push_back("ScheduledActionDrawAndSwapIfPossible");
84 states_
.push_back(scheduler_
->StateAsStringForTesting());
86 return ScheduledActionDrawAndSwapResult(draw_will_happen_
,
88 swap_will_happen_if_draw_happens_
);
90 virtual ScheduledActionDrawAndSwapResult
ScheduledActionDrawAndSwapForced()
92 actions_
.push_back("ScheduledActionDrawAndSwapForced");
93 states_
.push_back(scheduler_
->StateAsStringForTesting());
94 return ScheduledActionDrawAndSwapResult(true,
95 swap_will_happen_if_draw_happens_
);
97 virtual void ScheduledActionCommit() OVERRIDE
{
98 actions_
.push_back("ScheduledActionCommit");
99 states_
.push_back(scheduler_
->StateAsStringForTesting());
101 virtual void ScheduledActionCheckForCompletedTileUploads() OVERRIDE
{
102 actions_
.push_back("ScheduledActionCheckForCompletedTileUploads");
103 states_
.push_back(scheduler_
->StateAsStringForTesting());
105 virtual void ScheduledActionActivatePendingTreeIfNeeded() OVERRIDE
{
106 actions_
.push_back("ScheduledActionActivatePendingTreeIfNeeded");
107 states_
.push_back(scheduler_
->StateAsStringForTesting());
109 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE
{
110 actions_
.push_back("ScheduledActionBeginOutputSurfaceCreation");
111 states_
.push_back(scheduler_
->StateAsStringForTesting());
113 virtual void ScheduledActionAcquireLayerTexturesForMainThread() OVERRIDE
{
114 actions_
.push_back("ScheduledActionAcquireLayerTexturesForMainThread");
115 states_
.push_back(scheduler_
->StateAsStringForTesting());
117 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks
) OVERRIDE
{}
118 virtual base::TimeDelta
DrawDurationEstimate() OVERRIDE
{
119 return base::TimeDelta();
123 bool needs_begin_frame_
;
124 bool draw_will_happen_
;
125 bool swap_will_happen_if_draw_happens_
;
127 std::vector
<const char*> actions_
;
128 std::vector
<std::string
> states_
;
129 scoped_ptr
<Scheduler
> scheduler_
;
132 TEST(SchedulerTest
, InitializeOutputSurfaceDoesNotBeginFrame
) {
133 FakeSchedulerClient client
;
134 SchedulerSettings default_scheduler_settings
;
135 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
136 scheduler
->SetCanStart();
137 scheduler
->SetVisible(true);
138 scheduler
->SetCanDraw(true);
140 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
142 scheduler
->DidCreateAndInitializeOutputSurface();
143 EXPECT_EQ(0, client
.num_actions_());
146 TEST(SchedulerTest
, RequestCommit
) {
147 FakeSchedulerClient client
;
148 SchedulerSettings default_scheduler_settings
;
149 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
150 scheduler
->SetCanStart();
151 scheduler
->SetVisible(true);
152 scheduler
->SetCanDraw(true);
154 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
156 scheduler
->DidCreateAndInitializeOutputSurface();
158 // SetNeedsCommit should begin the frame.
159 scheduler
->SetNeedsCommit();
160 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client
, 0, 2);
161 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client
, 1, 2);
162 EXPECT_TRUE(client
.needs_begin_frame());
165 // FinishCommit should commit
166 scheduler
->FinishCommit();
167 EXPECT_ACTION("ScheduledActionCommit", client
, 0, 2);
168 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client
, 1, 2);
169 EXPECT_TRUE(client
.needs_begin_frame());
172 // BeginFrame should draw.
173 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
174 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 0, 2);
175 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client
, 1, 2);
176 EXPECT_FALSE(client
.needs_begin_frame());
180 TEST(SchedulerTest
, RequestCommitAfterBeginFrameSentToMainThread
) {
181 FakeSchedulerClient client
;
182 SchedulerSettings default_scheduler_settings
;
183 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
184 scheduler
->SetCanStart();
185 scheduler
->SetVisible(true);
186 scheduler
->SetCanDraw(true);
188 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
190 scheduler
->DidCreateAndInitializeOutputSurface();
192 // SetNedsCommit should begin the frame.
193 scheduler
->SetNeedsCommit();
194 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client
, 0, 2);
195 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client
, 1, 2);
198 // Now SetNeedsCommit again. Calling here means we need a second frame.
199 scheduler
->SetNeedsCommit();
200 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client
, 0, 1);
203 // Since another commit is needed, FinishCommit should commit,
204 // then begin another frame.
205 scheduler
->FinishCommit();
206 EXPECT_ACTION("ScheduledActionCommit", client
, 0, 2);
207 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client
, 1, 2);
210 // Tick should draw but then begin another frame.
211 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
212 EXPECT_TRUE(client
.needs_begin_frame());
213 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 0, 2);
214 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client
, 1, 2);
217 // Go back to quiescent state and verify we no longer request BeginFrames.
218 scheduler
->FinishCommit();
219 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
220 EXPECT_FALSE(client
.needs_begin_frame());
223 TEST(SchedulerTest
, TextureAcquisitionCausesCommitInsteadOfDraw
) {
224 FakeSchedulerClient client
;
225 SchedulerSettings default_scheduler_settings
;
226 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
227 scheduler
->SetCanStart();
228 scheduler
->SetVisible(true);
229 scheduler
->SetCanDraw(true);
230 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
233 scheduler
->DidCreateAndInitializeOutputSurface();
234 scheduler
->SetNeedsRedraw();
235 EXPECT_TRUE(scheduler
->RedrawPending());
236 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client
);
237 EXPECT_TRUE(client
.needs_begin_frame());
240 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
241 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 0, 2);
242 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client
, 1, 2);
243 EXPECT_FALSE(scheduler
->RedrawPending());
244 EXPECT_FALSE(client
.needs_begin_frame());
247 scheduler
->SetMainThreadNeedsLayerTextures();
248 EXPECT_ACTION("ScheduledActionAcquireLayerTexturesForMainThread",
252 // A commit was started by SetMainThreadNeedsLayerTextures().
253 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client
, 1, 3);
254 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client
, 2, 3);
256 // We should request a BeginFrame in anticipation of a draw.
258 scheduler
->SetNeedsRedraw();
259 EXPECT_TRUE(scheduler
->RedrawPending());
260 EXPECT_TRUE(client
.needs_begin_frame());
262 // No draw happens since the textures are acquired by the main thread.
264 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
265 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client
);
266 EXPECT_TRUE(scheduler
->RedrawPending());
267 EXPECT_TRUE(client
.needs_begin_frame());
269 // Commit will release the texture.
271 scheduler
->FinishCommit();
272 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client
);
273 EXPECT_TRUE(scheduler
->RedrawPending());
274 EXPECT_TRUE(client
.needs_begin_frame());
276 // Now we can draw again after the commit happens.
278 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
279 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 0, 2);
280 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client
, 1, 2);
281 EXPECT_FALSE(scheduler
->RedrawPending());
282 EXPECT_FALSE(client
.needs_begin_frame());
286 TEST(SchedulerTest
, TextureAcquisitionCollision
) {
287 FakeSchedulerClient client
;
288 SchedulerSettings default_scheduler_settings
;
289 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
290 scheduler
->SetCanStart();
291 scheduler
->SetVisible(true);
292 scheduler
->SetCanDraw(true);
294 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
296 scheduler
->DidCreateAndInitializeOutputSurface();
298 scheduler
->SetNeedsCommit();
299 scheduler
->SetMainThreadNeedsLayerTextures();
300 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client
, 0, 4);
301 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client
, 1, 4);
302 EXPECT_ACTION("ScheduledActionAcquireLayerTexturesForMainThread",
306 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client
, 3, 4);
309 // Although the compositor cannot draw because textures are locked by main
310 // thread, we continue requesting SetNeedsBeginFrame in anticipation of the
312 EXPECT_TRUE(client
.needs_begin_frame());
314 // Trigger the commit
315 scheduler
->FinishCommit();
316 EXPECT_TRUE(client
.needs_begin_frame());
319 // Between commit and draw, texture acquisition for main thread delayed,
320 // and main thread blocks.
321 scheduler
->SetMainThreadNeedsLayerTextures();
322 EXPECT_EQ(0, client
.num_actions_());
325 // Once compositor draw complete, the delayed texture acquisition fires.
326 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
327 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client
, 0, 3);
328 EXPECT_ACTION("ScheduledActionAcquireLayerTexturesForMainThread",
332 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client
, 2, 3);
336 TEST(SchedulerTest
, VisibilitySwitchWithTextureAcquisition
) {
337 FakeSchedulerClient client
;
338 SchedulerSettings default_scheduler_settings
;
339 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
340 scheduler
->SetCanStart();
341 scheduler
->SetVisible(true);
342 scheduler
->SetCanDraw(true);
344 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client
);
346 scheduler
->DidCreateAndInitializeOutputSurface();
348 scheduler
->SetNeedsCommit();
349 scheduler
->FinishCommit();
350 scheduler
->SetMainThreadNeedsLayerTextures();
352 // Verify that pending texture acquisition fires when visibility
353 // is lost in order to avoid a deadlock.
354 scheduler
->SetVisible(false);
355 EXPECT_SINGLE_ACTION("ScheduledActionAcquireLayerTexturesForMainThread",
359 // Regaining visibility with textures acquired by main thread while
360 // compositor is waiting for first draw should result in a request
361 // for a new frame in order to escape a deadlock.
362 scheduler
->SetVisible(true);
363 EXPECT_SINGLE_ACTION("ScheduledActionSendBeginFrameToMainThread", client
);
367 class SchedulerClientThatsetNeedsDrawInsideDraw
: public FakeSchedulerClient
{
369 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE
{}
370 virtual ScheduledActionDrawAndSwapResult
371 ScheduledActionDrawAndSwapIfPossible() OVERRIDE
{
372 // Only SetNeedsRedraw the first time this is called
374 scheduler_
->SetNeedsRedraw();
375 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
378 virtual ScheduledActionDrawAndSwapResult
ScheduledActionDrawAndSwapForced()
381 return ScheduledActionDrawAndSwapResult(true, true);
384 virtual void ScheduledActionCommit() OVERRIDE
{}
385 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE
{}
386 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks
) OVERRIDE
{}
389 // Tests for two different situations:
390 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside
391 // a ScheduledActionDrawAndSwap
392 // 2. the scheduler drawing twice inside a single tick
393 TEST(SchedulerTest
, RequestRedrawInsideDraw
) {
394 SchedulerClientThatsetNeedsDrawInsideDraw client
;
395 SchedulerSettings default_scheduler_settings
;
396 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
397 scheduler
->SetCanStart();
398 scheduler
->SetVisible(true);
399 scheduler
->SetCanDraw(true);
400 scheduler
->DidCreateAndInitializeOutputSurface();
402 scheduler
->SetNeedsRedraw();
403 EXPECT_TRUE(scheduler
->RedrawPending());
404 EXPECT_TRUE(client
.needs_begin_frame());
405 EXPECT_EQ(0, client
.num_draws());
407 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
408 EXPECT_EQ(1, client
.num_draws());
409 EXPECT_TRUE(scheduler
->RedrawPending());
410 EXPECT_TRUE(client
.needs_begin_frame());
412 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
413 EXPECT_EQ(2, client
.num_draws());
414 EXPECT_FALSE(scheduler
->RedrawPending());
415 EXPECT_FALSE(client
.needs_begin_frame());
418 // Test that requesting redraw inside a failed draw doesn't lose the request.
419 TEST(SchedulerTest
, RequestRedrawInsideFailedDraw
) {
420 SchedulerClientThatsetNeedsDrawInsideDraw client
;
421 SchedulerSettings default_scheduler_settings
;
422 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
423 scheduler
->SetCanStart();
424 scheduler
->SetVisible(true);
425 scheduler
->SetCanDraw(true);
426 scheduler
->DidCreateAndInitializeOutputSurface();
428 client
.SetDrawWillHappen(false);
430 scheduler
->SetNeedsRedraw();
431 EXPECT_TRUE(scheduler
->RedrawPending());
432 EXPECT_TRUE(client
.needs_begin_frame());
433 EXPECT_EQ(0, client
.num_draws());
436 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
437 EXPECT_EQ(1, client
.num_draws());
439 // We have a commit pending and the draw failed, and we didn't lose the redraw
441 EXPECT_TRUE(scheduler
->CommitPending());
442 EXPECT_TRUE(scheduler
->RedrawPending());
443 EXPECT_TRUE(client
.needs_begin_frame());
445 // Fail the draw again.
446 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
447 EXPECT_EQ(2, client
.num_draws());
448 EXPECT_TRUE(scheduler
->CommitPending());
449 EXPECT_TRUE(scheduler
->RedrawPending());
450 EXPECT_TRUE(client
.needs_begin_frame());
452 // Draw successfully.
453 client
.SetDrawWillHappen(true);
454 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
455 EXPECT_EQ(3, client
.num_draws());
456 EXPECT_TRUE(scheduler
->CommitPending());
457 EXPECT_FALSE(scheduler
->RedrawPending());
458 EXPECT_TRUE(client
.needs_begin_frame());
461 class SchedulerClientThatsetNeedsCommitInsideDraw
: public FakeSchedulerClient
{
463 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE
{}
464 virtual ScheduledActionDrawAndSwapResult
465 ScheduledActionDrawAndSwapIfPossible() OVERRIDE
{
466 // Only SetNeedsCommit the first time this is called
468 scheduler_
->SetNeedsCommit();
469 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
472 virtual ScheduledActionDrawAndSwapResult
ScheduledActionDrawAndSwapForced()
475 return ScheduledActionDrawAndSwapResult(true, true);
478 virtual void ScheduledActionCommit() OVERRIDE
{}
479 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE
{}
480 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks
) OVERRIDE
{}
483 // Tests for the scheduler infinite-looping on SetNeedsCommit requests that
484 // happen inside a ScheduledActionDrawAndSwap
485 TEST(SchedulerTest
, RequestCommitInsideDraw
) {
486 SchedulerClientThatsetNeedsCommitInsideDraw client
;
487 SchedulerSettings default_scheduler_settings
;
488 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
489 scheduler
->SetCanStart();
490 scheduler
->SetVisible(true);
491 scheduler
->SetCanDraw(true);
492 scheduler
->DidCreateAndInitializeOutputSurface();
494 scheduler
->SetNeedsRedraw();
495 EXPECT_TRUE(scheduler
->RedrawPending());
496 EXPECT_EQ(0, client
.num_draws());
497 EXPECT_TRUE(client
.needs_begin_frame());
499 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
500 EXPECT_EQ(1, client
.num_draws());
501 EXPECT_TRUE(scheduler
->CommitPending());
502 EXPECT_TRUE(client
.needs_begin_frame());
503 scheduler
->FinishCommit();
505 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
506 EXPECT_EQ(2, client
.num_draws());;
507 EXPECT_FALSE(scheduler
->RedrawPending());
508 EXPECT_FALSE(scheduler
->CommitPending());
509 EXPECT_FALSE(client
.needs_begin_frame());
512 // Tests that when a draw fails then the pending commit should not be dropped.
513 TEST(SchedulerTest
, RequestCommitInsideFailedDraw
) {
514 SchedulerClientThatsetNeedsDrawInsideDraw client
;
515 SchedulerSettings default_scheduler_settings
;
516 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
517 scheduler
->SetCanStart();
518 scheduler
->SetVisible(true);
519 scheduler
->SetCanDraw(true);
520 scheduler
->DidCreateAndInitializeOutputSurface();
522 client
.SetDrawWillHappen(false);
524 scheduler
->SetNeedsRedraw();
525 EXPECT_TRUE(scheduler
->RedrawPending());
526 EXPECT_TRUE(client
.needs_begin_frame());
527 EXPECT_EQ(0, client
.num_draws());
530 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
531 EXPECT_EQ(1, client
.num_draws());
533 // We have a commit pending and the draw failed, and we didn't lose the commit
535 EXPECT_TRUE(scheduler
->CommitPending());
536 EXPECT_TRUE(scheduler
->RedrawPending());
537 EXPECT_TRUE(client
.needs_begin_frame());
539 // Fail the draw again.
540 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
541 EXPECT_EQ(2, client
.num_draws());
542 EXPECT_TRUE(scheduler
->CommitPending());
543 EXPECT_TRUE(scheduler
->RedrawPending());
544 EXPECT_TRUE(client
.needs_begin_frame());
546 // Draw successfully.
547 client
.SetDrawWillHappen(true);
548 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
549 EXPECT_EQ(3, client
.num_draws());
550 EXPECT_TRUE(scheduler
->CommitPending());
551 EXPECT_FALSE(scheduler
->RedrawPending());
552 EXPECT_TRUE(client
.needs_begin_frame());
555 TEST(SchedulerTest
, NoSwapWhenDrawFails
) {
556 SchedulerClientThatsetNeedsCommitInsideDraw client
;
557 SchedulerSettings default_scheduler_settings
;
558 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
559 scheduler
->SetCanStart();
560 scheduler
->SetVisible(true);
561 scheduler
->SetCanDraw(true);
562 scheduler
->DidCreateAndInitializeOutputSurface();
564 scheduler
->SetNeedsRedraw();
565 EXPECT_TRUE(scheduler
->RedrawPending());
566 EXPECT_TRUE(client
.needs_begin_frame());
567 EXPECT_EQ(0, client
.num_draws());
569 // Draw successfully, this starts a new frame.
570 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
571 EXPECT_EQ(1, client
.num_draws());
573 scheduler
->SetNeedsRedraw();
574 EXPECT_TRUE(scheduler
->RedrawPending());
575 EXPECT_TRUE(client
.needs_begin_frame());
577 // Fail to draw, this should not start a frame.
578 client
.SetDrawWillHappen(false);
579 scheduler
->BeginFrame(BeginFrameArgs::CreateForTesting());
580 EXPECT_EQ(2, client
.num_draws());
583 TEST(SchedulerTest
, NoSwapWhenSwapFailsDuringForcedCommit
) {
584 FakeSchedulerClient client
;
585 SchedulerSettings default_scheduler_settings
;
586 Scheduler
* scheduler
= client
.CreateScheduler(default_scheduler_settings
);
588 // Tell the client that it will fail to swap.
589 client
.SetDrawWillHappen(true);
590 client
.SetSwapWillHappenIfDrawHappens(false);
592 // Get the compositor to do a ScheduledActionDrawAndSwapForced.
593 scheduler
->SetCanDraw(true);
594 scheduler
->SetNeedsRedraw();
595 scheduler
->SetNeedsForcedRedraw();
596 EXPECT_TRUE(client
.HasAction("ScheduledActionDrawAndSwapForced"));