blob: dddda055448293878beec5da54a9a8d969c8032d [file] [log] [blame]
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001/*
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
ramindani0491e642023-11-16 17:42:14 -080017#include <common/test/FlagUtils.h>
Leon Scroggins III67388622023-02-06 20:36:20 -050018#include <ftl/fake_guard.h>
Ana Krulec0c8cd522018-08-31 12:27:28 -070019#include <gmock/gmock.h>
20#include <gtest/gtest.h>
Ana Krulec0c8cd522018-08-31 12:27:28 -070021#include <log/log.h>
22
Ana Krulece588e312018-09-18 12:32:24 -070023#include <mutex>
24
Ana Krulec0c8cd522018-08-31 12:27:28 -070025#include "Scheduler/EventThread.h"
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040026#include "Scheduler/RefreshRateSelector.h"
ramindani0491e642023-11-16 17:42:14 -080027#include "Scheduler/VSyncPredictor.h"
Ady Abraham20024aa2024-03-05 01:32:49 +000028#include "Scheduler/VSyncReactor.h"
Dominik Laskowski98041832019-08-01 18:35:59 -070029#include "TestableScheduler.h"
Dominik Laskowski983f2b52020-06-25 16:54:06 -070030#include "TestableSurfaceFlinger.h"
Dominik Laskowskib0054a22022-03-03 09:03:06 -080031#include "mock/DisplayHardware/MockDisplayMode.h"
Ana Krulec0c8cd522018-08-31 12:27:28 -070032#include "mock/MockEventThread.h"
Dominik Laskowski983f2b52020-06-25 16:54:06 -070033#include "mock/MockLayer.h"
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070034#include "mock/MockSchedulerCallback.h"
Ana Krulec0c8cd522018-08-31 12:27:28 -070035
Ady Abraham822ecbd2023-07-07 16:16:09 -070036#include <FrontEnd/LayerHierarchy.h>
ramindani7b32b3a2024-07-02 10:17:47 -070037#include <scheduler/FrameTime.h>
Ady Abraham822ecbd2023-07-07 16:16:09 -070038
ramindani0491e642023-11-16 17:42:14 -080039#include <com_android_graphics_surfaceflinger_flags.h>
Ady Abraham822ecbd2023-07-07 16:16:09 -070040#include "FpsOps.h"
41
ramindani0491e642023-11-16 17:42:14 -080042using namespace com::android::graphics::surfaceflinger;
43
Dominik Laskowski068173d2021-08-11 17:22:59 -070044namespace android::scheduler {
45
Dominik Laskowskib0054a22022-03-03 09:03:06 -080046using android::mock::createDisplayMode;
ramindani0491e642023-11-16 17:42:14 -080047using android::mock::createVrrDisplayMode;
Dominik Laskowskib0054a22022-03-03 09:03:06 -080048
Ana Krulec0c8cd522018-08-31 12:27:28 -070049using testing::_;
50using testing::Return;
51
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070052namespace {
Ana Krulec0c8cd522018-08-31 12:27:28 -070053
Dominik Laskowski068173d2021-08-11 17:22:59 -070054using MockEventThread = android::mock::EventThread;
55using MockLayer = android::mock::MockLayer;
56
Ady Abraham822ecbd2023-07-07 16:16:09 -070057using LayerHierarchy = surfaceflinger::frontend::LayerHierarchy;
58using LayerHierarchyBuilder = surfaceflinger::frontend::LayerHierarchyBuilder;
59using RequestedLayerState = surfaceflinger::frontend::RequestedLayerState;
60
Ady Abraham77b4fb12024-03-05 17:51:53 -080061class ZeroClock : public Clock {
62public:
63 nsecs_t now() const override { return 0; }
64};
65
Ana Krulec0c8cd522018-08-31 12:27:28 -070066class SchedulerTest : public testing::Test {
67protected:
Ana Krulec85c39af2018-12-26 17:29:57 -080068 class MockEventThreadConnection : public android::EventThreadConnection {
Ana Krulec0c8cd522018-08-31 12:27:28 -070069 public:
Ana Krulec85c39af2018-12-26 17:29:57 -080070 explicit MockEventThreadConnection(EventThread* eventThread)
Ady Abrahamf2851612023-09-25 17:19:00 -070071 : EventThreadConnection(eventThread, /*callingUid*/ static_cast<uid_t>(0)) {}
Ana Krulec0c8cd522018-08-31 12:27:28 -070072 ~MockEventThreadConnection() = default;
73
Huihong Luo6fac5232021-11-22 16:05:23 -080074 MOCK_METHOD1(stealReceiveChannel, binder::Status(gui::BitTube* outChannel));
75 MOCK_METHOD1(setVsyncRate, binder::Status(int count));
76 MOCK_METHOD0(requestNextVsync, binder::Status());
Ana Krulec0c8cd522018-08-31 12:27:28 -070077 };
78
Ana Krulec0c8cd522018-08-31 12:27:28 -070079 SchedulerTest();
Ana Krulec0c8cd522018-08-31 12:27:28 -070080
Dominik Laskowskiaa49af72024-08-12 17:29:34 -040081 static constexpr RefreshRateSelector::LayerRequirement kLayer = {.weight = 1.f};
82
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040083 static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(255u);
Ady Abrahamace3d052022-11-17 16:25:05 -080084 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));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040088 static inline const DisplayModes kDisplay1Modes = makeModes(kDisplay1Mode60, kDisplay1Mode120);
89
Dominik Laskowskiaa49af72024-08-12 17:29:34 -040090 static inline FrameRateMode kDisplay1Mode60_60{60_Hz, kDisplay1Mode60};
91 static inline FrameRateMode kDisplay1Mode120_120{120_Hz, kDisplay1Mode120};
92
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040093 static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(254u);
Ady Abrahamace3d052022-11-17 16:25:05 -080094 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));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040098 static inline const DisplayModes kDisplay2Modes = makeModes(kDisplay2Mode60, kDisplay2Mode120);
99
100 static constexpr PhysicalDisplayId kDisplayId3 = PhysicalDisplayId::fromPort(253u);
Ady Abrahamace3d052022-11-17 16:25:05 -0800101 static inline const ftl::NonNull<DisplayModePtr> kDisplay3Mode60 =
102 ftl::as_non_null(createDisplayMode(kDisplayId3, DisplayModeId(0), 60_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400103 static inline const DisplayModes kDisplay3Modes = makeModes(kDisplay3Mode60);
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200104
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400105 std::shared_ptr<RefreshRateSelector> mSelector =
106 std::make_shared<RefreshRateSelector>(makeModes(kDisplay1Mode60),
107 kDisplay1Mode60->getId());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700108
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700109 mock::SchedulerCallback mSchedulerCallback;
Leon Scroggins III823d4ca2023-12-12 16:57:34 -0500110 TestableSurfaceFlinger mFlinger;
ramindaniae645822024-01-11 10:57:29 -0800111 TestableScheduler* mScheduler = new TestableScheduler{mSelector, mFlinger, mSchedulerCallback};
Vishnu Naira0292282023-12-16 14:32:00 -0800112 surfaceflinger::frontend::LayerHierarchyBuilder mLayerHierarchyBuilder;
Dominik Laskowski98041832019-08-01 18:35:59 -0700113
Dominik Laskowski068173d2021-08-11 17:22:59 -0700114 MockEventThread* mEventThread;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700115 sp<MockEventThreadConnection> mEventThreadConnection;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700116};
117
118SchedulerTest::SchedulerTest() {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700119 auto eventThread = std::make_unique<MockEventThread>();
Ana Krulec0c8cd522018-08-31 12:27:28 -0700120 mEventThread = eventThread.get();
Ana Krulec85c39af2018-12-26 17:29:57 -0800121 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
122
Ady Abrahamd11bade2022-08-01 16:18:03 -0700123 mEventThreadConnection = sp<MockEventThreadConnection>::make(mEventThread);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700124
125 // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
126 // sure that call gets executed and returns an EventThread::Connection object.
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700127 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
Ana Krulec0c8cd522018-08-31 12:27:28 -0700128 .WillRepeatedly(Return(mEventThreadConnection));
129
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500130 mScheduler->setEventThread(Cycle::Render, std::move(eventThread));
Dominik Laskowskiaa49af72024-08-12 17:29:34 -0400131 mScheduler->setEventThread(Cycle::LastComposite, std::make_unique<MockEventThread>());
Ady Abrahama0a16272021-03-03 15:23:35 -0800132
133 mFlinger.resetScheduler(mScheduler);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700134}
135
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700136} // namespace
Ana Krulec0c8cd522018-08-31 12:27:28 -0700137
Dominik Laskowski66295432023-03-14 12:25:36 -0400138TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) {
Dominik Laskowski008bec02023-03-14 12:04:58 -0400139 // Hardware VSYNC should not change if the display is already registered.
Dominik Laskowski66295432023-03-14 12:25:36 -0400140 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId1, false)).Times(0);
Dominik Laskowski008bec02023-03-14 12:04:58 -0400141 mScheduler->registerDisplay(kDisplayId1,
142 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
143 kDisplay1Mode60->getId()));
144
Dominik Laskowski66295432023-03-14 12:25:36 -0400145 // TODO(b/241285191): Restore once VsyncSchedule::getPendingHardwareVsyncState is called by
146 // Scheduler::setDisplayPowerMode rather than SF::setPowerModeInternal.
147#if 0
Dominik Laskowski008bec02023-03-14 12:04:58 -0400148 // Hardware VSYNC should be disabled for newly registered displays.
Dominik Laskowski66295432023-03-14 12:25:36 -0400149 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId2, false)).Times(1);
150 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId3, false)).Times(1);
151#endif
Dominik Laskowski008bec02023-03-14 12:04:58 -0400152
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()));
Dominik Laskowski66295432023-03-14 12:25:36 -0400159
160 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId1)->getPendingHardwareVsyncState());
161 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId2)->getPendingHardwareVsyncState());
162 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId3)->getPendingHardwareVsyncState());
Dominik Laskowski008bec02023-03-14 12:04:58 -0400163}
164
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200165TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) {
166 // The layer is registered at creation time and deregistered at destruction time.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700167 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700168
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200169 // recordLayerHistory should be a noop
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700170 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700171 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0, 0,
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000172 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700173 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700174
Rachel Lee6a9731d2022-06-06 17:08:14 -0700175 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500176 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700177
178 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700179 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700180
ramindani69b58e82022-09-26 16:48:36 -0700181 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700182 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
183 /*updateAttachedChoreographer*/ false);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700184}
185
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200186TEST_F(SchedulerTest, updateDisplayModes) {
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700187 ASSERT_EQ(0u, mScheduler->layerHistorySize());
Dominik Laskowski068173d2021-08-11 17:22:59 -0700188 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700189 ASSERT_EQ(1u, mScheduler->layerHistorySize());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200190
Dominik Laskowski596a2562022-10-28 11:26:12 -0400191 // Replace `mSelector` with a new `RefreshRateSelector` that has different display modes.
192 mScheduler->registerDisplay(kDisplayId1,
193 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
194 kDisplay1Mode60->getId()));
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200195
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700196 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700197 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0, 0,
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000198 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700199 ASSERT_EQ(1u, mScheduler->getNumActiveLayers());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200200}
201
Dominik Laskowskiaa49af72024-08-12 17:29:34 -0400202TEST_F(SchedulerTest, emitModeChangeEvent) {
203 const auto selectorPtr =
204 std::make_shared<RefreshRateSelector>(kDisplay1Modes, kDisplay1Mode120->getId());
205 mScheduler->registerDisplay(kDisplayId1, selectorPtr);
Dominik Laskowskibda52362024-08-04 00:41:46 -0400206 mScheduler->onDisplayModeChanged(kDisplayId1, kDisplay1Mode120_120);
Dominik Laskowski068173d2021-08-11 17:22:59 -0700207
Dominik Laskowskiaa49af72024-08-12 17:29:34 -0400208 mScheduler->setContentRequirements({kLayer});
209
210 // No event is emitted in response to idle.
Ady Abraham690f4612021-07-01 23:24:03 -0700211 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Dominik Laskowskiaa49af72024-08-12 17:29:34 -0400212
213 using TimerState = TestableScheduler::TimerState;
214
215 mScheduler->idleTimerCallback(TimerState::Expired);
216 selectorPtr->setActiveMode(kDisplay1Mode60->getId(), 60_Hz);
217
218 auto layer = kLayer;
219 layer.vote = RefreshRateSelector::LayerVoteType::ExplicitExact;
220 layer.desiredRefreshRate = 60_Hz;
221 mScheduler->setContentRequirements({layer});
222
223 // An event is emitted implicitly despite choosing the same mode as when idle.
224 EXPECT_CALL(*mEventThread, onModeChanged(kDisplay1Mode60_60)).Times(1);
225
226 mScheduler->idleTimerCallback(TimerState::Reset);
227
228 mScheduler->setContentRequirements({kLayer});
229
230 // An event is emitted explicitly for the mode change.
231 EXPECT_CALL(*mEventThread, onModeChanged(kDisplay1Mode120_120)).Times(1);
232
233 mScheduler->touchTimerCallback(TimerState::Reset);
Dominik Laskowskibda52362024-08-04 00:41:46 -0400234 mScheduler->onDisplayModeChanged(kDisplayId1, kDisplay1Mode120_120);
Ana Krulec6ddd2612020-09-24 13:06:33 -0700235}
236
Ady Abraham899dcdb2021-06-15 16:56:21 -0700237TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700238 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms));
239 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms));
240 EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(120_Hz, 30ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800241
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700242 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 40ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800243
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700244 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Piquea1456c12023-05-17 12:11:15 -0700245
Lloyd Pique30db6402023-06-26 18:56:51 +0000246 const auto savedMinAcquiredBuffers = mFlinger.mutableMinAcquiredBuffers();
247 mFlinger.mutableMinAcquiredBuffers() = 2;
Lloyd Piquea1456c12023-05-17 12:11:15 -0700248 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Pique30db6402023-06-26 18:56:51 +0000249 mFlinger.mutableMinAcquiredBuffers() = savedMinAcquiredBuffers;
Ady Abraham564f9de2021-02-03 18:34:33 -0800250}
251
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200252MATCHER(Is120Hz, "") {
Ady Abrahamace3d052022-11-17 16:25:05 -0800253 return isApproxEqual(arg.front().mode.fps, 120_Hz);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200254}
255
256TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
Dominik Laskowski596a2562022-10-28 11:26:12 -0400257 mScheduler->registerDisplay(kDisplayId1,
258 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
259 kDisplay1Mode60->getId()));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200260
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800261 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
262 EXPECT_CALL(*layer, isVisible()).WillOnce(Return(true));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200263
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700264 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0, systemTime(),
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000265 LayerHistory::LayerUpdateType::Buffer);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200266
Rachel Lee6a9731d2022-06-06 17:08:14 -0700267 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500268 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200269
270 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700271 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200272
ramindani69b58e82022-09-26 16:48:36 -0700273 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(Is120Hz())).Times(1);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700274 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
275 /*updateAttachedChoreographer*/ false);
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800276
277 // No-op if layer requirements have not changed.
ramindani69b58e82022-09-26 16:48:36 -0700278 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700279 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
280 /*updateAttachedChoreographer*/ false);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200281}
282
Dominik Laskowskiaa49af72024-08-12 17:29:34 -0400283TEST_F(SchedulerTest, chooseDisplayModes) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400284 mScheduler->registerDisplay(kDisplayId1,
285 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
286 kDisplay1Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700287
Dominik Laskowskiaa49af72024-08-12 17:29:34 -0400288 mScheduler->setContentRequirements({kLayer, kLayer});
ramindani69b58e82022-09-26 16:48:36 -0700289 GlobalSignals globalSignals = {.idle = true};
290 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
291
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400292 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
293
294 auto modeChoices = mScheduler->chooseDisplayModes();
295 ASSERT_EQ(1u, modeChoices.size());
296
297 auto choice = modeChoices.get(kDisplayId1);
298 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800299 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700300
301 globalSignals = {.idle = false};
302 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400303
304 modeChoices = mScheduler->chooseDisplayModes();
305 ASSERT_EQ(1u, modeChoices.size());
306
307 choice = modeChoices.get(kDisplayId1);
308 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800309 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700310
311 globalSignals = {.touch = true};
312 mScheduler->replaceTouchTimer(10);
313 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700314
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400315 modeChoices = mScheduler->chooseDisplayModes();
316 ASSERT_EQ(1u, modeChoices.size());
317
318 choice = modeChoices.get(kDisplayId1);
319 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800320 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700321}
322
Dominik Laskowskiaa49af72024-08-12 17:29:34 -0400323TEST_F(SchedulerTest, chooseDisplayModesHighHintTouchSignal) {
Rachel Lee6ed96c92024-02-07 14:37:38 -0800324 mScheduler->registerDisplay(kDisplayId1,
325 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
326 kDisplay1Mode60->getId()));
327
328 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
329
Dominik Laskowskiaa49af72024-08-12 17:29:34 -0400330 std::vector<RefreshRateSelector::LayerRequirement> layers = {kLayer, kLayer};
Rachel Lee6ed96c92024-02-07 14:37:38 -0800331 auto& lr1 = layers[0];
332 auto& lr2 = layers[1];
333
334 // Scenario that is similar to game. Expects no touch boost.
335 lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
336 lr1.frameRateCategory = FrameRateCategory::HighHint;
337 lr1.name = "ExplicitCategory HighHint";
338 lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitDefault;
339 lr2.desiredRefreshRate = 30_Hz;
340 lr2.name = "30Hz ExplicitDefault";
341 mScheduler->setContentRequirements(layers);
342 auto modeChoices = mScheduler->chooseDisplayModes();
343 ASSERT_EQ(1u, modeChoices.size());
344 auto choice = modeChoices.get(kDisplayId1);
345 ASSERT_TRUE(choice);
346 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, {.touch = false}));
347
348 // Scenario that is similar to video playback and interaction. Expects touch boost.
349 lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
350 lr1.frameRateCategory = FrameRateCategory::HighHint;
351 lr1.name = "ExplicitCategory HighHint";
352 lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitExactOrMultiple;
353 lr2.desiredRefreshRate = 30_Hz;
354 lr2.name = "30Hz ExplicitExactOrMultiple";
355 mScheduler->setContentRequirements(layers);
356 modeChoices = mScheduler->chooseDisplayModes();
357 ASSERT_EQ(1u, modeChoices.size());
358 choice = modeChoices.get(kDisplayId1);
359 ASSERT_TRUE(choice);
360 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, {.touch = true}));
361
362 // Scenario with explicit category and HighHint. Expects touch boost.
363 lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
364 lr1.frameRateCategory = FrameRateCategory::HighHint;
365 lr1.name = "ExplicitCategory HighHint";
366 lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
367 lr2.frameRateCategory = FrameRateCategory::Low;
368 lr2.name = "ExplicitCategory Low";
369 mScheduler->setContentRequirements(layers);
370 modeChoices = mScheduler->chooseDisplayModes();
371 ASSERT_EQ(1u, modeChoices.size());
372 choice = modeChoices.get(kDisplayId1);
373 ASSERT_TRUE(choice);
374 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, {.touch = true}));
375}
376
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400377TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
Dominik Laskowski3ff44c72024-06-17 11:03:30 -0400378 constexpr PhysicalDisplayId kActiveDisplayId = kDisplayId1;
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400379 mScheduler->registerDisplay(kDisplayId1,
380 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
Dominik Laskowski3ff44c72024-06-17 11:03:30 -0400381 kDisplay1Mode60->getId()),
382 kActiveDisplayId);
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400383 mScheduler->registerDisplay(kDisplayId2,
384 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
Dominik Laskowski3ff44c72024-06-17 11:03:30 -0400385 kDisplay2Mode60->getId()),
386 kActiveDisplayId);
ramindani69b58e82022-09-26 16:48:36 -0700387
Dominik Laskowski086507b2024-05-16 15:33:16 -0400388 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
389 mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON);
390
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400391 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
392 TestableScheduler::DisplayModeChoiceMap expectedChoices;
ramindani69b58e82022-09-26 16:48:36 -0700393
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400394 {
395 const GlobalSignals globalSignals = {.idle = true};
396 expectedChoices =
397 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800398 DisplayModeChoice>(kDisplayId1,
399 FrameRateMode{60_Hz, kDisplay1Mode60},
400 globalSignals)(kDisplayId2,
401 FrameRateMode{60_Hz,
402 kDisplay2Mode60},
Dominik Laskowski9e88d622024-03-06 17:42:39 -0500403 GlobalSignals{});
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400404
Dominik Laskowskiaa49af72024-08-12 17:29:34 -0400405 mScheduler->setContentRequirements({kLayer, kLayer});
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400406 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
407
408 const auto actualChoices = mScheduler->chooseDisplayModes();
409 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700410 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400411 {
412 const GlobalSignals globalSignals = {.idle = false};
413 expectedChoices =
414 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800415 DisplayModeChoice>(kDisplayId1,
416 FrameRateMode{120_Hz, kDisplay1Mode120},
417 globalSignals)(kDisplayId2,
418 FrameRateMode{120_Hz,
419 kDisplay2Mode120},
Dominik Laskowski9e88d622024-03-06 17:42:39 -0500420 GlobalSignals{});
ramindani69b58e82022-09-26 16:48:36 -0700421
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400422 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700423
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400424 const auto actualChoices = mScheduler->chooseDisplayModes();
425 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700426 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400427 {
428 const GlobalSignals globalSignals = {.touch = true};
429 mScheduler->replaceTouchTimer(10);
430 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700431
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400432 expectedChoices =
433 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800434 DisplayModeChoice>(kDisplayId1,
435 FrameRateMode{120_Hz, kDisplay1Mode120},
436 globalSignals)(kDisplayId2,
437 FrameRateMode{120_Hz,
438 kDisplay2Mode120},
Dominik Laskowski9e88d622024-03-06 17:42:39 -0500439 GlobalSignals{});
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400440
441 const auto actualChoices = mScheduler->chooseDisplayModes();
442 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700443 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400444 {
ramindani22f2ead2023-04-21 10:27:11 -0700445 // The kDisplayId3 does not support 120Hz, The pacesetter display rate is chosen to be 120
446 // Hz. In this case only the display kDisplayId3 choose 60Hz as it does not support 120Hz.
Dominik Laskowski3ff44c72024-06-17 11:03:30 -0400447 mScheduler->registerDisplay(kDisplayId3,
448 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
449 kDisplay3Mode60->getId()),
450 kActiveDisplayId);
Dominik Laskowski086507b2024-05-16 15:33:16 -0400451 mScheduler->setDisplayPowerMode(kDisplayId3, hal::PowerMode::ON);
Dominik Laskowski327d6092022-10-11 18:05:08 -0400452
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400453 const GlobalSignals globalSignals = {.touch = true};
454 mScheduler->replaceTouchTimer(10);
455 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani7c487282022-10-10 16:17:51 -0700456
Ady Abrahamace3d052022-11-17 16:25:05 -0800457 expectedChoices = ftl::init::map<
458 const PhysicalDisplayId&,
ramindani22f2ead2023-04-21 10:27:11 -0700459 DisplayModeChoice>(kDisplayId1, FrameRateMode{120_Hz, kDisplay1Mode120},
460 globalSignals)(kDisplayId2,
461 FrameRateMode{120_Hz, kDisplay2Mode120},
Dominik Laskowski9e88d622024-03-06 17:42:39 -0500462 GlobalSignals{})(kDisplayId3,
463 FrameRateMode{60_Hz,
464 kDisplay3Mode60},
465 GlobalSignals{});
ramindani22f2ead2023-04-21 10:27:11 -0700466
467 const auto actualChoices = mScheduler->chooseDisplayModes();
468 EXPECT_EQ(expectedChoices, actualChoices);
469 }
470 {
471 // We should choose 60Hz despite the touch signal as pacesetter only supports 60Hz
472 mScheduler->setPacesetterDisplay(kDisplayId3);
473 const GlobalSignals globalSignals = {.touch = true};
474 mScheduler->replaceTouchTimer(10);
475 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
476
477 expectedChoices = ftl::init::map<
478 const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800479 DisplayModeChoice>(kDisplayId1, FrameRateMode{60_Hz, kDisplay1Mode60},
Dominik Laskowski9e88d622024-03-06 17:42:39 -0500480 GlobalSignals{})(kDisplayId2,
481 FrameRateMode{60_Hz, kDisplay2Mode60},
482 GlobalSignals{})(kDisplayId3,
483 FrameRateMode{60_Hz,
484 kDisplay3Mode60},
485 globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400486
487 const auto actualChoices = mScheduler->chooseDisplayModes();
488 EXPECT_EQ(expectedChoices, actualChoices);
ramindani7c487282022-10-10 16:17:51 -0700489 }
ramindani69b58e82022-09-26 16:48:36 -0700490}
491
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400492TEST_F(SchedulerTest, onFrameSignalMultipleDisplays) {
Dominik Laskowski3ff44c72024-06-17 11:03:30 -0400493 constexpr PhysicalDisplayId kActiveDisplayId = kDisplayId1;
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400494 mScheduler->registerDisplay(kDisplayId1,
495 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
Dominik Laskowski3ff44c72024-06-17 11:03:30 -0400496 kDisplay1Mode60->getId()),
497 kActiveDisplayId);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400498 mScheduler->registerDisplay(kDisplayId2,
499 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
Dominik Laskowski3ff44c72024-06-17 11:03:30 -0400500 kDisplay2Mode60->getId()),
501 kActiveDisplayId);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400502
503 using VsyncIds = std::vector<std::pair<PhysicalDisplayId, VsyncId>>;
504
505 struct Compositor final : ICompositor {
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500506 explicit Compositor(TestableScheduler& scheduler) : scheduler(scheduler) {}
507
508 TestableScheduler& scheduler;
509
510 struct {
511 PhysicalDisplayId commit;
512 PhysicalDisplayId composite;
513 } pacesetterIds;
514
515 struct {
516 VsyncIds commit;
517 VsyncIds composite;
518 } vsyncIds;
519
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400520 bool committed = true;
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500521 bool changePacesetter = false;
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400522
523 void configure() override {}
524
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500525 bool commit(PhysicalDisplayId pacesetterId,
526 const scheduler::FrameTargets& targets) override {
527 pacesetterIds.commit = pacesetterId;
528
529 vsyncIds.commit.clear();
530 vsyncIds.composite.clear();
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400531
532 for (const auto& [id, target] : targets) {
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500533 vsyncIds.commit.emplace_back(id, target->vsyncId());
534 }
535
536 if (changePacesetter) {
537 scheduler.setPacesetterDisplay(kDisplayId2);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400538 }
539
540 return committed;
541 }
542
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500543 CompositeResultsPerDisplay composite(PhysicalDisplayId pacesetterId,
544 const scheduler::FrameTargeters& targeters) override {
545 pacesetterIds.composite = pacesetterId;
546
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400547 CompositeResultsPerDisplay results;
548
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500549 for (const auto& [id, targeter] : targeters) {
550 vsyncIds.composite.emplace_back(id, targeter->target().vsyncId());
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400551 results.try_emplace(id,
552 CompositeResult{.compositionCoverage =
553 CompositionCoverage::Hwc});
554 }
555
556 return results;
557 }
558
559 void sample() override {}
ramindaniae645822024-01-11 10:57:29 -0800560 void sendNotifyExpectedPresentHint(PhysicalDisplayId) override {}
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500561 } compositor(*mScheduler);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400562
563 mScheduler->doFrameSignal(compositor, VsyncId(42));
564
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500565 const auto makeVsyncIds = [](VsyncId vsyncId, bool swap = false) -> VsyncIds {
566 if (swap) {
567 return {{kDisplayId2, vsyncId}, {kDisplayId1, vsyncId}};
568 } else {
569 return {{kDisplayId1, vsyncId}, {kDisplayId2, vsyncId}};
570 }
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400571 };
572
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500573 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
574 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
575 EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.commit);
576 EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.composite);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400577
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500578 // FrameTargets should be updated despite the skipped commit.
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400579 compositor.committed = false;
580 mScheduler->doFrameSignal(compositor, VsyncId(43));
581
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500582 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
583 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
584 EXPECT_EQ(makeVsyncIds(VsyncId(43)), compositor.vsyncIds.commit);
585 EXPECT_TRUE(compositor.vsyncIds.composite.empty());
586
587 // The pacesetter may change during commit.
588 compositor.committed = true;
589 compositor.changePacesetter = true;
590 mScheduler->doFrameSignal(compositor, VsyncId(44));
591
592 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
593 EXPECT_EQ(kDisplayId2, compositor.pacesetterIds.composite);
594 EXPECT_EQ(makeVsyncIds(VsyncId(44)), compositor.vsyncIds.commit);
595 EXPECT_EQ(makeVsyncIds(VsyncId(44), true), compositor.vsyncIds.composite);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400596}
597
ramindani0491e642023-11-16 17:42:14 -0800598TEST_F(SchedulerTest, nextFrameIntervalTest) {
599 SET_FLAG_FOR_TEST(flags::vrr_config, true);
600
601 static constexpr size_t kHistorySize = 10;
602 static constexpr size_t kMinimumSamplesForPrediction = 6;
603 static constexpr size_t kOutlierTolerancePercent = 25;
604 const auto refreshRate = Fps::fromPeriodNsecs(500);
605 auto frameRate = Fps::fromPeriodNsecs(1000);
606
607 const ftl::NonNull<DisplayModePtr> kMode = ftl::as_non_null(
608 createVrrDisplayMode(DisplayModeId(0), refreshRate,
609 hal::VrrConfig{.minFrameIntervalNs = static_cast<int32_t>(
610 frameRate.getPeriodNsecs())}));
611 std::shared_ptr<VSyncPredictor> vrrTracker =
Ady Abraham77b4fb12024-03-05 17:51:53 -0800612 std::make_shared<VSyncPredictor>(std::make_unique<ZeroClock>(), kMode, kHistorySize,
Ady Abraham20024aa2024-03-05 01:32:49 +0000613 kMinimumSamplesForPrediction,
ramindaniae645822024-01-11 10:57:29 -0800614 kOutlierTolerancePercent);
ramindani0491e642023-11-16 17:42:14 -0800615 std::shared_ptr<RefreshRateSelector> vrrSelectorPtr =
616 std::make_shared<RefreshRateSelector>(makeModes(kMode), kMode->getId());
617 TestableScheduler scheduler{std::make_unique<android::mock::VsyncController>(),
618 vrrTracker,
619 vrrSelectorPtr,
Leon Scroggins III823d4ca2023-12-12 16:57:34 -0500620 mFlinger.getFactory(),
621 mFlinger.getTimeStats(),
ramindaniae645822024-01-11 10:57:29 -0800622 mSchedulerCallback};
ramindani0491e642023-11-16 17:42:14 -0800623
Dominik Laskowski3ff44c72024-06-17 11:03:30 -0400624 scheduler.registerDisplay(kMode->getPhysicalDisplayId(), vrrSelectorPtr, std::nullopt,
625 vrrTracker);
ramindani0491e642023-11-16 17:42:14 -0800626 vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
Ady Abrahamee6365b2024-03-06 14:31:45 -0800627 scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate, /*applyImmediately*/ false);
ramindani0491e642023-11-16 17:42:14 -0800628 vrrTracker->addVsyncTimestamp(0);
Ady Abraham20024aa2024-03-05 01:32:49 +0000629 // Set 1000 as vsync seq #0
630 vrrTracker->nextAnticipatedVSyncTimeFrom(700);
ramindani0491e642023-11-16 17:42:14 -0800631
ramindani0491e642023-11-16 17:42:14 -0800632 EXPECT_EQ(Fps::fromPeriodNsecs(1000),
633 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abraham4335afd2023-12-18 19:10:47 -0800634 TimePoint::fromNs(1000)));
ramindani0491e642023-11-16 17:42:14 -0800635 EXPECT_EQ(Fps::fromPeriodNsecs(1000),
636 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abraham4335afd2023-12-18 19:10:47 -0800637 TimePoint::fromNs(2000)));
ramindani0491e642023-11-16 17:42:14 -0800638
Ady Abraham4335afd2023-12-18 19:10:47 -0800639 // Not crossing the min frame period
ramindani7b32b3a2024-07-02 10:17:47 -0700640 vrrTracker->onFrameBegin(TimePoint::fromNs(2000),
641 {TimePoint::fromNs(1500), TimePoint::fromNs(1500)});
Ady Abraham20024aa2024-03-05 01:32:49 +0000642 EXPECT_EQ(Fps::fromPeriodNsecs(1000),
Ady Abraham4335afd2023-12-18 19:10:47 -0800643 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
644 TimePoint::fromNs(2500)));
ramindani0491e642023-11-16 17:42:14 -0800645 // Change render rate
646 frameRate = Fps::fromPeriodNsecs(2000);
647 vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
Ady Abrahamee6365b2024-03-06 14:31:45 -0800648 scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate, /*applyImmediately*/ false);
ramindani0491e642023-11-16 17:42:14 -0800649
650 EXPECT_EQ(Fps::fromPeriodNsecs(2000),
651 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abrahamfe15a352024-03-19 10:49:17 -0700652 TimePoint::fromNs(5500)));
ramindani0491e642023-11-16 17:42:14 -0800653 EXPECT_EQ(Fps::fromPeriodNsecs(2000),
654 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abrahamfe15a352024-03-19 10:49:17 -0700655 TimePoint::fromNs(7500)));
ramindani0491e642023-11-16 17:42:14 -0800656}
657
Leon Scroggins III792ea802023-11-27 17:32:51 -0500658TEST_F(SchedulerTest, resyncAllToHardwareVsync) FTL_FAKE_GUARD(kMainThreadContext) {
659 // resyncAllToHardwareVsync will result in requesting hardware VSYNC on both displays, since
660 // they are both on.
661 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
662 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, true)).Times(1);
663
664 mScheduler->registerDisplay(kDisplayId2,
665 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
666 kDisplay2Mode60->getId()));
667 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
668 mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON);
669
670 static constexpr bool kDisallow = true;
671 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
672 mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
673
674 static constexpr bool kAllowToEnable = true;
675 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
676}
677
678TEST_F(SchedulerTest, resyncAllDoNotAllow) FTL_FAKE_GUARD(kMainThreadContext) {
679 // Without setting allowToEnable to true, resyncAllToHardwareVsync does not
680 // result in requesting hardware VSYNC.
681 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, _)).Times(0);
682
683 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
684
685 static constexpr bool kDisallow = true;
686 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
687
688 static constexpr bool kAllowToEnable = false;
689 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
690}
691
692TEST_F(SchedulerTest, resyncAllSkipsOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) {
693 SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
694
695 // resyncAllToHardwareVsync will result in requesting hardware VSYNC on display 1, which is on,
696 // but not on display 2, which is off.
697 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
698 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, _)).Times(0);
699
700 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
701
702 mScheduler->registerDisplay(kDisplayId2,
703 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
704 kDisplay2Mode60->getId()));
705 ASSERT_EQ(hal::PowerMode::OFF, mScheduler->getDisplayPowerMode(kDisplayId2));
706
707 static constexpr bool kDisallow = true;
708 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
709 mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
710
711 static constexpr bool kAllowToEnable = true;
712 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
713}
714
715TEST_F(SchedulerTest, resyncAllLegacyAppliesToOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) {
716 SET_FLAG_FOR_TEST(flags::multithreaded_present, false);
717
718 // In the legacy code, prior to the flag, resync applied to OFF displays.
719 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
720 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, true)).Times(1);
721
722 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
723
724 mScheduler->registerDisplay(kDisplayId2,
725 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
726 kDisplay2Mode60->getId()));
727 ASSERT_EQ(hal::PowerMode::OFF, mScheduler->getDisplayPowerMode(kDisplayId2));
728
729 static constexpr bool kDisallow = true;
730 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
731 mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
732
733 static constexpr bool kAllowToEnable = true;
734 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
735}
736
Ady Abraham822ecbd2023-07-07 16:16:09 -0700737class AttachedChoreographerTest : public SchedulerTest {
738protected:
739 void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
740 Fps expectedChoreographerFps);
741};
742
743TEST_F(AttachedChoreographerTest, registerSingle) {
744 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
745
746 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
747
748 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
749 const sp<IDisplayEventConnection> connection =
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500750 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
Ady Abraham822ecbd2023-07-07 16:16:09 -0700751
752 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
753 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
754 EXPECT_EQ(1u,
755 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
756 EXPECT_FALSE(
757 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
758}
759
760TEST_F(AttachedChoreographerTest, registerMultipleOnSameLayer) {
761 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
762
763 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
764 const auto handle = layer->getHandle();
765
766 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
767
768 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_))
769 .WillOnce(Return(0))
770 .WillOnce(Return(0));
771
772 const auto mockConnection1 = sp<MockEventThreadConnection>::make(mEventThread);
773 const auto mockConnection2 = sp<MockEventThreadConnection>::make(mEventThread);
774 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
775 .WillOnce(Return(mockConnection1))
776 .WillOnce(Return(mockConnection2));
777
778 const sp<IDisplayEventConnection> connection1 =
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500779 mScheduler->createDisplayEventConnection(Cycle::Render, {}, handle);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700780 const sp<IDisplayEventConnection> connection2 =
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500781 mScheduler->createDisplayEventConnection(Cycle::Render, {}, handle);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700782
783 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
784 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
785 EXPECT_EQ(2u,
786 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
787 EXPECT_FALSE(
788 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
789}
790
791TEST_F(AttachedChoreographerTest, registerMultipleOnDifferentLayers) {
792 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
793
794 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
795 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
796
797 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
798 const sp<IDisplayEventConnection> connection1 =
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500799 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer1->getHandle());
Ady Abraham822ecbd2023-07-07 16:16:09 -0700800 const sp<IDisplayEventConnection> connection2 =
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500801 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer2->getHandle());
Ady Abraham822ecbd2023-07-07 16:16:09 -0700802
803 EXPECT_EQ(2u, mScheduler->mutableAttachedChoreographers().size());
804
805 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer1->getSequence()));
806 EXPECT_EQ(1u,
807 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()]
808 .connections.size());
809 EXPECT_FALSE(
810 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()].frameRate.isValid());
811
812 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer2->getSequence()));
813 EXPECT_EQ(1u,
814 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()]
815 .connections.size());
816 EXPECT_FALSE(
817 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()].frameRate.isValid());
818}
819
820TEST_F(AttachedChoreographerTest, removedWhenConnectionIsGone) {
821 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
822
823 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
824
825 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
826
827 sp<IDisplayEventConnection> connection =
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500828 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
Ady Abraham822ecbd2023-07-07 16:16:09 -0700829
830 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
831 EXPECT_EQ(1u,
832 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
833
834 // The connection is used all over this test, so it is quite hard to release it from here.
835 // Instead, we just do a small shortcut.
836 {
837 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
838 sp<MockEventThreadConnection> mockConnection =
839 sp<MockEventThreadConnection>::make(mEventThread);
840 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.clear();
841 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.emplace(
842 mockConnection);
843 }
844
845 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
846 LayerHierarchy hierarchy(&layerState);
847 mScheduler->updateAttachedChoreographers(hierarchy, 60_Hz);
848 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
849}
850
851TEST_F(AttachedChoreographerTest, removedWhenLayerIsGone) {
852 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
853
854 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
855
856 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
857 const sp<IDisplayEventConnection> connection =
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500858 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
Ady Abraham822ecbd2023-07-07 16:16:09 -0700859
860 layer.clear();
861 mFlinger.mutableLayersPendingRemoval().clear();
862 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
863}
864
865void AttachedChoreographerTest::frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility,
866 Fps displayFps,
867 Fps expectedChoreographerFps) {
868 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
869
870 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
871 sp<IDisplayEventConnection> connection =
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500872 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
Ady Abraham822ecbd2023-07-07 16:16:09 -0700873
874 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
875 LayerHierarchy hierarchy(&layerState);
876
877 layerState.frameRate = layerFps.getValue();
878 layerState.frameRateCompatibility = frameRateCompatibility;
879
880 mScheduler->updateAttachedChoreographers(hierarchy, displayFps);
881
882 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
883 EXPECT_EQ(expectedChoreographerFps,
884 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
885 EXPECT_EQ(expectedChoreographerFps, mEventThreadConnection->frameRate);
886}
887
888TEST_F(AttachedChoreographerTest, setsFrameRateDefault) {
889 Fps layerFps = 30_Hz;
890 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
891 Fps displayFps = 60_Hz;
892 Fps expectedChoreographerFps = 30_Hz;
893
894 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
895
896 layerFps = Fps::fromValue(32.7f);
897 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
898}
899
900TEST_F(AttachedChoreographerTest, setsFrameRateExact) {
901 Fps layerFps = 30_Hz;
902 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_EXACT;
903 Fps displayFps = 60_Hz;
904 Fps expectedChoreographerFps = 30_Hz;
905
906 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
907
908 layerFps = Fps::fromValue(32.7f);
909 expectedChoreographerFps = {};
910 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
911}
912
913TEST_F(AttachedChoreographerTest, setsFrameRateExactOrMultiple) {
914 Fps layerFps = 30_Hz;
915 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
916 Fps displayFps = 60_Hz;
917 Fps expectedChoreographerFps = 30_Hz;
918
919 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
920
921 layerFps = Fps::fromValue(32.7f);
922 expectedChoreographerFps = {};
923 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
924}
925
926TEST_F(AttachedChoreographerTest, setsFrameRateParent) {
927 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
928 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
929
930 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
931 sp<IDisplayEventConnection> connection =
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500932 mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
Ady Abraham822ecbd2023-07-07 16:16:09 -0700933
934 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
935 LayerHierarchy parentHierarchy(&parentState);
936
937 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
938 LayerHierarchy hierarchy(&layerState);
939 parentHierarchy.mChildren.push_back(
940 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
941
942 layerState.frameRate = (30_Hz).getValue();
943 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
944
945 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
946
947 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
948
949 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
950}
951
952TEST_F(AttachedChoreographerTest, setsFrameRateParent2Children) {
953 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
954 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
955 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
956
957 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
958 sp<IDisplayEventConnection> connection =
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500959 mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
Ady Abraham822ecbd2023-07-07 16:16:09 -0700960
961 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
962 LayerHierarchy parentHierarchy(&parentState);
963
964 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
965 LayerHierarchy layer1Hierarchy(&layer1State);
966 parentHierarchy.mChildren.push_back(
967 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
968
969 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
970 LayerHierarchy layer2Hierarchy(&layer2State);
971 parentHierarchy.mChildren.push_back(
972 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
973
974 layer1State.frameRate = (30_Hz).getValue();
975 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
976
977 layer2State.frameRate = (20_Hz).getValue();
978 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
979
980 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
981
982 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
983
984 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
985}
986
987TEST_F(AttachedChoreographerTest, setsFrameRateParentConflictingChildren) {
988 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
989 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
990 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
991
992 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
993 sp<IDisplayEventConnection> connection =
Dominik Laskowski4babfc42024-02-16 12:28:40 -0500994 mScheduler->createDisplayEventConnection(Cycle::Render, {}, parent->getHandle());
Ady Abraham822ecbd2023-07-07 16:16:09 -0700995
996 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
997 LayerHierarchy parentHierarchy(&parentState);
998
999 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
1000 LayerHierarchy layer1Hierarchy(&layer1State);
1001 parentHierarchy.mChildren.push_back(
1002 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
1003
1004 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
1005 LayerHierarchy layer2Hierarchy(&layer2State);
1006 parentHierarchy.mChildren.push_back(
1007 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
1008
1009 layer1State.frameRate = (30_Hz).getValue();
1010 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1011
1012 layer2State.frameRate = (25_Hz).getValue();
1013 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1014
1015 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1016
1017 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
1018
1019 EXPECT_EQ(Fps(), mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
1020}
1021
1022TEST_F(AttachedChoreographerTest, setsFrameRateChild) {
1023 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
1024 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
1025
1026 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
1027 sp<IDisplayEventConnection> connection =
Dominik Laskowski4babfc42024-02-16 12:28:40 -05001028 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
Ady Abraham822ecbd2023-07-07 16:16:09 -07001029
1030 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
1031 LayerHierarchy parentHierarchy(&parentState);
1032
1033 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
1034 LayerHierarchy hierarchy(&layerState);
1035 parentHierarchy.mChildren.push_back(
1036 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
1037
1038 parentState.frameRate = (30_Hz).getValue();
1039 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1040
1041 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1042
1043 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
1044
1045 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
1046}
1047
1048TEST_F(AttachedChoreographerTest, setsFrameRateChildNotOverriddenByParent) {
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 =
Dominik Laskowski4babfc42024-02-16 12:28:40 -05001054 mScheduler->createDisplayEventConnection(Cycle::Render, {}, layer->getHandle());
Ady Abraham822ecbd2023-07-07 16:16:09 -07001055
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 layerState.frameRate = (60_Hz).getValue();
1068 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1069
1070 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1071
1072 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
1073
1074 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
1075}
1076
Dominik Laskowski068173d2021-08-11 17:22:59 -07001077} // namespace android::scheduler