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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
143 PushAction("ScheduledActionPrepareTiles"); | 143 PushAction("ScheduledActionPrepareTiles"); |
144 } | 144 } |
145 void ScheduledActionInvalidateOutputSurface() override { | 145 void ScheduledActionInvalidateOutputSurface() override { |
146 actions_.push_back("ScheduledActionInvalidateOutputSurface"); | 146 actions_.push_back("ScheduledActionInvalidateOutputSurface"); |
147 states_.push_back(scheduler_->AsValue()); | 147 states_.push_back(scheduler_->AsValue()); |
148 } | 148 } |
149 void DidAnticipatedDrawTimeChange(base::TimeTicks) override { | 149 void DidAnticipatedDrawTimeChange(base::TimeTicks) override { |
150 if (log_anticipated_draw_time_change_) | 150 if (log_anticipated_draw_time_change_) |
151 PushAction("DidAnticipatedDrawTimeChange"); | 151 PushAction("DidAnticipatedDrawTimeChange"); |
152 } | 152 } |
153 base::TimeDelta DrawDurationEstimate() override { return base::TimeDelta(); } | 153 |
154 // Use really long estimations by default so we don't inadvertently | |
155 // test latency recovery logic unless a test explicitly wants to. | |
mithro-old
2015/05/27 04:40:14
These tests should be deterministic, so I'm not su
| |
156 base::TimeDelta DrawDurationEstimate() override { | |
157 return base::TimeDelta::FromHours(1); | |
158 } | |
154 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { | 159 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { |
155 return base::TimeDelta(); | 160 return base::TimeDelta::FromHours(1); |
156 } | 161 } |
157 base::TimeDelta CommitToActivateDurationEstimate() override { | 162 base::TimeDelta CommitToActivateDurationEstimate() override { |
158 return base::TimeDelta(); | 163 return base::TimeDelta::FromHours(1); |
159 } | 164 } |
160 | 165 |
161 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { | 166 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { |
162 begin_frame_args_sent_to_children_ = args; | 167 begin_frame_args_sent_to_children_ = args; |
163 } | 168 } |
164 | 169 |
165 void SendBeginMainFrameNotExpectedSoon() override { | 170 void SendBeginMainFrameNotExpectedSoon() override { |
166 PushAction("SendBeginMainFrameNotExpectedSoon"); | 171 PushAction("SendBeginMainFrameNotExpectedSoon"); |
167 } | 172 } |
168 | 173 |
(...skipping 27 matching lines...) Expand all Loading... | |
196 int num_draws_; | 201 int num_draws_; |
197 bool log_anticipated_draw_time_change_; | 202 bool log_anticipated_draw_time_change_; |
198 BeginFrameArgs begin_frame_args_sent_to_children_; | 203 BeginFrameArgs begin_frame_args_sent_to_children_; |
199 base::TimeTicks posted_begin_impl_frame_deadline_; | 204 base::TimeTicks posted_begin_impl_frame_deadline_; |
200 std::vector<const char*> actions_; | 205 std::vector<const char*> actions_; |
201 std::vector<scoped_refptr<base::trace_event::ConvertableToTraceFormat>> | 206 std::vector<scoped_refptr<base::trace_event::ConvertableToTraceFormat>> |
202 states_; | 207 states_; |
203 TestScheduler* scheduler_; | 208 TestScheduler* scheduler_; |
204 }; | 209 }; |
205 | 210 |
206 class SchedulerClientWithFixedEstimates : public FakeSchedulerClient { | 211 class SchedulerClientWithCustomEstimates : public FakeSchedulerClient { |
mithro-old
2015/05/27 04:40:14
Is there any reason we don't just make this part o
| |
207 public: | 212 public: |
208 SchedulerClientWithFixedEstimates( | 213 SchedulerClientWithCustomEstimates( |
209 base::TimeDelta draw_duration, | 214 base::TimeDelta draw_duration, |
210 base::TimeDelta begin_main_frame_to_commit_duration, | 215 base::TimeDelta begin_main_frame_to_commit_duration, |
211 base::TimeDelta commit_to_activate_duration) | 216 base::TimeDelta commit_to_activate_duration) |
212 : draw_duration_(draw_duration), | 217 : draw_duration_(draw_duration), |
213 begin_main_frame_to_commit_duration_( | 218 begin_main_frame_to_commit_duration_( |
214 begin_main_frame_to_commit_duration), | 219 begin_main_frame_to_commit_duration), |
215 commit_to_activate_duration_(commit_to_activate_duration) {} | 220 commit_to_activate_duration_(commit_to_activate_duration) {} |
216 | 221 |
217 base::TimeDelta DrawDurationEstimate() override { return draw_duration_; } | 222 base::TimeDelta DrawDurationEstimate() override { return draw_duration_; } |
218 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { | 223 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { |
219 return begin_main_frame_to_commit_duration_; | 224 return begin_main_frame_to_commit_duration_; |
220 } | 225 } |
221 base::TimeDelta CommitToActivateDurationEstimate() override { | 226 base::TimeDelta CommitToActivateDurationEstimate() override { |
222 return commit_to_activate_duration_; | 227 return commit_to_activate_duration_; |
223 } | 228 } |
224 | 229 |
225 private: | 230 public: |
226 base::TimeDelta draw_duration_; | 231 base::TimeDelta draw_duration_; |
227 base::TimeDelta begin_main_frame_to_commit_duration_; | 232 base::TimeDelta begin_main_frame_to_commit_duration_; |
228 base::TimeDelta commit_to_activate_duration_; | 233 base::TimeDelta commit_to_activate_duration_; |
229 }; | 234 }; |
230 | 235 |
231 class FakeExternalBeginFrameSource : public BeginFrameSourceMixIn { | 236 class FakeExternalBeginFrameSource : public BeginFrameSourceMixIn { |
232 public: | 237 public: |
233 explicit FakeExternalBeginFrameSource(FakeSchedulerClient* client) | 238 explicit FakeExternalBeginFrameSource(FakeSchedulerClient* client) |
234 : client_(client) {} | 239 : client_(client) {} |
235 ~FakeExternalBeginFrameSource() override {} | 240 ~FakeExternalBeginFrameSource() override {} |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
413 | 418 |
414 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { | 419 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { |
415 return fake_external_begin_frame_source_; | 420 return fake_external_begin_frame_source_; |
416 } | 421 } |
417 | 422 |
418 void MainFrameInHighLatencyMode( | 423 void MainFrameInHighLatencyMode( |
419 int64 begin_main_frame_to_commit_estimate_in_ms, | 424 int64 begin_main_frame_to_commit_estimate_in_ms, |
420 int64 commit_to_activate_estimate_in_ms, | 425 int64 commit_to_activate_estimate_in_ms, |
421 bool impl_latency_takes_priority, | 426 bool impl_latency_takes_priority, |
422 bool should_send_begin_main_frame); | 427 bool should_send_begin_main_frame); |
428 void SwapIsHighLatency(int64 draw_estimate_in_ms, | |
429 int64 begin_main_frame_to_commit_estimate_in_ms, | |
430 int64 commit_to_activate_estimate_in_ms, | |
431 bool has_impl_side_updates, | |
432 bool swap_ack_before_deadline, | |
433 bool should_draw_and_swap_in_high_latency); | |
423 void BeginFramesNotFromClient(bool use_external_begin_frame_source, | 434 void BeginFramesNotFromClient(bool use_external_begin_frame_source, |
424 bool throttle_frame_production); | 435 bool throttle_frame_production); |
425 void BeginFramesNotFromClient_SwapThrottled( | 436 void BeginFramesNotFromClient_SwapThrottled( |
426 bool use_external_begin_frame_source, | 437 bool use_external_begin_frame_source, |
427 bool throttle_frame_production); | 438 bool throttle_frame_production); |
428 void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency( | 439 void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency( |
429 bool impl_side_painting); | 440 bool impl_side_painting); |
430 void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting); | 441 void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting); |
431 | 442 |
432 scoped_refptr<TestNowSource> now_src_; | 443 scoped_refptr<TestNowSource> now_src_; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
479 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | 490 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
480 EXPECT_TRUE(client_->needs_begin_frames()); | 491 EXPECT_TRUE(client_->needs_begin_frames()); |
481 | 492 |
482 client_->Reset(); | 493 client_->Reset(); |
483 EXPECT_SCOPED(AdvanceFrame()); | 494 EXPECT_SCOPED(AdvanceFrame()); |
484 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); | 495 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); |
485 } | 496 } |
486 | 497 |
487 TEST_F(SchedulerTest, SendBeginFramesToChildrenDeadlineNotAdjusted) { | 498 TEST_F(SchedulerTest, SendBeginFramesToChildrenDeadlineNotAdjusted) { |
488 // Set up client with specified estimates. | 499 // Set up client with specified estimates. |
489 SchedulerClientWithFixedEstimates* client = | 500 SchedulerClientWithCustomEstimates* client = |
490 new SchedulerClientWithFixedEstimates( | 501 new SchedulerClientWithCustomEstimates( |
mithro-old
2015/05/27 04:40:15
It might be worth adding a comment which says whic
| |
491 base::TimeDelta::FromMilliseconds(1), | 502 base::TimeDelta::FromMilliseconds(1), |
492 base::TimeDelta::FromMilliseconds(2), | 503 base::TimeDelta::FromMilliseconds(2), |
493 base::TimeDelta::FromMilliseconds(4)); | 504 base::TimeDelta::FromMilliseconds(4)); |
494 scheduler_settings_.use_external_begin_frame_source = true; | 505 scheduler_settings_.use_external_begin_frame_source = true; |
495 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | 506 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
496 | 507 |
497 EXPECT_FALSE(client_->needs_begin_frames()); | 508 EXPECT_FALSE(client_->needs_begin_frames()); |
498 scheduler_->SetChildrenNeedBeginFrames(true); | 509 scheduler_->SetChildrenNeedBeginFrames(true); |
499 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | 510 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
500 EXPECT_TRUE(client_->needs_begin_frames()); | 511 EXPECT_TRUE(client_->needs_begin_frames()); |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1311 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3); | 1322 EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3); |
1312 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); | 1323 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); |
1313 } | 1324 } |
1314 | 1325 |
1315 void SchedulerTest::MainFrameInHighLatencyMode( | 1326 void SchedulerTest::MainFrameInHighLatencyMode( |
1316 int64 begin_main_frame_to_commit_estimate_in_ms, | 1327 int64 begin_main_frame_to_commit_estimate_in_ms, |
1317 int64 commit_to_activate_estimate_in_ms, | 1328 int64 commit_to_activate_estimate_in_ms, |
1318 bool impl_latency_takes_priority, | 1329 bool impl_latency_takes_priority, |
1319 bool should_send_begin_main_frame) { | 1330 bool should_send_begin_main_frame) { |
1320 // Set up client with specified estimates (draw duration is set to 1). | 1331 // Set up client with specified estimates (draw duration is set to 1). |
1321 SchedulerClientWithFixedEstimates* client = | 1332 SchedulerClientWithCustomEstimates* client = |
1322 new SchedulerClientWithFixedEstimates( | 1333 new SchedulerClientWithCustomEstimates( |
1323 base::TimeDelta::FromMilliseconds(1), | 1334 base::TimeDelta::FromMilliseconds(1), |
1324 base::TimeDelta::FromMilliseconds( | 1335 base::TimeDelta::FromMilliseconds( |
1325 begin_main_frame_to_commit_estimate_in_ms), | 1336 begin_main_frame_to_commit_estimate_in_ms), |
1326 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms)); | 1337 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms)); |
1327 | 1338 |
1328 scheduler_settings_.use_external_begin_frame_source = true; | 1339 scheduler_settings_.use_external_begin_frame_source = true; |
1329 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | 1340 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
1330 | 1341 |
1331 scheduler_->SetImplLatencyTakesPriority(impl_latency_takes_priority); | 1342 scheduler_->SetImplLatencyTakesPriority(impl_latency_takes_priority); |
1332 | 1343 |
(...skipping 17 matching lines...) Expand all Loading... | |
1350 task_runner().RunPendingTasks(); // Run posted deadline. | 1361 task_runner().RunPendingTasks(); // Run posted deadline. |
1351 EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(), | 1362 EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(), |
1352 should_send_begin_main_frame); | 1363 should_send_begin_main_frame); |
1353 EXPECT_EQ(client->HasAction("ScheduledActionSendBeginMainFrame"), | 1364 EXPECT_EQ(client->HasAction("ScheduledActionSendBeginMainFrame"), |
1354 should_send_begin_main_frame); | 1365 should_send_begin_main_frame); |
1355 } | 1366 } |
1356 | 1367 |
1357 TEST_F(SchedulerTest, | 1368 TEST_F(SchedulerTest, |
1358 SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) { | 1369 SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) { |
1359 // Set up client so that estimates indicate that we can commit and activate | 1370 // Set up client so that estimates indicate that we can commit and activate |
1360 // before the deadline (~8ms by default). | 1371 // before the deadline (~11ms by default). |
1361 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, false, false)); | 1372 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, false, false)); |
1362 } | 1373 } |
1363 | 1374 |
1364 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) { | 1375 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) { |
1365 // Set up client so that estimates indicate that the commit cannot finish | 1376 // Set up client so that estimates indicate that the commit cannot finish |
1366 // before the deadline (~8ms by default). | 1377 // before the deadline (~11ms by default). |
1367 EXPECT_SCOPED(MainFrameInHighLatencyMode(10, 1, false, true)); | 1378 EXPECT_SCOPED(MainFrameInHighLatencyMode(10, 1, false, true)); |
1368 } | 1379 } |
1369 | 1380 |
1370 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) { | 1381 TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) { |
1371 // Set up client so that estimates indicate that the activate cannot finish | 1382 // Set up client so that estimates indicate that the activate cannot finish |
1372 // before the deadline (~8ms by default). | 1383 // before the deadline (~11ms by default). |
1373 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true)); | 1384 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 10, false, true)); |
1374 } | 1385 } |
1375 | 1386 |
1376 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) { | 1387 TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) { |
1377 // Set up client so that estimates indicate that we can commit and activate | 1388 // Set up client so that estimates indicate that we can commit and activate |
1378 // before the deadline (~8ms by default), but also enable impl latency takes | 1389 // before the deadline (~11ms by default), but also enable impl latency takes |
1379 // priority mode. | 1390 // priority mode. |
1380 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true)); | 1391 EXPECT_SCOPED(MainFrameInHighLatencyMode(1, 1, true, true)); |
1381 } | 1392 } |
1382 | 1393 |
1394 void SchedulerTest::SwapIsHighLatency( | |
1395 int64 draw_estimate_in_ms, | |
1396 int64 begin_main_frame_to_commit_estimate_in_ms, | |
1397 int64 commit_to_activate_estimate_in_ms, | |
1398 bool has_impl_side_updates, | |
1399 bool swap_ack_before_deadline, | |
1400 bool should_draw_and_swap_in_high_latency) { | |
1401 // Set up client with specified estimates. | |
1402 SchedulerClientWithCustomEstimates* client = | |
1403 new SchedulerClientWithCustomEstimates( | |
1404 base::TimeDelta::FromMilliseconds(draw_estimate_in_ms), | |
1405 base::TimeDelta::FromMilliseconds( | |
1406 begin_main_frame_to_commit_estimate_in_ms), | |
1407 base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms)); | |
1408 | |
1409 scheduler_settings_.use_external_begin_frame_source = true; | |
1410 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | |
1411 | |
1412 // To get into a high latency state, this test disables automatic swap acks. | |
1413 scheduler_->SetMaxSwapsPending(1); | |
1414 client_->SetAutomaticSwapAck(false); | |
1415 | |
1416 // Draw and swap for first BeginFrame | |
1417 client->Reset(); | |
1418 scheduler_->SetNeedsCommit(); | |
1419 if (has_impl_side_updates) | |
1420 scheduler_->SetNeedsRedraw(); | |
1421 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1422 EXPECT_SCOPED(AdvanceFrame()); | |
1423 scheduler_->NotifyBeginMainFrameStarted(); | |
1424 scheduler_->NotifyReadyToCommit(); | |
1425 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1426 task_runner().RunPendingTasks(); // Run posted deadline. | |
1427 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); | |
1428 | |
1429 // Not calling scheduler_->DidSwapBuffersComplete() until after next frame | |
1430 // puts impl thread in high latency mode. | |
1431 client->Reset(); | |
1432 scheduler_->SetNeedsCommit(); | |
1433 if (has_impl_side_updates) | |
1434 scheduler_->SetNeedsRedraw(); | |
1435 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1436 if (should_draw_and_swap_in_high_latency) { | |
mithro-old
2015/05/27 04:40:14
Instead of using if statements here, does it make
| |
1437 AdvanceFrame(); | |
1438 } else { | |
1439 // Don't use AdvanceFrame since we expect the the Scheduler to | |
1440 // skip the BeginImplFrame. | |
mithro-old
2015/05/27 04:40:15
I feel like there isn't enough checks in this sect
| |
1441 SendNextBeginFrame(); | |
1442 EXPECT_FALSE(client->HasAction("WillBeginImplFrame")); | |
1443 EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending()); | |
1444 } | |
1445 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1446 | |
1447 if (should_draw_and_swap_in_high_latency) { | |
1448 DCHECK(swap_ack_before_deadline); | |
1449 scheduler_->DidSwapBuffersComplete(); | |
1450 scheduler_->NotifyBeginMainFrameStarted(); | |
1451 scheduler_->NotifyReadyToCommit(); | |
1452 task_runner().RunPendingTasks(); // Run posted deadline. | |
mithro-old
2015/05/27 04:40:14
Please run tasks until a condition is met rather t
| |
1453 } else if (swap_ack_before_deadline) { | |
1454 scheduler_->DidSwapBuffersComplete(); | |
1455 task_runner().RunPendingTasks(); // Run posted deadline. | |
1456 } else { | |
1457 task_runner().RunPendingTasks(); // Run posted deadline. | |
1458 scheduler_->DidSwapBuffersComplete(); | |
1459 } | |
1460 | |
1461 // Verify that we recovered immediately if we were supposed to. | |
1462 EXPECT_EQ(should_draw_and_swap_in_high_latency, | |
1463 client->HasAction("ScheduledActionDrawAndSwapIfPossible")); | |
1464 if (should_draw_and_swap_in_high_latency) | |
1465 scheduler_->DidSwapBuffersComplete(); | |
1466 | |
1467 // Verify that we: | |
1468 // 1) Don't skip two frames in a row. | |
1469 // 2) Continue normal operation if we didn't skip a frame. | |
1470 // 3) Make forward progress even when we aren't expecting another swap ack. | |
1471 client->Reset(); | |
1472 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1473 scheduler_->SetNeedsCommit(); | |
1474 if (has_impl_side_updates) | |
1475 scheduler_->SetNeedsRedraw(); | |
1476 EXPECT_SCOPED(AdvanceFrame()); | |
1477 scheduler_->NotifyBeginMainFrameStarted(); | |
1478 scheduler_->NotifyReadyToCommit(); | |
1479 task_runner().RunPendingTasks(); // Run posted deadline. | |
1480 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); | |
1481 } | |
1482 | |
1483 TEST_F(SchedulerTest, | |
1484 SkipSwapIfHighLatencyAndCanDrawBeforeDeadline_SwapAckThenDeadline) { | |
1485 // Set up client so that estimates indicate that we can commit and activate | |
1486 // before the deadline (~11ms by default). | |
1487 EXPECT_SCOPED(SwapIsHighLatency(1, 1, 1, true, true, false)); | |
mithro-old
2015/05/27 04:40:15
It's really hard to understand how the values (1,1
| |
1488 } | |
1489 | |
1490 TEST_F(SchedulerTest, | |
1491 SkipSwapIfHighLatencyAndCanDrawBeforeDeadline_DeadlineThenSwapAck) { | |
1492 // Set up client so that estimates indicate that we can commit and activate | |
1493 // before the deadline (~11ms by default). | |
1494 EXPECT_SCOPED(SwapIsHighLatency(1, 1, 1, true, false, false)); | |
1495 } | |
1496 | |
1497 TEST_F(SchedulerTest, NotSkipSwapIfHighLatencyAndCanDrawTooLong) { | |
1498 // Set up client so that estimates indicate that the commit cannot finish | |
1499 // before the deadline (~11ms by default). | |
1500 EXPECT_SCOPED(SwapIsHighLatency(20, 1, 1, true, true, true)); | |
1501 } | |
1502 | |
1503 TEST_F(SchedulerTest, NotSkipSwapIfHighLatencyAndCanActivateTooLong) { | |
1504 // Set up client so that estimates indicate that the activate cannot finish | |
1505 // before the deadline (~11ms by default). | |
1506 EXPECT_SCOPED(SwapIsHighLatency(1, 8, 8, false, true, true)); | |
1507 } | |
1508 | |
1509 TEST_F(SchedulerTest, MainAndSwapInHighLatencyMode) { | |
1510 // Set up client with custom estimates. | |
1511 // This test starts off with expensive estimates to prevent latency recovery | |
1512 // initially, the lowers the estimates to enable it once both the main | |
1513 // and impl threads are in a high latency mode. | |
1514 auto fast_duration = base::TimeDelta::FromMilliseconds(1); | |
1515 auto slow_duration = base::TimeDelta::FromMilliseconds(10); | |
mithro-old
2015/05/27 04:40:15
10ms it a slow estimate?
| |
1516 SchedulerClientWithCustomEstimates* client = | |
1517 new SchedulerClientWithCustomEstimates(slow_duration, slow_duration, | |
1518 slow_duration); | |
1519 | |
1520 scheduler_settings_.use_external_begin_frame_source = true; | |
1521 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | |
1522 | |
1523 // To get into a high latency state, this test disables automatic swap acks. | |
1524 scheduler_->SetMaxSwapsPending(1); | |
1525 client_->SetAutomaticSwapAck(false); | |
1526 | |
1527 // Impl thread hits deadline before commit finishes to make | |
1528 // MainThreadIsInHighLatencyMode true | |
1529 client->Reset(); | |
1530 scheduler_->SetNeedsCommit(); | |
1531 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1532 EXPECT_SCOPED(AdvanceFrame()); | |
1533 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1534 task_runner().RunPendingTasks(); // Run posted deadline. | |
1535 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1536 scheduler_->NotifyBeginMainFrameStarted(); | |
1537 scheduler_->NotifyReadyToCommit(); | |
1538 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1539 EXPECT_TRUE(client->HasAction("WillBeginImplFrame")); | |
1540 EXPECT_TRUE(client->HasAction("ScheduledActionSendBeginMainFrame")); | |
1541 | |
1542 // Draw and swap for first commit, start second commit. | |
1543 client->Reset(); | |
1544 scheduler_->SetNeedsCommit(); | |
1545 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1546 EXPECT_SCOPED(AdvanceFrame()); | |
1547 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1548 task_runner().RunPendingTasks(); // Run posted deadline. | |
1549 scheduler_->NotifyBeginMainFrameStarted(); | |
1550 scheduler_->NotifyReadyToCommit(); | |
1551 EXPECT_TRUE(client->HasAction("WillBeginImplFrame")); | |
1552 EXPECT_TRUE(client->HasAction("ScheduledActionSendBeginMainFrame")); | |
1553 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); | |
1554 | |
1555 // Don't call scheduler_->DidSwapBuffersComplete() until after next frame | |
1556 // to put the impl thread in a high latency mode. | |
1557 client->Reset(); | |
1558 scheduler_->SetNeedsCommit(); | |
1559 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1560 EXPECT_SCOPED(AdvanceFrame()); | |
1561 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1562 task_runner().RunPendingTasks(); // Run posted deadline. | |
1563 scheduler_->DidSwapBuffersComplete(); | |
1564 EXPECT_TRUE(client->HasAction("WillBeginImplFrame")); | |
1565 // Note: BeginMainFrame and BeginImplFrame are skipped here because | |
1566 // of backpressure, not because of latency recovery. | |
1567 EXPECT_FALSE(client->HasAction("ScheduledActionSendBeginMainFrame")); | |
1568 EXPECT_FALSE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); | |
1569 | |
1570 // Lower estimates so that the scheduler will attempt latency recovery. | |
mithro-old
2015/05/27 04:40:15
How would this happen in the "real" world?
| |
1571 client->begin_main_frame_to_commit_duration_ = fast_duration; | |
1572 client->commit_to_activate_duration_ = fast_duration; | |
1573 client->draw_duration_ = fast_duration; | |
1574 | |
1575 // Now that both threads are in a high latency mode, make sure we | |
mithro-old
2015/05/27 04:40:14
I think you should have checks here which verify y
| |
1576 // skip the BeginMainFrame, then the BeginImplFrame, but not both | |
1577 // at the same time. | |
1578 | |
1579 // Verify we skip BeginMainFrame first. | |
1580 client->Reset(); | |
1581 EXPECT_TRUE(scheduler_->NeedsCommit()); // Previous commit still outstanding. | |
1582 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1583 SendNextBeginFrame(); | |
1584 task_runner().RunPendingTasks(); // Run posted deadline. | |
mithro-old
2015/05/27 04:40:15
RunPendingTasks is the devil.... What are you actu
| |
1585 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1586 EXPECT_TRUE(client->HasAction("WillBeginImplFrame")); | |
1587 EXPECT_FALSE(client->HasAction("ScheduledActionSendBeginMainFrame")); | |
1588 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); | |
1589 | |
1590 // Verify we skip the DrawAndSwap second. | |
1591 client->Reset(); | |
1592 EXPECT_TRUE(scheduler_->NeedsCommit()); // Previous commit still outstanding. | |
1593 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1594 SendNextBeginFrame(); | |
1595 task_runner().RunPendingTasks(); // Run posted deadline. | |
mithro-old
2015/05/27 04:40:14
....
| |
1596 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1597 scheduler_->DidSwapBuffersComplete(); | |
1598 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1599 EXPECT_FALSE(client->HasAction("WillBeginImplFrame")); | |
1600 EXPECT_FALSE(client->HasAction("ScheduledActionSendBeginMainFrame")); | |
1601 EXPECT_FALSE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); | |
1602 | |
1603 // Then verify we operate in a low latency mode. | |
1604 client->Reset(); | |
1605 EXPECT_TRUE(scheduler_->NeedsCommit()); // Previous commit still outstanding. | |
1606 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1607 SendNextBeginFrame(); | |
1608 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1609 scheduler_->NotifyBeginMainFrameStarted(); | |
1610 scheduler_->NotifyReadyToCommit(); | |
1611 task_runner().RunPendingTasks(); // Run posted deadline. | |
1612 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1613 scheduler_->DidSwapBuffersComplete(); | |
1614 EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode()); | |
1615 EXPECT_TRUE(client->HasAction("WillBeginImplFrame")); | |
1616 EXPECT_TRUE(client->HasAction("ScheduledActionSendBeginMainFrame")); | |
1617 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); | |
1618 } | |
1619 | |
1383 TEST_F(SchedulerTest, | 1620 TEST_F(SchedulerTest, |
1384 Deadlock_NotifyReadyToCommitMakesProgressWhileSwapTrottled) { | 1621 Deadlock_NotifyReadyToCommitMakesProgressWhileSwapTrottled) { |
1385 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main | 1622 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main |
1386 // thread. This prevents the scheduler from receiving any pending swap acks. | 1623 // thread. This prevents the scheduler from receiving any pending swap acks. |
1387 // This test makes sure that we keep updating the TextureUploader with | 1624 // This test makes sure that we keep updating the TextureUploader with |
1388 // DidAnticipatedDrawTimeChange's so that it can make forward progress and | 1625 // DidAnticipatedDrawTimeChange's so that it can make forward progress and |
1389 // upload all the textures needed for the commit to complete. | 1626 // upload all the textures needed for the commit to complete. |
1390 | 1627 |
1391 // Since we are simulating a long commit, set up a client with draw duration | 1628 // Since we are simulating a long commit, set up a client with draw duration |
1392 // estimates that prevent skipping main frames to get to low latency mode. | 1629 // estimates that prevent skipping main frames to get to low latency mode. |
1393 SchedulerClientWithFixedEstimates* client = | 1630 SchedulerClientWithCustomEstimates* client = |
1394 new SchedulerClientWithFixedEstimates( | 1631 new SchedulerClientWithCustomEstimates( |
1395 base::TimeDelta::FromMilliseconds(1), | 1632 base::TimeDelta::FromMilliseconds(1), |
1396 base::TimeDelta::FromMilliseconds(32), | 1633 base::TimeDelta::FromMilliseconds(32), |
1397 base::TimeDelta::FromMilliseconds(32)); | 1634 base::TimeDelta::FromMilliseconds(32)); |
1398 scheduler_settings_.use_external_begin_frame_source = true; | 1635 scheduler_settings_.use_external_begin_frame_source = true; |
1399 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | 1636 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
1400 | 1637 |
1401 client->set_log_anticipated_draw_time_change(true); | 1638 client->set_log_anticipated_draw_time_change(true); |
1402 | 1639 |
1403 BeginFrameArgs frame_args = | 1640 BeginFrameArgs frame_args = |
1404 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); | 1641 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1449 } | 1686 } |
1450 | 1687 |
1451 TEST_F( | 1688 TEST_F( |
1452 SchedulerTest, | 1689 SchedulerTest, |
1453 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) { | 1690 Deadlock_CommitMakesProgressWhileSwapTrottledAndActiveTreeNeedsFirstDraw) { |
1454 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main | 1691 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main |
1455 // thread. This prevents the scheduler from receiving any pending swap acks. | 1692 // thread. This prevents the scheduler from receiving any pending swap acks. |
1456 | 1693 |
1457 // Since we are simulating a long commit, set up a client with draw duration | 1694 // Since we are simulating a long commit, set up a client with draw duration |
1458 // estimates that prevent skipping main frames to get to low latency mode. | 1695 // estimates that prevent skipping main frames to get to low latency mode. |
1459 SchedulerClientWithFixedEstimates* client = | 1696 SchedulerClientWithCustomEstimates* client = |
1460 new SchedulerClientWithFixedEstimates( | 1697 new SchedulerClientWithCustomEstimates( |
1461 base::TimeDelta::FromMilliseconds(1), | 1698 base::TimeDelta::FromMilliseconds(1), |
1462 base::TimeDelta::FromMilliseconds(32), | 1699 base::TimeDelta::FromMilliseconds(32), |
1463 base::TimeDelta::FromMilliseconds(32)); | 1700 base::TimeDelta::FromMilliseconds(32)); |
1464 scheduler_settings_.use_external_begin_frame_source = true; | 1701 scheduler_settings_.use_external_begin_frame_source = true; |
1465 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; | 1702 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; |
1466 scheduler_settings_.impl_side_painting = true; | 1703 scheduler_settings_.impl_side_painting = true; |
1467 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | 1704 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
1468 | 1705 |
1469 // Disables automatic swap acks so this test can force swap ack throttling | 1706 // Disables automatic swap acks so this test can force swap ack throttling |
1470 // to simulate a blocked Browser ui thread. | 1707 // to simulate a blocked Browser ui thread. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1527 Deadlock_NoBeginMainFrameWhileSwapTrottledAndPipelineFull) { | 1764 Deadlock_NoBeginMainFrameWhileSwapTrottledAndPipelineFull) { |
1528 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main | 1765 // NPAPI plugins on Windows block the Browser UI thread on the Renderer main |
1529 // thread. This prevents the scheduler from receiving any pending swap acks. | 1766 // thread. This prevents the scheduler from receiving any pending swap acks. |
1530 | 1767 |
1531 // This particular test makes sure we do not send a BeginMainFrame while | 1768 // This particular test makes sure we do not send a BeginMainFrame while |
1532 // swap trottled and we have a pending tree and active tree that | 1769 // swap trottled and we have a pending tree and active tree that |
1533 // still needs to be drawn for the first time. | 1770 // still needs to be drawn for the first time. |
1534 | 1771 |
1535 // Since we are simulating a long commit, set up a client with draw duration | 1772 // Since we are simulating a long commit, set up a client with draw duration |
1536 // estimates that prevent skipping main frames to get to low latency mode. | 1773 // estimates that prevent skipping main frames to get to low latency mode. |
1537 SchedulerClientWithFixedEstimates* client = | 1774 SchedulerClientWithCustomEstimates* client = |
1538 new SchedulerClientWithFixedEstimates( | 1775 new SchedulerClientWithCustomEstimates( |
1539 base::TimeDelta::FromMilliseconds(1), | 1776 base::TimeDelta::FromMilliseconds(1), |
1540 base::TimeDelta::FromMilliseconds(32), | 1777 base::TimeDelta::FromMilliseconds(32), |
1541 base::TimeDelta::FromMilliseconds(32)); | 1778 base::TimeDelta::FromMilliseconds(32)); |
1542 scheduler_settings_.use_external_begin_frame_source = true; | 1779 scheduler_settings_.use_external_begin_frame_source = true; |
1543 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; | 1780 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; |
1544 scheduler_settings_.main_frame_before_activation_enabled = true; | 1781 scheduler_settings_.main_frame_before_activation_enabled = true; |
1545 scheduler_settings_.impl_side_painting = true; | 1782 scheduler_settings_.impl_side_painting = true; |
1546 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | 1783 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
1547 | 1784 |
1548 // Disables automatic swap acks so this test can force swap ack throttling | 1785 // Disables automatic swap acks so this test can force swap ack throttling |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1614 } | 1851 } |
1615 | 1852 |
1616 TEST_F( | 1853 TEST_F( |
1617 SchedulerTest, | 1854 SchedulerTest, |
1618 CommitMakesProgressWhenIdleAndHasPendingTreeAndActiveTreeNeedsFirstDraw) { | 1855 CommitMakesProgressWhenIdleAndHasPendingTreeAndActiveTreeNeedsFirstDraw) { |
1619 // This verifies we don't block commits longer than we need to | 1856 // This verifies we don't block commits longer than we need to |
1620 // for performance reasons - not deadlock reasons. | 1857 // for performance reasons - not deadlock reasons. |
1621 | 1858 |
1622 // Since we are simulating a long commit, set up a client with draw duration | 1859 // Since we are simulating a long commit, set up a client with draw duration |
1623 // estimates that prevent skipping main frames to get to low latency mode. | 1860 // estimates that prevent skipping main frames to get to low latency mode. |
1624 SchedulerClientWithFixedEstimates* client = | 1861 SchedulerClientWithCustomEstimates* client = |
1625 new SchedulerClientWithFixedEstimates( | 1862 new SchedulerClientWithCustomEstimates( |
1626 base::TimeDelta::FromMilliseconds(1), | 1863 base::TimeDelta::FromMilliseconds(1), |
1627 base::TimeDelta::FromMilliseconds(32), | 1864 base::TimeDelta::FromMilliseconds(32), |
1628 base::TimeDelta::FromMilliseconds(32)); | 1865 base::TimeDelta::FromMilliseconds(32)); |
1629 scheduler_settings_.use_external_begin_frame_source = true; | 1866 scheduler_settings_.use_external_begin_frame_source = true; |
1630 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; | 1867 scheduler_settings_.main_frame_while_swap_throttled_enabled = true; |
1631 scheduler_settings_.main_frame_before_activation_enabled = true; | 1868 scheduler_settings_.main_frame_before_activation_enabled = true; |
1632 scheduler_settings_.impl_side_painting = true; | 1869 scheduler_settings_.impl_side_painting = true; |
1633 SetUpScheduler(make_scoped_ptr(client).Pass(), true); | 1870 SetUpScheduler(make_scoped_ptr(client).Pass(), true); |
1634 | 1871 |
1635 // Disables automatic swap acks so this test can force swap ack throttling | 1872 // Disables automatic swap acks so this test can force swap ack throttling |
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2937 | 3174 |
2938 // At the next BeginFrame, authoritative interval is used instead of previous | 3175 // At the next BeginFrame, authoritative interval is used instead of previous |
2939 // interval. | 3176 // interval. |
2940 EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval); | 3177 EXPECT_NE(initial_interval, scheduler_->begin_impl_frame_args().interval); |
2941 EXPECT_EQ(authoritative_interval, | 3178 EXPECT_EQ(authoritative_interval, |
2942 scheduler_->begin_impl_frame_args().interval); | 3179 scheduler_->begin_impl_frame_args().interval); |
2943 } | 3180 } |
2944 | 3181 |
2945 } // namespace | 3182 } // namespace |
2946 } // namespace cc | 3183 } // namespace cc |
OLD | NEW |