blob: 3200003edad2af5e4c5f11e31245abe24d1b5eaa [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
Leon Scroggins III67388622023-02-06 20:36:20 -050017#include <ftl/fake_guard.h>
Ana Krulec0c8cd522018-08-31 12:27:28 -070018#include <gmock/gmock.h>
19#include <gtest/gtest.h>
Ana Krulec0c8cd522018-08-31 12:27:28 -070020#include <log/log.h>
21
Ana Krulece588e312018-09-18 12:32:24 -070022#include <mutex>
23
Ana Krulec0c8cd522018-08-31 12:27:28 -070024#include "Scheduler/EventThread.h"
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040025#include "Scheduler/RefreshRateSelector.h"
Dominik Laskowski98041832019-08-01 18:35:59 -070026#include "TestableScheduler.h"
Dominik Laskowski983f2b52020-06-25 16:54:06 -070027#include "TestableSurfaceFlinger.h"
Dominik Laskowskib0054a22022-03-03 09:03:06 -080028#include "mock/DisplayHardware/MockDisplayMode.h"
Ana Krulec0c8cd522018-08-31 12:27:28 -070029#include "mock/MockEventThread.h"
Dominik Laskowski983f2b52020-06-25 16:54:06 -070030#include "mock/MockLayer.h"
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070031#include "mock/MockSchedulerCallback.h"
Ana Krulec0c8cd522018-08-31 12:27:28 -070032
Ady Abraham822ecbd2023-07-07 16:16:09 -070033#include <FrontEnd/LayerHierarchy.h>
34
35#include "FpsOps.h"
36
Dominik Laskowski068173d2021-08-11 17:22:59 -070037namespace android::scheduler {
38
Dominik Laskowskib0054a22022-03-03 09:03:06 -080039using android::mock::createDisplayMode;
40
Ana Krulec0c8cd522018-08-31 12:27:28 -070041using testing::_;
42using testing::Return;
43
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070044namespace {
Ana Krulec0c8cd522018-08-31 12:27:28 -070045
Dominik Laskowski068173d2021-08-11 17:22:59 -070046using MockEventThread = android::mock::EventThread;
47using MockLayer = android::mock::MockLayer;
48
Ady Abraham822ecbd2023-07-07 16:16:09 -070049using LayerHierarchy = surfaceflinger::frontend::LayerHierarchy;
50using LayerHierarchyBuilder = surfaceflinger::frontend::LayerHierarchyBuilder;
51using RequestedLayerState = surfaceflinger::frontend::RequestedLayerState;
52
Ana Krulec0c8cd522018-08-31 12:27:28 -070053class SchedulerTest : public testing::Test {
54protected:
Ana Krulec85c39af2018-12-26 17:29:57 -080055 class MockEventThreadConnection : public android::EventThreadConnection {
Ana Krulec0c8cd522018-08-31 12:27:28 -070056 public:
Ana Krulec85c39af2018-12-26 17:29:57 -080057 explicit MockEventThreadConnection(EventThread* eventThread)
Ady Abrahamd11bade2022-08-01 16:18:03 -070058 : EventThreadConnection(eventThread, /*callingUid*/ static_cast<uid_t>(0),
59 ResyncCallback()) {}
Ana Krulec0c8cd522018-08-31 12:27:28 -070060 ~MockEventThreadConnection() = default;
61
Huihong Luo6fac5232021-11-22 16:05:23 -080062 MOCK_METHOD1(stealReceiveChannel, binder::Status(gui::BitTube* outChannel));
63 MOCK_METHOD1(setVsyncRate, binder::Status(int count));
64 MOCK_METHOD0(requestNextVsync, binder::Status());
Ana Krulec0c8cd522018-08-31 12:27:28 -070065 };
66
Ana Krulec0c8cd522018-08-31 12:27:28 -070067 SchedulerTest();
Ana Krulec0c8cd522018-08-31 12:27:28 -070068
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040069 static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(255u);
Ady Abrahamace3d052022-11-17 16:25:05 -080070 static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode60 =
71 ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(0), 60_Hz));
72 static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode120 =
73 ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(1), 120_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040074 static inline const DisplayModes kDisplay1Modes = makeModes(kDisplay1Mode60, kDisplay1Mode120);
75
76 static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(254u);
Ady Abrahamace3d052022-11-17 16:25:05 -080077 static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode60 =
78 ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(0), 60_Hz));
79 static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode120 =
80 ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(1), 120_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040081 static inline const DisplayModes kDisplay2Modes = makeModes(kDisplay2Mode60, kDisplay2Mode120);
82
83 static constexpr PhysicalDisplayId kDisplayId3 = PhysicalDisplayId::fromPort(253u);
Ady Abrahamace3d052022-11-17 16:25:05 -080084 static inline const ftl::NonNull<DisplayModePtr> kDisplay3Mode60 =
85 ftl::as_non_null(createDisplayMode(kDisplayId3, DisplayModeId(0), 60_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040086 static inline const DisplayModes kDisplay3Modes = makeModes(kDisplay3Mode60);
Marin Shalamanov2cde1002021-06-08 19:50:10 +020087
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040088 std::shared_ptr<RefreshRateSelector> mSelector =
89 std::make_shared<RefreshRateSelector>(makeModes(kDisplay1Mode60),
90 kDisplay1Mode60->getId());
Dominik Laskowski983f2b52020-06-25 16:54:06 -070091
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070092 mock::SchedulerCallback mSchedulerCallback;
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040093 TestableScheduler* mScheduler = new TestableScheduler{mSelector, mSchedulerCallback};
Ady Abraham822ecbd2023-07-07 16:16:09 -070094 surfaceflinger::frontend::LayerHierarchyBuilder mLayerHierarchyBuilder{{}};
Dominik Laskowski98041832019-08-01 18:35:59 -070095
Dominik Laskowski068173d2021-08-11 17:22:59 -070096 ConnectionHandle mConnectionHandle;
97 MockEventThread* mEventThread;
Ana Krulec0c8cd522018-08-31 12:27:28 -070098 sp<MockEventThreadConnection> mEventThreadConnection;
Ady Abraham564f9de2021-02-03 18:34:33 -080099
100 TestableSurfaceFlinger mFlinger;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700101};
102
103SchedulerTest::SchedulerTest() {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700104 auto eventThread = std::make_unique<MockEventThread>();
Ana Krulec0c8cd522018-08-31 12:27:28 -0700105 mEventThread = eventThread.get();
Ana Krulec85c39af2018-12-26 17:29:57 -0800106 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
107
Ady Abrahamd11bade2022-08-01 16:18:03 -0700108 mEventThreadConnection = sp<MockEventThreadConnection>::make(mEventThread);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700109
110 // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
111 // sure that call gets executed and returns an EventThread::Connection object.
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700112 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
Ana Krulec0c8cd522018-08-31 12:27:28 -0700113 .WillRepeatedly(Return(mEventThreadConnection));
114
Ady Abrahama0a16272021-03-03 15:23:35 -0800115 mConnectionHandle = mScheduler->createConnection(std::move(eventThread));
Dominik Laskowski98041832019-08-01 18:35:59 -0700116 EXPECT_TRUE(mConnectionHandle);
Ady Abrahama0a16272021-03-03 15:23:35 -0800117
118 mFlinger.resetScheduler(mScheduler);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700119}
120
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700121} // namespace
Ana Krulec0c8cd522018-08-31 12:27:28 -0700122
Ana Krulec0c8cd522018-08-31 12:27:28 -0700123TEST_F(SchedulerTest, invalidConnectionHandle) {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700124 ConnectionHandle handle;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700125
Ady Abrahama0a16272021-03-03 15:23:35 -0800126 const sp<IDisplayEventConnection> connection = mScheduler->createDisplayEventConnection(handle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700127
Dominik Laskowski98041832019-08-01 18:35:59 -0700128 EXPECT_FALSE(connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800129 EXPECT_FALSE(mScheduler->getEventConnection(handle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700130
131 // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads.
132 EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400133 mScheduler->onHotplugReceived(handle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700134
Dominik Laskowski98041832019-08-01 18:35:59 -0700135 std::string output;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700136 EXPECT_CALL(*mEventThread, dump(_)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800137 mScheduler->dump(handle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700138 EXPECT_TRUE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700139
Ady Abraham9c53ee72020-07-22 21:16:18 -0700140 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800141 mScheduler->setDuration(handle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700142}
143
144TEST_F(SchedulerTest, validConnectionHandle) {
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700145 const sp<IDisplayEventConnection> connection =
Ady Abrahama0a16272021-03-03 15:23:35 -0800146 mScheduler->createDisplayEventConnection(mConnectionHandle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700147
Dominik Laskowski98041832019-08-01 18:35:59 -0700148 ASSERT_EQ(mEventThreadConnection, connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800149 EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700150
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400151 EXPECT_CALL(*mEventThread, onHotplugReceived(kDisplayId1, false)).Times(1);
152 mScheduler->onHotplugReceived(mConnectionHandle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700153
Dominik Laskowski98041832019-08-01 18:35:59 -0700154 std::string output("dump");
155 EXPECT_CALL(*mEventThread, dump(output)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800156 mScheduler->dump(mConnectionHandle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700157 EXPECT_FALSE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700158
Ady Abraham9c53ee72020-07-22 21:16:18 -0700159 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800160 mScheduler->setDuration(mConnectionHandle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700161}
Dominik Laskowski98041832019-08-01 18:35:59 -0700162
Dominik Laskowski66295432023-03-14 12:25:36 -0400163TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) {
Dominik Laskowski008bec02023-03-14 12:04:58 -0400164 // Hardware VSYNC should not change if the display is already registered.
Dominik Laskowski66295432023-03-14 12:25:36 -0400165 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId1, false)).Times(0);
Dominik Laskowski008bec02023-03-14 12:04:58 -0400166 mScheduler->registerDisplay(kDisplayId1,
167 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
168 kDisplay1Mode60->getId()));
169
Dominik Laskowski66295432023-03-14 12:25:36 -0400170 // TODO(b/241285191): Restore once VsyncSchedule::getPendingHardwareVsyncState is called by
171 // Scheduler::setDisplayPowerMode rather than SF::setPowerModeInternal.
172#if 0
Dominik Laskowski008bec02023-03-14 12:04:58 -0400173 // Hardware VSYNC should be disabled for newly registered displays.
Dominik Laskowski66295432023-03-14 12:25:36 -0400174 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId2, false)).Times(1);
175 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId3, false)).Times(1);
176#endif
Dominik Laskowski008bec02023-03-14 12:04:58 -0400177
178 mScheduler->registerDisplay(kDisplayId2,
179 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
180 kDisplay2Mode60->getId()));
181 mScheduler->registerDisplay(kDisplayId3,
182 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
183 kDisplay3Mode60->getId()));
Dominik Laskowski66295432023-03-14 12:25:36 -0400184
185 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId1)->getPendingHardwareVsyncState());
186 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId2)->getPendingHardwareVsyncState());
187 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId3)->getPendingHardwareVsyncState());
Dominik Laskowski008bec02023-03-14 12:04:58 -0400188}
189
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200190TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) {
191 // The layer is registered at creation time and deregistered at destruction time.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700192 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700193
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200194 // recordLayerHistory should be a noop
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700195 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000196 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
197 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700198 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700199
Rachel Lee6a9731d2022-06-06 17:08:14 -0700200 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500201 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700202
203 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700204 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700205
ramindani69b58e82022-09-26 16:48:36 -0700206 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700207 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
208 /*updateAttachedChoreographer*/ false);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700209}
210
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200211TEST_F(SchedulerTest, updateDisplayModes) {
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700212 ASSERT_EQ(0u, mScheduler->layerHistorySize());
Dominik Laskowski068173d2021-08-11 17:22:59 -0700213 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700214 ASSERT_EQ(1u, mScheduler->layerHistorySize());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200215
Dominik Laskowski596a2562022-10-28 11:26:12 -0400216 // Replace `mSelector` with a new `RefreshRateSelector` that has different display modes.
217 mScheduler->registerDisplay(kDisplayId1,
218 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
219 kDisplay1Mode60->getId()));
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200220
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700221 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000222 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
223 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700224 ASSERT_EQ(1u, mScheduler->getNumActiveLayers());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200225}
226
Dominik Laskowski068173d2021-08-11 17:22:59 -0700227TEST_F(SchedulerTest, dispatchCachedReportedMode) {
228 mScheduler->clearCachedReportedMode();
229
Ady Abraham690f4612021-07-01 23:24:03 -0700230 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Dominik Laskowski068173d2021-08-11 17:22:59 -0700231 EXPECT_NO_FATAL_FAILURE(mScheduler->dispatchCachedReportedMode());
Ana Krulec6ddd2612020-09-24 13:06:33 -0700232}
233
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100234TEST_F(SchedulerTest, onNonPrimaryDisplayModeChanged_invalidParameters) {
Ady Abraham690f4612021-07-01 23:24:03 -0700235 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
236 .setId(DisplayModeId(111))
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400237 .setPhysicalDisplayId(kDisplayId1)
Ady Abraham690f4612021-07-01 23:24:03 -0700238 .setVsyncPeriod(111111)
239 .build();
Ana Krulec6ddd2612020-09-24 13:06:33 -0700240
241 // If the handle is incorrect, the function should return before
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100242 // onModeChange is called.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700243 ConnectionHandle invalidHandle = {.id = 123};
Ady Abrahamace3d052022-11-17 16:25:05 -0800244 EXPECT_NO_FATAL_FAILURE(
245 mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle,
246 {90_Hz, ftl::as_non_null(mode)}));
Ady Abraham690f4612021-07-01 23:24:03 -0700247 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Ana Krulec6ddd2612020-09-24 13:06:33 -0700248}
249
Ady Abraham899dcdb2021-06-15 16:56:21 -0700250TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700251 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms));
252 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms));
253 EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(120_Hz, 30ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800254
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700255 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 40ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800256
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700257 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Piquea1456c12023-05-17 12:11:15 -0700258
Lloyd Pique30db6402023-06-26 18:56:51 +0000259 const auto savedMinAcquiredBuffers = mFlinger.mutableMinAcquiredBuffers();
260 mFlinger.mutableMinAcquiredBuffers() = 2;
Lloyd Piquea1456c12023-05-17 12:11:15 -0700261 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Pique30db6402023-06-26 18:56:51 +0000262 mFlinger.mutableMinAcquiredBuffers() = savedMinAcquiredBuffers;
Ady Abraham564f9de2021-02-03 18:34:33 -0800263}
264
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200265MATCHER(Is120Hz, "") {
Ady Abrahamace3d052022-11-17 16:25:05 -0800266 return isApproxEqual(arg.front().mode.fps, 120_Hz);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200267}
268
269TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
Dominik Laskowski596a2562022-10-28 11:26:12 -0400270 mScheduler->registerDisplay(kDisplayId1,
271 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
272 kDisplay1Mode60->getId()));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200273
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800274 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
275 EXPECT_CALL(*layer, isVisible()).WillOnce(Return(true));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200276
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000277 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
278 LayerHistory::LayerUpdateType::Buffer);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200279
Rachel Lee6a9731d2022-06-06 17:08:14 -0700280 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500281 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200282
283 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700284 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200285
ramindani69b58e82022-09-26 16:48:36 -0700286 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(Is120Hz())).Times(1);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700287 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
288 /*updateAttachedChoreographer*/ false);
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800289
290 // No-op if layer requirements have not changed.
ramindani69b58e82022-09-26 16:48:36 -0700291 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700292 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
293 /*updateAttachedChoreographer*/ false);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200294}
295
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400296TEST_F(SchedulerTest, chooseDisplayModesSingleDisplay) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400297 mScheduler->registerDisplay(kDisplayId1,
298 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
299 kDisplay1Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700300
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400301 std::vector<RefreshRateSelector::LayerRequirement> layers =
302 std::vector<RefreshRateSelector::LayerRequirement>({{.weight = 1.f}, {.weight = 1.f}});
ramindani69b58e82022-09-26 16:48:36 -0700303 mScheduler->setContentRequirements(layers);
304 GlobalSignals globalSignals = {.idle = true};
305 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
306
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400307 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
308
309 auto modeChoices = mScheduler->chooseDisplayModes();
310 ASSERT_EQ(1u, modeChoices.size());
311
312 auto choice = modeChoices.get(kDisplayId1);
313 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800314 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700315
316 globalSignals = {.idle = false};
317 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400318
319 modeChoices = mScheduler->chooseDisplayModes();
320 ASSERT_EQ(1u, modeChoices.size());
321
322 choice = modeChoices.get(kDisplayId1);
323 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800324 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700325
326 globalSignals = {.touch = true};
327 mScheduler->replaceTouchTimer(10);
328 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700329
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400330 modeChoices = mScheduler->chooseDisplayModes();
331 ASSERT_EQ(1u, modeChoices.size());
332
333 choice = modeChoices.get(kDisplayId1);
334 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800335 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700336}
337
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400338TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400339 mScheduler->registerDisplay(kDisplayId1,
340 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
341 kDisplay1Mode60->getId()));
342 mScheduler->registerDisplay(kDisplayId2,
343 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
344 kDisplay2Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700345
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400346 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
347 TestableScheduler::DisplayModeChoiceMap expectedChoices;
ramindani69b58e82022-09-26 16:48:36 -0700348
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400349 {
350 const GlobalSignals globalSignals = {.idle = true};
351 expectedChoices =
352 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800353 DisplayModeChoice>(kDisplayId1,
354 FrameRateMode{60_Hz, kDisplay1Mode60},
355 globalSignals)(kDisplayId2,
356 FrameRateMode{60_Hz,
357 kDisplay2Mode60},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400358 globalSignals);
359
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400360 std::vector<RefreshRateSelector::LayerRequirement> layers = {{.weight = 1.f},
361 {.weight = 1.f}};
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400362 mScheduler->setContentRequirements(layers);
363 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
364
365 const auto actualChoices = mScheduler->chooseDisplayModes();
366 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700367 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400368 {
369 const GlobalSignals globalSignals = {.idle = false};
370 expectedChoices =
371 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800372 DisplayModeChoice>(kDisplayId1,
373 FrameRateMode{120_Hz, kDisplay1Mode120},
374 globalSignals)(kDisplayId2,
375 FrameRateMode{120_Hz,
376 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400377 globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700378
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400379 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700380
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400381 const auto actualChoices = mScheduler->chooseDisplayModes();
382 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700383 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400384 {
385 const GlobalSignals globalSignals = {.touch = true};
386 mScheduler->replaceTouchTimer(10);
387 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700388
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400389 expectedChoices =
390 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800391 DisplayModeChoice>(kDisplayId1,
392 FrameRateMode{120_Hz, kDisplay1Mode120},
393 globalSignals)(kDisplayId2,
394 FrameRateMode{120_Hz,
395 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400396 globalSignals);
397
398 const auto actualChoices = mScheduler->chooseDisplayModes();
399 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700400 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400401 {
ramindani22f2ead2023-04-21 10:27:11 -0700402 // The kDisplayId3 does not support 120Hz, The pacesetter display rate is chosen to be 120
403 // Hz. In this case only the display kDisplayId3 choose 60Hz as it does not support 120Hz.
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400404 mScheduler
405 ->registerDisplay(kDisplayId3,
406 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
407 kDisplay3Mode60->getId()));
Dominik Laskowski327d6092022-10-11 18:05:08 -0400408
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400409 const GlobalSignals globalSignals = {.touch = true};
410 mScheduler->replaceTouchTimer(10);
411 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani7c487282022-10-10 16:17:51 -0700412
Ady Abrahamace3d052022-11-17 16:25:05 -0800413 expectedChoices = ftl::init::map<
414 const PhysicalDisplayId&,
ramindani22f2ead2023-04-21 10:27:11 -0700415 DisplayModeChoice>(kDisplayId1, FrameRateMode{120_Hz, kDisplay1Mode120},
416 globalSignals)(kDisplayId2,
417 FrameRateMode{120_Hz, kDisplay2Mode120},
418 globalSignals)(kDisplayId3,
419 FrameRateMode{60_Hz,
420 kDisplay3Mode60},
421 globalSignals);
422
423 const auto actualChoices = mScheduler->chooseDisplayModes();
424 EXPECT_EQ(expectedChoices, actualChoices);
425 }
426 {
427 // We should choose 60Hz despite the touch signal as pacesetter only supports 60Hz
428 mScheduler->setPacesetterDisplay(kDisplayId3);
429 const GlobalSignals globalSignals = {.touch = true};
430 mScheduler->replaceTouchTimer(10);
431 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
432
433 expectedChoices = ftl::init::map<
434 const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800435 DisplayModeChoice>(kDisplayId1, FrameRateMode{60_Hz, kDisplay1Mode60},
436 globalSignals)(kDisplayId2,
437 FrameRateMode{60_Hz, kDisplay2Mode60},
438 globalSignals)(kDisplayId3,
439 FrameRateMode{60_Hz,
440 kDisplay3Mode60},
441 globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400442
443 const auto actualChoices = mScheduler->chooseDisplayModes();
444 EXPECT_EQ(expectedChoices, actualChoices);
ramindani7c487282022-10-10 16:17:51 -0700445 }
ramindani69b58e82022-09-26 16:48:36 -0700446}
447
Ady Abraham822ecbd2023-07-07 16:16:09 -0700448class AttachedChoreographerTest : public SchedulerTest {
449protected:
450 void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
451 Fps expectedChoreographerFps);
452};
453
454TEST_F(AttachedChoreographerTest, registerSingle) {
455 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
456
457 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
458
459 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
460 const sp<IDisplayEventConnection> connection =
461 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
462
463 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
464 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
465 EXPECT_EQ(1u,
466 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
467 EXPECT_FALSE(
468 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
469}
470
471TEST_F(AttachedChoreographerTest, registerMultipleOnSameLayer) {
472 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
473
474 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
475 const auto handle = layer->getHandle();
476
477 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
478
479 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_))
480 .WillOnce(Return(0))
481 .WillOnce(Return(0));
482
483 const auto mockConnection1 = sp<MockEventThreadConnection>::make(mEventThread);
484 const auto mockConnection2 = sp<MockEventThreadConnection>::make(mEventThread);
485 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
486 .WillOnce(Return(mockConnection1))
487 .WillOnce(Return(mockConnection2));
488
489 const sp<IDisplayEventConnection> connection1 =
490 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
491 const sp<IDisplayEventConnection> connection2 =
492 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
493
494 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
495 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
496 EXPECT_EQ(2u,
497 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
498 EXPECT_FALSE(
499 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
500}
501
502TEST_F(AttachedChoreographerTest, registerMultipleOnDifferentLayers) {
503 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
504
505 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
506 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
507
508 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
509 const sp<IDisplayEventConnection> connection1 =
510 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer1->getHandle());
511 const sp<IDisplayEventConnection> connection2 =
512 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer2->getHandle());
513
514 EXPECT_EQ(2u, mScheduler->mutableAttachedChoreographers().size());
515
516 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer1->getSequence()));
517 EXPECT_EQ(1u,
518 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()]
519 .connections.size());
520 EXPECT_FALSE(
521 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()].frameRate.isValid());
522
523 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer2->getSequence()));
524 EXPECT_EQ(1u,
525 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()]
526 .connections.size());
527 EXPECT_FALSE(
528 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()].frameRate.isValid());
529}
530
531TEST_F(AttachedChoreographerTest, removedWhenConnectionIsGone) {
532 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
533
534 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
535
536 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
537
538 sp<IDisplayEventConnection> connection =
539 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
540
541 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
542 EXPECT_EQ(1u,
543 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
544
545 // The connection is used all over this test, so it is quite hard to release it from here.
546 // Instead, we just do a small shortcut.
547 {
548 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
549 sp<MockEventThreadConnection> mockConnection =
550 sp<MockEventThreadConnection>::make(mEventThread);
551 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.clear();
552 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.emplace(
553 mockConnection);
554 }
555
556 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
557 LayerHierarchy hierarchy(&layerState);
558 mScheduler->updateAttachedChoreographers(hierarchy, 60_Hz);
559 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
560}
561
562TEST_F(AttachedChoreographerTest, removedWhenLayerIsGone) {
563 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
564
565 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
566
567 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
568 const sp<IDisplayEventConnection> connection =
569 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
570
571 layer.clear();
572 mFlinger.mutableLayersPendingRemoval().clear();
573 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
574}
575
576void AttachedChoreographerTest::frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility,
577 Fps displayFps,
578 Fps expectedChoreographerFps) {
579 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
580
581 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
582 sp<IDisplayEventConnection> connection =
583 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
584
585 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
586 LayerHierarchy hierarchy(&layerState);
587
588 layerState.frameRate = layerFps.getValue();
589 layerState.frameRateCompatibility = frameRateCompatibility;
590
591 mScheduler->updateAttachedChoreographers(hierarchy, displayFps);
592
593 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
594 EXPECT_EQ(expectedChoreographerFps,
595 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
596 EXPECT_EQ(expectedChoreographerFps, mEventThreadConnection->frameRate);
597}
598
599TEST_F(AttachedChoreographerTest, setsFrameRateDefault) {
600 Fps layerFps = 30_Hz;
601 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
602 Fps displayFps = 60_Hz;
603 Fps expectedChoreographerFps = 30_Hz;
604
605 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
606
607 layerFps = Fps::fromValue(32.7f);
608 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
609}
610
611TEST_F(AttachedChoreographerTest, setsFrameRateExact) {
612 Fps layerFps = 30_Hz;
613 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_EXACT;
614 Fps displayFps = 60_Hz;
615 Fps expectedChoreographerFps = 30_Hz;
616
617 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
618
619 layerFps = Fps::fromValue(32.7f);
620 expectedChoreographerFps = {};
621 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
622}
623
624TEST_F(AttachedChoreographerTest, setsFrameRateExactOrMultiple) {
625 Fps layerFps = 30_Hz;
626 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
627 Fps displayFps = 60_Hz;
628 Fps expectedChoreographerFps = 30_Hz;
629
630 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
631
632 layerFps = Fps::fromValue(32.7f);
633 expectedChoreographerFps = {};
634 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
635}
636
637TEST_F(AttachedChoreographerTest, setsFrameRateParent) {
638 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
639 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
640
641 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
642 sp<IDisplayEventConnection> connection =
643 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
644
645 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
646 LayerHierarchy parentHierarchy(&parentState);
647
648 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
649 LayerHierarchy hierarchy(&layerState);
650 parentHierarchy.mChildren.push_back(
651 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
652
653 layerState.frameRate = (30_Hz).getValue();
654 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
655
656 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
657
658 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
659
660 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
661}
662
663TEST_F(AttachedChoreographerTest, setsFrameRateParent2Children) {
664 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
665 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
666 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
667
668 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
669 sp<IDisplayEventConnection> connection =
670 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
671
672 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
673 LayerHierarchy parentHierarchy(&parentState);
674
675 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
676 LayerHierarchy layer1Hierarchy(&layer1State);
677 parentHierarchy.mChildren.push_back(
678 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
679
680 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
681 LayerHierarchy layer2Hierarchy(&layer2State);
682 parentHierarchy.mChildren.push_back(
683 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
684
685 layer1State.frameRate = (30_Hz).getValue();
686 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
687
688 layer2State.frameRate = (20_Hz).getValue();
689 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
690
691 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
692
693 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
694
695 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
696}
697
698TEST_F(AttachedChoreographerTest, setsFrameRateParentConflictingChildren) {
699 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
700 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
701 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
702
703 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
704 sp<IDisplayEventConnection> connection =
705 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
706
707 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
708 LayerHierarchy parentHierarchy(&parentState);
709
710 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
711 LayerHierarchy layer1Hierarchy(&layer1State);
712 parentHierarchy.mChildren.push_back(
713 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
714
715 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
716 LayerHierarchy layer2Hierarchy(&layer2State);
717 parentHierarchy.mChildren.push_back(
718 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
719
720 layer1State.frameRate = (30_Hz).getValue();
721 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
722
723 layer2State.frameRate = (25_Hz).getValue();
724 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
725
726 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
727
728 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
729
730 EXPECT_EQ(Fps(), mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
731}
732
733TEST_F(AttachedChoreographerTest, setsFrameRateChild) {
734 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
735 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
736
737 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
738 sp<IDisplayEventConnection> connection =
739 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
740
741 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
742 LayerHierarchy parentHierarchy(&parentState);
743
744 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
745 LayerHierarchy hierarchy(&layerState);
746 parentHierarchy.mChildren.push_back(
747 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
748
749 parentState.frameRate = (30_Hz).getValue();
750 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
751
752 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
753
754 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
755
756 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
757}
758
759TEST_F(AttachedChoreographerTest, setsFrameRateChildNotOverriddenByParent) {
760 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
761 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
762
763 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
764 sp<IDisplayEventConnection> connection =
765 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
766
767 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
768 LayerHierarchy parentHierarchy(&parentState);
769
770 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
771 LayerHierarchy hierarchy(&layerState);
772 parentHierarchy.mChildren.push_back(
773 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
774
775 parentState.frameRate = (30_Hz).getValue();
776 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
777
778 layerState.frameRate = (60_Hz).getValue();
779 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
780
781 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
782
783 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
784
785 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
786}
787
Dominik Laskowski068173d2021-08-11 17:22:59 -0700788} // namespace android::scheduler