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

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

Issue 2632563003: [cc] Calculate the correct latest_confirmed_sequence_number in cc::Scheduler. (Closed)
Patch Set: add todo for impl-side invalidations. Created 3 years, 10 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 <stddef.h> 7 #include <stddef.h>
8 8
9 #include <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 UNTHROTTLED_BFS, 234 UNTHROTTLED_BFS,
235 THROTTLED_BFS, 235 THROTTLED_BFS,
236 }; 236 };
237 237
238 class SchedulerTest : public testing::Test { 238 class SchedulerTest : public testing::Test {
239 public: 239 public:
240 SchedulerTest() 240 SchedulerTest()
241 : now_src_(new base::SimpleTestTickClock()), 241 : now_src_(new base::SimpleTestTickClock()),
242 task_runner_(new OrderedSimpleTaskRunner(now_src_.get(), true)), 242 task_runner_(new OrderedSimpleTaskRunner(now_src_.get(), true)),
243 fake_external_begin_frame_source_(nullptr), 243 fake_external_begin_frame_source_(nullptr),
244 fake_compositor_timing_history_(nullptr), 244 fake_compositor_timing_history_(nullptr) {
245 next_begin_frame_number_(BeginFrameArgs::kStartingFrameNumber) {
246 now_src_->Advance(base::TimeDelta::FromMicroseconds(10000)); 245 now_src_->Advance(base::TimeDelta::FromMicroseconds(10000));
247 // A bunch of tests require NowTicks() 246 // A bunch of tests require NowTicks()
248 // to be > BeginFrameArgs::DefaultInterval() 247 // to be > BeginFrameArgs::DefaultInterval()
249 now_src_->Advance(base::TimeDelta::FromMilliseconds(100)); 248 now_src_->Advance(base::TimeDelta::FromMilliseconds(100));
250 // Fail if we need to run 100 tasks in a row. 249 // Fail if we need to run 100 tasks in a row.
251 task_runner_->SetRunTaskLimit(100); 250 task_runner_->SetRunTaskLimit(100);
252 } 251 }
253 252
254 ~SchedulerTest() override {} 253 ~SchedulerTest() override {}
255 254
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 task_runner_->RunTasksWhile(client_->FrameHasNotAdvancedCallback()); 403 task_runner_->RunTasksWhile(client_->FrameHasNotAdvancedCallback());
405 } 404 }
406 } 405 }
407 406
408 BeginFrameArgs SendNextBeginFrame() { 407 BeginFrameArgs SendNextBeginFrame() {
409 DCHECK_EQ(scheduler_->begin_frame_source(), 408 DCHECK_EQ(scheduler_->begin_frame_source(),
410 fake_external_begin_frame_source_.get()); 409 fake_external_begin_frame_source_.get());
411 // Creep the time forward so that any BeginFrameArgs is not equal to the 410 // Creep the time forward so that any BeginFrameArgs is not equal to the
412 // last one otherwise we violate the BeginFrameSource contract. 411 // last one otherwise we violate the BeginFrameSource contract.
413 now_src_->Advance(BeginFrameArgs::DefaultInterval()); 412 now_src_->Advance(BeginFrameArgs::DefaultInterval());
414 BeginFrameArgs args = CreateBeginFrameArgsForTesting( 413 BeginFrameArgs args =
415 BEGINFRAME_FROM_HERE, fake_external_begin_frame_source_->source_id(), 414 fake_external_begin_frame_source_->CreateBeginFrameArgs(
416 next_begin_frame_number_, now_src()); 415 BEGINFRAME_FROM_HERE, now_src());
417 next_begin_frame_number_++;
418 fake_external_begin_frame_source_->TestOnBeginFrame(args); 416 fake_external_begin_frame_source_->TestOnBeginFrame(args);
419 return args; 417 return args;
420 } 418 }
421 419
422 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { 420 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const {
423 return fake_external_begin_frame_source_.get(); 421 return fake_external_begin_frame_source_.get();
424 } 422 }
425 423
426 void AdvanceAndMissOneFrame(); 424 void AdvanceAndMissOneFrame();
427 void CheckMainFrameSkippedAfterLateCommit(bool expect_send_begin_main_frame); 425 void CheckMainFrameSkippedAfterLateCommit(bool expect_send_begin_main_frame);
428 void ImplFrameSkippedAfterLateAck(bool receive_ack_before_deadline); 426 void ImplFrameSkippedAfterLateAck(bool receive_ack_before_deadline);
429 void ImplFrameNotSkippedAfterLateAck(); 427 void ImplFrameNotSkippedAfterLateAck();
430 void BeginFramesNotFromClient(BeginFrameSourceType bfs_type); 428 void BeginFramesNotFromClient(BeginFrameSourceType bfs_type);
431 void BeginFramesNotFromClient_IsDrawThrottled(BeginFrameSourceType bfs_type); 429 void BeginFramesNotFromClient_IsDrawThrottled(BeginFrameSourceType bfs_type);
432 bool BeginMainFrameOnCriticalPath(TreePriority tree_priority, 430 bool BeginMainFrameOnCriticalPath(TreePriority tree_priority,
433 ScrollHandlerState scroll_handler_state, 431 ScrollHandlerState scroll_handler_state,
434 base::TimeDelta durations); 432 base::TimeDelta durations);
435 433
436 std::unique_ptr<base::SimpleTestTickClock> now_src_; 434 std::unique_ptr<base::SimpleTestTickClock> now_src_;
437 scoped_refptr<OrderedSimpleTaskRunner> task_runner_; 435 scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
438 std::unique_ptr<FakeExternalBeginFrameSource> 436 std::unique_ptr<FakeExternalBeginFrameSource>
439 fake_external_begin_frame_source_; 437 fake_external_begin_frame_source_;
440 std::unique_ptr<SyntheticBeginFrameSource> synthetic_frame_source_; 438 std::unique_ptr<SyntheticBeginFrameSource> synthetic_frame_source_;
441 std::unique_ptr<SyntheticBeginFrameSource> unthrottled_frame_source_; 439 std::unique_ptr<SyntheticBeginFrameSource> unthrottled_frame_source_;
442 SchedulerSettings scheduler_settings_; 440 SchedulerSettings scheduler_settings_;
443 std::unique_ptr<FakeSchedulerClient> client_; 441 std::unique_ptr<FakeSchedulerClient> client_;
444 std::unique_ptr<TestScheduler> scheduler_; 442 std::unique_ptr<TestScheduler> scheduler_;
445 FakeCompositorTimingHistory* fake_compositor_timing_history_; 443 FakeCompositorTimingHistory* fake_compositor_timing_history_;
446 uint64_t next_begin_frame_number_;
447 }; 444 };
448 445
449 TEST_F(SchedulerTest, InitializeCompositorFrameSinkDoesNotBeginImplFrame) { 446 TEST_F(SchedulerTest, InitializeCompositorFrameSinkDoesNotBeginImplFrame) {
450 SetUpSchedulerWithNoCompositorFrameSink(EXTERNAL_BFS); 447 SetUpSchedulerWithNoCompositorFrameSink(EXTERNAL_BFS);
451 scheduler_->SetVisible(true); 448 scheduler_->SetVisible(true);
452 scheduler_->SetCanDraw(true); 449 scheduler_->SetCanDraw(true);
453 450
454 EXPECT_SINGLE_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", 451 EXPECT_SINGLE_ACTION("ScheduledActionBeginCompositorFrameSinkCreation",
455 client_); 452 client_);
456 client_->Reset(); 453 client_->Reset();
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after
1334 // if it can activate before the deadline. 1331 // if it can activate before the deadline.
1335 SetUpScheduler(EXTERNAL_BFS); 1332 SetUpScheduler(EXTERNAL_BFS);
1336 fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); 1333 fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
1337 1334
1338 AdvanceAndMissOneFrame(); 1335 AdvanceAndMissOneFrame();
1339 EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline()); 1336 EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
1340 scheduler_->SetNeedsBeginMainFrame(); 1337 scheduler_->SetNeedsBeginMainFrame();
1341 1338
1342 // Advance frame and create a begin frame. 1339 // Advance frame and create a begin frame.
1343 now_src_->Advance(BeginFrameArgs::DefaultInterval()); 1340 now_src_->Advance(BeginFrameArgs::DefaultInterval());
1344 BeginFrameArgs args = CreateBeginFrameArgsForTesting( 1341 BeginFrameArgs args = fake_external_begin_frame_source_->CreateBeginFrameArgs(
1345 BEGINFRAME_FROM_HERE, fake_external_begin_frame_source_->source_id(), 1342 BEGINFRAME_FROM_HERE, now_src());
1346 next_begin_frame_number_, now_src());
1347 next_begin_frame_number_++;
1348 1343
1349 // Deliver this begin frame super late. 1344 // Deliver this begin frame super late.
1350 now_src_->Advance(BeginFrameArgs::DefaultInterval() * 100); 1345 now_src_->Advance(BeginFrameArgs::DefaultInterval() * 100);
1351 fake_external_begin_frame_source_->TestOnBeginFrame(args); 1346 fake_external_begin_frame_source_->TestOnBeginFrame(args);
1352 1347
1353 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); 1348 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true));
1354 EXPECT_EQ(true, scheduler_->MainThreadMissedLastDeadline()); 1349 EXPECT_EQ(true, scheduler_->MainThreadMissedLastDeadline());
1355 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3); 1350 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
1356 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 3); 1351 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 3);
1357 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3); 1352 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3);
(...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after
2854 2849
2855 // End that frame's deadline. 2850 // End that frame's deadline.
2856 task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true)); 2851 task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
2857 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); 2852 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
2858 2853
2859 // Scheduler shuts down the source now that no begin frame is requested. 2854 // Scheduler shuts down the source now that no begin frame is requested.
2860 EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2); 2855 EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
2861 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); 2856 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
2862 } 2857 }
2863 2858
2864 TEST_F(SchedulerTest, SynchronousCompositorCommit) { 2859 TEST_F(SchedulerTest, SynchronousCompositorCommitAndVerifyBeginFrameAcks) {
2865 scheduler_settings_.using_synchronous_renderer_compositor = true; 2860 scheduler_settings_.using_synchronous_renderer_compositor = true;
2866 SetUpScheduler(EXTERNAL_BFS); 2861 SetUpScheduler(EXTERNAL_BFS);
2867 2862
2863 // Expect the last ack to be for last BeginFrame, which didn't cause damage.
2864 uint64_t last_begin_frame_number =
2865 fake_external_begin_frame_source_->next_begin_frame_number() - 1;
2866 uint64_t latest_confirmed_sequence_number = last_begin_frame_number;
2867 bool has_damage = false;
2868 EXPECT_EQ(
2869 BeginFrameAck(fake_external_begin_frame_source_->source_id(),
2870 last_begin_frame_number, latest_confirmed_sequence_number,
2871 0, has_damage),
2872 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
2873
2868 scheduler_->SetNeedsBeginMainFrame(); 2874 scheduler_->SetNeedsBeginMainFrame();
2869 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); 2875 EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
2870 client_->Reset(); 2876 client_->Reset();
2871 2877
2872 // Next vsync. 2878 // Next vsync.
2873 AdvanceFrame(); 2879 BeginFrameArgs args = SendNextBeginFrame();
2874 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); 2880 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2875 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); 2881 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
2876 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); 2882 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
2877 client_->Reset(); 2883 client_->Reset();
2878 2884
2885 has_damage = false;
2886 EXPECT_EQ(
2887 BeginFrameAck(args.source_id, args.sequence_number,
2888 latest_confirmed_sequence_number, 0, has_damage),
2889 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
2890
2879 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); 2891 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks());
2880 EXPECT_NO_ACTION(client_); 2892 EXPECT_NO_ACTION(client_);
2881 2893
2882 // Next vsync. 2894 // Next vsync.
2883 AdvanceFrame(); 2895 args = SendNextBeginFrame();
2884 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); 2896 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
2885 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); 2897 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
2886 client_->Reset(); 2898 client_->Reset();
2887 2899
2900 has_damage = false;
2901 EXPECT_EQ(
2902 BeginFrameAck(args.source_id, args.sequence_number,
2903 latest_confirmed_sequence_number, 0, has_damage),
2904 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
2905
2888 scheduler_->NotifyReadyToCommit(); 2906 scheduler_->NotifyReadyToCommit();
2889 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); 2907 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
2890 client_->Reset(); 2908 client_->Reset();
2891 2909
2892 scheduler_->NotifyReadyToActivate(); 2910 scheduler_->NotifyReadyToActivate();
2893 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); 2911 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
2894 client_->Reset(); 2912 client_->Reset();
2895 2913
2896 // Next vsync. 2914 // Next vsync.
2897 AdvanceFrame(); 2915 args = SendNextBeginFrame();
2898 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); 2916 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
2899 EXPECT_ACTION("ScheduledActionInvalidateCompositorFrameSink", client_, 1, 2); 2917 EXPECT_ACTION("ScheduledActionInvalidateCompositorFrameSink", client_, 1, 2);
2900 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); 2918 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
2901 client_->Reset(); 2919 client_->Reset();
2902 2920
2921 // Not confirmed yet and no damage, since not drawn yet.
2922 // TODO(eseckler): In the future, |has_damage = false| will prevent us from
2923 // filtering this ack (in CompositorExternalBeginFrameSource) and instead
2924 // forwarding the one attached to the later submitted CompositorFrame.
2925 has_damage = false;
2926 EXPECT_EQ(
2927 BeginFrameAck(args.source_id, args.sequence_number,
2928 latest_confirmed_sequence_number, 0, has_damage),
2929 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
2930
2903 // Android onDraw. 2931 // Android onDraw.
2904 scheduler_->SetNeedsRedraw(); 2932 scheduler_->SetNeedsRedraw();
2905 bool resourceless_software_draw = false; 2933 bool resourceless_software_draw = false;
2906 scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); 2934 scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw);
2907 EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); 2935 EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_);
2908 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); 2936 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
2909 client_->Reset(); 2937 client_->Reset();
2910 2938
2911 // Idle on next vsync. 2939 // Idle on next vsync.
2912 AdvanceFrame(); 2940 args = SendNextBeginFrame();
2913 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3); 2941 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3);
2914 EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3); 2942 EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
2915 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); 2943 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
2916 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); 2944 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
2917 client_->Reset(); 2945 client_->Reset();
2946
2947 latest_confirmed_sequence_number = args.sequence_number;
2948 has_damage = false;
2949 EXPECT_EQ(
2950 BeginFrameAck(args.source_id, args.sequence_number,
2951 latest_confirmed_sequence_number, 0, has_damage),
2952 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
2918 } 2953 }
2919 2954
2920 TEST_F(SchedulerTest, SynchronousCompositorDoubleCommitWithoutDraw) { 2955 TEST_F(SchedulerTest, SynchronousCompositorDoubleCommitWithoutDraw) {
2921 scheduler_settings_.using_synchronous_renderer_compositor = true; 2956 scheduler_settings_.using_synchronous_renderer_compositor = true;
2922 SetUpScheduler(EXTERNAL_BFS); 2957 SetUpScheduler(EXTERNAL_BFS);
2923 2958
2924 scheduler_->SetNeedsBeginMainFrame(); 2959 scheduler_->SetNeedsBeginMainFrame();
2925 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); 2960 EXPECT_SINGLE_ACTION("AddObserver(this)", client_);
2926 client_->Reset(); 2961 client_->Reset();
2927 2962
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
3332 SMOOTHNESS_TAKES_PRIORITY, 3367 SMOOTHNESS_TAKES_PRIORITY,
3333 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kFastDuration)); 3368 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kFastDuration));
3334 } 3369 }
3335 3370
3336 TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) { 3371 TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) {
3337 EXPECT_FALSE(BeginMainFrameOnCriticalPath( 3372 EXPECT_FALSE(BeginMainFrameOnCriticalPath(
3338 SMOOTHNESS_TAKES_PRIORITY, 3373 SMOOTHNESS_TAKES_PRIORITY,
3339 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration)); 3374 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration));
3340 } 3375 }
3341 3376
3377 TEST_F(SchedulerTest, BeginFrameAckForFinishedImplFrame) {
3378 // Sets up scheduler and sends two BeginFrames, both finished.
3379 SetUpScheduler(EXTERNAL_BFS);
3380
3381 // Expect the last ack to be for last BeginFrame, which didn't cause damage.
3382 uint64_t last_begin_frame_number =
3383 fake_external_begin_frame_source_->next_begin_frame_number() - 1;
3384 uint64_t latest_confirmed_sequence_number = last_begin_frame_number;
3385 bool has_damage = false;
3386 EXPECT_EQ(
3387 BeginFrameAck(fake_external_begin_frame_source_->source_id(),
3388 last_begin_frame_number, latest_confirmed_sequence_number,
3389 0, has_damage),
3390 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
3391
3392 // Run a successful redraw and verify that a new ack is sent.
3393 scheduler_->SetNeedsRedraw();
3394 client_->Reset();
3395
3396 BeginFrameArgs args = SendNextBeginFrame();
3397 EXPECT_LT(latest_confirmed_sequence_number, args.sequence_number);
3398 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
3399 EXPECT_TRUE(client_->IsInsideBeginImplFrame());
3400 EXPECT_TRUE(scheduler_->begin_frames_expected());
3401 client_->Reset();
3402
3403 task_runner().RunPendingTasks(); // Run posted deadline.
3404 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
3405 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
3406 EXPECT_TRUE(scheduler_->begin_frames_expected());
3407 client_->Reset();
3408
3409 // Successful draw caused damage.
3410 latest_confirmed_sequence_number = args.sequence_number;
3411 has_damage = true;
3412 EXPECT_EQ(
3413 BeginFrameAck(args.source_id, args.sequence_number,
3414 latest_confirmed_sequence_number, 0, has_damage),
3415 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
3416
3417 // Request another redraw, but fail it. Verify that a new ack is sent, but
3418 // that its |latest_confirmed_sequence_number| didn't change.
3419 scheduler_->SetNeedsRedraw();
3420 client_->Reset();
3421
3422 args = SendNextBeginFrame();
3423 EXPECT_LT(latest_confirmed_sequence_number, args.sequence_number);
3424 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
3425 EXPECT_TRUE(client_->IsInsideBeginImplFrame());
3426 EXPECT_TRUE(scheduler_->begin_frames_expected());
3427 client_->Reset();
3428
3429 client_->SetDrawWillHappen(false);
3430 task_runner().RunPendingTasks(); // Run posted deadline.
3431 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2);
3432 // Failed draw triggers SendBeginMainFrame.
3433 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
3434 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
3435 EXPECT_TRUE(scheduler_->begin_frames_expected());
3436 client_->Reset();
3437
3438 // Failed draw: no damage and unconfirmed frame.
3439 has_damage = false;
3440 EXPECT_EQ(
3441 BeginFrameAck(args.source_id, args.sequence_number,
3442 latest_confirmed_sequence_number, 0, has_damage),
3443 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
3444 }
3445
3446 TEST_F(SchedulerTest, BeginFrameAckForSkippedImplFrame) {
3447 SetUpScheduler(EXTERNAL_BFS);
3448
3449 // To get into a high latency state, this test disables automatic swap acks.
3450 client_->SetAutomaticSubmitCompositorFrameAck(false);
3451 fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration);
3452
3453 // Run a successful redraw that submits a compositor frame but doesn't receive
3454 // a swap ack. Verify that a BeginFrameAck is sent for it.
3455 scheduler_->SetNeedsRedraw();
3456 client_->Reset();
3457
3458 BeginFrameArgs args = SendNextBeginFrame();
3459 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
3460 EXPECT_TRUE(client_->IsInsideBeginImplFrame());
3461 EXPECT_TRUE(scheduler_->begin_frames_expected());
3462 client_->Reset();
3463
3464 task_runner().RunPendingTasks(); // Run posted deadline.
3465 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
3466 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
3467 EXPECT_TRUE(scheduler_->begin_frames_expected());
3468 client_->Reset();
3469
3470 // Successful draw caused damage.
3471 uint64_t latest_confirmed_sequence_number = args.sequence_number;
3472 bool has_damage = true;
3473 EXPECT_EQ(
3474 BeginFrameAck(args.source_id, args.sequence_number,
3475 latest_confirmed_sequence_number, 0, has_damage),
3476 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
3477
3478 // Request another redraw that will be skipped because the swap ack is still
3479 // missing. Verify that a new BeginFrameAck is sent.
3480 scheduler_->SetNeedsRedraw();
3481 client_->Reset();
3482
3483 args = SendNextBeginFrame();
3484 EXPECT_LT(latest_confirmed_sequence_number, args.sequence_number);
3485 EXPECT_NO_ACTION(client_);
3486 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
3487 EXPECT_TRUE(scheduler_->begin_frames_expected());
3488 client_->Reset();
3489
3490 // Skipped draw: no damage and unconfirmed frame.
3491 has_damage = false;
3492 EXPECT_EQ(
3493 BeginFrameAck(args.source_id, args.sequence_number,
3494 latest_confirmed_sequence_number, 0, has_damage),
3495 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
3496 }
3497
3498 TEST_F(SchedulerTest, BeginFrameAckForBeginFrameBeforeLastDeadline) {
3499 SetUpScheduler(EXTERNAL_BFS);
3500
3501 // Request tile preparation to schedule a proactive BeginFrame.
3502 scheduler_->SetNeedsPrepareTiles();
3503 client_->Reset();
3504
3505 SendNextBeginFrame();
3506 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
3507 EXPECT_TRUE(client_->IsInsideBeginImplFrame());
3508 // Until tiles were prepared, further proactive BeginFrames are expected.
3509 EXPECT_TRUE(scheduler_->begin_frames_expected());
3510 client_->Reset();
3511
3512 // Send the next BeginFrame before the previous one's deadline was executed.
3513 // This should trigger the previous BeginFrame's deadline synchronously,
3514 // during which tiles will be prepared. As a result of that, no further
3515 // BeginFrames will be needed, and the new BeginFrame should be dropped.
3516 BeginFrameArgs args = SendNextBeginFrame();
3517 EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 3);
3518 EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3);
3519 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
3520 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
3521 EXPECT_FALSE(scheduler_->begin_frames_expected());
3522 client_->Reset();
3523
3524 // Latest ack should be for the dropped BeginFrame. Since we don't have
3525 // further updates, its |latest_confirmed_sequence_number| should be for the
3526 // dropped BeginFrame, too.
3527 uint64_t latest_confirmed_sequence_number = args.sequence_number;
3528 bool has_damage = false;
3529 EXPECT_EQ(
3530 BeginFrameAck(args.source_id, args.sequence_number,
3531 latest_confirmed_sequence_number, 0, has_damage),
3532 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
3533 }
3534
3535 TEST_F(SchedulerTest, BeginFrameAckForDroppedBeginFrame) {
3536 SetUpScheduler(EXTERNAL_BFS);
3537
3538 // Last confirmed frame was last BeginFrame.
3539 uint64_t latest_confirmed_sequence_number =
3540 fake_external_begin_frame_source_->next_begin_frame_number() - 1;
3541
3542 // Request a single BeginFrame.
3543 scheduler_->SetNeedsOneBeginImplFrame();
3544 EXPECT_TRUE(scheduler_->begin_frames_expected());
3545 client_->Reset();
3546
3547 // First BeginFrame is handled by StateMachine.
3548 BeginFrameArgs first_args = SendNextBeginFrame();
3549 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
3550 EXPECT_TRUE(client_->IsInsideBeginImplFrame());
3551 // State machine is no longer interested in BeginFrames, but scheduler is
3552 // still observing the source.
3553 EXPECT_TRUE(scheduler_->begin_frames_expected());
3554 EXPECT_FALSE(scheduler_->BeginFrameNeeded());
3555 client_->Reset();
3556
3557 // Send the next BeginFrame before the previous one's deadline was executed.
3558 // The BeginFrame should be dropped immediately, since the state machine is
3559 // not expecting any BeginFrames.
3560 BeginFrameArgs second_args = SendNextBeginFrame();
3561 EXPECT_NO_ACTION(client_);
3562 client_->Reset();
3563
3564 // Latest ack should be for the dropped (and unconfirmed) BeginFrame.
3565 bool has_damage = false;
3566 EXPECT_EQ(
3567 BeginFrameAck(second_args.source_id, second_args.sequence_number,
3568 latest_confirmed_sequence_number, 0, has_damage),
3569 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
3570
3571 task_runner().RunPendingTasks(); // Run deadline of prior BeginFrame.
3572 EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2);
3573 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
3574 client_->Reset();
3575
3576 // We'd expect an out-of-order ack for the prior BeginFrame, confirming it.
3577 latest_confirmed_sequence_number = first_args.sequence_number;
3578 has_damage = false;
3579 EXPECT_EQ(
3580 BeginFrameAck(first_args.source_id, first_args.sequence_number,
3581 latest_confirmed_sequence_number, 0, has_damage),
3582 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
3583 }
3584
3585 TEST_F(SchedulerTest, BeginFrameAckForLateMissedBeginFrame) {
3586 SetUpScheduler(EXTERNAL_BFS);
3587
3588 // Last confirmed frame was last BeginFrame.
3589 uint64_t latest_confirmed_sequence_number =
3590 fake_external_begin_frame_source_->next_begin_frame_number() - 1;
3591
3592 scheduler_->SetNeedsRedraw();
3593 client_->Reset();
3594
3595 // Send a missed BeginFrame with a passed deadline.
3596 now_src_->Advance(BeginFrameArgs::DefaultInterval());
3597 BeginFrameArgs args = fake_external_begin_frame_source_->CreateBeginFrameArgs(
3598 BEGINFRAME_FROM_HERE, now_src());
3599 args.type = BeginFrameArgs::MISSED;
3600 now_src_->Advance(BeginFrameArgs::DefaultInterval());
3601 EXPECT_GT(now_src_->NowTicks(), args.deadline);
3602 fake_external_begin_frame_source_->TestOnBeginFrame(args);
3603
3604 EXPECT_NO_ACTION(client_);
3605 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
3606 client_->Reset();
3607
3608 // Latest ack should be for the missed BeginFrame that was too late: no damage
3609 // and unconfirmed frame.
3610 bool has_damage = false;
3611 EXPECT_EQ(
3612 BeginFrameAck(args.source_id, args.sequence_number,
3613 latest_confirmed_sequence_number, 0, has_damage),
3614 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
3615 }
3616
3617 TEST_F(SchedulerTest, BeginFrameAckForFinishedBeginFrameWithNewSourceId) {
3618 SetUpScheduler(EXTERNAL_BFS);
3619
3620 scheduler_->SetNeedsRedraw();
3621 client_->Reset();
3622
3623 // Send a BeginFrame with a different source_id.
3624 now_src_->Advance(BeginFrameArgs::DefaultInterval());
3625 uint32_t source_id = fake_external_begin_frame_source_->source_id() + 1;
3626 BeginFrameArgs args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE,
3627 source_id, 1, now_src());
3628 fake_external_begin_frame_source_->TestOnBeginFrame(args);
3629
3630 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1);
3631 EXPECT_TRUE(client_->IsInsideBeginImplFrame());
3632 EXPECT_TRUE(scheduler_->begin_frames_expected());
3633 client_->Reset();
3634
3635 task_runner().RunPendingTasks(); // Run posted deadline.
3636 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1);
3637 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
3638 EXPECT_TRUE(scheduler_->begin_frames_expected());
3639 client_->Reset();
3640
3641 // Successful draw caused damage.
3642 uint64_t latest_confirmed_sequence_number = args.sequence_number;
3643 bool has_damage = true;
3644 EXPECT_EQ(
3645 BeginFrameAck(args.source_id, args.sequence_number,
3646 latest_confirmed_sequence_number, 0, has_damage),
3647 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
3648 }
3649
3650 TEST_F(SchedulerTest,
3651 BeginFrameAckForLateMissedBeginFrameWithDifferentSourceId) {
3652 SetUpScheduler(EXTERNAL_BFS);
3653
3654 scheduler_->SetNeedsRedraw();
3655 client_->Reset();
3656
3657 // Send a missed BeginFrame with a passed deadline and different source_id.
3658 now_src_->Advance(BeginFrameArgs::DefaultInterval());
3659 uint32_t source_id = fake_external_begin_frame_source_->source_id() + 1;
3660 BeginFrameArgs args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE,
3661 source_id, 1, now_src());
3662 args.type = BeginFrameArgs::MISSED;
3663 now_src_->Advance(BeginFrameArgs::DefaultInterval());
3664 EXPECT_GT(now_src_->NowTicks(), args.deadline);
3665 fake_external_begin_frame_source_->TestOnBeginFrame(args);
3666
3667 EXPECT_NO_ACTION(client_);
3668 EXPECT_FALSE(client_->IsInsideBeginImplFrame());
3669 client_->Reset();
3670
3671 // Latest ack should be for the missed BeginFrame that was too late: no damage
3672 // and unconfirmed frame. Because the source_id changed, the
3673 // |latest_confirmed_sequence_number| should be set to invalid.
3674 uint64_t latest_confirmed_sequence_number =
3675 BeginFrameArgs::kInvalidFrameNumber;
3676 bool has_damage = false;
3677 EXPECT_EQ(
3678 BeginFrameAck(args.source_id, args.sequence_number,
3679 latest_confirmed_sequence_number, 0, has_damage),
3680 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get()));
3681 }
3682
3342 } // namespace 3683 } // namespace
3343 } // namespace cc 3684 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler_state_machine_unittest.cc ('k') | cc/surfaces/display_scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698