1 /*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <common/test/FlagUtils.h>
18 #include <ftl/fake_guard.h>
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21 #include <log/log.h>
22
23 #include <mutex>
24
25 #include "Scheduler/EventThread.h"
26 #include "Scheduler/RefreshRateSelector.h"
27 #include "Scheduler/VSyncPredictor.h"
28 #include "Scheduler/VSyncReactor.h"
29 #include "TestableScheduler.h"
30 #include "TestableSurfaceFlinger.h"
31 #include "mock/DisplayHardware/MockDisplayMode.h"
32 #include "mock/MockEventThread.h"
33 #include "mock/MockLayer.h"
34 #include "mock/MockSchedulerCallback.h"
35
36 #include <FrontEnd/LayerHierarchy.h>
37 #include <scheduler/FrameTime.h>
38
39 #include <com_android_graphics_surfaceflinger_flags.h>
40 #include "FpsOps.h"
41
42 using namespace com::android::graphics::surfaceflinger;
43
44 namespace android::scheduler {
45
46 using android::mock::createDisplayMode;
47 using android::mock::createVrrDisplayMode;
48
49 using testing::_;
50 using testing::Return;
51
52 namespace {
53
54 using MockEventThread = android::mock::EventThread;
55 using MockLayer = android::mock::MockLayer;
56
57 using LayerHierarchy = surfaceflinger::frontend::LayerHierarchy;
58 using LayerHierarchyBuilder = surfaceflinger::frontend::LayerHierarchyBuilder;
59 using RequestedLayerState = surfaceflinger::frontend::RequestedLayerState;
60
61 class ZeroClock : public Clock {
62 public:
now() const63 nsecs_t now() const override { return 0; }
64 };
65
66 class SchedulerTest : public testing::Test {
67 protected:
68 class MockEventThreadConnection : public android::EventThreadConnection {
69 public:
MockEventThreadConnection(EventThread * eventThread)70 explicit MockEventThreadConnection(EventThread* eventThread)
71 : EventThreadConnection(eventThread, /*callingUid*/ static_cast<uid_t>(0)) {}
72 ~MockEventThreadConnection() = default;
73
74 MOCK_METHOD1(stealReceiveChannel, binder::Status(gui::BitTube* outChannel));
75 MOCK_METHOD1(setVsyncRate, binder::Status(int count));
76 MOCK_METHOD0(requestNextVsync, binder::Status());
77 };
78
79 SchedulerTest();
80
81 static constexpr RefreshRateSelector::LayerRequirement kLayer = {.weight = 1.f};
82
83 static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(255u);
84 static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode60 =
85 ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(0), 60_Hz));
86 static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode120 =
87 ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(1), 120_Hz));
88 static inline const DisplayModes kDisplay1Modes = makeModes(kDisplay1Mode60, kDisplay1Mode120);
89
90 static inline FrameRateMode kDisplay1Mode60_60{60_Hz, kDisplay1Mode60};
91 static inline FrameRateMode kDisplay1Mode120_120{120_Hz, kDisplay1Mode120};
92
93 static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(254u);
94 static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode60 =
95 ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(0), 60_Hz));
96 static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode120 =
97 ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(1), 120_Hz));
98 static inline const DisplayModes kDisplay2Modes = makeModes(kDisplay2Mode60, kDisplay2Mode120);
99
100 static constexpr PhysicalDisplayId kDisplayId3 = PhysicalDisplayId::fromPort(253u);
101 static inline const ftl::NonNull<DisplayModePtr> kDisplay3Mode60 =
102 ftl::as_non_null(createDisplayMode(kDisplayId3, DisplayModeId(0), 60_Hz));
103 static inline const DisplayModes kDisplay3Modes = makeModes(kDisplay3Mode60);
104
105 std::shared_ptr<RefreshRateSelector> mSelector =
106 std::make_shared<RefreshRateSelector>(makeModes(kDisplay1Mode60),
107 kDisplay1Mode60->getId());
108
109 mock::SchedulerCallback mSchedulerCallback;
110 TestableSurfaceFlinger mFlinger;
111 TestableScheduler* mScheduler = new TestableScheduler{mSelector, mFlinger, mSchedulerCallback};
112 surfaceflinger::frontend::LayerHierarchyBuilder mLayerHierarchyBuilder;
113
114 MockEventThread* mEventThread;
115 sp<MockEventThreadConnection> mEventThreadConnection;
116 };
117
SchedulerTest()118 SchedulerTest::SchedulerTest() {
119 auto eventThread = std::make_unique<MockEventThread>();
120 mEventThread = eventThread.get();
121 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
122
123 mEventThreadConnection = sp<MockEventThreadConnection>::make(mEventThread);
124
125 // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
126 // sure that call gets executed and returns an EventThread::Connection object.
127 EXPECT_CALL(*mEventThread, createEventConnection(_))
128 .WillRepeatedly(Return(mEventThreadConnection));
129
130 mScheduler->setEventThread(Cycle::Render, std::move(eventThread));
131 mScheduler->setEventThread(Cycle::LastComposite, std::make_unique<MockEventThread>());
132
133 mFlinger.resetScheduler(mScheduler);
134 }
135
136 } // namespace
137
TEST_F(SchedulerTest,registerDisplay)138 TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) {
139 // Hardware VSYNC should not change if the display is already registered.
140 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId1, false)).Times(0);
141 mScheduler->registerDisplay(kDisplayId1,
142 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
143 kDisplay1Mode60->getId()));
144
145 // TODO(b/241285191): Restore once VsyncSchedule::getPendingHardwareVsyncState is called by
146 // Scheduler::setDisplayPowerMode rather than SF::setPhysicalDisplayPowerMode.
147 #if 0
148 // Hardware VSYNC should be disabled for newly registered displays.
149 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId2, false)).Times(1);
150 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId3, false)).Times(1);
151 #endif
152
153 mScheduler->registerDisplay(kDisplayId2,
154 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
155 kDisplay2Mode60->getId()));
156 mScheduler->registerDisplay(kDisplayId3,
157 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
158 kDisplay3Mode60->getId()));
159
160 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId1)->getPendingHardwareVsyncState());
161 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId2)->getPendingHardwareVsyncState());
162 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId3)->getPendingHardwareVsyncState());
163 }
164
TEST_F(SchedulerTest,chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported)165 TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) {
166 // The layer is registered at creation time and deregistered at destruction time.
167 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
168
169 // recordLayerHistory should be a noop
170 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
171 scheduler::LayerProps layerProps = {
172 .visible = true,
173 .bounds = {0, 0, 100, 100},
174 .transform = {},
175 .setFrameRateVote = {},
176 .frameRateSelectionPriority = Layer::PRIORITY_UNSET,
177 .isSmallDirty = false,
178 .isFrontBuffered = false,
179 };
180
181 mScheduler->recordLayerHistory(layer->getSequence(), layerProps, 0, 0,
182 LayerHistory::LayerUpdateType::Buffer);
183 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
184
185 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
186 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
187
188 constexpr uint32_t kDisplayArea = 999'999;
189 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
190
191 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
192 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
193 /*updateAttachedChoreographer*/ false);
194 }
195
TEST_F(SchedulerTest,updateDisplayModes)196 TEST_F(SchedulerTest, updateDisplayModes) {
197 ASSERT_EQ(0u, mScheduler->layerHistorySize());
198 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
199 ASSERT_EQ(1u, mScheduler->layerHistorySize());
200
201 // Replace `mSelector` with a new `RefreshRateSelector` that has different display modes.
202 mScheduler->registerDisplay(kDisplayId1,
203 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
204 kDisplay1Mode60->getId()));
205
206 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
207 scheduler::LayerProps layerProps = {
208 .visible = true,
209 .bounds = {0, 0, 100, 100},
210 .transform = {},
211 .setFrameRateVote = {},
212 .frameRateSelectionPriority = Layer::PRIORITY_UNSET,
213 .isSmallDirty = false,
214 .isFrontBuffered = false,
215 };
216 mScheduler->recordLayerHistory(layer->getSequence(), layerProps, 0, 0,
217 LayerHistory::LayerUpdateType::Buffer);
218 ASSERT_EQ(1u, mScheduler->getNumActiveLayers());
219 }
220
TEST_F(SchedulerTest,emitModeChangeEvent)221 TEST_F(SchedulerTest, emitModeChangeEvent) {
222 const auto selectorPtr =
223 std::make_shared<RefreshRateSelector>(kDisplay1Modes, kDisplay1Mode120->getId());
224 mScheduler->registerDisplay(kDisplayId1, selectorPtr);
225 mScheduler->onDisplayModeChanged(kDisplayId1, kDisplay1Mode120_120, true);
226
227 mScheduler->setContentRequirements({kLayer});
228
229 // No event is emitted in response to idle.
230 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
231
232 using TimerState = TestableScheduler::TimerState;
233
234 mScheduler->idleTimerCallback(TimerState::Expired);
235 selectorPtr->setActiveMode(kDisplay1Mode60->getId(), 60_Hz);
236
237 auto layer = kLayer;
238 layer.vote = RefreshRateSelector::LayerVoteType::ExplicitExact;
239 layer.desiredRefreshRate = 60_Hz;
240 mScheduler->setContentRequirements({layer});
241
242 // An event is emitted implicitly despite choosing the same mode as when idle.
243 EXPECT_CALL(*mEventThread, onModeChanged(kDisplay1Mode60_60)).Times(1);
244
245 mScheduler->idleTimerCallback(TimerState::Reset);
246
247 mScheduler->setContentRequirements({kLayer});
248
249 // An event is emitted explicitly for the mode change.
250 EXPECT_CALL(*mEventThread, onModeChanged(kDisplay1Mode120_120)).Times(1);
251
252 mScheduler->touchTimerCallback(TimerState::Reset);
253 mScheduler->onDisplayModeChanged(kDisplayId1, kDisplay1Mode120_120, true);
254 }
255
TEST_F(SchedulerTest,calculateMaxAcquiredBufferCount)256 TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
257 struct TestCase {
258 Fps refreshRate;
259 std::chrono::nanoseconds presentLatency;
260 int expectedBufferCount;
261 };
262
263 const auto verifyTestCases = [&](std::vector<TestCase> tests) {
264 for (const auto testCase : tests) {
265 EXPECT_EQ(testCase.expectedBufferCount,
266 mFlinger.calculateMaxAcquiredBufferCount(testCase.refreshRate,
267 testCase.presentLatency));
268 }
269 };
270
271 std::vector<TestCase> testCases{{60_Hz, 30ms, 1},
272 {90_Hz, 30ms, 2},
273 {120_Hz, 30ms, 3},
274 {60_Hz, 40ms, 2},
275 {60_Hz, 10ms, 1}};
276 verifyTestCases(testCases);
277
278 const auto savedMinAcquiredBuffers = mFlinger.mutableMinAcquiredBuffers();
279 mFlinger.mutableMinAcquiredBuffers() = 2;
280 verifyTestCases({{60_Hz, 10ms, 2}});
281 mFlinger.mutableMinAcquiredBuffers() = savedMinAcquiredBuffers;
282
283 const auto savedMaxAcquiredBuffers = mFlinger.mutableMaxAcquiredBuffers();
284 mFlinger.mutableMaxAcquiredBuffers() = 2;
285 testCases = {{60_Hz, 30ms, 1},
286 {90_Hz, 30ms, 2},
287 {120_Hz, 30ms, 2}, // max buffers allowed is 2
288 {60_Hz, 40ms, 2},
289 {60_Hz, 10ms, 1}};
290 verifyTestCases(testCases);
291 mFlinger.mutableMaxAcquiredBuffers() = 3; // max buffers allowed is 3
292 verifyTestCases({{120_Hz, 30ms, 3}});
293 mFlinger.mutableMaxAcquiredBuffers() = savedMaxAcquiredBuffers;
294 }
295
296 MATCHER(Is120Hz, "") {
297 return isApproxEqual(arg.front().mode.fps, 120_Hz);
298 }
299
TEST_F(SchedulerTest,chooseRefreshRateForContentSelectsMaxRefreshRate)300 TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
301 mScheduler->registerDisplay(kDisplayId1,
302 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
303 kDisplay1Mode60->getId()));
304
305 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
306 scheduler::LayerProps layerProps = {
307 .visible = true,
308 .bounds = {0, 0, 0, 0},
309 .transform = {},
310 .setFrameRateVote = {},
311 .frameRateSelectionPriority = Layer::PRIORITY_UNSET,
312 .isSmallDirty = false,
313 .isFrontBuffered = false,
314 };
315 mScheduler->recordLayerHistory(layer->getSequence(), layerProps, 0, systemTime(),
316 LayerHistory::LayerUpdateType::Buffer);
317
318 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
319 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
320
321 constexpr uint32_t kDisplayArea = 999'999;
322 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
323
324 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(Is120Hz())).Times(1);
325 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
326 /*updateAttachedChoreographer*/ false);
327
328 // No-op if layer requirements have not changed.
329 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
330 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
331 /*updateAttachedChoreographer*/ false);
332 }
333
TEST_F(SchedulerTest,chooseDisplayModes)334 TEST_F(SchedulerTest, chooseDisplayModes) {
335 mScheduler->registerDisplay(kDisplayId1,
336 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
337 kDisplay1Mode60->getId()));
338
339 mScheduler->setContentRequirements({kLayer, kLayer});
340 GlobalSignals globalSignals = {.idle = true};
341 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
342
343 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
344
345 auto modeChoices = mScheduler->chooseDisplayModes();
346 ASSERT_EQ(1u, modeChoices.size());
347
348 auto choice = modeChoices.get(kDisplayId1);
349 ASSERT_TRUE(choice);
350 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, globalSignals));
351
352 globalSignals = {.idle = false};
353 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
354
355 modeChoices = mScheduler->chooseDisplayModes();
356 ASSERT_EQ(1u, modeChoices.size());
357
358 choice = modeChoices.get(kDisplayId1);
359 ASSERT_TRUE(choice);
360 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
361
362 globalSignals = {.touch = true};
363 mScheduler->replaceTouchTimer(10);
364 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
365
366 modeChoices = mScheduler->chooseDisplayModes();
367 ASSERT_EQ(1u, modeChoices.size());
368
369 choice = modeChoices.get(kDisplayId1);
370 ASSERT_TRUE(choice);
371 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
372 }
373
TEST_F(SchedulerTest,chooseDisplayModesHighHintTouchSignal)374 TEST_F(SchedulerTest, chooseDisplayModesHighHintTouchSignal) {
375 mScheduler->registerDisplay(kDisplayId1,
376 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
377 kDisplay1Mode60->getId()));
378
379 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
380
381 std::vector<RefreshRateSelector::LayerRequirement> layers = {kLayer, kLayer};
382 auto& lr1 = layers[0];
383 auto& lr2 = layers[1];
384
385 // Scenario that is similar to game. Expects no touch boost.
386 lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
387 lr1.frameRateCategory = FrameRateCategory::HighHint;
388 lr1.name = "ExplicitCategory HighHint";
389 lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitDefault;
390 lr2.desiredRefreshRate = 30_Hz;
391 lr2.name = "30Hz ExplicitDefault";
392 mScheduler->setContentRequirements(layers);
393 auto modeChoices = mScheduler->chooseDisplayModes();
394 ASSERT_EQ(1u, modeChoices.size());
395 auto choice = modeChoices.get(kDisplayId1);
396 ASSERT_TRUE(choice);
397 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, {.touch = false}));
398
399 // Scenario that is similar to video playback and interaction. Expects touch boost.
400 lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
401 lr1.frameRateCategory = FrameRateCategory::HighHint;
402 lr1.name = "ExplicitCategory HighHint";
403 lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitExactOrMultiple;
404 lr2.desiredRefreshRate = 30_Hz;
405 lr2.name = "30Hz ExplicitExactOrMultiple";
406 mScheduler->setContentRequirements(layers);
407 modeChoices = mScheduler->chooseDisplayModes();
408 ASSERT_EQ(1u, modeChoices.size());
409 choice = modeChoices.get(kDisplayId1);
410 ASSERT_TRUE(choice);
411 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, {.touch = true}));
412
413 // Scenario with explicit category and HighHint. Expects touch boost.
414 lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
415 lr1.frameRateCategory = FrameRateCategory::HighHint;
416 lr1.name = "ExplicitCategory HighHint";
417 lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
418 lr2.frameRateCategory = FrameRateCategory::Low;
419 lr2.name = "ExplicitCategory Low";
420 mScheduler->setContentRequirements(layers);
421 modeChoices = mScheduler->chooseDisplayModes();
422 ASSERT_EQ(1u, modeChoices.size());
423 choice = modeChoices.get(kDisplayId1);
424 ASSERT_TRUE(choice);
425 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, {.touch = true}));
426 }
427
TEST_F(SchedulerTest,chooseDisplayModesMultipleDisplays)428 TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
429 constexpr PhysicalDisplayId kActiveDisplayId = kDisplayId1;
430 mScheduler->registerDisplay(kDisplayId1,
431 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
432 kDisplay1Mode60->getId()),
433 kActiveDisplayId);
434 mScheduler->registerDisplay(kDisplayId2,
435 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
436 kDisplay2Mode60->getId()),
437 kActiveDisplayId);
438
439 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
440 mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON);
441
442 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
443 TestableScheduler::DisplayModeChoiceMap expectedChoices;
444
445 {
446 const GlobalSignals globalSignals = {.idle = true};
447 expectedChoices =
448 ftl::init::map<const PhysicalDisplayId&,
449 DisplayModeChoice>(kDisplayId1,
450 FrameRateMode{60_Hz, kDisplay1Mode60},
451 globalSignals)(kDisplayId2,
452 FrameRateMode{60_Hz,
453 kDisplay2Mode60},
454 GlobalSignals{});
455
456 mScheduler->setContentRequirements({kLayer, kLayer});
457 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
458
459 const auto actualChoices = mScheduler->chooseDisplayModes();
460 EXPECT_EQ(expectedChoices, actualChoices);
461 }
462 {
463 const GlobalSignals globalSignals = {.idle = false};
464 expectedChoices =
465 ftl::init::map<const PhysicalDisplayId&,
466 DisplayModeChoice>(kDisplayId1,
467 FrameRateMode{120_Hz, kDisplay1Mode120},
468 globalSignals)(kDisplayId2,
469 FrameRateMode{120_Hz,
470 kDisplay2Mode120},
471 GlobalSignals{});
472
473 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
474
475 const auto actualChoices = mScheduler->chooseDisplayModes();
476 EXPECT_EQ(expectedChoices, actualChoices);
477 }
478 {
479 const GlobalSignals globalSignals = {.touch = true};
480 mScheduler->replaceTouchTimer(10);
481 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
482
483 expectedChoices =
484 ftl::init::map<const PhysicalDisplayId&,
485 DisplayModeChoice>(kDisplayId1,
486 FrameRateMode{120_Hz, kDisplay1Mode120},
487 globalSignals)(kDisplayId2,
488 FrameRateMode{120_Hz,
489 kDisplay2Mode120},
490 GlobalSignals{});
491
492 const auto actualChoices = mScheduler->chooseDisplayModes();
493 EXPECT_EQ(expectedChoices, actualChoices);
494 }
495 {
496 // The kDisplayId3 does not support 120Hz, The pacesetter display rate is chosen to be 120
497 // Hz. In this case only the display kDisplayId3 choose 60Hz as it does not support 120Hz.
498 mScheduler->registerDisplay(kDisplayId3,
499 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
500 kDisplay3Mode60->getId()),
501 kActiveDisplayId);
502 mScheduler->setDisplayPowerMode(kDisplayId3, hal::PowerMode::ON);
503
504 const GlobalSignals globalSignals = {.touch = true};
505 mScheduler->replaceTouchTimer(10);
506 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
507
508 expectedChoices = ftl::init::map<
509 const PhysicalDisplayId&,
510 DisplayModeChoice>(kDisplayId1, FrameRateMode{120_Hz, kDisplay1Mode120},
511 globalSignals)(kDisplayId2,
512 FrameRateMode{120_Hz, kDisplay2Mode120},
513 GlobalSignals{})(kDisplayId3,
514 FrameRateMode{60_Hz,
515 kDisplay3Mode60},
516 GlobalSignals{});
517
518 const auto actualChoices = mScheduler->chooseDisplayModes();
519 EXPECT_EQ(expectedChoices, actualChoices);
520 }
521 {
522 // We should choose 60Hz despite the touch signal as pacesetter only supports 60Hz
523 mScheduler->setPacesetterDisplay(kDisplayId3);
524 const GlobalSignals globalSignals = {.touch = true};
525 mScheduler->replaceTouchTimer(10);
526 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
527
528 expectedChoices = ftl::init::map<
529 const PhysicalDisplayId&,
530 DisplayModeChoice>(kDisplayId1, FrameRateMode{60_Hz, kDisplay1Mode60},
531 GlobalSignals{})(kDisplayId2,
532 FrameRateMode{60_Hz, kDisplay2Mode60},
533 GlobalSignals{})(kDisplayId3,
534 FrameRateMode{60_Hz,
535 kDisplay3Mode60},
536 globalSignals);
537
538 const auto actualChoices = mScheduler->chooseDisplayModes();
539 EXPECT_EQ(expectedChoices, actualChoices);
540 }
541 }
542
TEST_F(SchedulerTest,onFrameSignalMultipleDisplays)543 TEST_F(SchedulerTest, onFrameSignalMultipleDisplays) {
544 constexpr PhysicalDisplayId kActiveDisplayId = kDisplayId1;
545 mScheduler->registerDisplay(kDisplayId1,
546 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
547 kDisplay1Mode60->getId()),
548 kActiveDisplayId);
549 mScheduler->registerDisplay(kDisplayId2,
550 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
551 kDisplay2Mode60->getId()),
552 kActiveDisplayId);
553
554 using VsyncIds = std::vector<std::pair<PhysicalDisplayId, VsyncId>>;
555
556 struct Compositor final : ICompositor {
557 explicit Compositor(TestableScheduler& scheduler) : scheduler(scheduler) {}
558
559 TestableScheduler& scheduler;
560
561 struct {
562 PhysicalDisplayId commit;
563 PhysicalDisplayId composite;
564 } pacesetterIds;
565
566 struct {
567 VsyncIds commit;
568 VsyncIds composite;
569 } vsyncIds;
570
571 bool committed = true;
572 bool changePacesetter = false;
573
574 void configure() override {}
575
576 bool commit(PhysicalDisplayId pacesetterId,
577 const scheduler::FrameTargets& targets) override {
578 pacesetterIds.commit = pacesetterId;
579
580 vsyncIds.commit.clear();
581 vsyncIds.composite.clear();
582
583 for (const auto& [id, target] : targets) {
584 vsyncIds.commit.emplace_back(id, target->vsyncId());
585 }
586
587 if (changePacesetter) {
588 scheduler.setPacesetterDisplay(kDisplayId2);
589 }
590
591 return committed;
592 }
593
594 CompositeResultsPerDisplay composite(PhysicalDisplayId pacesetterId,
595 const scheduler::FrameTargeters& targeters) override {
596 pacesetterIds.composite = pacesetterId;
597
598 CompositeResultsPerDisplay results;
599
600 for (const auto& [id, targeter] : targeters) {
601 vsyncIds.composite.emplace_back(id, targeter->target().vsyncId());
602 results.try_emplace(id,
603 CompositeResult{.compositionCoverage =
604 CompositionCoverage::Hwc});
605 }
606
607 return results;
608 }
609
610 void sample() override {}
611 void sendNotifyExpectedPresentHint(PhysicalDisplayId) override {}
612 } compositor(*mScheduler);
613
614 mScheduler->doFrameSignal(compositor, VsyncId(42));
615
616 const auto makeVsyncIds = [](VsyncId vsyncId, bool swap = false) -> VsyncIds {
617 if (swap) {
618 return {{kDisplayId2, vsyncId}, {kDisplayId1, vsyncId}};
619 } else {
620 return {{kDisplayId1, vsyncId}, {kDisplayId2, vsyncId}};
621 }
622 };
623
624 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
625 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
626 EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.commit);
627 EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.composite);
628
629 // FrameTargets should be updated despite the skipped commit.
630 compositor.committed = false;
631 mScheduler->doFrameSignal(compositor, VsyncId(43));
632
633 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
634 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
635 EXPECT_EQ(makeVsyncIds(VsyncId(43)), compositor.vsyncIds.commit);
636 EXPECT_TRUE(compositor.vsyncIds.composite.empty());
637
638 // The pacesetter may change during commit.
639 compositor.committed = true;
640 compositor.changePacesetter = true;
641 mScheduler->doFrameSignal(compositor, VsyncId(44));
642
643 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
644 EXPECT_EQ(kDisplayId2, compositor.pacesetterIds.composite);
645 EXPECT_EQ(makeVsyncIds(VsyncId(44)), compositor.vsyncIds.commit);
646 EXPECT_EQ(makeVsyncIds(VsyncId(44), true), compositor.vsyncIds.composite);
647 }
648
TEST_F(SchedulerTest,nextFrameIntervalTest)649 TEST_F(SchedulerTest, nextFrameIntervalTest) {
650 SET_FLAG_FOR_TEST(flags::vrr_config, true);
651
652 static constexpr size_t kHistorySize = 10;
653 static constexpr size_t kMinimumSamplesForPrediction = 6;
654 static constexpr size_t kOutlierTolerancePercent = 25;
655 const auto refreshRate = Fps::fromPeriodNsecs(500);
656 auto frameRate = Fps::fromPeriodNsecs(1000);
657
658 const ftl::NonNull<DisplayModePtr> kMode = ftl::as_non_null(
659 createVrrDisplayMode(DisplayModeId(0), refreshRate,
660 hal::VrrConfig{.minFrameIntervalNs = static_cast<int32_t>(
661 frameRate.getPeriodNsecs())}));
662 std::shared_ptr<VSyncPredictor> vrrTracker =
663 std::make_shared<VSyncPredictor>(std::make_unique<ZeroClock>(), kMode, kHistorySize,
664 kMinimumSamplesForPrediction,
665 kOutlierTolerancePercent);
666 std::shared_ptr<RefreshRateSelector> vrrSelectorPtr =
667 std::make_shared<RefreshRateSelector>(makeModes(kMode), kMode->getId());
668 TestableScheduler scheduler{std::make_unique<android::mock::VsyncController>(),
669 vrrTracker,
670 vrrSelectorPtr,
671 mFlinger.getFactory(),
672 mFlinger.getTimeStats(),
673 mSchedulerCallback};
674
675 scheduler.registerDisplay(kMode->getPhysicalDisplayId(), vrrSelectorPtr, std::nullopt,
676 vrrTracker);
677 vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
678 scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate, /*applyImmediately*/ false);
679 vrrTracker->addVsyncTimestamp(0);
680 // Set 1000 as vsync seq #0
681 vrrTracker->nextAnticipatedVSyncTimeFrom(700);
682
683 EXPECT_EQ(Fps::fromPeriodNsecs(1000),
684 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
685 TimePoint::fromNs(1000)));
686 EXPECT_EQ(Fps::fromPeriodNsecs(1000),
687 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
688 TimePoint::fromNs(2000)));
689
690 // Not crossing the min frame period
691 vrrTracker->onFrameBegin(TimePoint::fromNs(2000),
692 {TimePoint::fromNs(1500), TimePoint::fromNs(1500)});
693 EXPECT_EQ(Fps::fromPeriodNsecs(1000),
694 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
695 TimePoint::fromNs(2500)));
696 // Change render rate
697 frameRate = Fps::fromPeriodNsecs(2000);
698 vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
699 scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate, /*applyImmediately*/ false);
700
701 EXPECT_EQ(Fps::fromPeriodNsecs(2000),
702 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
703 TimePoint::fromNs(5500)));
704 EXPECT_EQ(Fps::fromPeriodNsecs(2000),
705 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
706 TimePoint::fromNs(7500)));
707 }
708
TEST_F(SchedulerTest,resyncAllToHardwareVsync)709 TEST_F(SchedulerTest, resyncAllToHardwareVsync) FTL_FAKE_GUARD(kMainThreadContext) {
710 // resyncAllToHardwareVsync will result in requesting hardware VSYNC on both displays, since
711 // they are both on.
712 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
713 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, true)).Times(1);
714
715 mScheduler->registerDisplay(kDisplayId2,
716 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
717 kDisplay2Mode60->getId()));
718 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
719 mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON);
720
721 static constexpr bool kDisallow = true;
722 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
723 mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
724
725 static constexpr bool kAllowToEnable = true;
726 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
727 }
728
TEST_F(SchedulerTest,resyncAllDoNotAllow)729 TEST_F(SchedulerTest, resyncAllDoNotAllow) FTL_FAKE_GUARD(kMainThreadContext) {
730 // Without setting allowToEnable to true, resyncAllToHardwareVsync does not
731 // result in requesting hardware VSYNC.
732 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, _)).Times(0);
733
734 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
735
736 static constexpr bool kDisallow = true;
737 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
738
739 static constexpr bool kAllowToEnable = false;
740 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
741 }
742
TEST_F(SchedulerTest,resyncAllSkipsOffDisplays)743 TEST_F(SchedulerTest, resyncAllSkipsOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) {
744 // resyncAllToHardwareVsync will result in requesting hardware VSYNC on display 1, which is on,
745 // but not on display 2, which is off.
746 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
747 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, _)).Times(0);
748
749 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
750
751 mScheduler->registerDisplay(kDisplayId2,
752 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
753 kDisplay2Mode60->getId()));
754 ASSERT_EQ(hal::PowerMode::OFF, mScheduler->getDisplayPowerMode(kDisplayId2));
755
756 static constexpr bool kDisallow = true;
757 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
758 mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
759
760 static constexpr bool kAllowToEnable = true;
761 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
762 }
763
764 class AttachedChoreographerTest : public SchedulerTest {
765 protected:
766 void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
767 Fps expectedChoreographerFps);
768 };
769
TEST_F(AttachedChoreographerTest,registerSingle)770 TEST_F(AttachedChoreographerTest, registerSingle) {
771 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
772
773 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
774
775 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
776 const sp<IDisplayEventConnection> connection =
777 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
778
779 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
780 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
781 EXPECT_EQ(1u,
782 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
783 EXPECT_FALSE(
784 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
785 }
786
TEST_F(AttachedChoreographerTest,registerMultipleOnSameLayer)787 TEST_F(AttachedChoreographerTest, registerMultipleOnSameLayer) {
788 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
789
790 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
791 const auto handle = layer->getHandle();
792
793 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
794
795 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_))
796 .WillOnce(Return(0))
797 .WillOnce(Return(0));
798
799 const auto mockConnection1 = sp<MockEventThreadConnection>::make(mEventThread);
800 const auto mockConnection2 = sp<MockEventThreadConnection>::make(mEventThread);
801 EXPECT_CALL(*mEventThread, createEventConnection(_))
802 .WillOnce(Return(mockConnection1))
803 .WillOnce(Return(mockConnection2));
804
805 const sp<IDisplayEventConnection> connection1 =
806 mScheduler->createDisplayEventConnection(Cycle::Render, {}, handle);
807 const sp<IDisplayEventConnection> connection2 =
808 mScheduler->createDisplayEventConnection(Cycle::Render, {}, handle);
809
810 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
811 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
812 EXPECT_EQ(2u,
813 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
814 EXPECT_FALSE(
815 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
816 }
817
TEST_F(AttachedChoreographerTest,registerMultipleOnDifferentLayers)818 TEST_F(AttachedChoreographerTest, registerMultipleOnDifferentLayers) {
819 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
820
821 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
822 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
823
824 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
825 const sp<IDisplayEventConnection> connection1 =
826 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer1->getHandle());
827 const sp<IDisplayEventConnection> connection2 =
828 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer2->getHandle());
829
830 EXPECT_EQ(2u, mScheduler->mutableAttachedChoreographers().size());
831
832 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer1->getSequence()));
833 EXPECT_EQ(1u,
834 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()]
835 .connections.size());
836 EXPECT_FALSE(
837 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()].frameRate.isValid());
838
839 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer2->getSequence()));
840 EXPECT_EQ(1u,
841 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()]
842 .connections.size());
843 EXPECT_FALSE(
844 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()].frameRate.isValid());
845 }
846
TEST_F(AttachedChoreographerTest,removedWhenConnectionIsGone)847 TEST_F(AttachedChoreographerTest, removedWhenConnectionIsGone) {
848 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
849
850 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
851
852 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
853
854 sp<IDisplayEventConnection> connection =
855 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
856
857 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
858 EXPECT_EQ(1u,
859 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
860
861 // The connection is used all over this test, so it is quite hard to release it from here.
862 // Instead, we just do a small shortcut.
863 {
864 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
865 sp<MockEventThreadConnection> mockConnection =
866 sp<MockEventThreadConnection>::make(mEventThread);
867 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.clear();
868 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.emplace(
869 mockConnection);
870 }
871
872 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
873 LayerHierarchy hierarchy(&layerState);
874 mScheduler->updateAttachedChoreographers(hierarchy, 60_Hz);
875 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
876 }
877
TEST_F(AttachedChoreographerTest,removedWhenLayerIsGone)878 TEST_F(AttachedChoreographerTest, removedWhenLayerIsGone) {
879 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
880
881 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
882
883 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
884 const sp<IDisplayEventConnection> connection =
885 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
886
887 layer.clear();
888 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
889 }
890
frameRateTestScenario(Fps layerFps,int8_t frameRateCompatibility,Fps displayFps,Fps expectedChoreographerFps)891 void AttachedChoreographerTest::frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility,
892 Fps displayFps,
893 Fps expectedChoreographerFps) {
894 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
895
896 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
897 sp<IDisplayEventConnection> connection =
898 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
899
900 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
901 LayerHierarchy hierarchy(&layerState);
902
903 layerState.frameRate = layerFps.getValue();
904 layerState.frameRateCompatibility = frameRateCompatibility;
905
906 mScheduler->updateAttachedChoreographers(hierarchy, displayFps);
907
908 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
909 EXPECT_EQ(expectedChoreographerFps,
910 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
911 EXPECT_EQ(expectedChoreographerFps, mEventThreadConnection->frameRate);
912 }
913
TEST_F(AttachedChoreographerTest,setsFrameRateDefault)914 TEST_F(AttachedChoreographerTest, setsFrameRateDefault) {
915 Fps layerFps = 30_Hz;
916 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
917 Fps displayFps = 60_Hz;
918 Fps expectedChoreographerFps = 30_Hz;
919
920 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
921
922 layerFps = Fps::fromValue(32.7f);
923 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
924 }
925
TEST_F(AttachedChoreographerTest,setsFrameRateExact)926 TEST_F(AttachedChoreographerTest, setsFrameRateExact) {
927 Fps layerFps = 30_Hz;
928 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_EXACT;
929 Fps displayFps = 60_Hz;
930 Fps expectedChoreographerFps = 30_Hz;
931
932 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
933
934 layerFps = Fps::fromValue(32.7f);
935 expectedChoreographerFps = {};
936 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
937 }
938
TEST_F(AttachedChoreographerTest,setsFrameRateExactOrMultiple)939 TEST_F(AttachedChoreographerTest, setsFrameRateExactOrMultiple) {
940 Fps layerFps = 30_Hz;
941 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
942 Fps displayFps = 60_Hz;
943 Fps expectedChoreographerFps = 30_Hz;
944
945 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
946
947 layerFps = Fps::fromValue(32.7f);
948 expectedChoreographerFps = {};
949 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
950 }
951
TEST_F(AttachedChoreographerTest,setsFrameRateParent)952 TEST_F(AttachedChoreographerTest, setsFrameRateParent) {
953 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
954 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
955
956 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
957 sp<IDisplayEventConnection> connection =
958 mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
959
960 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
961 LayerHierarchy parentHierarchy(&parentState);
962
963 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
964 LayerHierarchy hierarchy(&layerState);
965 parentHierarchy.mChildren.push_back(
966 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
967
968 layerState.frameRate = (30_Hz).getValue();
969 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
970
971 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
972
973 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
974
975 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
976 }
977
TEST_F(AttachedChoreographerTest,setsFrameRateParent2Children)978 TEST_F(AttachedChoreographerTest, setsFrameRateParent2Children) {
979 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
980 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
981 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
982
983 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
984 sp<IDisplayEventConnection> connection =
985 mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
986
987 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
988 LayerHierarchy parentHierarchy(&parentState);
989
990 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
991 LayerHierarchy layer1Hierarchy(&layer1State);
992 parentHierarchy.mChildren.push_back(
993 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
994
995 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
996 LayerHierarchy layer2Hierarchy(&layer2State);
997 parentHierarchy.mChildren.push_back(
998 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
999
1000 layer1State.frameRate = (30_Hz).getValue();
1001 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1002
1003 layer2State.frameRate = (20_Hz).getValue();
1004 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1005
1006 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1007
1008 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
1009
1010 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
1011 }
1012
TEST_F(AttachedChoreographerTest,setsFrameRateParentConflictingChildren)1013 TEST_F(AttachedChoreographerTest, setsFrameRateParentConflictingChildren) {
1014 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
1015 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
1016 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
1017
1018 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
1019 sp<IDisplayEventConnection> connection =
1020 mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
1021
1022 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
1023 LayerHierarchy parentHierarchy(&parentState);
1024
1025 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
1026 LayerHierarchy layer1Hierarchy(&layer1State);
1027 parentHierarchy.mChildren.push_back(
1028 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
1029
1030 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
1031 LayerHierarchy layer2Hierarchy(&layer2State);
1032 parentHierarchy.mChildren.push_back(
1033 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
1034
1035 layer1State.frameRate = (30_Hz).getValue();
1036 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1037
1038 layer2State.frameRate = (25_Hz).getValue();
1039 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1040
1041 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1042
1043 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
1044
1045 EXPECT_EQ(Fps(), mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
1046 }
1047
TEST_F(AttachedChoreographerTest,setsFrameRateChild)1048 TEST_F(AttachedChoreographerTest, setsFrameRateChild) {
1049 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
1050 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
1051
1052 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
1053 sp<IDisplayEventConnection> connection =
1054 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
1055
1056 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
1057 LayerHierarchy parentHierarchy(&parentState);
1058
1059 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
1060 LayerHierarchy hierarchy(&layerState);
1061 parentHierarchy.mChildren.push_back(
1062 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
1063
1064 parentState.frameRate = (30_Hz).getValue();
1065 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1066
1067 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1068
1069 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
1070
1071 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
1072 }
1073
TEST_F(AttachedChoreographerTest,setsFrameRateChildNotOverriddenByParent)1074 TEST_F(AttachedChoreographerTest, setsFrameRateChildNotOverriddenByParent) {
1075 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
1076 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
1077
1078 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
1079 sp<IDisplayEventConnection> connection =
1080 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
1081
1082 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
1083 LayerHierarchy parentHierarchy(&parentState);
1084
1085 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
1086 LayerHierarchy hierarchy(&layerState);
1087 parentHierarchy.mChildren.push_back(
1088 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
1089
1090 parentState.frameRate = (30_Hz).getValue();
1091 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1092
1093 layerState.frameRate = (60_Hz).getValue();
1094 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1095
1096 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1097
1098 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
1099
1100 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
1101 }
1102
1103 } // namespace android::scheduler
1104