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

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: rebase; really simplify heuristic Created 5 years, 7 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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
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.
156 base::TimeDelta DrawDurationEstimate() override {
157 return base::TimeDelta::FromHours(1);
sunnyps 2015/05/22 21:15:05 nit: base::TimeDelta::Max()
brianderson 2015/05/23 00:53:57 Tried this and ended up with test failures - I thi
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
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 {
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:
sunnyps 2015/05/22 21:15:05 Why public?
brianderson 2015/05/23 00:53:56 One of the tests changes the settings dynamically
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
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
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(
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
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
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(
sunnyps 2015/05/22 21:15:05 nit: ImplFrameInHighLatencyMode or similar? feel f
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);
sunnyps 2015/05/22 21:15:05 No need to call Pass() here.
brianderson 2015/06/30 22:03:52 NA in latest patch set.
1411
1412 // To get into a high latency state, this test disables automatic swap acks.
1413 scheduler_->SetMaxSwapsPending(1);
1414 client_->SetAutomaticSwapAck(false);
sunnyps 2015/05/22 21:15:05 Use either client_ or client consistently. I would
brianderson 2015/06/30 22:03:53 NA in latest patch set.
1415
sunnyps 2015/05/22 21:15:05 Please make these changes to the MainFrameInHighLa
brianderson 2015/06/30 22:03:53 Also NA now. Looked into using client_ in all sch
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.
sunnyps 2015/05/22 21:15:05 nit: RunTasksWhile(deadline)
brianderson 2015/06/30 22:03:53 Done.
1427 EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible"));
sunnyps 2015/05/22 21:15:06 nit: consider using EXPECT_ACTION
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());
sunnyps 2015/05/22 21:15:06 Use SendNextBeginFrame in both cases. Use differen
brianderson 2015/06/30 22:03:52 Done.
1436 if (should_draw_and_swap_in_high_latency) {
1437 AdvanceFrame();
1438 } else {
1439 // Don't use AdvanceFrame since we expect the the Scheduler to
1440 // skip the BeginImplFrame.
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.
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,
sunnyps 2015/05/22 21:15:05 Is this meant to be an implication or equality? If
brianderson 2015/06/30 22:03:52 Meant to test equality. Will update comment.
1463 client->HasAction("ScheduledActionDrawAndSwapIfPossible"));
1464 if (should_draw_and_swap_in_high_latency)
sunnyps 2015/05/22 21:15:05 nit: Consider combining this and the above expect
brianderson 2015/06/30 22:03:53 Done.
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());
sunnyps 2015/05/22 21:15:06 There are a bunch of expectations about MainThread
brianderson 2015/05/23 00:53:56 I was able to check expectations in previous patch
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));
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
sunnyps 2015/05/22 21:15:05 the draw cannot finish before the deadline.
brianderson 2015/06/30 22:03:53 Done.
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
sunnyps 2015/05/22 21:15:05 commit and activation cannot finish before the dea
brianderson 2015/06/30 22:03:52 Done.
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);
sunnyps 2015/05/22 21:15:05 nit: base::TimeDelta instead of auto.
brianderson 2015/06/30 22:03:52 Done.
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.
sunnyps 2015/05/22 21:15:06 nit: RunTasksWhile(deadline) instead of RunPending
brianderson 2015/06/30 22:03:52 Done.
1535 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1536 scheduler_->NotifyBeginMainFrameStarted();
1537 scheduler_->NotifyReadyToCommit();
1538 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1539 EXPECT_TRUE(client->HasAction("WillBeginImplFrame"));
sunnyps 2015/05/22 21:15:05 nit: EXPECT_ACTION
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
sunnyps 2015/05/22 21:15:05 You mean Draw and not BeginImplFrame right?
brianderson 2015/06/30 22:03:52 Fixed.
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.
1571 client->begin_main_frame_to_commit_duration_ = fast_duration;
sunnyps 2015/05/22 21:15:05 nit: Use setters instead of accessing member vars
brianderson 2015/06/30 22:03:53 Done.
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
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.
sunnyps 2015/05/22 21:15:05 NeedsCommit doesn't mean that previous commit is o
brianderson 2015/06/30 22:03:53 Updated the comment.
1582 EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
1583 SendNextBeginFrame();
1584 task_runner().RunPendingTasks(); // Run posted deadline.
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.
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698