xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/tests/unittests/SchedulerTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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::setPowerModeInternal.
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     EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms));
258     EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms));
259     EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(120_Hz, 30ms));
260 
261     EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 40ms));
262 
263     EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
264 
265     const auto savedMinAcquiredBuffers = mFlinger.mutableMinAcquiredBuffers();
266     mFlinger.mutableMinAcquiredBuffers() = 2;
267     EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
268     mFlinger.mutableMinAcquiredBuffers() = savedMinAcquiredBuffers;
269 }
270 
271 MATCHER(Is120Hz, "") {
272     return isApproxEqual(arg.front().mode.fps, 120_Hz);
273 }
274 
TEST_F(SchedulerTest,chooseRefreshRateForContentSelectsMaxRefreshRate)275 TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
276     mScheduler->registerDisplay(kDisplayId1,
277                                 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
278                                                                       kDisplay1Mode60->getId()));
279 
280     const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
281     scheduler::LayerProps layerProps = {
282             .visible = true,
283             .bounds = {0, 0, 0, 0},
284             .transform = {},
285             .setFrameRateVote = {},
286             .frameRateSelectionPriority = Layer::PRIORITY_UNSET,
287             .isSmallDirty = false,
288             .isFrontBuffered = false,
289     };
290     mScheduler->recordLayerHistory(layer->getSequence(), layerProps, 0, systemTime(),
291                                    LayerHistory::LayerUpdateType::Buffer);
292 
293     constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
294     FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
295 
296     constexpr uint32_t kDisplayArea = 999'999;
297     mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
298 
299     EXPECT_CALL(mSchedulerCallback, requestDisplayModes(Is120Hz())).Times(1);
300     mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
301                                             /*updateAttachedChoreographer*/ false);
302 
303     // No-op if layer requirements have not changed.
304     EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
305     mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
306                                             /*updateAttachedChoreographer*/ false);
307 }
308 
TEST_F(SchedulerTest,chooseDisplayModes)309 TEST_F(SchedulerTest, chooseDisplayModes) {
310     mScheduler->registerDisplay(kDisplayId1,
311                                 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
312                                                                       kDisplay1Mode60->getId()));
313 
314     mScheduler->setContentRequirements({kLayer, kLayer});
315     GlobalSignals globalSignals = {.idle = true};
316     mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
317 
318     using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
319 
320     auto modeChoices = mScheduler->chooseDisplayModes();
321     ASSERT_EQ(1u, modeChoices.size());
322 
323     auto choice = modeChoices.get(kDisplayId1);
324     ASSERT_TRUE(choice);
325     EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, globalSignals));
326 
327     globalSignals = {.idle = false};
328     mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
329 
330     modeChoices = mScheduler->chooseDisplayModes();
331     ASSERT_EQ(1u, modeChoices.size());
332 
333     choice = modeChoices.get(kDisplayId1);
334     ASSERT_TRUE(choice);
335     EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
336 
337     globalSignals = {.touch = true};
338     mScheduler->replaceTouchTimer(10);
339     mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
340 
341     modeChoices = mScheduler->chooseDisplayModes();
342     ASSERT_EQ(1u, modeChoices.size());
343 
344     choice = modeChoices.get(kDisplayId1);
345     ASSERT_TRUE(choice);
346     EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
347 }
348 
TEST_F(SchedulerTest,chooseDisplayModesHighHintTouchSignal)349 TEST_F(SchedulerTest, chooseDisplayModesHighHintTouchSignal) {
350     mScheduler->registerDisplay(kDisplayId1,
351                                 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
352                                                                       kDisplay1Mode60->getId()));
353 
354     using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
355 
356     std::vector<RefreshRateSelector::LayerRequirement> layers = {kLayer, kLayer};
357     auto& lr1 = layers[0];
358     auto& lr2 = layers[1];
359 
360     // Scenario that is similar to game. Expects no touch boost.
361     lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
362     lr1.frameRateCategory = FrameRateCategory::HighHint;
363     lr1.name = "ExplicitCategory HighHint";
364     lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitDefault;
365     lr2.desiredRefreshRate = 30_Hz;
366     lr2.name = "30Hz ExplicitDefault";
367     mScheduler->setContentRequirements(layers);
368     auto modeChoices = mScheduler->chooseDisplayModes();
369     ASSERT_EQ(1u, modeChoices.size());
370     auto choice = modeChoices.get(kDisplayId1);
371     ASSERT_TRUE(choice);
372     EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, {.touch = false}));
373 
374     // Scenario that is similar to video playback and interaction. Expects touch boost.
375     lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
376     lr1.frameRateCategory = FrameRateCategory::HighHint;
377     lr1.name = "ExplicitCategory HighHint";
378     lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitExactOrMultiple;
379     lr2.desiredRefreshRate = 30_Hz;
380     lr2.name = "30Hz ExplicitExactOrMultiple";
381     mScheduler->setContentRequirements(layers);
382     modeChoices = mScheduler->chooseDisplayModes();
383     ASSERT_EQ(1u, modeChoices.size());
384     choice = modeChoices.get(kDisplayId1);
385     ASSERT_TRUE(choice);
386     EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, {.touch = true}));
387 
388     // Scenario with explicit category and HighHint. Expects touch boost.
389     lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
390     lr1.frameRateCategory = FrameRateCategory::HighHint;
391     lr1.name = "ExplicitCategory HighHint";
392     lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
393     lr2.frameRateCategory = FrameRateCategory::Low;
394     lr2.name = "ExplicitCategory Low";
395     mScheduler->setContentRequirements(layers);
396     modeChoices = mScheduler->chooseDisplayModes();
397     ASSERT_EQ(1u, modeChoices.size());
398     choice = modeChoices.get(kDisplayId1);
399     ASSERT_TRUE(choice);
400     EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, {.touch = true}));
401 }
402 
TEST_F(SchedulerTest,chooseDisplayModesMultipleDisplays)403 TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
404     constexpr PhysicalDisplayId kActiveDisplayId = kDisplayId1;
405     mScheduler->registerDisplay(kDisplayId1,
406                                 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
407                                                                       kDisplay1Mode60->getId()),
408                                 kActiveDisplayId);
409     mScheduler->registerDisplay(kDisplayId2,
410                                 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
411                                                                       kDisplay2Mode60->getId()),
412                                 kActiveDisplayId);
413 
414     mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
415     mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON);
416 
417     using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
418     TestableScheduler::DisplayModeChoiceMap expectedChoices;
419 
420     {
421         const GlobalSignals globalSignals = {.idle = true};
422         expectedChoices =
423                 ftl::init::map<const PhysicalDisplayId&,
424                                DisplayModeChoice>(kDisplayId1,
425                                                   FrameRateMode{60_Hz, kDisplay1Mode60},
426                                                   globalSignals)(kDisplayId2,
427                                                                  FrameRateMode{60_Hz,
428                                                                                kDisplay2Mode60},
429                                                                  GlobalSignals{});
430 
431         mScheduler->setContentRequirements({kLayer, kLayer});
432         mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
433 
434         const auto actualChoices = mScheduler->chooseDisplayModes();
435         EXPECT_EQ(expectedChoices, actualChoices);
436     }
437     {
438         const GlobalSignals globalSignals = {.idle = false};
439         expectedChoices =
440                 ftl::init::map<const PhysicalDisplayId&,
441                                DisplayModeChoice>(kDisplayId1,
442                                                   FrameRateMode{120_Hz, kDisplay1Mode120},
443                                                   globalSignals)(kDisplayId2,
444                                                                  FrameRateMode{120_Hz,
445                                                                                kDisplay2Mode120},
446                                                                  GlobalSignals{});
447 
448         mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
449 
450         const auto actualChoices = mScheduler->chooseDisplayModes();
451         EXPECT_EQ(expectedChoices, actualChoices);
452     }
453     {
454         const GlobalSignals globalSignals = {.touch = true};
455         mScheduler->replaceTouchTimer(10);
456         mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
457 
458         expectedChoices =
459                 ftl::init::map<const PhysicalDisplayId&,
460                                DisplayModeChoice>(kDisplayId1,
461                                                   FrameRateMode{120_Hz, kDisplay1Mode120},
462                                                   globalSignals)(kDisplayId2,
463                                                                  FrameRateMode{120_Hz,
464                                                                                kDisplay2Mode120},
465                                                                  GlobalSignals{});
466 
467         const auto actualChoices = mScheduler->chooseDisplayModes();
468         EXPECT_EQ(expectedChoices, actualChoices);
469     }
470     {
471         // The kDisplayId3 does not support 120Hz, The pacesetter display rate is chosen to be 120
472         // Hz. In this case only the display kDisplayId3 choose 60Hz as it does not support 120Hz.
473         mScheduler->registerDisplay(kDisplayId3,
474                                     std::make_shared<RefreshRateSelector>(kDisplay3Modes,
475                                                                           kDisplay3Mode60->getId()),
476                                     kActiveDisplayId);
477         mScheduler->setDisplayPowerMode(kDisplayId3, hal::PowerMode::ON);
478 
479         const GlobalSignals globalSignals = {.touch = true};
480         mScheduler->replaceTouchTimer(10);
481         mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
482 
483         expectedChoices = ftl::init::map<
484                 const PhysicalDisplayId&,
485                 DisplayModeChoice>(kDisplayId1, FrameRateMode{120_Hz, kDisplay1Mode120},
486                                    globalSignals)(kDisplayId2,
487                                                   FrameRateMode{120_Hz, kDisplay2Mode120},
488                                                   GlobalSignals{})(kDisplayId3,
489                                                                    FrameRateMode{60_Hz,
490                                                                                  kDisplay3Mode60},
491                                                                    GlobalSignals{});
492 
493         const auto actualChoices = mScheduler->chooseDisplayModes();
494         EXPECT_EQ(expectedChoices, actualChoices);
495     }
496     {
497         // We should choose 60Hz despite the touch signal as pacesetter only supports 60Hz
498         mScheduler->setPacesetterDisplay(kDisplayId3);
499         const GlobalSignals globalSignals = {.touch = true};
500         mScheduler->replaceTouchTimer(10);
501         mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
502 
503         expectedChoices = ftl::init::map<
504                 const PhysicalDisplayId&,
505                 DisplayModeChoice>(kDisplayId1, FrameRateMode{60_Hz, kDisplay1Mode60},
506                                    GlobalSignals{})(kDisplayId2,
507                                                     FrameRateMode{60_Hz, kDisplay2Mode60},
508                                                     GlobalSignals{})(kDisplayId3,
509                                                                      FrameRateMode{60_Hz,
510                                                                                    kDisplay3Mode60},
511                                                                      globalSignals);
512 
513         const auto actualChoices = mScheduler->chooseDisplayModes();
514         EXPECT_EQ(expectedChoices, actualChoices);
515     }
516 }
517 
TEST_F(SchedulerTest,onFrameSignalMultipleDisplays)518 TEST_F(SchedulerTest, onFrameSignalMultipleDisplays) {
519     constexpr PhysicalDisplayId kActiveDisplayId = kDisplayId1;
520     mScheduler->registerDisplay(kDisplayId1,
521                                 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
522                                                                       kDisplay1Mode60->getId()),
523                                 kActiveDisplayId);
524     mScheduler->registerDisplay(kDisplayId2,
525                                 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
526                                                                       kDisplay2Mode60->getId()),
527                                 kActiveDisplayId);
528 
529     using VsyncIds = std::vector<std::pair<PhysicalDisplayId, VsyncId>>;
530 
531     struct Compositor final : ICompositor {
532         explicit Compositor(TestableScheduler& scheduler) : scheduler(scheduler) {}
533 
534         TestableScheduler& scheduler;
535 
536         struct {
537             PhysicalDisplayId commit;
538             PhysicalDisplayId composite;
539         } pacesetterIds;
540 
541         struct {
542             VsyncIds commit;
543             VsyncIds composite;
544         } vsyncIds;
545 
546         bool committed = true;
547         bool changePacesetter = false;
548 
549         void configure() override {}
550 
551         bool commit(PhysicalDisplayId pacesetterId,
552                     const scheduler::FrameTargets& targets) override {
553             pacesetterIds.commit = pacesetterId;
554 
555             vsyncIds.commit.clear();
556             vsyncIds.composite.clear();
557 
558             for (const auto& [id, target] : targets) {
559                 vsyncIds.commit.emplace_back(id, target->vsyncId());
560             }
561 
562             if (changePacesetter) {
563                 scheduler.setPacesetterDisplay(kDisplayId2);
564             }
565 
566             return committed;
567         }
568 
569         CompositeResultsPerDisplay composite(PhysicalDisplayId pacesetterId,
570                                              const scheduler::FrameTargeters& targeters) override {
571             pacesetterIds.composite = pacesetterId;
572 
573             CompositeResultsPerDisplay results;
574 
575             for (const auto& [id, targeter] : targeters) {
576                 vsyncIds.composite.emplace_back(id, targeter->target().vsyncId());
577                 results.try_emplace(id,
578                                     CompositeResult{.compositionCoverage =
579                                                             CompositionCoverage::Hwc});
580             }
581 
582             return results;
583         }
584 
585         void sample() override {}
586         void sendNotifyExpectedPresentHint(PhysicalDisplayId) override {}
587     } compositor(*mScheduler);
588 
589     mScheduler->doFrameSignal(compositor, VsyncId(42));
590 
591     const auto makeVsyncIds = [](VsyncId vsyncId, bool swap = false) -> VsyncIds {
592         if (swap) {
593             return {{kDisplayId2, vsyncId}, {kDisplayId1, vsyncId}};
594         } else {
595             return {{kDisplayId1, vsyncId}, {kDisplayId2, vsyncId}};
596         }
597     };
598 
599     EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
600     EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
601     EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.commit);
602     EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.composite);
603 
604     // FrameTargets should be updated despite the skipped commit.
605     compositor.committed = false;
606     mScheduler->doFrameSignal(compositor, VsyncId(43));
607 
608     EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
609     EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
610     EXPECT_EQ(makeVsyncIds(VsyncId(43)), compositor.vsyncIds.commit);
611     EXPECT_TRUE(compositor.vsyncIds.composite.empty());
612 
613     // The pacesetter may change during commit.
614     compositor.committed = true;
615     compositor.changePacesetter = true;
616     mScheduler->doFrameSignal(compositor, VsyncId(44));
617 
618     EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
619     EXPECT_EQ(kDisplayId2, compositor.pacesetterIds.composite);
620     EXPECT_EQ(makeVsyncIds(VsyncId(44)), compositor.vsyncIds.commit);
621     EXPECT_EQ(makeVsyncIds(VsyncId(44), true), compositor.vsyncIds.composite);
622 }
623 
TEST_F(SchedulerTest,nextFrameIntervalTest)624 TEST_F(SchedulerTest, nextFrameIntervalTest) {
625     SET_FLAG_FOR_TEST(flags::vrr_config, true);
626 
627     static constexpr size_t kHistorySize = 10;
628     static constexpr size_t kMinimumSamplesForPrediction = 6;
629     static constexpr size_t kOutlierTolerancePercent = 25;
630     const auto refreshRate = Fps::fromPeriodNsecs(500);
631     auto frameRate = Fps::fromPeriodNsecs(1000);
632 
633     const ftl::NonNull<DisplayModePtr> kMode = ftl::as_non_null(
634             createVrrDisplayMode(DisplayModeId(0), refreshRate,
635                                  hal::VrrConfig{.minFrameIntervalNs = static_cast<int32_t>(
636                                                         frameRate.getPeriodNsecs())}));
637     std::shared_ptr<VSyncPredictor> vrrTracker =
638             std::make_shared<VSyncPredictor>(std::make_unique<ZeroClock>(), kMode, kHistorySize,
639                                              kMinimumSamplesForPrediction,
640                                              kOutlierTolerancePercent);
641     std::shared_ptr<RefreshRateSelector> vrrSelectorPtr =
642             std::make_shared<RefreshRateSelector>(makeModes(kMode), kMode->getId());
643     TestableScheduler scheduler{std::make_unique<android::mock::VsyncController>(),
644                                 vrrTracker,
645                                 vrrSelectorPtr,
646                                 mFlinger.getFactory(),
647                                 mFlinger.getTimeStats(),
648                                 mSchedulerCallback};
649 
650     scheduler.registerDisplay(kMode->getPhysicalDisplayId(), vrrSelectorPtr, std::nullopt,
651                               vrrTracker);
652     vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
653     scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate, /*applyImmediately*/ false);
654     vrrTracker->addVsyncTimestamp(0);
655     // Set 1000 as vsync seq #0
656     vrrTracker->nextAnticipatedVSyncTimeFrom(700);
657 
658     EXPECT_EQ(Fps::fromPeriodNsecs(1000),
659               scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
660                                              TimePoint::fromNs(1000)));
661     EXPECT_EQ(Fps::fromPeriodNsecs(1000),
662               scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
663                                              TimePoint::fromNs(2000)));
664 
665     // Not crossing the min frame period
666     vrrTracker->onFrameBegin(TimePoint::fromNs(2000),
667                              {TimePoint::fromNs(1500), TimePoint::fromNs(1500)});
668     EXPECT_EQ(Fps::fromPeriodNsecs(1000),
669               scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
670                                              TimePoint::fromNs(2500)));
671     // Change render rate
672     frameRate = Fps::fromPeriodNsecs(2000);
673     vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
674     scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate, /*applyImmediately*/ false);
675 
676     EXPECT_EQ(Fps::fromPeriodNsecs(2000),
677               scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
678                                              TimePoint::fromNs(5500)));
679     EXPECT_EQ(Fps::fromPeriodNsecs(2000),
680               scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
681                                              TimePoint::fromNs(7500)));
682 }
683 
TEST_F(SchedulerTest,resyncAllToHardwareVsync)684 TEST_F(SchedulerTest, resyncAllToHardwareVsync) FTL_FAKE_GUARD(kMainThreadContext) {
685     // resyncAllToHardwareVsync will result in requesting hardware VSYNC on both displays, since
686     // they are both on.
687     EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
688     EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, true)).Times(1);
689 
690     mScheduler->registerDisplay(kDisplayId2,
691                                 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
692                                                                       kDisplay2Mode60->getId()));
693     mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
694     mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON);
695 
696     static constexpr bool kDisallow = true;
697     mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
698     mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
699 
700     static constexpr bool kAllowToEnable = true;
701     mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
702 }
703 
TEST_F(SchedulerTest,resyncAllDoNotAllow)704 TEST_F(SchedulerTest, resyncAllDoNotAllow) FTL_FAKE_GUARD(kMainThreadContext) {
705     // Without setting allowToEnable to true, resyncAllToHardwareVsync does not
706     // result in requesting hardware VSYNC.
707     EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, _)).Times(0);
708 
709     mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
710 
711     static constexpr bool kDisallow = true;
712     mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
713 
714     static constexpr bool kAllowToEnable = false;
715     mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
716 }
717 
TEST_F(SchedulerTest,resyncAllSkipsOffDisplays)718 TEST_F(SchedulerTest, resyncAllSkipsOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) {
719     SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
720 
721     // resyncAllToHardwareVsync will result in requesting hardware VSYNC on display 1, which is on,
722     // but not on display 2, which is off.
723     EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
724     EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, _)).Times(0);
725 
726     mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
727 
728     mScheduler->registerDisplay(kDisplayId2,
729                                 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
730                                                                       kDisplay2Mode60->getId()));
731     ASSERT_EQ(hal::PowerMode::OFF, mScheduler->getDisplayPowerMode(kDisplayId2));
732 
733     static constexpr bool kDisallow = true;
734     mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
735     mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
736 
737     static constexpr bool kAllowToEnable = true;
738     mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
739 }
740 
TEST_F(SchedulerTest,resyncAllLegacyAppliesToOffDisplays)741 TEST_F(SchedulerTest, resyncAllLegacyAppliesToOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) {
742     SET_FLAG_FOR_TEST(flags::multithreaded_present, false);
743 
744     // In the legacy code, prior to the flag, resync applied to OFF displays.
745     EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
746     EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, true)).Times(1);
747 
748     mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
749 
750     mScheduler->registerDisplay(kDisplayId2,
751                                 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
752                                                                       kDisplay2Mode60->getId()));
753     ASSERT_EQ(hal::PowerMode::OFF, mScheduler->getDisplayPowerMode(kDisplayId2));
754 
755     static constexpr bool kDisallow = true;
756     mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
757     mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
758 
759     static constexpr bool kAllowToEnable = true;
760     mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
761 }
762 
763 class AttachedChoreographerTest : public SchedulerTest {
764 protected:
765     void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
766                                Fps expectedChoreographerFps);
767 };
768 
TEST_F(AttachedChoreographerTest,registerSingle)769 TEST_F(AttachedChoreographerTest, registerSingle) {
770     EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
771 
772     const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
773 
774     EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
775     const sp<IDisplayEventConnection> connection =
776             mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
777 
778     EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
779     ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
780     EXPECT_EQ(1u,
781               mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
782     EXPECT_FALSE(
783             mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
784 }
785 
TEST_F(AttachedChoreographerTest,registerMultipleOnSameLayer)786 TEST_F(AttachedChoreographerTest, registerMultipleOnSameLayer) {
787     EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
788 
789     const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
790     const auto handle = layer->getHandle();
791 
792     EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
793 
794     EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_))
795             .WillOnce(Return(0))
796             .WillOnce(Return(0));
797 
798     const auto mockConnection1 = sp<MockEventThreadConnection>::make(mEventThread);
799     const auto mockConnection2 = sp<MockEventThreadConnection>::make(mEventThread);
800     EXPECT_CALL(*mEventThread, createEventConnection(_))
801             .WillOnce(Return(mockConnection1))
802             .WillOnce(Return(mockConnection2));
803 
804     const sp<IDisplayEventConnection> connection1 =
805             mScheduler->createDisplayEventConnection(Cycle::Render, {}, handle);
806     const sp<IDisplayEventConnection> connection2 =
807             mScheduler->createDisplayEventConnection(Cycle::Render, {}, handle);
808 
809     EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
810     ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
811     EXPECT_EQ(2u,
812               mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
813     EXPECT_FALSE(
814             mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
815 }
816 
TEST_F(AttachedChoreographerTest,registerMultipleOnDifferentLayers)817 TEST_F(AttachedChoreographerTest, registerMultipleOnDifferentLayers) {
818     EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
819 
820     const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
821     const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
822 
823     EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
824     const sp<IDisplayEventConnection> connection1 =
825             mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer1->getHandle());
826     const sp<IDisplayEventConnection> connection2 =
827             mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer2->getHandle());
828 
829     EXPECT_EQ(2u, mScheduler->mutableAttachedChoreographers().size());
830 
831     ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer1->getSequence()));
832     EXPECT_EQ(1u,
833               mScheduler->mutableAttachedChoreographers()[layer1->getSequence()]
834                       .connections.size());
835     EXPECT_FALSE(
836             mScheduler->mutableAttachedChoreographers()[layer1->getSequence()].frameRate.isValid());
837 
838     ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer2->getSequence()));
839     EXPECT_EQ(1u,
840               mScheduler->mutableAttachedChoreographers()[layer2->getSequence()]
841                       .connections.size());
842     EXPECT_FALSE(
843             mScheduler->mutableAttachedChoreographers()[layer2->getSequence()].frameRate.isValid());
844 }
845 
TEST_F(AttachedChoreographerTest,removedWhenConnectionIsGone)846 TEST_F(AttachedChoreographerTest, removedWhenConnectionIsGone) {
847     EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
848 
849     const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
850 
851     EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
852 
853     sp<IDisplayEventConnection> connection =
854             mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
855 
856     ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
857     EXPECT_EQ(1u,
858               mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
859 
860     // The connection is used all over this test, so it is quite hard to release it from here.
861     // Instead, we just do a small shortcut.
862     {
863         EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
864         sp<MockEventThreadConnection> mockConnection =
865                 sp<MockEventThreadConnection>::make(mEventThread);
866         mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.clear();
867         mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.emplace(
868                 mockConnection);
869     }
870 
871     RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
872     LayerHierarchy hierarchy(&layerState);
873     mScheduler->updateAttachedChoreographers(hierarchy, 60_Hz);
874     EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
875 }
876 
TEST_F(AttachedChoreographerTest,removedWhenLayerIsGone)877 TEST_F(AttachedChoreographerTest, removedWhenLayerIsGone) {
878     EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
879 
880     sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
881 
882     EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
883     const sp<IDisplayEventConnection> connection =
884             mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
885 
886     layer.clear();
887     EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
888 }
889 
frameRateTestScenario(Fps layerFps,int8_t frameRateCompatibility,Fps displayFps,Fps expectedChoreographerFps)890 void AttachedChoreographerTest::frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility,
891                                                       Fps displayFps,
892                                                       Fps expectedChoreographerFps) {
893     const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
894 
895     EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
896     sp<IDisplayEventConnection> connection =
897             mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
898 
899     RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
900     LayerHierarchy hierarchy(&layerState);
901 
902     layerState.frameRate = layerFps.getValue();
903     layerState.frameRateCompatibility = frameRateCompatibility;
904 
905     mScheduler->updateAttachedChoreographers(hierarchy, displayFps);
906 
907     ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
908     EXPECT_EQ(expectedChoreographerFps,
909               mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
910     EXPECT_EQ(expectedChoreographerFps, mEventThreadConnection->frameRate);
911 }
912 
TEST_F(AttachedChoreographerTest,setsFrameRateDefault)913 TEST_F(AttachedChoreographerTest, setsFrameRateDefault) {
914     Fps layerFps = 30_Hz;
915     int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
916     Fps displayFps = 60_Hz;
917     Fps expectedChoreographerFps = 30_Hz;
918 
919     frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
920 
921     layerFps = Fps::fromValue(32.7f);
922     frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
923 }
924 
TEST_F(AttachedChoreographerTest,setsFrameRateExact)925 TEST_F(AttachedChoreographerTest, setsFrameRateExact) {
926     Fps layerFps = 30_Hz;
927     int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_EXACT;
928     Fps displayFps = 60_Hz;
929     Fps expectedChoreographerFps = 30_Hz;
930 
931     frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
932 
933     layerFps = Fps::fromValue(32.7f);
934     expectedChoreographerFps = {};
935     frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
936 }
937 
TEST_F(AttachedChoreographerTest,setsFrameRateExactOrMultiple)938 TEST_F(AttachedChoreographerTest, setsFrameRateExactOrMultiple) {
939     Fps layerFps = 30_Hz;
940     int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
941     Fps displayFps = 60_Hz;
942     Fps expectedChoreographerFps = 30_Hz;
943 
944     frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
945 
946     layerFps = Fps::fromValue(32.7f);
947     expectedChoreographerFps = {};
948     frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
949 }
950 
TEST_F(AttachedChoreographerTest,setsFrameRateParent)951 TEST_F(AttachedChoreographerTest, setsFrameRateParent) {
952     const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
953     const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
954 
955     EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
956     sp<IDisplayEventConnection> connection =
957             mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
958 
959     RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
960     LayerHierarchy parentHierarchy(&parentState);
961 
962     RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
963     LayerHierarchy hierarchy(&layerState);
964     parentHierarchy.mChildren.push_back(
965             std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
966 
967     layerState.frameRate = (30_Hz).getValue();
968     layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
969 
970     mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
971 
972     ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
973 
974     EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
975 }
976 
TEST_F(AttachedChoreographerTest,setsFrameRateParent2Children)977 TEST_F(AttachedChoreographerTest, setsFrameRateParent2Children) {
978     const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
979     const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
980     const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
981 
982     EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
983     sp<IDisplayEventConnection> connection =
984             mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
985 
986     RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
987     LayerHierarchy parentHierarchy(&parentState);
988 
989     RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
990     LayerHierarchy layer1Hierarchy(&layer1State);
991     parentHierarchy.mChildren.push_back(
992             std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
993 
994     RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
995     LayerHierarchy layer2Hierarchy(&layer2State);
996     parentHierarchy.mChildren.push_back(
997             std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
998 
999     layer1State.frameRate = (30_Hz).getValue();
1000     layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1001 
1002     layer2State.frameRate = (20_Hz).getValue();
1003     layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1004 
1005     mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1006 
1007     ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
1008 
1009     EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
1010 }
1011 
TEST_F(AttachedChoreographerTest,setsFrameRateParentConflictingChildren)1012 TEST_F(AttachedChoreographerTest, setsFrameRateParentConflictingChildren) {
1013     const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
1014     const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
1015     const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
1016 
1017     EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
1018     sp<IDisplayEventConnection> connection =
1019             mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
1020 
1021     RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
1022     LayerHierarchy parentHierarchy(&parentState);
1023 
1024     RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
1025     LayerHierarchy layer1Hierarchy(&layer1State);
1026     parentHierarchy.mChildren.push_back(
1027             std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
1028 
1029     RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
1030     LayerHierarchy layer2Hierarchy(&layer2State);
1031     parentHierarchy.mChildren.push_back(
1032             std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
1033 
1034     layer1State.frameRate = (30_Hz).getValue();
1035     layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1036 
1037     layer2State.frameRate = (25_Hz).getValue();
1038     layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1039 
1040     mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1041 
1042     ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
1043 
1044     EXPECT_EQ(Fps(), mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
1045 }
1046 
TEST_F(AttachedChoreographerTest,setsFrameRateChild)1047 TEST_F(AttachedChoreographerTest, setsFrameRateChild) {
1048     const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
1049     const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
1050 
1051     EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
1052     sp<IDisplayEventConnection> connection =
1053             mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
1054 
1055     RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
1056     LayerHierarchy parentHierarchy(&parentState);
1057 
1058     RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
1059     LayerHierarchy hierarchy(&layerState);
1060     parentHierarchy.mChildren.push_back(
1061             std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
1062 
1063     parentState.frameRate = (30_Hz).getValue();
1064     parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1065 
1066     mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1067 
1068     ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
1069 
1070     EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
1071 }
1072 
TEST_F(AttachedChoreographerTest,setsFrameRateChildNotOverriddenByParent)1073 TEST_F(AttachedChoreographerTest, setsFrameRateChildNotOverriddenByParent) {
1074     const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
1075     const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
1076 
1077     EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
1078     sp<IDisplayEventConnection> connection =
1079             mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
1080 
1081     RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
1082     LayerHierarchy parentHierarchy(&parentState);
1083 
1084     RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
1085     LayerHierarchy hierarchy(&layerState);
1086     parentHierarchy.mChildren.push_back(
1087             std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
1088 
1089     parentState.frameRate = (30_Hz).getValue();
1090     parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1091 
1092     layerState.frameRate = (60_Hz).getValue();
1093     layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1094 
1095     mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1096 
1097     ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
1098 
1099     EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
1100 }
1101 
1102 } // namespace android::scheduler
1103