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