| 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 <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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |