blob: fab3c0e8872a54cb8f3e636028ff10c3aab02498 [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
Dominik Laskowski068173d2021-08-11 17:22:59 -070033namespace android::scheduler {
34
Dominik Laskowskib0054a22022-03-03 09:03:06 -080035using android::mock::createDisplayMode;
36
Ana Krulec0c8cd522018-08-31 12:27:28 -070037using testing::_;
38using testing::Return;
39
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070040namespace {
Ana Krulec0c8cd522018-08-31 12:27:28 -070041
Dominik Laskowski068173d2021-08-11 17:22:59 -070042using MockEventThread = android::mock::EventThread;
43using MockLayer = android::mock::MockLayer;
44
Ana Krulec0c8cd522018-08-31 12:27:28 -070045class SchedulerTest : public testing::Test {
46protected:
Ana Krulec85c39af2018-12-26 17:29:57 -080047 class MockEventThreadConnection : public android::EventThreadConnection {
Ana Krulec0c8cd522018-08-31 12:27:28 -070048 public:
Ana Krulec85c39af2018-12-26 17:29:57 -080049 explicit MockEventThreadConnection(EventThread* eventThread)
Ady Abrahamd11bade2022-08-01 16:18:03 -070050 : EventThreadConnection(eventThread, /*callingUid*/ static_cast<uid_t>(0),
51 ResyncCallback()) {}
Ana Krulec0c8cd522018-08-31 12:27:28 -070052 ~MockEventThreadConnection() = default;
53
Huihong Luo6fac5232021-11-22 16:05:23 -080054 MOCK_METHOD1(stealReceiveChannel, binder::Status(gui::BitTube* outChannel));
55 MOCK_METHOD1(setVsyncRate, binder::Status(int count));
56 MOCK_METHOD0(requestNextVsync, binder::Status());
Ana Krulec0c8cd522018-08-31 12:27:28 -070057 };
58
Ana Krulec0c8cd522018-08-31 12:27:28 -070059 SchedulerTest();
Ana Krulec0c8cd522018-08-31 12:27:28 -070060
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040061 static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(255u);
Ady Abrahamace3d052022-11-17 16:25:05 -080062 static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode60 =
63 ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(0), 60_Hz));
64 static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode120 =
65 ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(1), 120_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040066 static inline const DisplayModes kDisplay1Modes = makeModes(kDisplay1Mode60, kDisplay1Mode120);
67
68 static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(254u);
Ady Abrahamace3d052022-11-17 16:25:05 -080069 static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode60 =
70 ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(0), 60_Hz));
71 static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode120 =
72 ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(1), 120_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040073 static inline const DisplayModes kDisplay2Modes = makeModes(kDisplay2Mode60, kDisplay2Mode120);
74
75 static constexpr PhysicalDisplayId kDisplayId3 = PhysicalDisplayId::fromPort(253u);
Ady Abrahamace3d052022-11-17 16:25:05 -080076 static inline const ftl::NonNull<DisplayModePtr> kDisplay3Mode60 =
77 ftl::as_non_null(createDisplayMode(kDisplayId3, DisplayModeId(0), 60_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040078 static inline const DisplayModes kDisplay3Modes = makeModes(kDisplay3Mode60);
Marin Shalamanov2cde1002021-06-08 19:50:10 +020079
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040080 std::shared_ptr<RefreshRateSelector> mSelector =
81 std::make_shared<RefreshRateSelector>(makeModes(kDisplay1Mode60),
82 kDisplay1Mode60->getId());
Dominik Laskowski983f2b52020-06-25 16:54:06 -070083
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070084 mock::SchedulerCallback mSchedulerCallback;
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040085 TestableScheduler* mScheduler = new TestableScheduler{mSelector, mSchedulerCallback};
Dominik Laskowski98041832019-08-01 18:35:59 -070086
Dominik Laskowski068173d2021-08-11 17:22:59 -070087 ConnectionHandle mConnectionHandle;
88 MockEventThread* mEventThread;
Ana Krulec0c8cd522018-08-31 12:27:28 -070089 sp<MockEventThreadConnection> mEventThreadConnection;
Ady Abraham564f9de2021-02-03 18:34:33 -080090
91 TestableSurfaceFlinger mFlinger;
Ana Krulec0c8cd522018-08-31 12:27:28 -070092};
93
94SchedulerTest::SchedulerTest() {
Dominik Laskowski068173d2021-08-11 17:22:59 -070095 auto eventThread = std::make_unique<MockEventThread>();
Ana Krulec0c8cd522018-08-31 12:27:28 -070096 mEventThread = eventThread.get();
Ana Krulec85c39af2018-12-26 17:29:57 -080097 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
98
Ady Abrahamd11bade2022-08-01 16:18:03 -070099 mEventThreadConnection = sp<MockEventThreadConnection>::make(mEventThread);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700100
101 // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
102 // sure that call gets executed and returns an EventThread::Connection object.
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700103 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
Ana Krulec0c8cd522018-08-31 12:27:28 -0700104 .WillRepeatedly(Return(mEventThreadConnection));
105
Ady Abrahama0a16272021-03-03 15:23:35 -0800106 mConnectionHandle = mScheduler->createConnection(std::move(eventThread));
Dominik Laskowski98041832019-08-01 18:35:59 -0700107 EXPECT_TRUE(mConnectionHandle);
Ady Abrahama0a16272021-03-03 15:23:35 -0800108
109 mFlinger.resetScheduler(mScheduler);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700110}
111
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700112} // namespace
Ana Krulec0c8cd522018-08-31 12:27:28 -0700113
Ana Krulec0c8cd522018-08-31 12:27:28 -0700114TEST_F(SchedulerTest, invalidConnectionHandle) {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700115 ConnectionHandle handle;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700116
Ady Abrahama0a16272021-03-03 15:23:35 -0800117 const sp<IDisplayEventConnection> connection = mScheduler->createDisplayEventConnection(handle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700118
Dominik Laskowski98041832019-08-01 18:35:59 -0700119 EXPECT_FALSE(connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800120 EXPECT_FALSE(mScheduler->getEventConnection(handle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700121
122 // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads.
123 EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400124 mScheduler->onHotplugReceived(handle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700125
Dominik Laskowski98041832019-08-01 18:35:59 -0700126 std::string output;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700127 EXPECT_CALL(*mEventThread, dump(_)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800128 mScheduler->dump(handle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700129 EXPECT_TRUE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700130
Ady Abraham9c53ee72020-07-22 21:16:18 -0700131 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800132 mScheduler->setDuration(handle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700133}
134
135TEST_F(SchedulerTest, validConnectionHandle) {
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700136 const sp<IDisplayEventConnection> connection =
Ady Abrahama0a16272021-03-03 15:23:35 -0800137 mScheduler->createDisplayEventConnection(mConnectionHandle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700138
Dominik Laskowski98041832019-08-01 18:35:59 -0700139 ASSERT_EQ(mEventThreadConnection, connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800140 EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700141
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400142 EXPECT_CALL(*mEventThread, onHotplugReceived(kDisplayId1, false)).Times(1);
143 mScheduler->onHotplugReceived(mConnectionHandle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700144
Dominik Laskowski98041832019-08-01 18:35:59 -0700145 std::string output("dump");
146 EXPECT_CALL(*mEventThread, dump(output)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800147 mScheduler->dump(mConnectionHandle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700148 EXPECT_FALSE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700149
Ady Abraham9c53ee72020-07-22 21:16:18 -0700150 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800151 mScheduler->setDuration(mConnectionHandle, 10ns, 20ns);
Alec Mouri717bcb62020-02-10 17:07:19 -0800152
153 static constexpr size_t kEventConnections = 5;
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700154 EXPECT_CALL(*mEventThread, getEventThreadConnectionCount()).WillOnce(Return(kEventConnections));
Ady Abrahama0a16272021-03-03 15:23:35 -0800155 EXPECT_EQ(kEventConnections, mScheduler->getEventThreadConnectionCount(mConnectionHandle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700156}
Dominik Laskowski98041832019-08-01 18:35:59 -0700157
Dominik Laskowski66295432023-03-14 12:25:36 -0400158TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) {
Dominik Laskowski008bec02023-03-14 12:04:58 -0400159 // Hardware VSYNC should not change if the display is already registered.
Dominik Laskowski66295432023-03-14 12:25:36 -0400160 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId1, false)).Times(0);
Dominik Laskowski008bec02023-03-14 12:04:58 -0400161 mScheduler->registerDisplay(kDisplayId1,
162 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
163 kDisplay1Mode60->getId()));
164
Dominik Laskowski66295432023-03-14 12:25:36 -0400165 // TODO(b/241285191): Restore once VsyncSchedule::getPendingHardwareVsyncState is called by
166 // Scheduler::setDisplayPowerMode rather than SF::setPowerModeInternal.
167#if 0
Dominik Laskowski008bec02023-03-14 12:04:58 -0400168 // Hardware VSYNC should be disabled for newly registered displays.
Dominik Laskowski66295432023-03-14 12:25:36 -0400169 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId2, false)).Times(1);
170 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId3, false)).Times(1);
171#endif
Dominik Laskowski008bec02023-03-14 12:04:58 -0400172
173 mScheduler->registerDisplay(kDisplayId2,
174 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
175 kDisplay2Mode60->getId()));
176 mScheduler->registerDisplay(kDisplayId3,
177 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
178 kDisplay3Mode60->getId()));
Dominik Laskowski66295432023-03-14 12:25:36 -0400179
180 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId1)->getPendingHardwareVsyncState());
181 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId2)->getPendingHardwareVsyncState());
182 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId3)->getPendingHardwareVsyncState());
Dominik Laskowski008bec02023-03-14 12:04:58 -0400183}
184
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200185TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) {
186 // The layer is registered at creation time and deregistered at destruction time.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700187 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700188
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200189 // recordLayerHistory should be a noop
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700190 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000191 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
192 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700193 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700194
Rachel Lee6a9731d2022-06-06 17:08:14 -0700195 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500196 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700197
198 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700199 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700200
ramindani69b58e82022-09-26 16:48:36 -0700201 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800202 mScheduler->chooseRefreshRateForContent();
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700203}
204
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200205TEST_F(SchedulerTest, updateDisplayModes) {
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700206 ASSERT_EQ(0u, mScheduler->layerHistorySize());
Dominik Laskowski068173d2021-08-11 17:22:59 -0700207 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700208 ASSERT_EQ(1u, mScheduler->layerHistorySize());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200209
Dominik Laskowski596a2562022-10-28 11:26:12 -0400210 // Replace `mSelector` with a new `RefreshRateSelector` that has different display modes.
211 mScheduler->registerDisplay(kDisplayId1,
212 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
213 kDisplay1Mode60->getId()));
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200214
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700215 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000216 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
217 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700218 ASSERT_EQ(1u, mScheduler->getNumActiveLayers());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200219}
220
Dominik Laskowski068173d2021-08-11 17:22:59 -0700221TEST_F(SchedulerTest, dispatchCachedReportedMode) {
222 mScheduler->clearCachedReportedMode();
223
Ady Abraham690f4612021-07-01 23:24:03 -0700224 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Dominik Laskowski068173d2021-08-11 17:22:59 -0700225 EXPECT_NO_FATAL_FAILURE(mScheduler->dispatchCachedReportedMode());
Ana Krulec6ddd2612020-09-24 13:06:33 -0700226}
227
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100228TEST_F(SchedulerTest, onNonPrimaryDisplayModeChanged_invalidParameters) {
Ady Abraham690f4612021-07-01 23:24:03 -0700229 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
230 .setId(DisplayModeId(111))
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400231 .setPhysicalDisplayId(kDisplayId1)
Ady Abraham690f4612021-07-01 23:24:03 -0700232 .setVsyncPeriod(111111)
233 .build();
Ana Krulec6ddd2612020-09-24 13:06:33 -0700234
235 // If the handle is incorrect, the function should return before
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100236 // onModeChange is called.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700237 ConnectionHandle invalidHandle = {.id = 123};
Ady Abrahamace3d052022-11-17 16:25:05 -0800238 EXPECT_NO_FATAL_FAILURE(
239 mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle,
240 {90_Hz, ftl::as_non_null(mode)}));
Ady Abraham690f4612021-07-01 23:24:03 -0700241 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Ana Krulec6ddd2612020-09-24 13:06:33 -0700242}
243
Ady Abraham899dcdb2021-06-15 16:56:21 -0700244TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700245 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms));
246 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms));
247 EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(120_Hz, 30ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800248
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700249 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 40ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800250
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700251 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Piquea1456c12023-05-17 12:11:15 -0700252
Lloyd Pique30db6402023-06-26 18:56:51 +0000253 const auto savedMinAcquiredBuffers = mFlinger.mutableMinAcquiredBuffers();
254 mFlinger.mutableMinAcquiredBuffers() = 2;
Lloyd Piquea1456c12023-05-17 12:11:15 -0700255 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Pique30db6402023-06-26 18:56:51 +0000256 mFlinger.mutableMinAcquiredBuffers() = savedMinAcquiredBuffers;
Ady Abraham564f9de2021-02-03 18:34:33 -0800257}
258
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200259MATCHER(Is120Hz, "") {
Ady Abrahamace3d052022-11-17 16:25:05 -0800260 return isApproxEqual(arg.front().mode.fps, 120_Hz);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200261}
262
263TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
Dominik Laskowski596a2562022-10-28 11:26:12 -0400264 mScheduler->registerDisplay(kDisplayId1,
265 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
266 kDisplay1Mode60->getId()));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200267
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800268 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
269 EXPECT_CALL(*layer, isVisible()).WillOnce(Return(true));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200270
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000271 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
272 LayerHistory::LayerUpdateType::Buffer);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200273
Rachel Lee6a9731d2022-06-06 17:08:14 -0700274 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500275 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200276
277 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700278 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200279
ramindani69b58e82022-09-26 16:48:36 -0700280 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(Is120Hz())).Times(1);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200281 mScheduler->chooseRefreshRateForContent();
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800282
283 // No-op if layer requirements have not changed.
ramindani69b58e82022-09-26 16:48:36 -0700284 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800285 mScheduler->chooseRefreshRateForContent();
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200286}
287
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400288TEST_F(SchedulerTest, chooseDisplayModesSingleDisplay) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400289 mScheduler->registerDisplay(kDisplayId1,
290 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
291 kDisplay1Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700292
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400293 std::vector<RefreshRateSelector::LayerRequirement> layers =
294 std::vector<RefreshRateSelector::LayerRequirement>({{.weight = 1.f}, {.weight = 1.f}});
ramindani69b58e82022-09-26 16:48:36 -0700295 mScheduler->setContentRequirements(layers);
296 GlobalSignals globalSignals = {.idle = true};
297 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
298
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400299 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
300
301 auto modeChoices = mScheduler->chooseDisplayModes();
302 ASSERT_EQ(1u, modeChoices.size());
303
304 auto choice = modeChoices.get(kDisplayId1);
305 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800306 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700307
308 globalSignals = {.idle = false};
309 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400310
311 modeChoices = mScheduler->chooseDisplayModes();
312 ASSERT_EQ(1u, modeChoices.size());
313
314 choice = modeChoices.get(kDisplayId1);
315 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800316 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700317
318 globalSignals = {.touch = true};
319 mScheduler->replaceTouchTimer(10);
320 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700321
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400322 modeChoices = mScheduler->chooseDisplayModes();
323 ASSERT_EQ(1u, modeChoices.size());
324
325 choice = modeChoices.get(kDisplayId1);
326 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800327 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700328}
329
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400330TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400331 mScheduler->registerDisplay(kDisplayId1,
332 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
333 kDisplay1Mode60->getId()));
334 mScheduler->registerDisplay(kDisplayId2,
335 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
336 kDisplay2Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700337
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400338 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
339 TestableScheduler::DisplayModeChoiceMap expectedChoices;
ramindani69b58e82022-09-26 16:48:36 -0700340
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400341 {
342 const GlobalSignals globalSignals = {.idle = true};
343 expectedChoices =
344 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800345 DisplayModeChoice>(kDisplayId1,
346 FrameRateMode{60_Hz, kDisplay1Mode60},
347 globalSignals)(kDisplayId2,
348 FrameRateMode{60_Hz,
349 kDisplay2Mode60},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400350 globalSignals);
351
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400352 std::vector<RefreshRateSelector::LayerRequirement> layers = {{.weight = 1.f},
353 {.weight = 1.f}};
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400354 mScheduler->setContentRequirements(layers);
355 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
356
357 const auto actualChoices = mScheduler->chooseDisplayModes();
358 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700359 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400360 {
361 const GlobalSignals globalSignals = {.idle = false};
362 expectedChoices =
363 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800364 DisplayModeChoice>(kDisplayId1,
365 FrameRateMode{120_Hz, kDisplay1Mode120},
366 globalSignals)(kDisplayId2,
367 FrameRateMode{120_Hz,
368 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400369 globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700370
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400371 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700372
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400373 const auto actualChoices = mScheduler->chooseDisplayModes();
374 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700375 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400376 {
377 const GlobalSignals globalSignals = {.touch = true};
378 mScheduler->replaceTouchTimer(10);
379 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700380
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400381 expectedChoices =
382 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800383 DisplayModeChoice>(kDisplayId1,
384 FrameRateMode{120_Hz, kDisplay1Mode120},
385 globalSignals)(kDisplayId2,
386 FrameRateMode{120_Hz,
387 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400388 globalSignals);
389
390 const auto actualChoices = mScheduler->chooseDisplayModes();
391 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700392 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400393 {
ramindani22f2ead2023-04-21 10:27:11 -0700394 // The kDisplayId3 does not support 120Hz, The pacesetter display rate is chosen to be 120
395 // Hz. In this case only the display kDisplayId3 choose 60Hz as it does not support 120Hz.
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400396 mScheduler
397 ->registerDisplay(kDisplayId3,
398 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
399 kDisplay3Mode60->getId()));
Dominik Laskowski327d6092022-10-11 18:05:08 -0400400
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400401 const GlobalSignals globalSignals = {.touch = true};
402 mScheduler->replaceTouchTimer(10);
403 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani7c487282022-10-10 16:17:51 -0700404
Ady Abrahamace3d052022-11-17 16:25:05 -0800405 expectedChoices = ftl::init::map<
406 const PhysicalDisplayId&,
ramindani22f2ead2023-04-21 10:27:11 -0700407 DisplayModeChoice>(kDisplayId1, FrameRateMode{120_Hz, kDisplay1Mode120},
408 globalSignals)(kDisplayId2,
409 FrameRateMode{120_Hz, kDisplay2Mode120},
410 globalSignals)(kDisplayId3,
411 FrameRateMode{60_Hz,
412 kDisplay3Mode60},
413 globalSignals);
414
415 const auto actualChoices = mScheduler->chooseDisplayModes();
416 EXPECT_EQ(expectedChoices, actualChoices);
417 }
418 {
419 // We should choose 60Hz despite the touch signal as pacesetter only supports 60Hz
420 mScheduler->setPacesetterDisplay(kDisplayId3);
421 const GlobalSignals globalSignals = {.touch = true};
422 mScheduler->replaceTouchTimer(10);
423 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
424
425 expectedChoices = ftl::init::map<
426 const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800427 DisplayModeChoice>(kDisplayId1, FrameRateMode{60_Hz, kDisplay1Mode60},
428 globalSignals)(kDisplayId2,
429 FrameRateMode{60_Hz, kDisplay2Mode60},
430 globalSignals)(kDisplayId3,
431 FrameRateMode{60_Hz,
432 kDisplay3Mode60},
433 globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400434
435 const auto actualChoices = mScheduler->chooseDisplayModes();
436 EXPECT_EQ(expectedChoices, actualChoices);
ramindani7c487282022-10-10 16:17:51 -0700437 }
ramindani69b58e82022-09-26 16:48:36 -0700438}
439
Dominik Laskowski068173d2021-08-11 17:22:59 -0700440} // namespace android::scheduler