| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/surfaces/display_scheduler.h" | 5 #include "cc/surfaces/display_scheduler.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/memory/ptr_util.h" |
| 8 #include "base/test/null_task_runner.h" | 9 #include "base/test/null_task_runner.h" |
| 9 #include "base/test/simple_test_tick_clock.h" | 10 #include "base/test/simple_test_tick_clock.h" |
| 10 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
| 11 #include "cc/output/begin_frame_args.h" | 12 #include "cc/output/begin_frame_args.h" |
| 12 #include "cc/surfaces/display.h" | 13 #include "cc/surfaces/display.h" |
| 14 #include "cc/surfaces/display_begin_frame_source.h" |
| 13 #include "cc/test/fake_external_begin_frame_source.h" | 15 #include "cc/test/fake_external_begin_frame_source.h" |
| 14 #include "cc/test/scheduler_test_common.h" | 16 #include "cc/test/scheduler_test_common.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 18 |
| 17 namespace cc { | 19 namespace cc { |
| 18 namespace { | 20 namespace { |
| 19 | 21 |
| 20 const int kMaxPendingSwaps = 1; | 22 const int kMaxPendingSwaps = 1; |
| 21 | 23 |
| 22 static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); | 24 static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 33 } | 35 } |
| 34 | 36 |
| 35 void Reset() { draw_and_swap_count_ = 0; } | 37 void Reset() { draw_and_swap_count_ = 0; } |
| 36 | 38 |
| 37 int draw_and_swap_count() const { return draw_and_swap_count_; } | 39 int draw_and_swap_count() const { return draw_and_swap_count_; } |
| 38 | 40 |
| 39 protected: | 41 protected: |
| 40 int draw_and_swap_count_; | 42 int draw_and_swap_count_; |
| 41 }; | 43 }; |
| 42 | 44 |
| 45 // TODO(eseckler): Test with a mocked DisplayBeginFrameSource. |
| 46 // TODO(eseckler): Replace/add tests around expected child damage. |
| 47 // TODO(eseckler): Add tests for DisplayBeginFrameSource (elsewhere). |
| 48 |
| 43 class TestDisplayScheduler : public DisplayScheduler { | 49 class TestDisplayScheduler : public DisplayScheduler { |
| 44 public: | 50 public: |
| 45 TestDisplayScheduler(BeginFrameSource* begin_frame_source, | 51 TestDisplayScheduler(DisplayBeginFrameSource* begin_frame_source, |
| 46 base::SingleThreadTaskRunner* task_runner, | 52 base::SingleThreadTaskRunner* task_runner, |
| 47 int max_pending_swaps) | 53 int max_pending_swaps) |
| 48 : DisplayScheduler(begin_frame_source, task_runner, max_pending_swaps), | 54 : DisplayScheduler(task_runner, max_pending_swaps), |
| 49 scheduler_begin_frame_deadline_count_(0) {} | 55 scheduler_begin_frame_deadline_count_(0) { |
| 56 SetBeginFrameSource(begin_frame_source); |
| 57 } |
| 50 | 58 |
| 51 base::TimeTicks DesiredBeginFrameDeadlineTimeForTest() { | 59 base::TimeTicks DesiredBeginFrameDeadlineTimeForTest() { |
| 52 return DesiredBeginFrameDeadlineTime(); | 60 return DesiredBeginFrameDeadlineTime(); |
| 53 } | 61 } |
| 54 | 62 |
| 55 void BeginFrameDeadlineForTest() { OnBeginFrameDeadline(); } | 63 void BeginFrameDeadlineForTest() { OnBeginFrameDeadline(); } |
| 56 | 64 |
| 57 void ScheduleBeginFrameDeadline() override { | 65 void ScheduleBeginFrameDeadline() override { |
| 58 scheduler_begin_frame_deadline_count_++; | 66 scheduler_begin_frame_deadline_count_++; |
| 59 DisplayScheduler::ScheduleBeginFrameDeadline(); | 67 DisplayScheduler::ScheduleBeginFrameDeadline(); |
| 60 } | 68 } |
| 61 | 69 |
| 62 int scheduler_begin_frame_deadline_count() { | 70 int scheduler_begin_frame_deadline_count() { |
| 63 return scheduler_begin_frame_deadline_count_; | 71 return scheduler_begin_frame_deadline_count_; |
| 64 } | 72 } |
| 65 | 73 |
| 66 protected: | 74 protected: |
| 67 int scheduler_begin_frame_deadline_count_; | 75 int scheduler_begin_frame_deadline_count_; |
| 68 }; | 76 }; |
| 69 | 77 |
| 78 // TODO(eseckler): Update all these tests. Consider mocking out DisplayBFS and |
| 79 // testing it separately? |
| 70 class DisplaySchedulerTest : public testing::Test { | 80 class DisplaySchedulerTest : public testing::Test { |
| 71 public: | 81 public: |
| 72 DisplaySchedulerTest() | 82 DisplaySchedulerTest() |
| 73 : fake_begin_frame_source_(0.f, false), | 83 : display_begin_frame_source_(nullptr), |
| 84 next_begin_frame_number_(BeginFrameArgs::kStartingFrameNumber), |
| 74 task_runner_(new base::NullTaskRunner), | 85 task_runner_(new base::NullTaskRunner), |
| 75 scheduler_(&fake_begin_frame_source_, | 86 scheduler_(&display_begin_frame_source_, |
| 76 task_runner_.get(), | 87 task_runner_.get(), |
| 77 kMaxPendingSwaps) { | 88 kMaxPendingSwaps) { |
| 89 std::unique_ptr<BeginFrameSource> fake_begin_frame_source = |
| 90 base::MakeUnique<FakeExternalBeginFrameSource>(0.f, false); |
| 91 fake_begin_frame_source_ = static_cast<FakeExternalBeginFrameSource*>( |
| 92 fake_begin_frame_source.get()); |
| 93 display_begin_frame_source_.SwapWrappedSource(&fake_begin_frame_source); |
| 78 now_src_.Advance(base::TimeDelta::FromMicroseconds(10000)); | 94 now_src_.Advance(base::TimeDelta::FromMicroseconds(10000)); |
| 79 scheduler_.SetClient(&client_); | 95 scheduler_.SetClient(&client_); |
| 80 } | 96 } |
| 81 | 97 |
| 82 ~DisplaySchedulerTest() override {} | 98 ~DisplaySchedulerTest() override {} |
| 83 | 99 |
| 84 void SetUp() override { scheduler_.SetRootSurfaceResourcesLocked(false); } | 100 void SetUp() override { scheduler_.SetRootSurfaceResourcesLocked(false); } |
| 85 | 101 |
| 86 void BeginFrameForTest() { | 102 void BeginFrameForTest() { |
| 87 base::TimeTicks frame_time = now_src_.NowTicks(); | 103 base::TimeTicks frame_time = now_src_.NowTicks(); |
| 88 base::TimeDelta interval = BeginFrameArgs::DefaultInterval(); | 104 base::TimeDelta interval = BeginFrameArgs::DefaultInterval(); |
| 89 base::TimeTicks deadline = frame_time + interval; | 105 base::TimeTicks deadline = frame_time + interval; |
| 90 fake_begin_frame_source_.TestOnBeginFrame( | 106 fake_begin_frame_source_->TestOnBeginFrame(BeginFrameArgs::Create( |
| 91 BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline, | 107 BEGINFRAME_FROM_HERE, fake_begin_frame_source_->source_id(), |
| 92 interval, BeginFrameArgs::NORMAL)); | 108 next_begin_frame_number_++, frame_time, deadline, interval, |
| 109 BeginFrameArgs::NORMAL)); |
| 93 } | 110 } |
| 94 | 111 |
| 95 protected: | 112 protected: |
| 96 base::SimpleTestTickClock& now_src() { return now_src_; } | 113 base::SimpleTestTickClock& now_src() { return now_src_; } |
| 97 FakeDisplaySchedulerClient& client() { return client_; } | 114 FakeDisplaySchedulerClient& client() { return client_; } |
| 98 DisplayScheduler& scheduler() { return scheduler_; } | 115 DisplayScheduler& scheduler() { return scheduler_; } |
| 99 | 116 |
| 100 FakeExternalBeginFrameSource fake_begin_frame_source_; | 117 FakeExternalBeginFrameSource* fake_begin_frame_source_; // Not owned. |
| 118 DisplayBeginFrameSource display_begin_frame_source_; |
| 119 uint64_t next_begin_frame_number_; |
| 101 | 120 |
| 102 base::SimpleTestTickClock now_src_; | 121 base::SimpleTestTickClock now_src_; |
| 103 scoped_refptr<base::NullTaskRunner> task_runner_; | 122 scoped_refptr<base::NullTaskRunner> task_runner_; |
| 104 FakeDisplaySchedulerClient client_; | 123 FakeDisplaySchedulerClient client_; |
| 105 TestDisplayScheduler scheduler_; | 124 TestDisplayScheduler scheduler_; |
| 106 }; | 125 }; |
| 107 | 126 |
| 108 TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilNewRootSurface) { | 127 TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilNewRootSurface) { |
| 109 SurfaceId root_surface_id1(kArbitraryFrameSinkId, | 128 SurfaceId root_surface_id1(kArbitraryFrameSinkId, |
| 110 LocalFrameId(1, base::UnguessableToken::Create())); | 129 LocalFrameId(1, base::UnguessableToken::Create())); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 scheduler_.BeginFrameDeadlineForTest(); | 305 scheduler_.BeginFrameDeadlineForTest(); |
| 287 EXPECT_EQ(1, client_.draw_and_swap_count()); | 306 EXPECT_EQ(1, client_.draw_and_swap_count()); |
| 288 } | 307 } |
| 289 | 308 |
| 290 TEST_F(DisplaySchedulerTest, VisibleWithoutDamageNoTicks) { | 309 TEST_F(DisplaySchedulerTest, VisibleWithoutDamageNoTicks) { |
| 291 SurfaceId root_surface_id(kArbitraryFrameSinkId, | 310 SurfaceId root_surface_id(kArbitraryFrameSinkId, |
| 292 LocalFrameId(0, base::UnguessableToken::Create())); | 311 LocalFrameId(0, base::UnguessableToken::Create())); |
| 293 SurfaceId sid1(kArbitraryFrameSinkId, | 312 SurfaceId sid1(kArbitraryFrameSinkId, |
| 294 LocalFrameId(1, base::UnguessableToken::Create())); | 313 LocalFrameId(1, base::UnguessableToken::Create())); |
| 295 | 314 |
| 296 EXPECT_EQ(0u, fake_begin_frame_source_.num_observers()); | 315 EXPECT_EQ(0u, fake_begin_frame_source_->num_observers()); |
| 297 scheduler_.SetVisible(true); | 316 scheduler_.SetVisible(true); |
| 298 | 317 |
| 299 // When becoming visible, don't start listening for begin frames until there | 318 // When becoming visible, don't start listening for begin frames until there |
| 300 // is some damage. | 319 // is some damage. |
| 301 EXPECT_EQ(0u, fake_begin_frame_source_.num_observers()); | 320 EXPECT_EQ(0u, fake_begin_frame_source_->num_observers()); |
| 302 scheduler_.SetNewRootSurface(root_surface_id); | 321 scheduler_.SetNewRootSurface(root_surface_id); |
| 303 | 322 |
| 304 EXPECT_EQ(1u, fake_begin_frame_source_.num_observers()); | 323 EXPECT_EQ(1u, fake_begin_frame_source_->num_observers()); |
| 305 } | 324 } |
| 306 | 325 |
| 307 TEST_F(DisplaySchedulerTest, VisibleWithDamageTicks) { | 326 TEST_F(DisplaySchedulerTest, VisibleWithDamageTicks) { |
| 308 SurfaceId root_surface_id(kArbitraryFrameSinkId, | 327 SurfaceId root_surface_id(kArbitraryFrameSinkId, |
| 309 LocalFrameId(0, base::UnguessableToken::Create())); | 328 LocalFrameId(0, base::UnguessableToken::Create())); |
| 310 SurfaceId sid1(kArbitraryFrameSinkId, | 329 SurfaceId sid1(kArbitraryFrameSinkId, |
| 311 LocalFrameId(1, base::UnguessableToken::Create())); | 330 LocalFrameId(1, base::UnguessableToken::Create())); |
| 312 | 331 |
| 313 scheduler_.SetNewRootSurface(root_surface_id); | 332 scheduler_.SetNewRootSurface(root_surface_id); |
| 314 | 333 |
| 315 // When there is damage, start listening for begin frames once becoming | 334 // When there is damage, start listening for begin frames once becoming |
| 316 // visible. | 335 // visible. |
| 317 EXPECT_EQ(0u, fake_begin_frame_source_.num_observers()); | 336 EXPECT_EQ(0u, fake_begin_frame_source_->num_observers()); |
| 318 scheduler_.SetVisible(true); | 337 scheduler_.SetVisible(true); |
| 319 | 338 |
| 320 EXPECT_EQ(1u, fake_begin_frame_source_.num_observers()); | 339 EXPECT_EQ(1u, fake_begin_frame_source_->num_observers()); |
| 321 } | 340 } |
| 322 | 341 |
| 323 TEST_F(DisplaySchedulerTest, Visibility) { | 342 TEST_F(DisplaySchedulerTest, Visibility) { |
| 324 SurfaceId root_surface_id(kArbitraryFrameSinkId, | 343 SurfaceId root_surface_id(kArbitraryFrameSinkId, |
| 325 LocalFrameId(0, base::UnguessableToken::Create())); | 344 LocalFrameId(0, base::UnguessableToken::Create())); |
| 326 SurfaceId sid1(kArbitraryFrameSinkId, | 345 SurfaceId sid1(kArbitraryFrameSinkId, |
| 327 LocalFrameId(1, base::UnguessableToken::Create())); | 346 LocalFrameId(1, base::UnguessableToken::Create())); |
| 328 | 347 |
| 329 scheduler_.SetNewRootSurface(root_surface_id); | 348 scheduler_.SetNewRootSurface(root_surface_id); |
| 330 scheduler_.SetVisible(true); | 349 scheduler_.SetVisible(true); |
| 331 EXPECT_EQ(1u, fake_begin_frame_source_.num_observers()); | 350 EXPECT_EQ(1u, fake_begin_frame_source_->num_observers()); |
| 332 | 351 |
| 333 // DrawAndSwap normally. | 352 // DrawAndSwap normally. |
| 334 BeginFrameForTest(); | 353 BeginFrameForTest(); |
| 335 EXPECT_LT(now_src().NowTicks(), | 354 EXPECT_LT(now_src().NowTicks(), |
| 336 scheduler_.DesiredBeginFrameDeadlineTimeForTest()); | 355 scheduler_.DesiredBeginFrameDeadlineTimeForTest()); |
| 337 EXPECT_EQ(0, client_.draw_and_swap_count()); | 356 EXPECT_EQ(0, client_.draw_and_swap_count()); |
| 338 scheduler_.SurfaceDamaged(sid1); | 357 scheduler_.SurfaceDamaged(sid1); |
| 339 scheduler_.BeginFrameDeadlineForTest(); | 358 scheduler_.BeginFrameDeadlineForTest(); |
| 340 EXPECT_EQ(1, client_.draw_and_swap_count()); | 359 EXPECT_EQ(1, client_.draw_and_swap_count()); |
| 341 | 360 |
| 342 BeginFrameForTest(); | 361 BeginFrameForTest(); |
| 343 EXPECT_LT(now_src().NowTicks(), | 362 EXPECT_LT(now_src().NowTicks(), |
| 344 scheduler_.DesiredBeginFrameDeadlineTimeForTest()); | 363 scheduler_.DesiredBeginFrameDeadlineTimeForTest()); |
| 345 | 364 |
| 346 // Become not visible. | 365 // Become not visible. |
| 347 scheduler_.SetVisible(false); | 366 scheduler_.SetVisible(false); |
| 348 | 367 |
| 349 // It will stop listening for begin frames after the current deadline. | 368 // It will stop listening for begin frames after the current deadline. |
| 350 EXPECT_EQ(1u, fake_begin_frame_source_.num_observers()); | 369 EXPECT_EQ(1u, fake_begin_frame_source_->num_observers()); |
| 351 | 370 |
| 352 // Deadline does not DrawAndSwap when not visible. | 371 // Deadline does not DrawAndSwap when not visible. |
| 353 EXPECT_EQ(1, client_.draw_and_swap_count()); | 372 EXPECT_EQ(1, client_.draw_and_swap_count()); |
| 354 scheduler_.BeginFrameDeadlineForTest(); | 373 scheduler_.BeginFrameDeadlineForTest(); |
| 355 EXPECT_EQ(1, client_.draw_and_swap_count()); | 374 EXPECT_EQ(1, client_.draw_and_swap_count()); |
| 356 // Now it stops listening for begin frames. | 375 // Now it stops listening for begin frames. |
| 357 EXPECT_EQ(0u, fake_begin_frame_source_.num_observers()); | 376 EXPECT_EQ(0u, fake_begin_frame_source_->num_observers()); |
| 358 | 377 |
| 359 // Does not start listening for begin frames when becoming visible without | 378 // Does not start listening for begin frames when becoming visible without |
| 360 // damage. | 379 // damage. |
| 361 scheduler_.SetVisible(true); | 380 scheduler_.SetVisible(true); |
| 362 EXPECT_EQ(0u, fake_begin_frame_source_.num_observers()); | 381 EXPECT_EQ(0u, fake_begin_frame_source_->num_observers()); |
| 363 scheduler_.SetVisible(false); | 382 scheduler_.SetVisible(false); |
| 364 | 383 |
| 365 // Does not start listening for begin frames when damage arrives. | 384 // Does not start listening for begin frames when damage arrives. |
| 366 scheduler_.SurfaceDamaged(sid1); | 385 scheduler_.SurfaceDamaged(sid1); |
| 367 EXPECT_EQ(0u, fake_begin_frame_source_.num_observers()); | 386 EXPECT_EQ(0u, fake_begin_frame_source_->num_observers()); |
| 368 | 387 |
| 369 // But does when becoming visible with damage again. | 388 // But does when becoming visible with damage again. |
| 370 scheduler_.SetVisible(true); | 389 scheduler_.SetVisible(true); |
| 371 EXPECT_EQ(1u, fake_begin_frame_source_.num_observers()); | 390 EXPECT_EQ(1u, fake_begin_frame_source_->num_observers()); |
| 372 } | 391 } |
| 373 | 392 |
| 374 TEST_F(DisplaySchedulerTest, ResizeCausesSwap) { | 393 TEST_F(DisplaySchedulerTest, ResizeCausesSwap) { |
| 375 SurfaceId root_surface_id(kArbitraryFrameSinkId, | 394 SurfaceId root_surface_id(kArbitraryFrameSinkId, |
| 376 LocalFrameId(0, base::UnguessableToken::Create())); | 395 LocalFrameId(0, base::UnguessableToken::Create())); |
| 377 SurfaceId sid1(kArbitraryFrameSinkId, | 396 SurfaceId sid1(kArbitraryFrameSinkId, |
| 378 LocalFrameId(1, base::UnguessableToken::Create())); | 397 LocalFrameId(1, base::UnguessableToken::Create())); |
| 379 | 398 |
| 380 scheduler_.SetVisible(true); | 399 scheduler_.SetVisible(true); |
| 381 | 400 |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 | 587 |
| 569 scheduler_.SetRootSurfaceResourcesLocked(true); | 588 scheduler_.SetRootSurfaceResourcesLocked(true); |
| 570 EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count()); | 589 EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count()); |
| 571 | 590 |
| 572 scheduler_.OutputSurfaceLost(); | 591 scheduler_.OutputSurfaceLost(); |
| 573 EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count()); | 592 EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count()); |
| 574 } | 593 } |
| 575 | 594 |
| 576 } // namespace | 595 } // namespace |
| 577 } // namespace cc | 596 } // namespace cc |
| OLD | NEW |