Chromium Code Reviews| 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 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 231 UNTHROTTLED_BFS, | 231 UNTHROTTLED_BFS, |
| 232 THROTTLED_BFS, | 232 THROTTLED_BFS, |
| 233 }; | 233 }; |
| 234 | 234 |
| 235 class SchedulerTest : public testing::Test { | 235 class SchedulerTest : public testing::Test { |
| 236 public: | 236 public: |
| 237 SchedulerTest() | 237 SchedulerTest() |
| 238 : now_src_(new base::SimpleTestTickClock()), | 238 : now_src_(new base::SimpleTestTickClock()), |
| 239 task_runner_(new OrderedSimpleTaskRunner(now_src_.get(), true)), | 239 task_runner_(new OrderedSimpleTaskRunner(now_src_.get(), true)), |
| 240 fake_external_begin_frame_source_(nullptr), | 240 fake_external_begin_frame_source_(nullptr), |
| 241 fake_compositor_timing_history_(nullptr), | 241 fake_compositor_timing_history_(nullptr) { |
| 242 next_begin_frame_number_(BeginFrameArgs::kStartingFrameNumber) { | |
| 243 now_src_->Advance(base::TimeDelta::FromMicroseconds(10000)); | 242 now_src_->Advance(base::TimeDelta::FromMicroseconds(10000)); |
| 244 // A bunch of tests require NowTicks() | 243 // A bunch of tests require NowTicks() |
| 245 // to be > BeginFrameArgs::DefaultInterval() | 244 // to be > BeginFrameArgs::DefaultInterval() |
| 246 now_src_->Advance(base::TimeDelta::FromMilliseconds(100)); | 245 now_src_->Advance(base::TimeDelta::FromMilliseconds(100)); |
| 247 // Fail if we need to run 100 tasks in a row. | 246 // Fail if we need to run 100 tasks in a row. |
| 248 task_runner_->SetRunTaskLimit(100); | 247 task_runner_->SetRunTaskLimit(100); |
| 249 } | 248 } |
| 250 | 249 |
| 251 ~SchedulerTest() override {} | 250 ~SchedulerTest() override {} |
| 252 | 251 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 task_runner_->RunTasksWhile(client_->FrameHasNotAdvancedCallback()); | 400 task_runner_->RunTasksWhile(client_->FrameHasNotAdvancedCallback()); |
| 402 } | 401 } |
| 403 } | 402 } |
| 404 | 403 |
| 405 BeginFrameArgs SendNextBeginFrame() { | 404 BeginFrameArgs SendNextBeginFrame() { |
| 406 DCHECK_EQ(scheduler_->begin_frame_source(), | 405 DCHECK_EQ(scheduler_->begin_frame_source(), |
| 407 fake_external_begin_frame_source_.get()); | 406 fake_external_begin_frame_source_.get()); |
| 408 // Creep the time forward so that any BeginFrameArgs is not equal to the | 407 // Creep the time forward so that any BeginFrameArgs is not equal to the |
| 409 // last one otherwise we violate the BeginFrameSource contract. | 408 // last one otherwise we violate the BeginFrameSource contract. |
| 410 now_src_->Advance(BeginFrameArgs::DefaultInterval()); | 409 now_src_->Advance(BeginFrameArgs::DefaultInterval()); |
| 411 BeginFrameArgs args = CreateBeginFrameArgsForTesting( | 410 BeginFrameArgs args = |
| 412 BEGINFRAME_FROM_HERE, fake_external_begin_frame_source_->source_id(), | 411 fake_external_begin_frame_source_->CreateBeginFrameArgs( |
| 413 next_begin_frame_number_, now_src()); | 412 BEGINFRAME_FROM_HERE, now_src()); |
| 414 next_begin_frame_number_++; | |
| 415 fake_external_begin_frame_source_->TestOnBeginFrame(args); | 413 fake_external_begin_frame_source_->TestOnBeginFrame(args); |
| 416 return args; | 414 return args; |
| 417 } | 415 } |
| 418 | 416 |
| 419 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { | 417 FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { |
| 420 return fake_external_begin_frame_source_.get(); | 418 return fake_external_begin_frame_source_.get(); |
| 421 } | 419 } |
| 422 | 420 |
| 423 void AdvanceAndMissOneFrame(); | 421 void AdvanceAndMissOneFrame(); |
| 424 void CheckMainFrameSkippedAfterLateCommit(bool expect_send_begin_main_frame); | 422 void CheckMainFrameSkippedAfterLateCommit(bool expect_send_begin_main_frame); |
| 425 void ImplFrameSkippedAfterLateAck(bool receive_ack_before_deadline); | 423 void ImplFrameSkippedAfterLateAck(bool receive_ack_before_deadline); |
| 426 void ImplFrameNotSkippedAfterLateAck(); | 424 void ImplFrameNotSkippedAfterLateAck(); |
| 427 void BeginFramesNotFromClient(BeginFrameSourceType bfs_type); | 425 void BeginFramesNotFromClient(BeginFrameSourceType bfs_type); |
| 428 void BeginFramesNotFromClient_IsDrawThrottled(BeginFrameSourceType bfs_type); | 426 void BeginFramesNotFromClient_IsDrawThrottled(BeginFrameSourceType bfs_type); |
| 429 bool BeginMainFrameOnCriticalPath(TreePriority tree_priority, | 427 bool BeginMainFrameOnCriticalPath(TreePriority tree_priority, |
| 430 ScrollHandlerState scroll_handler_state, | 428 ScrollHandlerState scroll_handler_state, |
| 431 base::TimeDelta durations); | 429 base::TimeDelta durations); |
| 432 | 430 |
| 433 std::unique_ptr<base::SimpleTestTickClock> now_src_; | 431 std::unique_ptr<base::SimpleTestTickClock> now_src_; |
| 434 scoped_refptr<OrderedSimpleTaskRunner> task_runner_; | 432 scoped_refptr<OrderedSimpleTaskRunner> task_runner_; |
| 435 std::unique_ptr<FakeExternalBeginFrameSource> | 433 std::unique_ptr<FakeExternalBeginFrameSource> |
| 436 fake_external_begin_frame_source_; | 434 fake_external_begin_frame_source_; |
| 437 std::unique_ptr<SyntheticBeginFrameSource> synthetic_frame_source_; | 435 std::unique_ptr<SyntheticBeginFrameSource> synthetic_frame_source_; |
| 438 std::unique_ptr<SyntheticBeginFrameSource> unthrottled_frame_source_; | 436 std::unique_ptr<SyntheticBeginFrameSource> unthrottled_frame_source_; |
| 439 SchedulerSettings scheduler_settings_; | 437 SchedulerSettings scheduler_settings_; |
| 440 std::unique_ptr<FakeSchedulerClient> client_; | 438 std::unique_ptr<FakeSchedulerClient> client_; |
| 441 std::unique_ptr<TestScheduler> scheduler_; | 439 std::unique_ptr<TestScheduler> scheduler_; |
| 442 FakeCompositorTimingHistory* fake_compositor_timing_history_; | 440 FakeCompositorTimingHistory* fake_compositor_timing_history_; |
| 443 uint64_t next_begin_frame_number_; | |
| 444 }; | 441 }; |
| 445 | 442 |
| 446 TEST_F(SchedulerTest, InitializeCompositorFrameSinkDoesNotBeginImplFrame) { | 443 TEST_F(SchedulerTest, InitializeCompositorFrameSinkDoesNotBeginImplFrame) { |
| 447 SetUpSchedulerWithNoCompositorFrameSink(EXTERNAL_BFS); | 444 SetUpSchedulerWithNoCompositorFrameSink(EXTERNAL_BFS); |
| 448 scheduler_->SetVisible(true); | 445 scheduler_->SetVisible(true); |
| 449 scheduler_->SetCanDraw(true); | 446 scheduler_->SetCanDraw(true); |
| 450 | 447 |
| 451 EXPECT_SINGLE_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", | 448 EXPECT_SINGLE_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", |
| 452 client_); | 449 client_); |
| 453 client_->Reset(); | 450 client_->Reset(); |
| (...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1331 // if it can activate before the deadline. | 1328 // if it can activate before the deadline. |
| 1332 SetUpScheduler(EXTERNAL_BFS); | 1329 SetUpScheduler(EXTERNAL_BFS); |
| 1333 fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); | 1330 fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); |
| 1334 | 1331 |
| 1335 AdvanceAndMissOneFrame(); | 1332 AdvanceAndMissOneFrame(); |
| 1336 EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline()); | 1333 EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline()); |
| 1337 scheduler_->SetNeedsBeginMainFrame(); | 1334 scheduler_->SetNeedsBeginMainFrame(); |
| 1338 | 1335 |
| 1339 // Advance frame and create a begin frame. | 1336 // Advance frame and create a begin frame. |
| 1340 now_src_->Advance(BeginFrameArgs::DefaultInterval()); | 1337 now_src_->Advance(BeginFrameArgs::DefaultInterval()); |
| 1341 BeginFrameArgs args = CreateBeginFrameArgsForTesting( | 1338 BeginFrameArgs args = fake_external_begin_frame_source_->CreateBeginFrameArgs( |
| 1342 BEGINFRAME_FROM_HERE, fake_external_begin_frame_source_->source_id(), | 1339 BEGINFRAME_FROM_HERE, now_src()); |
| 1343 next_begin_frame_number_, now_src()); | |
| 1344 next_begin_frame_number_++; | |
| 1345 | 1340 |
| 1346 // Deliver this begin frame super late. | 1341 // Deliver this begin frame super late. |
| 1347 now_src_->Advance(BeginFrameArgs::DefaultInterval() * 100); | 1342 now_src_->Advance(BeginFrameArgs::DefaultInterval() * 100); |
| 1348 fake_external_begin_frame_source_->TestOnBeginFrame(args); | 1343 fake_external_begin_frame_source_->TestOnBeginFrame(args); |
| 1349 | 1344 |
| 1350 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); | 1345 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 1351 EXPECT_EQ(true, scheduler_->MainThreadMissedLastDeadline()); | 1346 EXPECT_EQ(true, scheduler_->MainThreadMissedLastDeadline()); |
| 1352 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3); | 1347 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3); |
| 1353 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 3); | 1348 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 3); |
| 1354 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3); | 1349 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3); |
| (...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2851 | 2846 |
| 2852 // End that frame's deadline. | 2847 // End that frame's deadline. |
| 2853 task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true)); | 2848 task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 2854 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | 2849 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2855 | 2850 |
| 2856 // Scheduler shuts down the source now that no begin frame is requested. | 2851 // Scheduler shuts down the source now that no begin frame is requested. |
| 2857 EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2); | 2852 EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2); |
| 2858 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); | 2853 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); |
| 2859 } | 2854 } |
| 2860 | 2855 |
| 2861 TEST_F(SchedulerTest, SynchronousCompositorCommit) { | 2856 TEST_F(SchedulerTest, SynchronousCompositorCommitAndVerifyBeginFrameAcks) { |
| 2862 scheduler_settings_.using_synchronous_renderer_compositor = true; | 2857 scheduler_settings_.using_synchronous_renderer_compositor = true; |
| 2863 SetUpScheduler(EXTERNAL_BFS); | 2858 SetUpScheduler(EXTERNAL_BFS); |
| 2864 | 2859 |
| 2860 // Expect the last ack to be for last BeginFrame, which didn't cause damage. | |
| 2861 uint64_t last_begin_frame_number = | |
| 2862 fake_external_begin_frame_source_->next_begin_frame_number() - 1; | |
| 2863 uint64_t latest_confirmed_sequence_number = last_begin_frame_number; | |
| 2864 bool has_damage = false; | |
| 2865 EXPECT_EQ( | |
| 2866 BeginFrameAck(fake_external_begin_frame_source_->source_id(), | |
| 2867 last_begin_frame_number, latest_confirmed_sequence_number, | |
| 2868 0, has_damage), | |
| 2869 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 2870 | |
| 2865 scheduler_->SetNeedsBeginMainFrame(); | 2871 scheduler_->SetNeedsBeginMainFrame(); |
| 2866 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); | 2872 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2867 client_->Reset(); | 2873 client_->Reset(); |
| 2868 | 2874 |
| 2869 // Next vsync. | 2875 // Next vsync. |
| 2870 AdvanceFrame(); | 2876 BeginFrameArgs args = SendNextBeginFrame(); |
| 2871 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 2877 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2872 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); | 2878 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2873 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | 2879 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2874 client_->Reset(); | 2880 client_->Reset(); |
| 2875 | 2881 |
| 2882 has_damage = false; | |
| 2883 EXPECT_EQ( | |
| 2884 BeginFrameAck(args.source_id, args.sequence_number, | |
| 2885 latest_confirmed_sequence_number, 0, has_damage), | |
| 2886 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 2887 | |
| 2876 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); | 2888 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2877 EXPECT_NO_ACTION(client_); | 2889 EXPECT_NO_ACTION(client_); |
| 2878 | 2890 |
| 2879 // Next vsync. | 2891 // Next vsync. |
| 2880 AdvanceFrame(); | 2892 args = SendNextBeginFrame(); |
| 2881 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); | 2893 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); |
| 2882 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | 2894 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2883 client_->Reset(); | 2895 client_->Reset(); |
| 2884 | 2896 |
| 2897 has_damage = false; | |
| 2898 EXPECT_EQ( | |
| 2899 BeginFrameAck(args.source_id, args.sequence_number, | |
| 2900 latest_confirmed_sequence_number, 0, has_damage), | |
| 2901 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 2902 | |
| 2885 scheduler_->NotifyReadyToCommit(); | 2903 scheduler_->NotifyReadyToCommit(); |
| 2886 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); | 2904 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
| 2887 client_->Reset(); | 2905 client_->Reset(); |
| 2888 | 2906 |
| 2889 scheduler_->NotifyReadyToActivate(); | 2907 scheduler_->NotifyReadyToActivate(); |
| 2890 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); | 2908 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); |
| 2891 client_->Reset(); | 2909 client_->Reset(); |
| 2892 | 2910 |
| 2893 // Next vsync. | 2911 // Next vsync. |
| 2894 AdvanceFrame(); | 2912 args = SendNextBeginFrame(); |
| 2895 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 2913 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2896 EXPECT_ACTION("ScheduledActionInvalidateCompositorFrameSink", client_, 1, 2); | 2914 EXPECT_ACTION("ScheduledActionInvalidateCompositorFrameSink", client_, 1, 2); |
| 2897 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | 2915 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2898 client_->Reset(); | 2916 client_->Reset(); |
| 2899 | 2917 |
| 2918 // Not confirmed yet and no damage, since not drawn yet. | |
| 2919 // TODO(eseckler): In the future, |has_damage = false| will prevent us from | |
| 2920 // filtering this ack (in CompositorExternalBeginFrameSource) and instead | |
| 2921 // forwarding the one attached to the later submitted CompositorFrame. | |
|
Eric Seckler
2017/02/22 12:09:01
Here's the problem I mentioned :)
Because cc::Sch
brianderson
2017/02/22 23:27:05
We can leave it as a TODO for now and follow up wh
boliu
2017/02/23 05:28:24
Webview does not have a "browser" compositor, so t
| |
| 2922 has_damage = false; | |
| 2923 EXPECT_EQ( | |
| 2924 BeginFrameAck(args.source_id, args.sequence_number, | |
| 2925 latest_confirmed_sequence_number, 0, has_damage), | |
| 2926 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 2927 | |
| 2900 // Android onDraw. | 2928 // Android onDraw. |
| 2901 scheduler_->SetNeedsRedraw(); | 2929 scheduler_->SetNeedsRedraw(); |
| 2902 bool resourceless_software_draw = false; | 2930 bool resourceless_software_draw = false; |
| 2903 scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); | 2931 scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); |
| 2904 EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); | 2932 EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); |
| 2905 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | 2933 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2906 client_->Reset(); | 2934 client_->Reset(); |
| 2907 | 2935 |
| 2908 // Idle on next vsync. | 2936 // Idle on next vsync. |
| 2909 AdvanceFrame(); | 2937 args = SendNextBeginFrame(); |
| 2910 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3); | 2938 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3); |
| 2911 EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3); | 2939 EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3); |
| 2912 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); | 2940 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); |
| 2913 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | 2941 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2914 client_->Reset(); | 2942 client_->Reset(); |
| 2943 | |
| 2944 latest_confirmed_sequence_number = args.sequence_number; | |
| 2945 has_damage = false; | |
| 2946 EXPECT_EQ( | |
| 2947 BeginFrameAck(args.source_id, args.sequence_number, | |
| 2948 latest_confirmed_sequence_number, 0, has_damage), | |
| 2949 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 2915 } | 2950 } |
| 2916 | 2951 |
| 2917 TEST_F(SchedulerTest, SynchronousCompositorDoubleCommitWithoutDraw) { | 2952 TEST_F(SchedulerTest, SynchronousCompositorDoubleCommitWithoutDraw) { |
| 2918 scheduler_settings_.using_synchronous_renderer_compositor = true; | 2953 scheduler_settings_.using_synchronous_renderer_compositor = true; |
| 2919 SetUpScheduler(EXTERNAL_BFS); | 2954 SetUpScheduler(EXTERNAL_BFS); |
| 2920 | 2955 |
| 2921 scheduler_->SetNeedsBeginMainFrame(); | 2956 scheduler_->SetNeedsBeginMainFrame(); |
| 2922 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); | 2957 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2923 client_->Reset(); | 2958 client_->Reset(); |
| 2924 | 2959 |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3249 SMOOTHNESS_TAKES_PRIORITY, | 3284 SMOOTHNESS_TAKES_PRIORITY, |
| 3250 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kFastDuration)); | 3285 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kFastDuration)); |
| 3251 } | 3286 } |
| 3252 | 3287 |
| 3253 TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) { | 3288 TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) { |
| 3254 EXPECT_FALSE(BeginMainFrameOnCriticalPath( | 3289 EXPECT_FALSE(BeginMainFrameOnCriticalPath( |
| 3255 SMOOTHNESS_TAKES_PRIORITY, | 3290 SMOOTHNESS_TAKES_PRIORITY, |
| 3256 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration)); | 3291 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration)); |
| 3257 } | 3292 } |
| 3258 | 3293 |
| 3294 TEST_F(SchedulerTest, BeginFrameAckForFinishedImplFrame) { | |
| 3295 // Sets up scheduler and sends two BeginFrames, both finished. | |
| 3296 SetUpScheduler(EXTERNAL_BFS); | |
| 3297 | |
| 3298 // Expect the last ack to be for last BeginFrame, which didn't cause damage. | |
| 3299 uint64_t last_begin_frame_number = | |
| 3300 fake_external_begin_frame_source_->next_begin_frame_number() - 1; | |
| 3301 uint64_t latest_confirmed_sequence_number = last_begin_frame_number; | |
| 3302 bool has_damage = false; | |
| 3303 EXPECT_EQ( | |
| 3304 BeginFrameAck(fake_external_begin_frame_source_->source_id(), | |
| 3305 last_begin_frame_number, latest_confirmed_sequence_number, | |
| 3306 0, has_damage), | |
| 3307 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 3308 | |
| 3309 // Run a successful redraw and verify that a new ack is sent. | |
| 3310 scheduler_->SetNeedsRedraw(); | |
| 3311 client_->Reset(); | |
| 3312 | |
| 3313 BeginFrameArgs args = SendNextBeginFrame(); | |
| 3314 EXPECT_LT(latest_confirmed_sequence_number, args.sequence_number); | |
| 3315 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); | |
| 3316 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); | |
| 3317 EXPECT_TRUE(scheduler_->begin_frames_expected()); | |
| 3318 client_->Reset(); | |
| 3319 | |
| 3320 task_runner().RunPendingTasks(); // Run posted deadline. | |
| 3321 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); | |
| 3322 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | |
| 3323 EXPECT_TRUE(scheduler_->begin_frames_expected()); | |
| 3324 client_->Reset(); | |
| 3325 | |
| 3326 // Successful draw caused damage. | |
| 3327 latest_confirmed_sequence_number = args.sequence_number; | |
| 3328 has_damage = true; | |
| 3329 EXPECT_EQ( | |
| 3330 BeginFrameAck(args.source_id, args.sequence_number, | |
| 3331 latest_confirmed_sequence_number, 0, has_damage), | |
| 3332 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 3333 | |
| 3334 // Request another redraw, but fail it. Verify that a new ack is sent, but | |
| 3335 // that its |latest_confirmed_sequence_number| didn't change. | |
| 3336 scheduler_->SetNeedsRedraw(); | |
| 3337 client_->Reset(); | |
| 3338 | |
| 3339 args = SendNextBeginFrame(); | |
| 3340 EXPECT_LT(latest_confirmed_sequence_number, args.sequence_number); | |
| 3341 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); | |
| 3342 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); | |
| 3343 EXPECT_TRUE(scheduler_->begin_frames_expected()); | |
| 3344 client_->Reset(); | |
| 3345 | |
| 3346 client_->SetDrawWillHappen(false); | |
| 3347 task_runner().RunPendingTasks(); // Run posted deadline. | |
| 3348 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2); | |
| 3349 // Failed draw triggers SendBeginMainFrame. | |
| 3350 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); | |
| 3351 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | |
| 3352 EXPECT_TRUE(scheduler_->begin_frames_expected()); | |
| 3353 client_->Reset(); | |
| 3354 | |
| 3355 // Failed draw: no damage and unconfirmed frame. | |
| 3356 has_damage = false; | |
| 3357 EXPECT_EQ( | |
| 3358 BeginFrameAck(args.source_id, args.sequence_number, | |
| 3359 latest_confirmed_sequence_number, 0, has_damage), | |
| 3360 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 3361 } | |
| 3362 | |
| 3363 TEST_F(SchedulerTest, BeginFrameAckForSkippedImplFrame) { | |
| 3364 SetUpScheduler(EXTERNAL_BFS); | |
| 3365 | |
| 3366 // To get into a high latency state, this test disables automatic swap acks. | |
| 3367 client_->SetAutomaticSubmitCompositorFrameAck(false); | |
| 3368 fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); | |
| 3369 | |
| 3370 // Run a successful redraw that submits a compositor frame but doesn't receive | |
| 3371 // a swap ack. Verify that a BeginFrameAck is sent for it. | |
| 3372 scheduler_->SetNeedsRedraw(); | |
| 3373 client_->Reset(); | |
| 3374 | |
| 3375 BeginFrameArgs args = SendNextBeginFrame(); | |
| 3376 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); | |
| 3377 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); | |
| 3378 EXPECT_TRUE(scheduler_->begin_frames_expected()); | |
| 3379 client_->Reset(); | |
| 3380 | |
| 3381 task_runner().RunPendingTasks(); // Run posted deadline. | |
| 3382 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); | |
| 3383 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | |
| 3384 EXPECT_TRUE(scheduler_->begin_frames_expected()); | |
| 3385 client_->Reset(); | |
| 3386 | |
| 3387 // Successful draw caused damage. | |
| 3388 uint64_t latest_confirmed_sequence_number = args.sequence_number; | |
| 3389 bool has_damage = true; | |
| 3390 EXPECT_EQ( | |
| 3391 BeginFrameAck(args.source_id, args.sequence_number, | |
| 3392 latest_confirmed_sequence_number, 0, has_damage), | |
| 3393 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 3394 | |
| 3395 // Request another redraw that will be skipped because the swap ack is still | |
| 3396 // missing. Verify that a new BeginFrameAck is sent. | |
| 3397 scheduler_->SetNeedsRedraw(); | |
| 3398 client_->Reset(); | |
| 3399 | |
| 3400 args = SendNextBeginFrame(); | |
| 3401 EXPECT_LT(latest_confirmed_sequence_number, args.sequence_number); | |
| 3402 EXPECT_NO_ACTION(client_); | |
| 3403 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | |
| 3404 EXPECT_TRUE(scheduler_->begin_frames_expected()); | |
| 3405 client_->Reset(); | |
| 3406 | |
| 3407 // Skipped draw: no damage and unconfirmed frame. | |
| 3408 has_damage = false; | |
| 3409 EXPECT_EQ( | |
| 3410 BeginFrameAck(args.source_id, args.sequence_number, | |
| 3411 latest_confirmed_sequence_number, 0, has_damage), | |
| 3412 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 3413 } | |
| 3414 | |
| 3415 TEST_F(SchedulerTest, BeginFrameAckForBeginFrameBeforeLastDeadline) { | |
| 3416 SetUpScheduler(EXTERNAL_BFS); | |
| 3417 | |
| 3418 // Request tile preparation to schedule a proactive BeginFrame. | |
| 3419 scheduler_->SetNeedsPrepareTiles(); | |
| 3420 client_->Reset(); | |
| 3421 | |
| 3422 SendNextBeginFrame(); | |
| 3423 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); | |
| 3424 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); | |
| 3425 // Until tiles were prepared, further proactive BeginFrames are expected. | |
| 3426 EXPECT_TRUE(scheduler_->begin_frames_expected()); | |
| 3427 client_->Reset(); | |
| 3428 | |
| 3429 // Send the next BeginFrame before the previous one's deadline was executed. | |
| 3430 // This should trigger the previous BeginFrame's deadline synchronously, | |
| 3431 // during which tiles will be prepared. As a result of that, no further | |
| 3432 // BeginFrames will be needed, and the new BeginFrame should be dropped. | |
| 3433 BeginFrameArgs args = SendNextBeginFrame(); | |
| 3434 EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 3); | |
| 3435 EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3); | |
| 3436 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); | |
| 3437 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | |
| 3438 EXPECT_FALSE(scheduler_->begin_frames_expected()); | |
| 3439 client_->Reset(); | |
| 3440 | |
| 3441 // Latest ack should be for the dropped BeginFrame. Since we don't have | |
| 3442 // further updates, its |latest_confirmed_sequence_number| should be for the | |
| 3443 // dropped BeginFrame, too. | |
| 3444 uint64_t latest_confirmed_sequence_number = args.sequence_number; | |
| 3445 bool has_damage = false; | |
| 3446 EXPECT_EQ( | |
| 3447 BeginFrameAck(args.source_id, args.sequence_number, | |
| 3448 latest_confirmed_sequence_number, 0, has_damage), | |
| 3449 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 3450 } | |
| 3451 | |
| 3452 TEST_F(SchedulerTest, BeginFrameAckForLateMissedBeginFrame) { | |
| 3453 SetUpScheduler(EXTERNAL_BFS); | |
| 3454 | |
| 3455 // Last confirmed frame was last BeginFrame. | |
| 3456 uint64_t latest_confirmed_sequence_number = | |
| 3457 fake_external_begin_frame_source_->next_begin_frame_number() - 1; | |
| 3458 | |
| 3459 scheduler_->SetNeedsRedraw(); | |
| 3460 client_->Reset(); | |
| 3461 | |
| 3462 // Send a missed BeginFrame with a passed deadline. | |
| 3463 now_src_->Advance(BeginFrameArgs::DefaultInterval()); | |
| 3464 BeginFrameArgs args = fake_external_begin_frame_source_->CreateBeginFrameArgs( | |
| 3465 BEGINFRAME_FROM_HERE, now_src()); | |
| 3466 args.type = BeginFrameArgs::MISSED; | |
| 3467 now_src_->Advance(BeginFrameArgs::DefaultInterval()); | |
| 3468 EXPECT_GT(now_src_->NowTicks(), args.deadline); | |
| 3469 fake_external_begin_frame_source_->TestOnBeginFrame(args); | |
| 3470 | |
| 3471 EXPECT_NO_ACTION(client_); | |
| 3472 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | |
| 3473 client_->Reset(); | |
| 3474 | |
| 3475 // Latest ack should be for the missed BeginFrame that was too late: no damage | |
| 3476 // and unconfirmed frame. | |
| 3477 bool has_damage = false; | |
| 3478 EXPECT_EQ( | |
| 3479 BeginFrameAck(args.source_id, args.sequence_number, | |
| 3480 latest_confirmed_sequence_number, 0, has_damage), | |
| 3481 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 3482 } | |
| 3483 | |
| 3484 TEST_F(SchedulerTest, BeginFrameAckForFinishedBeginFrameWithNewSourceId) { | |
| 3485 SetUpScheduler(EXTERNAL_BFS); | |
| 3486 | |
| 3487 scheduler_->SetNeedsRedraw(); | |
| 3488 client_->Reset(); | |
| 3489 | |
| 3490 // Send a BeginFrame with a different source_id. | |
| 3491 now_src_->Advance(BeginFrameArgs::DefaultInterval()); | |
| 3492 uint32_t source_id = fake_external_begin_frame_source_->source_id() + 1; | |
| 3493 BeginFrameArgs args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, | |
| 3494 source_id, 1, now_src()); | |
| 3495 fake_external_begin_frame_source_->TestOnBeginFrame(args); | |
| 3496 | |
| 3497 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); | |
| 3498 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); | |
| 3499 EXPECT_TRUE(scheduler_->begin_frames_expected()); | |
| 3500 client_->Reset(); | |
| 3501 | |
| 3502 task_runner().RunPendingTasks(); // Run posted deadline. | |
| 3503 EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); | |
| 3504 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | |
| 3505 EXPECT_TRUE(scheduler_->begin_frames_expected()); | |
| 3506 client_->Reset(); | |
| 3507 | |
| 3508 // Successful draw caused damage. | |
| 3509 uint64_t latest_confirmed_sequence_number = args.sequence_number; | |
| 3510 bool has_damage = true; | |
| 3511 EXPECT_EQ( | |
| 3512 BeginFrameAck(args.source_id, args.sequence_number, | |
| 3513 latest_confirmed_sequence_number, 0, has_damage), | |
| 3514 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 3515 } | |
| 3516 | |
| 3517 TEST_F(SchedulerTest, | |
| 3518 BeginFrameAckForLateMissedBeginFrameWithDifferentSourceId) { | |
| 3519 SetUpScheduler(EXTERNAL_BFS); | |
| 3520 | |
| 3521 scheduler_->SetNeedsRedraw(); | |
| 3522 client_->Reset(); | |
| 3523 | |
| 3524 // Send a missed BeginFrame with a passed deadline and different source_id. | |
| 3525 now_src_->Advance(BeginFrameArgs::DefaultInterval()); | |
| 3526 uint32_t source_id = fake_external_begin_frame_source_->source_id() + 1; | |
| 3527 BeginFrameArgs args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, | |
| 3528 source_id, 1, now_src()); | |
| 3529 args.type = BeginFrameArgs::MISSED; | |
| 3530 now_src_->Advance(BeginFrameArgs::DefaultInterval()); | |
| 3531 EXPECT_GT(now_src_->NowTicks(), args.deadline); | |
| 3532 fake_external_begin_frame_source_->TestOnBeginFrame(args); | |
| 3533 | |
| 3534 EXPECT_NO_ACTION(client_); | |
| 3535 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | |
| 3536 client_->Reset(); | |
| 3537 | |
| 3538 // Latest ack should be for the missed BeginFrame that was too late: no damage | |
| 3539 // and unconfirmed frame. Because the source_id changed, the | |
| 3540 // |latest_confirmed_sequence_number| should be set to invalid. | |
| 3541 uint64_t latest_confirmed_sequence_number = | |
| 3542 BeginFrameArgs::kInvalidFrameNumber; | |
| 3543 bool has_damage = false; | |
| 3544 EXPECT_EQ( | |
| 3545 BeginFrameAck(args.source_id, args.sequence_number, | |
| 3546 latest_confirmed_sequence_number, 0, has_damage), | |
| 3547 fake_external_begin_frame_source_->LastAckForObserver(scheduler_.get())); | |
| 3548 } | |
| 3549 | |
| 3259 } // namespace | 3550 } // namespace |
| 3260 } // namespace cc | 3551 } // namespace cc |
| OLD | NEW |