OLD | NEW |
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 Loading... |
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 slow_duration = base::TimeDelta::FromSeconds(1); |
| 253 fake_compositor_timing_history_->SetAllEstimatesTo(slow_duration); |
| 254 |
249 return scheduler_.get(); | 255 return scheduler_.get(); |
250 } | 256 } |
251 | 257 |
252 void CreateSchedulerAndInitSurface() { | 258 void CreateSchedulerAndInitSurface() { |
253 CreateScheduler(); | 259 CreateScheduler(); |
254 EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit()); | 260 EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit()); |
255 } | 261 } |
256 | 262 |
257 void SetUpScheduler(bool initSurface) { | 263 void SetUpScheduler(bool initSurface) { |
258 SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient), initSurface); | 264 SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient), initSurface); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 BeginFrameArgs args = | 383 BeginFrameArgs args = |
378 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); | 384 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
379 fake_external_begin_frame_source_->TestOnBeginFrame(args); | 385 fake_external_begin_frame_source_->TestOnBeginFrame(args); |
380 return args; | 386 return args; |
381 } | 387 } |
382 | 388 |
383 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { | 389 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { |
384 return fake_external_begin_frame_source_.get(); | 390 return fake_external_begin_frame_source_.get(); |
385 } | 391 } |
386 | 392 |
387 void MainFrameInHighLatencyMode( | 393 void CheckMainFrameSkippedAfterLateCommit(bool expect_send_begin_main_frame); |
388 int64 begin_main_frame_to_commit_estimate_in_ms, | 394 void ImplFrameSkippedAfterLateSwapAck(bool swap_ack_before_deadline); |
389 int64 commit_to_activate_estimate_in_ms, | 395 void ImplFrameIsNotSkippedAfterLateSwapAck(); |
390 bool impl_latency_takes_priority, | |
391 bool should_send_begin_main_frame); | |
392 void BeginFramesNotFromClient(bool use_external_begin_frame_source, | 396 void BeginFramesNotFromClient(bool use_external_begin_frame_source, |
393 bool throttle_frame_production); | 397 bool throttle_frame_production); |
394 void BeginFramesNotFromClient_SwapThrottled( | 398 void BeginFramesNotFromClient_SwapThrottled( |
395 bool use_external_begin_frame_source, | 399 bool use_external_begin_frame_source, |
396 bool throttle_frame_production); | 400 bool throttle_frame_production); |
397 | 401 |
398 scoped_ptr<base::SimpleTestTickClock> now_src_; | 402 scoped_ptr<base::SimpleTestTickClock> now_src_; |
399 scoped_refptr<OrderedSimpleTaskRunner> task_runner_; | 403 scoped_refptr<OrderedSimpleTaskRunner> task_runner_; |
400 scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source_; | 404 scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source_; |
401 SchedulerSettings scheduler_settings_; | 405 SchedulerSettings scheduler_settings_; |
(...skipping 914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 // Scheduler loses output surface, and stops waiting for ready to draw signal. | 1320 // Scheduler loses output surface, and stops waiting for ready to draw signal. |
1317 client_->Reset(); | 1321 client_->Reset(); |
1318 scheduler_->DidLoseOutputSurface(); | 1322 scheduler_->DidLoseOutputSurface(); |
1319 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 1323 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
1320 task_runner().RunPendingTasks(); // Run posted deadline. | 1324 task_runner().RunPendingTasks(); // Run posted deadline. |
1321 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3); | 1325 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3); |
1322 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3); | 1326 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3); |
1323 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); | 1327 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); |
1324 } | 1328 } |
1325 | 1329 |
1326 void SchedulerTest::MainFrameInHighLatencyMode( | 1330 void SchedulerTest::CheckMainFrameSkippedAfterLateCommit( |
1327 int64 begin_main_frame_to_commit_estimate_in_ms, | 1331 bool expect_send_begin_main_frame) { |
1328 int64 commit_to_activate_estimate_in_ms, | |
1329 bool impl_latency_takes_priority, | |
1330 bool should_send_begin_main_frame) { | |
1331 scheduler_settings_.use_external_begin_frame_source = true; | |
1332 SetUpScheduler(true); | |
1333 | |
1334 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate( | |
1335 base::TimeDelta::FromMilliseconds( | |
1336 begin_main_frame_to_commit_estimate_in_ms)); | |
1337 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate( | |
1338 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms)); | |
1339 fake_compositor_timing_history_->SetDrawDurationEstimate( | |
1340 base::TimeDelta::FromMilliseconds(1)); | |
1341 | |
1342 scheduler_->SetImplLatencyTakesPriority(impl_latency_takes_priority); | |
1343 | |
1344 // Impl thread hits deadline before commit finishes. | 1332 // Impl thread hits deadline before commit finishes. |
1345 scheduler_->SetNeedsCommit(); | 1333 scheduler_->SetNeedsCommit(); |
1346 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | 1334 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
1347 EXPECT_SCOPED(AdvanceFrame()); | 1335 EXPECT_SCOPED(AdvanceFrame()); |
1348 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | 1336 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
1349 task_runner().RunPendingTasks(); // Run posted deadline. | 1337 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
1350 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); | 1338 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
1351 scheduler_->NotifyBeginMainFrameStarted(); | 1339 scheduler_->NotifyBeginMainFrameStarted(); |
1352 scheduler_->NotifyReadyToCommit(); | 1340 scheduler_->NotifyReadyToCommit(); |
1353 scheduler_->NotifyReadyToActivate(); | 1341 scheduler_->NotifyReadyToActivate(); |
1354 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); | 1342 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 5); |
1355 EXPECT_TRUE(client_->HasAction("ScheduledActionSendBeginMainFrame")); | 1343 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5); |
| 1344 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5); |
| 1345 EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5); |
| 1346 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5); |
| 1347 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
1356 | 1348 |
1357 client_->Reset(); | 1349 client_->Reset(); |
1358 scheduler_->SetNeedsCommit(); | 1350 scheduler_->SetNeedsCommit(); |
1359 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); | 1351 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
1360 EXPECT_SCOPED(AdvanceFrame()); | 1352 EXPECT_SCOPED(AdvanceFrame()); |
1361 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); | 1353 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
1362 task_runner().RunPendingTasks(); // Run posted deadline. | 1354 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
1363 EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(), | 1355 EXPECT_EQ(expect_send_begin_main_frame, |
1364 should_send_begin_main_frame); | 1356 scheduler_->MainThreadIsInHighLatencyMode()); |
1365 EXPECT_EQ(client_->HasAction("ScheduledActionSendBeginMainFrame"), | 1357 EXPECT_EQ(expect_send_begin_main_frame, |
1366 should_send_begin_main_frame); | 1358 client_->HasAction("ScheduledActionSendBeginMainFrame")); |
1367 } | 1359 } |
1368 | 1360 |
1369 TEST_F(SchedulerTest, | 1361 TEST_F(SchedulerTest, MainFrameSkippedAfterLateCommit) { |
1370 SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) { | 1362 scheduler_settings_.use_external_begin_frame_source = true; |
1371 // Set up client so that estimates indicate that we can commit and activate | 1363 SetUpScheduler(true); |
1372 // before the deadline (~8ms by default). | 1364 |
1373 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, false, false)); | 1365 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
1374 } | 1366 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
1375 | 1367 |
1376 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) { | 1368 bool expect_send_begin_main_frame = false; |
1377 // Set up client so that estimates indicate that the commit cannot finish | 1369 EXPECT_SCOPED( |
1378 // before the deadline (~8ms by default). | 1370 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame)); |
1379 EXPECT_SCOPED(MainFrameInHighLatencyMode(10, 1, false, true)); | 1371 } |
1380 } | 1372 |
1381 | 1373 TEST_F(SchedulerTest, |
1382 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) { | 1374 MainFrameNotSkippedAfterLateCommitInPreferImplLatencyMode) { |
1383 // Set up client so that estimates indicate that the activate cannot finish | 1375 scheduler_settings_.use_external_begin_frame_source = true; |
1384 // before the deadline (~8ms by default). | 1376 SetUpScheduler(true); |
1385 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true)); | 1377 scheduler_->SetImplLatencyTakesPriority(true); |
1386 } | 1378 |
1387 | 1379 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
1388 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) { | 1380 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
1389 // Set up client so that estimates indicate that we can commit and activate | 1381 |
1390 // before the deadline (~8ms by default), but also enable impl latency takes | 1382 bool expect_send_begin_main_frame = true; |
1391 // priority mode. | 1383 EXPECT_SCOPED( |
1392 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true)); | 1384 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame)); |
| 1385 } |
| 1386 |
| 1387 TEST_F(SchedulerTest, |
| 1388 MainFrameNotSkippedAfterLateCommit_CommitEstimateTooLong) { |
| 1389 scheduler_settings_.use_external_begin_frame_source = true; |
| 1390 SetUpScheduler(true); |
| 1391 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1392 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
| 1393 auto slow_duration = base::TimeDelta::FromSeconds(1); |
| 1394 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate( |
| 1395 slow_duration); |
| 1396 |
| 1397 bool expect_send_begin_main_frame = true; |
| 1398 EXPECT_SCOPED( |
| 1399 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame)); |
| 1400 } |
| 1401 |
| 1402 TEST_F(SchedulerTest, |
| 1403 MainFrameNotSkippedAfterLateCommit_ReadyToActivateEstimateTooLong) { |
| 1404 scheduler_settings_.use_external_begin_frame_source = true; |
| 1405 SetUpScheduler(true); |
| 1406 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1407 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
| 1408 auto slow_duration = base::TimeDelta::FromSeconds(1); |
| 1409 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate( |
| 1410 slow_duration); |
| 1411 |
| 1412 bool expect_send_begin_main_frame = true; |
| 1413 EXPECT_SCOPED( |
| 1414 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame)); |
| 1415 } |
| 1416 |
| 1417 TEST_F(SchedulerTest, |
| 1418 MainFrameNotSkippedAfterLateCommit_ActivateEstimateTooLong) { |
| 1419 scheduler_settings_.use_external_begin_frame_source = true; |
| 1420 SetUpScheduler(true); |
| 1421 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1422 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
| 1423 auto slow_duration = base::TimeDelta::FromSeconds(1); |
| 1424 fake_compositor_timing_history_->SetActivateDurationEstimate(slow_duration); |
| 1425 |
| 1426 bool expect_send_begin_main_frame = true; |
| 1427 EXPECT_SCOPED( |
| 1428 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame)); |
| 1429 } |
| 1430 |
| 1431 TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateCommit_DrawEstimateTooLong) { |
| 1432 scheduler_settings_.use_external_begin_frame_source = true; |
| 1433 SetUpScheduler(true); |
| 1434 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1435 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
| 1436 auto slow_duration = base::TimeDelta::FromSeconds(1); |
| 1437 fake_compositor_timing_history_->SetDrawDurationEstimate(slow_duration); |
| 1438 |
| 1439 bool expect_send_begin_main_frame = true; |
| 1440 EXPECT_SCOPED( |
| 1441 CheckMainFrameSkippedAfterLateCommit(expect_send_begin_main_frame)); |
| 1442 } |
| 1443 |
| 1444 void SchedulerTest::ImplFrameSkippedAfterLateSwapAck( |
| 1445 bool swap_ack_before_deadline) { |
| 1446 // To get into a high latency state, this test disables automatic swap acks. |
| 1447 scheduler_->SetMaxSwapsPending(1); |
| 1448 client_->SetAutomaticSwapAck(false); |
| 1449 |
| 1450 // Draw and swap for first BeginFrame |
| 1451 client_->Reset(); |
| 1452 scheduler_->SetNeedsCommit(); |
| 1453 scheduler_->SetNeedsRedraw(); |
| 1454 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1455 SendNextBeginFrame(); |
| 1456 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 4); |
| 1457 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 4); |
| 1458 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4); |
| 1459 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 3, 4); |
| 1460 |
| 1461 client_->Reset(); |
| 1462 scheduler_->NotifyBeginMainFrameStarted(); |
| 1463 scheduler_->NotifyReadyToCommit(); |
| 1464 scheduler_->NotifyReadyToActivate(); |
| 1465 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1466 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1467 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4); |
| 1468 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4); |
| 1469 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4); |
| 1470 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4); |
| 1471 |
| 1472 // Verify we skip every other frame if the swap ack consistently |
| 1473 // comes back late. |
| 1474 for (int i = 0; i < 10; i++) { |
| 1475 // Not calling scheduler_->DidSwapBuffersComplete() until after next |
| 1476 // BeginImplFrame puts the impl thread in high latency mode. |
| 1477 client_->Reset(); |
| 1478 scheduler_->SetNeedsCommit(); |
| 1479 scheduler_->SetNeedsRedraw(); |
| 1480 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1481 SendNextBeginFrame(); |
| 1482 // Verify that we skip the BeginImplFrame |
| 1483 EXPECT_NO_ACTION(client_); |
| 1484 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); |
| 1485 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1486 |
| 1487 // Verify that we do not perform any actions after we are no longer |
| 1488 // swap throttled. |
| 1489 client_->Reset(); |
| 1490 if (swap_ack_before_deadline) { |
| 1491 // It shouldn't matter if the swap ack comes back before the deadline... |
| 1492 scheduler_->DidSwapBuffersComplete(); |
| 1493 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1494 } else { |
| 1495 // ... or after the deadline. |
| 1496 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1497 scheduler_->DidSwapBuffersComplete(); |
| 1498 } |
| 1499 EXPECT_NO_ACTION(client_); |
| 1500 |
| 1501 // Verify that we start the next BeginImplFrame and continue normally |
| 1502 // after having just skipped a BeginImplFrame. |
| 1503 client_->Reset(); |
| 1504 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1505 SendNextBeginFrame(); |
| 1506 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3); |
| 1507 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3); |
| 1508 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3); |
| 1509 |
| 1510 client_->Reset(); |
| 1511 scheduler_->NotifyBeginMainFrameStarted(); |
| 1512 scheduler_->NotifyReadyToCommit(); |
| 1513 scheduler_->NotifyReadyToActivate(); |
| 1514 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1515 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4); |
| 1516 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4); |
| 1517 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4); |
| 1518 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4); |
| 1519 } |
| 1520 } |
| 1521 |
| 1522 TEST_F(SchedulerTest, |
| 1523 ImplFrameSkippedAfterLateSwapAck_FastEstimates_SwapAckThenDeadline) { |
| 1524 scheduler_settings_.use_external_begin_frame_source = true; |
| 1525 SetUpScheduler(true); |
| 1526 |
| 1527 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1528 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
| 1529 |
| 1530 bool swap_ack_before_deadline = true; |
| 1531 EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline)); |
| 1532 } |
| 1533 |
| 1534 TEST_F(SchedulerTest, |
| 1535 ImplFrameSkippedAfterLateSwapAck_FastEstimates_DeadlineThenSwapAck) { |
| 1536 scheduler_settings_.use_external_begin_frame_source = true; |
| 1537 SetUpScheduler(true); |
| 1538 |
| 1539 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1540 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
| 1541 |
| 1542 bool swap_ack_before_deadline = false; |
| 1543 EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline)); |
| 1544 } |
| 1545 |
| 1546 TEST_F(SchedulerTest, |
| 1547 ImplFrameSkippedAfterLateSwapAck_ImplLatencyTakesPriority) { |
| 1548 scheduler_settings_.use_external_begin_frame_source = true; |
| 1549 SetUpScheduler(true); |
| 1550 |
| 1551 // Even if every estimate related to the main thread is slow, we should |
| 1552 // still expect to recover impl thread latency if the draw is fast and we |
| 1553 // are in impl latency takes priority. |
| 1554 scheduler_->SetImplLatencyTakesPriority(true); |
| 1555 auto slow_duration = base::TimeDelta::FromSeconds(1); |
| 1556 fake_compositor_timing_history_->SetAllEstimatesTo(slow_duration); |
| 1557 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1558 fake_compositor_timing_history_->SetDrawDurationEstimate(fast_duration); |
| 1559 |
| 1560 bool swap_ack_before_deadline = false; |
| 1561 EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline)); |
| 1562 } |
| 1563 |
| 1564 TEST_F(SchedulerTest, |
| 1565 ImplFrameSkippedAfterLateSwapAck_OnlyImplSideUpdatesExpected) { |
| 1566 // This tests that we recover impl thread latency when there are no commits. |
| 1567 scheduler_settings_.use_external_begin_frame_source = true; |
| 1568 SetUpScheduler(true); |
| 1569 |
| 1570 // To get into a high latency state, this test disables automatic swap acks. |
| 1571 scheduler_->SetMaxSwapsPending(1); |
| 1572 client_->SetAutomaticSwapAck(false); |
| 1573 |
| 1574 // Even if every estimate related to the main thread is slow, we should |
| 1575 // still expect to recover impl thread latency if there are no commits from |
| 1576 // the main thread. |
| 1577 auto slow_duration = base::TimeDelta::FromSeconds(1); |
| 1578 fake_compositor_timing_history_->SetAllEstimatesTo(slow_duration); |
| 1579 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1580 fake_compositor_timing_history_->SetDrawDurationEstimate(fast_duration); |
| 1581 |
| 1582 // Draw and swap for first BeginFrame |
| 1583 client_->Reset(); |
| 1584 scheduler_->SetNeedsRedraw(); |
| 1585 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1586 SendNextBeginFrame(); |
| 1587 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 3); |
| 1588 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3); |
| 1589 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 3); |
| 1590 |
| 1591 client_->Reset(); |
| 1592 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1593 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1594 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); |
| 1595 |
| 1596 // Verify we skip every other frame if the swap ack consistently |
| 1597 // comes back late. |
| 1598 for (int i = 0; i < 10; i++) { |
| 1599 // Not calling scheduler_->DidSwapBuffersComplete() until after next |
| 1600 // BeginImplFrame puts the impl thread in high latency mode. |
| 1601 client_->Reset(); |
| 1602 scheduler_->SetNeedsRedraw(); |
| 1603 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1604 SendNextBeginFrame(); |
| 1605 // Verify that we skip the BeginImplFrame |
| 1606 EXPECT_NO_ACTION(client_); |
| 1607 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); |
| 1608 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1609 |
| 1610 // Verify that we do not perform any actions after we are no longer |
| 1611 // swap throttled. |
| 1612 client_->Reset(); |
| 1613 scheduler_->DidSwapBuffersComplete(); |
| 1614 EXPECT_NO_ACTION(client_); |
| 1615 |
| 1616 // Verify that we start the next BeginImplFrame and continue normally |
| 1617 // after having just skipped a BeginImplFrame. |
| 1618 client_->Reset(); |
| 1619 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1620 SendNextBeginFrame(); |
| 1621 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 1622 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2); |
| 1623 |
| 1624 client_->Reset(); |
| 1625 // Deadline should be immediate. |
| 1626 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
| 1627 task_runner().RunUntilTime(now_src_->NowTicks()); |
| 1628 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); |
| 1629 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); |
| 1630 } |
| 1631 } |
| 1632 |
| 1633 void SchedulerTest::ImplFrameIsNotSkippedAfterLateSwapAck() { |
| 1634 // To get into a high latency state, this test disables automatic swap acks. |
| 1635 scheduler_->SetMaxSwapsPending(1); |
| 1636 client_->SetAutomaticSwapAck(false); |
| 1637 |
| 1638 // Draw and swap for first BeginFrame |
| 1639 client_->Reset(); |
| 1640 scheduler_->SetNeedsCommit(); |
| 1641 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1642 SendNextBeginFrame(); |
| 1643 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 3); |
| 1644 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 3); |
| 1645 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 3); |
| 1646 |
| 1647 client_->Reset(); |
| 1648 scheduler_->NotifyBeginMainFrameStarted(); |
| 1649 scheduler_->NotifyReadyToCommit(); |
| 1650 scheduler_->NotifyReadyToActivate(); |
| 1651 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1652 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1653 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 4); |
| 1654 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 4); |
| 1655 EXPECT_ACTION("ScheduledActionAnimate", client_, 2, 4); |
| 1656 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4); |
| 1657 |
| 1658 // Verify impl thread consistently operates in high latency mode |
| 1659 // without skipping any frames. |
| 1660 for (int i = 0; i < 10; i++) { |
| 1661 // Not calling scheduler_->DidSwapBuffersComplete() until after next frame |
| 1662 // puts the impl thread in high latency mode. |
| 1663 client_->Reset(); |
| 1664 scheduler_->SetNeedsCommit(); |
| 1665 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1666 SendNextBeginFrame(); |
| 1667 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); |
| 1668 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
| 1669 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1670 |
| 1671 client_->Reset(); |
| 1672 scheduler_->DidSwapBuffersComplete(); |
| 1673 scheduler_->NotifyBeginMainFrameStarted(); |
| 1674 scheduler_->NotifyReadyToCommit(); |
| 1675 scheduler_->NotifyReadyToActivate(); |
| 1676 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1677 |
| 1678 // Verify that we don't skip the actions of the BeginImplFrame |
| 1679 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 0, 5); |
| 1680 EXPECT_ACTION("ScheduledActionCommit", client_, 1, 5); |
| 1681 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 2, 5); |
| 1682 EXPECT_ACTION("ScheduledActionAnimate", client_, 3, 5); |
| 1683 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 5); |
| 1684 } |
| 1685 } |
| 1686 |
| 1687 TEST_F(SchedulerTest, |
| 1688 ImplFrameIsNotSkippedAfterLateSwapAck_CommitEstimateTooLong) { |
| 1689 scheduler_settings_.use_external_begin_frame_source = true; |
| 1690 SetUpScheduler(true); |
| 1691 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1692 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
| 1693 auto slow_duration = base::TimeDelta::FromSeconds(1); |
| 1694 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate( |
| 1695 slow_duration); |
| 1696 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck()); |
| 1697 } |
| 1698 |
| 1699 TEST_F(SchedulerTest, |
| 1700 ImplFrameIsNotSkippedAfterLateSwapAck_ReadyToActivateEstimateTooLong) { |
| 1701 scheduler_settings_.use_external_begin_frame_source = true; |
| 1702 SetUpScheduler(true); |
| 1703 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1704 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
| 1705 auto slow_duration = base::TimeDelta::FromSeconds(1); |
| 1706 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate( |
| 1707 slow_duration); |
| 1708 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck()); |
| 1709 } |
| 1710 |
| 1711 TEST_F(SchedulerTest, |
| 1712 ImplFrameIsNotSkippedAfterLateSwapAck_ActivateEstimateTooLong) { |
| 1713 scheduler_settings_.use_external_begin_frame_source = true; |
| 1714 SetUpScheduler(true); |
| 1715 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1716 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
| 1717 auto slow_duration = base::TimeDelta::FromSeconds(1); |
| 1718 fake_compositor_timing_history_->SetActivateDurationEstimate(slow_duration); |
| 1719 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck()); |
| 1720 } |
| 1721 |
| 1722 TEST_F(SchedulerTest, |
| 1723 ImplFrameIsNotSkippedAfterLateSwapAck_DrawEstimateTooLong) { |
| 1724 scheduler_settings_.use_external_begin_frame_source = true; |
| 1725 SetUpScheduler(true); |
| 1726 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1727 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
| 1728 auto slow_duration = base::TimeDelta::FromSeconds(1); |
| 1729 fake_compositor_timing_history_->SetDrawDurationEstimate(slow_duration); |
| 1730 EXPECT_SCOPED(ImplFrameIsNotSkippedAfterLateSwapAck()); |
| 1731 } |
| 1732 |
| 1733 TEST_F(SchedulerTest, |
| 1734 MainFrameThenImplFrameSkippedAfterLateCommitAndLateSwapAck) { |
| 1735 // Set up client with custom estimates. |
| 1736 // This test starts off with expensive estimates to prevent latency recovery |
| 1737 // initially, then lowers the estimates to enable it once both the main |
| 1738 // and impl threads are in a high latency mode. |
| 1739 scheduler_settings_.use_external_begin_frame_source = true; |
| 1740 SetUpScheduler(true); |
| 1741 |
| 1742 auto slow_duration = base::TimeDelta::FromSeconds(1); |
| 1743 fake_compositor_timing_history_->SetAllEstimatesTo(slow_duration); |
| 1744 |
| 1745 // To get into a high latency state, this test disables automatic swap acks. |
| 1746 scheduler_->SetMaxSwapsPending(1); |
| 1747 client_->SetAutomaticSwapAck(false); |
| 1748 |
| 1749 // Impl thread hits deadline before commit finishes to make |
| 1750 // MainThreadIsInHighLatencyMode true |
| 1751 client_->Reset(); |
| 1752 scheduler_->SetNeedsCommit(); |
| 1753 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1754 EXPECT_SCOPED(AdvanceFrame()); |
| 1755 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1756 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1757 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1758 scheduler_->NotifyBeginMainFrameStarted(); |
| 1759 scheduler_->NotifyReadyToCommit(); |
| 1760 scheduler_->NotifyReadyToActivate(); |
| 1761 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1762 |
| 1763 EXPECT_ACTION("SetNeedsBeginFrames(true)", client_, 0, 5); |
| 1764 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5); |
| 1765 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5); |
| 1766 EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5); |
| 1767 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5); |
| 1768 |
| 1769 // Draw and swap for first commit, start second commit. |
| 1770 client_->Reset(); |
| 1771 scheduler_->SetNeedsCommit(); |
| 1772 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1773 EXPECT_SCOPED(AdvanceFrame()); |
| 1774 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1775 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1776 scheduler_->NotifyBeginMainFrameStarted(); |
| 1777 scheduler_->NotifyReadyToCommit(); |
| 1778 scheduler_->NotifyReadyToActivate(); |
| 1779 |
| 1780 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 6); |
| 1781 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 6); |
| 1782 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 6); |
| 1783 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 6); |
| 1784 EXPECT_ACTION("ScheduledActionCommit", client_, 4, 6); |
| 1785 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 5, 6); |
| 1786 |
| 1787 // Don't call scheduler_->DidSwapBuffersComplete() until after next frame |
| 1788 // to put the impl thread in a high latency mode. |
| 1789 client_->Reset(); |
| 1790 scheduler_->SetNeedsCommit(); |
| 1791 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1792 EXPECT_TRUE(scheduler_->SwapThrottled()); |
| 1793 EXPECT_SCOPED(AdvanceFrame()); |
| 1794 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1795 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1796 |
| 1797 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 1798 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2); |
| 1799 // Note: BeginMainFrame and swap are skipped here because of |
| 1800 // swap ack backpressure, not because of latency recovery. |
| 1801 EXPECT_FALSE(client_->HasAction("ScheduledActionSendBeginMainFrame")); |
| 1802 EXPECT_FALSE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible")); |
| 1803 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1804 |
| 1805 // Lower estimates so that the scheduler will attempt latency recovery. |
| 1806 auto fast_duration = base::TimeDelta::FromMilliseconds(1); |
| 1807 fake_compositor_timing_history_->SetAllEstimatesTo(fast_duration); |
| 1808 |
| 1809 // Now that both threads are in a high latency mode, make sure we |
| 1810 // skip the BeginMainFrame, then the BeginImplFrame, but not both |
| 1811 // at the same time. |
| 1812 |
| 1813 // Verify we skip BeginMainFrame first. |
| 1814 client_->Reset(); |
| 1815 // Previous commit request is still outstanding. |
| 1816 EXPECT_TRUE(scheduler_->NeedsCommit()); |
| 1817 EXPECT_TRUE(scheduler_->SwapThrottled()); |
| 1818 SendNextBeginFrame(); |
| 1819 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1820 scheduler_->DidSwapBuffersComplete(); |
| 1821 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1822 |
| 1823 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1824 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3); |
| 1825 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 3); |
| 1826 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 3); |
| 1827 |
| 1828 // Verify we skip the BeginImplFrame second. |
| 1829 client_->Reset(); |
| 1830 // Previous commit request is still outstanding. |
| 1831 EXPECT_TRUE(scheduler_->NeedsCommit()); |
| 1832 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1833 SendNextBeginFrame(); |
| 1834 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1835 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1836 scheduler_->DidSwapBuffersComplete(); |
| 1837 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1838 |
| 1839 EXPECT_NO_ACTION(client_); |
| 1840 |
| 1841 // Then verify we operate in a low latency mode. |
| 1842 client_->Reset(); |
| 1843 // Previous commit request is still outstanding. |
| 1844 EXPECT_TRUE(scheduler_->NeedsCommit()); |
| 1845 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1846 SendNextBeginFrame(); |
| 1847 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1848 scheduler_->NotifyBeginMainFrameStarted(); |
| 1849 scheduler_->NotifyReadyToCommit(); |
| 1850 scheduler_->NotifyReadyToActivate(); |
| 1851 task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true)); |
| 1852 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1853 scheduler_->DidSwapBuffersComplete(); |
| 1854 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); |
| 1855 |
| 1856 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 6); |
| 1857 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 6); |
| 1858 EXPECT_ACTION("ScheduledActionCommit", client_, 2, 6); |
| 1859 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 3, 6); |
| 1860 EXPECT_ACTION("ScheduledActionAnimate", client_, 4, 6); |
| 1861 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 5, 6); |
1393 } | 1862 } |
1394 | 1863 |
1395 TEST_F( | 1864 TEST_F( |
1396 SchedulerTest, | 1865 SchedulerTest, |
1397 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) { | 1866 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) { |
1398 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main | 1867 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main |
1399 // thread. This prevents the scheduler from receiving any pending swap acks. | 1868 // thread. This prevents the scheduler from receiving any pending swap acks. |
1400 | 1869 |
1401 // Since we are simulating a long commit, set up a client with draw duration | |
1402 // estimates that prevent skipping main frames to get to low latency mode. | |
1403 scheduler_settings_.use_external_begin_frame_source = true; | 1870 scheduler_settings_.use_external_begin_frame_source = true; |
1404 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; | 1871 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; |
1405 SetUpScheduler(true); | 1872 SetUpScheduler(true); |
1406 | 1873 |
1407 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate( | |
1408 base::TimeDelta::FromMilliseconds(32)); | |
1409 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate( | |
1410 base::TimeDelta::FromMilliseconds(32)); | |
1411 fake_compositor_timing_history_->SetDrawDurationEstimate( | |
1412 base::TimeDelta::FromMilliseconds(1)); | |
1413 | |
1414 // Disables automatic swap acks so this test can force swap ack throttling | 1874 // Disables automatic swap acks so this test can force swap ack throttling |
1415 // to simulate a blocked Browser ui thread. | 1875 // to simulate a blocked Browser ui thread. |
1416 scheduler_->SetMaxSwapsPending(1); | 1876 scheduler_->SetMaxSwapsPending(1); |
1417 client_->SetAutomaticSwapAck(false); | 1877 client_->SetAutomaticSwapAck(false); |
1418 | 1878 |
1419 // Get a new active tree in main-thread high latency mode and put us | 1879 // Get a new active tree in main-thread high latency mode and put us |
1420 // in a swap throttled state. | 1880 // in a swap throttled state. |
1421 client_->Reset(); | 1881 client_->Reset(); |
1422 EXPECT_FALSE(scheduler_->CommitPending()); | 1882 EXPECT_FALSE(scheduler_->CommitPending()); |
1423 scheduler_->SetNeedsCommit(); | 1883 scheduler_->SetNeedsCommit(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1470 | 1930 |
1471 TEST_F(SchedulerTest, | 1931 TEST_F(SchedulerTest, |
1472 Deadlock_NoBeginMainFrameWhileSwapTrottledAndPipelineFull) { | 1932 Deadlock_NoBeginMainFrameWhileSwapTrottledAndPipelineFull) { |
1473 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main | 1933 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main |
1474 // thread. This prevents the scheduler from receiving any pending swap acks. | 1934 // thread. This prevents the scheduler from receiving any pending swap acks. |
1475 | 1935 |
1476 // This particular test makes sure we do not send a BeginMainFrame while | 1936 // This particular test makes sure we do not send a BeginMainFrame while |
1477 // swap trottled and we have a pending tree and active tree that | 1937 // swap trottled and we have a pending tree and active tree that |
1478 // still needs to be drawn for the first time. | 1938 // still needs to be drawn for the first time. |
1479 | 1939 |
1480 // Since we are simulating a long commit, set up a client with draw duration | |
1481 // estimates that prevent skipping main frames to get to low latency mode. | |
1482 scheduler_settings_.use_external_begin_frame_source = true; | 1940 scheduler_settings_.use_external_begin_frame_source = true; |
1483 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; | 1941 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; |
1484 scheduler_settings_.main_frame_before_activation_enabled = true; | 1942 scheduler_settings_.main_frame_before_activation_enabled = true; |
1485 SetUpScheduler(true); | 1943 SetUpScheduler(true); |
1486 | 1944 |
1487 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate( | |
1488 base::TimeDelta::FromMilliseconds(32)); | |
1489 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate( | |
1490 base::TimeDelta::FromMilliseconds(32)); | |
1491 fake_compositor_timing_history_->SetDrawDurationEstimate( | |
1492 base::TimeDelta::FromMilliseconds(1)); | |
1493 | |
1494 // Disables automatic swap acks so this test can force swap ack throttling | 1945 // Disables automatic swap acks so this test can force swap ack throttling |
1495 // to simulate a blocked Browser ui thread. | 1946 // to simulate a blocked Browser ui thread. |
1496 scheduler_->SetMaxSwapsPending(1); | 1947 scheduler_->SetMaxSwapsPending(1); |
1497 client_->SetAutomaticSwapAck(false); | 1948 client_->SetAutomaticSwapAck(false); |
1498 | 1949 |
1499 // Start a new commit in main-thread high latency mode and hold off on | 1950 // Start a new commit in main-thread high latency mode and hold off on |
1500 // activation. | 1951 // activation. |
1501 client_->Reset(); | 1952 client_->Reset(); |
1502 EXPECT_FALSE(scheduler_->CommitPending()); | 1953 EXPECT_FALSE(scheduler_->CommitPending()); |
1503 scheduler_->SetNeedsCommit(); | 1954 scheduler_->SetNeedsCommit(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1565 // This verifies we don't block commits longer than we need to | 2016 // This verifies we don't block commits longer than we need to |
1566 // for performance reasons - not deadlock reasons. | 2017 // for performance reasons - not deadlock reasons. |
1567 | 2018 |
1568 // Since we are simulating a long commit, set up a client with draw duration | 2019 // Since we are simulating a long commit, set up a client with draw duration |
1569 // estimates that prevent skipping main frames to get to low latency mode. | 2020 // estimates that prevent skipping main frames to get to low latency mode. |
1570 scheduler_settings_.use_external_begin_frame_source = true; | 2021 scheduler_settings_.use_external_begin_frame_source = true; |
1571 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; | 2022 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; |
1572 scheduler_settings_.main_frame_before_activation_enabled = true; | 2023 scheduler_settings_.main_frame_before_activation_enabled = true; |
1573 SetUpScheduler(true); | 2024 SetUpScheduler(true); |
1574 | 2025 |
1575 fake_compositor_timing_history_->SetBeginMainFrameToCommitDurationEstimate( | |
1576 base::TimeDelta::FromMilliseconds(32)); | |
1577 fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate( | |
1578 base::TimeDelta::FromMilliseconds(32)); | |
1579 fake_compositor_timing_history_->SetDrawDurationEstimate( | |
1580 base::TimeDelta::FromMilliseconds(1)); | |
1581 | |
1582 // Disables automatic swap acks so this test can force swap ack throttling | 2026 // Disables automatic swap acks so this test can force swap ack throttling |
1583 // to simulate a blocked Browser ui thread. | 2027 // to simulate a blocked Browser ui thread. |
1584 scheduler_->SetMaxSwapsPending(1); | 2028 scheduler_->SetMaxSwapsPending(1); |
1585 client_->SetAutomaticSwapAck(false); | 2029 client_->SetAutomaticSwapAck(false); |
1586 | 2030 |
1587 // Start a new commit in main-thread high latency mode and hold off on | 2031 // Start a new commit in main-thread high latency mode and hold off on |
1588 // activation. | 2032 // activation. |
1589 client_->Reset(); | 2033 client_->Reset(); |
1590 EXPECT_FALSE(scheduler_->CommitPending()); | 2034 EXPECT_FALSE(scheduler_->CommitPending()); |
1591 scheduler_->SetNeedsCommit(); | 2035 scheduler_->SetNeedsCommit(); |
(...skipping 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2989 scheduler_->SetImplLatencyTakesPriority(true); | 3433 scheduler_->SetImplLatencyTakesPriority(true); |
2990 scheduler_->SetChildrenNeedBeginFrames(true); | 3434 scheduler_->SetChildrenNeedBeginFrames(true); |
2991 | 3435 |
2992 EXPECT_SCOPED(AdvanceFrame()); | 3436 EXPECT_SCOPED(AdvanceFrame()); |
2993 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); | 3437 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); |
2994 EXPECT_FALSE(client_->begin_frame_args_sent_to_children().on_critical_path); | 3438 EXPECT_FALSE(client_->begin_frame_args_sent_to_children().on_critical_path); |
2995 } | 3439 } |
2996 | 3440 |
2997 } // namespace | 3441 } // namespace |
2998 } // namespace cc | 3442 } // namespace cc |
OLD | NEW |