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

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

Issue 1133673004: cc: Heuristic for Renderer latency recovery (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Better names and durations Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/scheduler/scheduler.h" 5 #include "cc/scheduler/scheduler.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 scoped_ptr<FakeCompositorTimingHistory> fake_compositor_timing_history = 239 scoped_ptr<FakeCompositorTimingHistory> fake_compositor_timing_history =
240 FakeCompositorTimingHistory::Create(); 240 FakeCompositorTimingHistory::Create();
241 fake_compositor_timing_history_ = fake_compositor_timing_history.get(); 241 fake_compositor_timing_history_ = fake_compositor_timing_history.get();
242 242
243 scheduler_ = TestScheduler::Create( 243 scheduler_ = TestScheduler::Create(
244 now_src_.get(), client_.get(), scheduler_settings_, 0, 244 now_src_.get(), client_.get(), scheduler_settings_, 0,
245 task_runner_.get(), fake_external_begin_frame_source_.get(), 245 task_runner_.get(), fake_external_begin_frame_source_.get(),
246 fake_compositor_timing_history.Pass()); 246 fake_compositor_timing_history.Pass());
247 DCHECK(scheduler_); 247 DCHECK(scheduler_);
248 client_->set_scheduler(scheduler_.get()); 248 client_->set_scheduler(scheduler_.get());
249
250 // Use large estimates by default to avoid latency recovery
251 // in most tests.
252 base::TimeDelta one_second = base::TimeDelta::FromSeconds(1);
253 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
254 one_second);
255 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
256 one_second);
257 fake_compositor_timing_history_->SetDrawDurationEstimate(one_second);
258
249 return scheduler_.get(); 259 return scheduler_.get();
250 } 260 }
251 261
252 void CreateSchedulerAndInitSurface() { 262 void CreateSchedulerAndInitSurface() {
253 CreateScheduler(); 263 CreateScheduler();
254 EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit()); 264 EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit());
255 } 265 }
256 266
257 void SetUpScheduler(bool initSurface) { 267 void SetUpScheduler(bool initSurface) {
258 SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient), initSurface); 268 SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient), initSurface);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 BeginFrameArgs args = 387 BeginFrameArgs args =
378 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); 388 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
379 fake_external_begin_frame_source_->TestOnBeginFrame(args); 389 fake_external_begin_frame_source_->TestOnBeginFrame(args);
380 return args; 390 return args;
381 } 391 }
382 392
383 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { 393 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const {
384 return fake_external_begin_frame_source_.get(); 394 return fake_external_begin_frame_source_.get();
385 } 395 }
386 396
387 void MainFrameInHighLatencyMode( 397 void CheckMainFrameSkippedAfterLateCommit(bool expect_send_begin_main_frame);
388 int64 begin_main_frame_to_commit_estimate_in_ms, 398 void ImplFrameSkippedAfterLateSwapAck(bool swap_ack_before_deadline);
389 int64 commit_to_activate_estimate_in_ms, 399 void ImplFrameIsNotSkippedAfterLateSwapAck();
390 bool impl_latency_takes_priority,
391 bool should_send_begin_main_frame);
392 void BeginFramesNotFromClient(bool use_external_begin_frame_source, 400 void BeginFramesNotFromClient(bool use_external_begin_frame_source,
393 bool throttle_frame_production); 401 bool throttle_frame_production);
394 void BeginFramesNotFromClient_SwapThrottled( 402 void BeginFramesNotFromClient_SwapThrottled(
395 bool use_external_begin_frame_source, 403 bool use_external_begin_frame_source,
396 bool throttle_frame_production); 404 bool throttle_frame_production);
397 405
398 scoped_ptr<base::SimpleTestTickClock> now_src_; 406 scoped_ptr<base::SimpleTestTickClock> now_src_;
399 scoped_refptr<OrderedSimpleTaskRunner> task_runner_; 407 scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
400 scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source_; 408 scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source_;
401 SchedulerSettings scheduler_settings_; 409 SchedulerSettings scheduler_settings_;
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 // Scheduler loses output surface, and stops waiting for ready to draw signal. 1290 // Scheduler loses output surface, and stops waiting for ready to draw signal.
1283 client_->Reset(); 1291 client_->Reset();
1284 scheduler_->DidLoseOutputSurface(); 1292 scheduler_->DidLoseOutputSurface();
1285 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); 1293 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1286 task_runner().RunPendingTasks(); // Run posted deadline. 1294 task_runner().RunPendingTasks(); // Run posted deadline.
1287 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3); 1295 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
1288 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3); 1296 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
1289 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); 1297 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
1290 } 1298 }
1291 1299
1292 void SchedulerTest::MainFrameInHighLatencyMode( 1300 void SchedulerTest::CheckMainFrameSkippedAfterLateCommit(
1293 int64 begin_main_frame_to_commit_estimate_in_ms, 1301 bool expect_send_begin_main_frame) {
1294 int64 commit_to_activate_estimate_in_ms,
1295 bool impl_latency_takes_priority,
1296 bool should_send_begin_main_frame) {
1297 scheduler_settings_.use_external_begin_frame_source = true;
1298 SetUpScheduler(true);
1299
1300 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
1301 base::TimeDelta::FromMilliseconds(
1302 begin_main_frame_to_commit_estimate_in_ms));
1303 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
1304 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms));
1305 fake_compositor_timing_history_->SetDrawDurationEstimate(
1306 base::TimeDelta::FromMilliseconds(1));
1307
1308 scheduler_->SetImplLatencyTakesPriority(impl_latency_takes_priority);
1309
1310 // Impl thread hits deadline before commit finishes. 1302 // Impl thread hits deadline before commit finishes.
1311 scheduler_->SetNeedsCommit(); 1303 scheduler_->SetNeedsCommit();
1312 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); 1304 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1313 EXPECT_SCOPED(AdvanceFrame()); 1305 EXPECT_SCOPED(AdvanceFrame());
1314 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); 1306 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1315 task_runner().RunPendingTasks(); // Run posted deadline. 1307 task_runner().RunPendingTasks(); // Run posted deadline.
sunnyps 2015/07/08 22:37:13 nit: RunTasksWhile(DeadlinePending(true))
brianderson 2015/07/09 01:28:11 Done.
1316 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); 1308 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1317 scheduler_->NotifyBeginMainFrameStarted(); 1309 scheduler_->NotifyBeginMainFrameStarted();
1318 scheduler_->NotifyReadyToCommit(); 1310 scheduler_->NotifyReadyToCommit();
1319 scheduler_->NotifyReadyToActivate(); 1311 scheduler_->NotifyReadyToActivate();
sunnyps 2015/07/08 22:37:13 Can you add the necessary EXPECT_ACTION calls here
brianderson 2015/07/09 01:28:11 Done.
1320 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); 1312 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1321 EXPECT_TRUE(client_->HasAction("ScheduledActionSendBeginMainFrame")); 1313 EXPECT_TRUE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
1322 1314
1323 client_->Reset(); 1315 client_->Reset();
1324 scheduler_->SetNeedsCommit(); 1316 scheduler_->SetNeedsCommit();
1325 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); 1317 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1326 EXPECT_SCOPED(AdvanceFrame()); 1318 EXPECT_SCOPED(AdvanceFrame());
1327 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); 1319 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1328 task_runner().RunPendingTasks(); // Run posted deadline. 1320 task_runner().RunPendingTasks(); // Run posted deadline.
1329 EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(), 1321 EXPECT_EQ(expect_send_begin_main_frame,
1330 should_send_begin_main_frame); 1322 scheduler_->MainThreadIsInHighLatencyMode());
1331 EXPECT_EQ(client_->HasAction("ScheduledActionSendBeginMainFrame"), 1323 EXPECT_EQ(expect_send_begin_main_frame,
1332 should_send_begin_main_frame); 1324 client_->HasAction("ScheduledActionSendBeginMainFrame"));
1333 } 1325 }
1334 1326
1335 TEST_F(SchedulerTest, 1327 TEST_F(SchedulerTest, MainFrameSkippedAfterLateCommit) {
1336 SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) { 1328 scheduler_settings_.use_external_begin_frame_source = true;
1337 // Set up client so that estimates indicate that we can commit and activate 1329 SetUpScheduler(true);
1338 // before the deadline (~8ms by default). 1330
1339 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, false, false)); 1331 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1340 } 1332 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1341 1333
1342 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) { 1334 bool expect_send_begin_main_frame = false;
1343 // Set up client so that estimates indicate that the commit cannot finish 1335 EXPECT_SCOPED(
1344 // before the deadline (~8ms by default). 1336 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
1345 EXPECT_SCOPED(MainFrameInHighLatencyMode(10, 1, false, true)); 1337 }
1346 } 1338
1347 1339 TEST_F(SchedulerTest,
1348 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) { 1340 MainFrameNotSkippedAfterLateCommitInPreferImplLatencyMode) {
sunnyps 2015/07/08 22:37:13 This test should be generalized - we want to check
brianderson 2015/07/09 01:28:11 Not sure if this needs to be generalized. See my c
1349 // Set up client so that estimates indicate that the activate cannot finish 1341 scheduler_settings_.use_external_begin_frame_source = true;
1350 // before the deadline (~8ms by default). 1342 SetUpScheduler(true);
1351 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true)); 1343 scheduler_->SetImplLatencyTakesPriority(true);
1352 } 1344
1353 1345 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1354 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) { 1346 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1355 // Set up client so that estimates indicate that we can commit and activate 1347
1356 // before the deadline (~8ms by default), but also enable impl latency takes 1348 bool expect_send_begin_main_frame = true;
1357 // priority mode. 1349 EXPECT_SCOPED(
1358 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true)); 1350 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
1351 }
1352
1353 TEST_F(SchedulerTest,
1354 MainFrameNotSkippedAfterLateCommit_CommitEstimateTooLong) {
1355 scheduler_settings_.use_external_begin_frame_source = true;
1356 SetUpScheduler(true);
1357 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1358 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1359 auto slow_duration = base::TimeDelta::FromSeconds(1);
1360 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
1361 slow_duration);
1362
1363 bool expect_send_begin_main_frame = true;
1364 EXPECT_SCOPED(
1365 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
1366 }
1367
1368 TEST_F(SchedulerTest,
1369 MainFrameNotSkippedAfterLateCommit_ReadyToActivateEstimateTooLong) {
1370 scheduler_settings_.use_external_begin_frame_source = true;
1371 SetUpScheduler(true);
1372 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1373 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1374 auto slow_duration = base::TimeDelta::FromSeconds(1);
1375 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
1376 slow_duration);
1377
1378 bool expect_send_begin_main_frame = true;
1379 EXPECT_SCOPED(
1380 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
1381 }
1382
1383 TEST_F(SchedulerTest,
1384 MainFrameNotSkippedAfterLateCommit_ActivateEstimateTooLong) {
1385 scheduler_settings_.use_external_begin_frame_source = true;
1386 SetUpScheduler(true);
1387 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1388 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1389 auto slow_duration = base::TimeDelta::FromSeconds(1);
1390 fake_compositor_timing_history_->SetActivateDurationEstimate(slow_duration);
1391
1392 bool expect_send_begin_main_frame = true;
1393 EXPECT_SCOPED(
1394 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
1395 }
1396
1397 TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateCommit_DrawEstimateTooLong) {
1398 scheduler_settings_.use_external_begin_frame_source = true;
1399 SetUpScheduler(true);
1400 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1401 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1402 auto slow_duration = base::TimeDelta::FromSeconds(1);
1403 fake_compositor_timing_history_->SetDrawDurationEstimate(slow_duration);
1404
1405 bool expect_send_begin_main_frame = true;
1406 EXPECT_SCOPED(
1407 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame));
1408 }
1409
1410 void SchedulerTest::ImplFrameSkippedAfterLateSwapAck(
1411 bool swap_ack_before_deadline) {
1412 scheduler_settings_.use_external_begin_frame_source = true;
1413 SetUpScheduler(true);
1414
1415 // Use estimates that indicate commit and activate can finish before the
1416 // deadline.
sunnyps 2015/07/08 22:37:13 nit: Move setting the estimates to the test - so t
brianderson 2015/07/09 01:28:11 Done.
1417 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1418 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1419
1420 // To get into a high latency state, this test disables automatic swap acks.
1421 scheduler_->SetMaxSwapsPending(1);
1422 client_->SetAutomaticSwapAck(false);
1423
1424 // Draw and swap for first BeginFrame
1425 client_->Reset();
1426 scheduler_->SetNeedsCommit();
1427 scheduler_->SetNeedsRedraw();
1428 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1429 SendNextBeginFrame();
1430 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 4);
1431 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 4);
1432 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
1433 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 3, 4);
1434
1435 client_->Reset();
1436 scheduler_->NotifyBeginMainFrameStarted();
1437 scheduler_->NotifyReadyToCommit();
1438 scheduler_->NotifyReadyToActivate();
1439 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1440 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1441 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4);
1442 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4);
1443 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
1444 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
1445
1446 // Verify we skip every other frame if the swap ack consistently
1447 // comes back late.
1448 for (int i = 0; i < 10; i++) {
1449 // Not calling scheduler_->DidSwapBuffersComplete() until after next
1450 // BeginImplFrame puts the impl thread in high latency mode.
1451 client_->Reset();
1452 scheduler_->SetNeedsCommit();
1453 scheduler_->SetNeedsRedraw();
1454 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1455 SendNextBeginFrame();
1456 // Verify that we skip the BeginImplFrame
1457 EXPECT_NO_ACTION(client_);
1458 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
1459 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1460
1461 // Verify that we do not perform any actions after we are no longer
1462 // swap throttled.
1463 client_->Reset();
1464 if (swap_ack_before_deadline) {
1465 // It shouldn't matter if the swap ack comes back before the deadline...
1466 scheduler_->DidSwapBuffersComplete();
1467 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1468 } else {
1469 // ... or after the deadline.
1470 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1471 scheduler_->DidSwapBuffersComplete();
1472 }
1473 EXPECT_NO_ACTION(client_);
1474
1475 // Verify that we start the next BeginImplFrame and continue normally
1476 // after having just skipped a BeginImplFrame.
1477 client_->Reset();
1478 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1479 scheduler_->SetNeedsCommit();
sunnyps 2015/07/08 22:37:13 Shouldn't need to call SetNeedsCommit or SetNeedsR
brianderson 2015/07/09 01:28:12 Ah, these calls are redundant. Will remove them.
1480 scheduler_->SetNeedsRedraw();
1481 SendNextBeginFrame();
1482 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
1483 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
1484 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
1485
1486 client_->Reset();
1487 scheduler_->NotifyBeginMainFrameStarted();
1488 scheduler_->NotifyReadyToCommit();
1489 scheduler_->NotifyReadyToActivate();
1490 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1491 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4);
1492 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4);
1493 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
1494 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
1495 }
1496 }
1497
1498 TEST_F(SchedulerTest, ImplFrameSkippedAfterLateSwapAck_SwapAckThenDeadline) {
1499 bool swap_ack_before_deadline = true;
1500 EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline));
1501 }
1502
1503 TEST_F(SchedulerTest, ImplFrameSkippedAfterLateSwapAck_DeadlineThenSwapAck) {
1504 bool swap_ack_before_deadline = false;
1505 EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline));
1506 }
1507
1508 void SchedulerTest::ImplFrameIsNotSkippedAfterLateSwapAck() {
1509 // To get into a high latency state, this test disables automatic swap acks.
1510 scheduler_->SetMaxSwapsPending(1);
1511 client_->SetAutomaticSwapAck(false);
1512
1513 // Draw and swap for first BeginFrame
1514 client_->Reset();
1515 scheduler_->SetNeedsCommit();
1516 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1517 SendNextBeginFrame();
1518 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 3);
1519 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3);
1520 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3);
1521
1522 client_->Reset();
1523 scheduler_->NotifyBeginMainFrameStarted();
1524 scheduler_->NotifyReadyToCommit();
1525 scheduler_->NotifyReadyToActivate();
1526 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1527 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1528 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4);
1529 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4);
1530 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4);
1531 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4);
1532
1533 // Verify impl thread consistently operates in high latency mode
1534 // without skipping any frames.
1535 for (int i = 0; i < 10; i++) {
1536 // Not calling scheduler_->DidSwapBuffersComplete() until after next frame
1537 // puts the impl thread in high latency mode.
1538 client_->Reset();
1539 scheduler_->SetNeedsCommit();
1540 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1541 SendNextBeginFrame();
1542 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
1543 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
1544 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1545
1546 client_->Reset();
1547 scheduler_->DidSwapBuffersComplete();
1548 scheduler_->NotifyBeginMainFrameStarted();
1549 scheduler_->NotifyReadyToCommit();
1550 scheduler_->NotifyReadyToActivate();
1551 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1552
1553 // Verify that we don't skip the actions of the BeginImplFrame
1554 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 0, 5);
1555 EXPECT_ACTION("ScheduledActionCommit", client_, 1, 5);
1556 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 2, 5);
1557 EXPECT_ACTION("ScheduledActionAnimate", client_, 3, 5);
1558 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 5);
1559 }
1560 }
1561
1562 TEST_F(SchedulerTest,
1563 ImplFrameIsNotSkippedAfterLateSwapAck_CommitEstimateTooLong) {
1564 scheduler_settings_.use_external_begin_frame_source = true;
1565 SetUpScheduler(true);
1566 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1567 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1568 auto slow_duration = base::TimeDelta::FromSeconds(1);
1569 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate(
1570 slow_duration);
1571 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1572 }
1573
1574 TEST_F(SchedulerTest,
1575 ImplFrameIsNotSkippedAfterLateSwapAck_ReadyToActivateEstimateTooLong) {
1576 scheduler_settings_.use_external_begin_frame_source = true;
1577 SetUpScheduler(true);
1578 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1579 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1580 auto slow_duration = base::TimeDelta::FromSeconds(1);
1581 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate(
1582 slow_duration);
1583 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1584 }
1585
1586 TEST_F(SchedulerTest,
1587 ImplFrameIsNotSkippedAfterLateSwapAck_ActivateEstimateTooLong) {
1588 scheduler_settings_.use_external_begin_frame_source = true;
1589 SetUpScheduler(true);
1590 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1591 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1592 auto slow_duration = base::TimeDelta::FromSeconds(1);
1593 fake_compositor_timing_history_->SetActivateDurationEstimate(slow_duration);
1594 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1595 }
1596
1597 TEST_F(SchedulerTest,
1598 ImplFrameIsNotSkippedAfterLateSwapAck_DrawEstimateTooLong) {
1599 scheduler_settings_.use_external_begin_frame_source = true;
1600 SetUpScheduler(true);
1601 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1602 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1603 auto slow_duration = base::TimeDelta::FromSeconds(1);
1604 fake_compositor_timing_history_->SetDrawDurationEstimate(slow_duration);
1605 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck());
1606 }
1607
1608 TEST_F(SchedulerTest,
1609 MainFrameThenImplFrameSkippedAfterLateCommitAndLateSwapAck) {
1610 // Set up client with custom estimates.
1611 // This test starts off with expensive estimates to prevent latency recovery
1612 // initially, then lowers the estimates to enable it once both the main
1613 // and impl threads are in a high latency mode.
1614 scheduler_settings_.use_external_begin_frame_source = true;
1615 SetUpScheduler(true);
1616
1617 auto fast_duration = base::TimeDelta::FromMilliseconds(1);
1618 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1619 auto slow_duration = base::TimeDelta::FromSeconds(1);
1620 fake_compositor_timing_history_->SetDrawDurationEstimate(slow_duration);
sunnyps 2015/07/08 22:37:13 This doesn't match the comment above.
brianderson 2015/07/09 01:28:12 Done.
1621
1622 // To get into a high latency state, this test disables automatic swap acks.
1623 scheduler_->SetMaxSwapsPending(1);
1624 client_->SetAutomaticSwapAck(false);
1625
1626 // Impl thread hits deadline before commit finishes to make
1627 // MainThreadIsInHighLatencyMode true
1628 client_->Reset();
1629 scheduler_->SetNeedsCommit();
1630 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1631 EXPECT_SCOPED(AdvanceFrame());
1632 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1633 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1634 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1635 scheduler_->NotifyBeginMainFrameStarted();
1636 scheduler_->NotifyReadyToCommit();
1637 scheduler_->NotifyReadyToActivate();
1638 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1639
1640 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 5);
1641 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5);
1642 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5);
1643 EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5);
1644 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5);
1645
1646 // Draw and swap for first commit, start second commit.
1647 client_->Reset();
1648 scheduler_->SetNeedsCommit();
1649 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1650 EXPECT_SCOPED(AdvanceFrame());
1651 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1652 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1653 scheduler_->NotifyBeginMainFrameStarted();
1654 scheduler_->NotifyReadyToCommit();
1655 scheduler_->NotifyReadyToActivate();
1656
1657 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 6);
1658 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 6);
1659 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 6);
1660 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 6);
1661 EXPECT_ACTION("ScheduledActionCommit", client_, 4, 6);
1662 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 5, 6);
1663
1664 // Don't call scheduler_->DidSwapBuffersComplete() until after next frame
1665 // to put the impl thread in a high latency mode.
1666 client_->Reset();
1667 scheduler_->SetNeedsCommit();
1668 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1669 EXPECT_SCOPED(AdvanceFrame());
1670 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1671 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1672 scheduler_->DidSwapBuffersComplete();
1673
1674 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
1675 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
1676 // Note: BeginMainFrame and swap are skipped here because of
1677 // swap ack backpressure, not because of latency recovery.
1678 EXPECT_FALSE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
1679 EXPECT_FALSE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
sunnyps 2015/07/08 22:37:13 EXPECT_TRUE that both impl thread and main thread
brianderson 2015/07/09 01:28:12 Done.
1680
1681 // Lower estimates so that the scheduler will attempt latency recovery.
1682 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration);
1683
1684 // Now that both threads are in a high latency mode, make sure we
1685 // skip the BeginMainFrame, then the BeginImplFrame, but not both
1686 // at the same time.
1687
1688 // Verify we skip BeginMainFrame first.
1689 client_->Reset();
1690 // Previous commit request is still outstanding.
1691 EXPECT_TRUE(scheduler_->NeedsCommit());
1692 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1693 SendNextBeginFrame();
sunnyps 2015/07/08 22:37:13 Same as above (before the deadline runs).
brianderson 2015/07/09 01:28:12 Thanks for the suggestion. Found out I was calling
1694 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1695 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
sunnyps 2015/07/08 22:37:13 nit: Move this EXPECT below so that it reads seque
brianderson 2015/07/09 01:28:11 Done.
1696
1697 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
1698 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3);
1699 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 3);
1700 EXPECT_FALSE(client_->HasAction("ScheduledActionSendBeginMainFrame"));
sunnyps 2015/07/08 22:37:13 nit: Don't need the last EXPECT_FALSE.
brianderson 2015/07/09 01:28:11 Done.
1701
1702 // Verify we skip the BeginImplFrame second.
1703 client_->Reset();
1704 // Previous commit request is still outstanding.
1705 EXPECT_TRUE(scheduler_->NeedsCommit());
1706 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1707 SendNextBeginFrame();
1708 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1709 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1710 scheduler_->DidSwapBuffersComplete();
1711 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1712
1713 EXPECT_NO_ACTION(client_);
1714
1715 // Then verify we operate in a low latency mode.
1716 client_->Reset();
1717 // Previous commit request is still outstanding.
1718 EXPECT_TRUE(scheduler_->NeedsCommit());
1719 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1720 SendNextBeginFrame();
1721 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1722 scheduler_->NotifyBeginMainFrameStarted();
1723 scheduler_->NotifyReadyToCommit();
1724 scheduler_->NotifyReadyToActivate();
1725 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
1726 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1727 scheduler_->DidSwapBuffersComplete();
1728 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
1729
1730 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 6);
1731 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 6);
1732 EXPECT_ACTION("ScheduledActionCommit", client_, 2, 6);
1733 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 3, 6);
1734 EXPECT_ACTION("ScheduledActionAnimate", client_, 4, 6);
1735 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 5, 6);
1359 } 1736 }
1360 1737
1361 TEST_F( 1738 TEST_F(
1362 SchedulerTest, 1739 SchedulerTest,
1363 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) { 1740 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) {
1364 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main 1741 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main
1365 // thread. This prevents the scheduler from receiving any pending swap acks. 1742 // thread. This prevents the scheduler from receiving any pending swap acks.
1366 1743
1367 // Since we are simulating a long commit, set up a client with draw duration 1744 // Since we are simulating a long commit, set up a client with draw duration
1368 // estimates that prevent skipping main frames to get to low latency mode. 1745 // estimates that prevent skipping main frames to get to low latency mode.
(...skipping 1586 matching lines...) Expand 10 before | Expand all | Expand 10 after
2955 scheduler_->SetImplLatencyTakesPriority(true); 3332 scheduler_->SetImplLatencyTakesPriority(true);
2956 scheduler_->SetChildrenNeedBeginFrames(true); 3333 scheduler_->SetChildrenNeedBeginFrames(true);
2957 3334
2958 EXPECT_SCOPED(AdvanceFrame()); 3335 EXPECT_SCOPED(AdvanceFrame());
2959 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); 3336 EXPECT_TRUE(client_->begin_frame_is_sent_to_children());
2960 EXPECT_FALSE(client_->begin_frame_args_sent_to_children().on_critical_path); 3337 EXPECT_FALSE(client_->begin_frame_args_sent_to_children().on_critical_path);
2961 } 3338 }
2962 3339
2963 } // namespace 3340 } // namespace
2964 } // namespace cc 3341 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698