• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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