blob: 8a8f771a1d70d0f7cac6e77fa7cdc5903407e51e [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 Abrahamf2851612023-09-25 17:19:00 -070058 : EventThreadConnection(eventThread, /*callingUid*/ static_cast<uid_t>(0)) {}
Ana Krulec0c8cd522018-08-31 12:27:28 -070059 ~MockEventThreadConnection() = default;
60
Huihong Luo6fac5232021-11-22 16:05:23 -080061 MOCK_METHOD1(stealReceiveChannel, binder::Status(gui::BitTube* outChannel));
62 MOCK_METHOD1(setVsyncRate, binder::Status(int count));
63 MOCK_METHOD0(requestNextVsync, binder::Status());
Ana Krulec0c8cd522018-08-31 12:27:28 -070064 };
65
Ana Krulec0c8cd522018-08-31 12:27:28 -070066 SchedulerTest();
Ana Krulec0c8cd522018-08-31 12:27:28 -070067
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040068 static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(255u);
Ady Abrahamace3d052022-11-17 16:25:05 -080069 static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode60 =
70 ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(0), 60_Hz));
71 static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode120 =
72 ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(1), 120_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040073 static inline const DisplayModes kDisplay1Modes = makeModes(kDisplay1Mode60, kDisplay1Mode120);
74
75 static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(254u);
Ady Abrahamace3d052022-11-17 16:25:05 -080076 static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode60 =
77 ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(0), 60_Hz));
78 static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode120 =
79 ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(1), 120_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040080 static inline const DisplayModes kDisplay2Modes = makeModes(kDisplay2Mode60, kDisplay2Mode120);
81
82 static constexpr PhysicalDisplayId kDisplayId3 = PhysicalDisplayId::fromPort(253u);
Ady Abrahamace3d052022-11-17 16:25:05 -080083 static inline const ftl::NonNull<DisplayModePtr> kDisplay3Mode60 =
84 ftl::as_non_null(createDisplayMode(kDisplayId3, DisplayModeId(0), 60_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040085 static inline const DisplayModes kDisplay3Modes = makeModes(kDisplay3Mode60);
Marin Shalamanov2cde1002021-06-08 19:50:10 +020086
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040087 std::shared_ptr<RefreshRateSelector> mSelector =
88 std::make_shared<RefreshRateSelector>(makeModes(kDisplay1Mode60),
89 kDisplay1Mode60->getId());
Dominik Laskowski983f2b52020-06-25 16:54:06 -070090
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070091 mock::SchedulerCallback mSchedulerCallback;
ramindanid4354a92023-10-02 15:11:09 -070092 mock::VsyncTrackerCallback mVsyncTrackerCallback;
93 TestableScheduler* mScheduler =
94 new TestableScheduler{mSelector, mSchedulerCallback, mVsyncTrackerCallback};
Ady Abraham822ecbd2023-07-07 16:16:09 -070095 surfaceflinger::frontend::LayerHierarchyBuilder mLayerHierarchyBuilder{{}};
Dominik Laskowski98041832019-08-01 18:35:59 -070096
Dominik Laskowski068173d2021-08-11 17:22:59 -070097 ConnectionHandle mConnectionHandle;
98 MockEventThread* mEventThread;
Ana Krulec0c8cd522018-08-31 12:27:28 -070099 sp<MockEventThreadConnection> mEventThreadConnection;
Ady Abraham564f9de2021-02-03 18:34:33 -0800100
101 TestableSurfaceFlinger mFlinger;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700102};
103
104SchedulerTest::SchedulerTest() {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700105 auto eventThread = std::make_unique<MockEventThread>();
Ana Krulec0c8cd522018-08-31 12:27:28 -0700106 mEventThread = eventThread.get();
Ana Krulec85c39af2018-12-26 17:29:57 -0800107 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
108
Ady Abrahamd11bade2022-08-01 16:18:03 -0700109 mEventThreadConnection = sp<MockEventThreadConnection>::make(mEventThread);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700110
111 // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
112 // sure that call gets executed and returns an EventThread::Connection object.
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700113 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
Ana Krulec0c8cd522018-08-31 12:27:28 -0700114 .WillRepeatedly(Return(mEventThreadConnection));
115
Ady Abrahama0a16272021-03-03 15:23:35 -0800116 mConnectionHandle = mScheduler->createConnection(std::move(eventThread));
Dominik Laskowski98041832019-08-01 18:35:59 -0700117 EXPECT_TRUE(mConnectionHandle);
Ady Abrahama0a16272021-03-03 15:23:35 -0800118
119 mFlinger.resetScheduler(mScheduler);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700120}
121
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700122} // namespace
Ana Krulec0c8cd522018-08-31 12:27:28 -0700123
Ana Krulec0c8cd522018-08-31 12:27:28 -0700124TEST_F(SchedulerTest, invalidConnectionHandle) {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700125 ConnectionHandle handle;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700126
Ady Abrahama0a16272021-03-03 15:23:35 -0800127 const sp<IDisplayEventConnection> connection = mScheduler->createDisplayEventConnection(handle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700128
Dominik Laskowski98041832019-08-01 18:35:59 -0700129 EXPECT_FALSE(connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800130 EXPECT_FALSE(mScheduler->getEventConnection(handle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700131
132 // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads.
133 EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400134 mScheduler->onHotplugReceived(handle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700135
Dominik Laskowski98041832019-08-01 18:35:59 -0700136 std::string output;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700137 EXPECT_CALL(*mEventThread, dump(_)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800138 mScheduler->dump(handle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700139 EXPECT_TRUE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700140
Ady Abraham9c53ee72020-07-22 21:16:18 -0700141 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800142 mScheduler->setDuration(handle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700143}
144
145TEST_F(SchedulerTest, validConnectionHandle) {
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700146 const sp<IDisplayEventConnection> connection =
Ady Abrahama0a16272021-03-03 15:23:35 -0800147 mScheduler->createDisplayEventConnection(mConnectionHandle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700148
Dominik Laskowski98041832019-08-01 18:35:59 -0700149 ASSERT_EQ(mEventThreadConnection, connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800150 EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700151
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400152 EXPECT_CALL(*mEventThread, onHotplugReceived(kDisplayId1, false)).Times(1);
153 mScheduler->onHotplugReceived(mConnectionHandle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700154
Dominik Laskowski98041832019-08-01 18:35:59 -0700155 std::string output("dump");
156 EXPECT_CALL(*mEventThread, dump(output)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800157 mScheduler->dump(mConnectionHandle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700158 EXPECT_FALSE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700159
Ady Abraham9c53ee72020-07-22 21:16:18 -0700160 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800161 mScheduler->setDuration(mConnectionHandle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700162}
Dominik Laskowski98041832019-08-01 18:35:59 -0700163
Dominik Laskowski66295432023-03-14 12:25:36 -0400164TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) {
Dominik Laskowski008bec02023-03-14 12:04:58 -0400165 // Hardware VSYNC should not change if the display is already registered.
Dominik Laskowski66295432023-03-14 12:25:36 -0400166 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId1, false)).Times(0);
Dominik Laskowski008bec02023-03-14 12:04:58 -0400167 mScheduler->registerDisplay(kDisplayId1,
168 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
169 kDisplay1Mode60->getId()));
170
Dominik Laskowski66295432023-03-14 12:25:36 -0400171 // TODO(b/241285191): Restore once VsyncSchedule::getPendingHardwareVsyncState is called by
172 // Scheduler::setDisplayPowerMode rather than SF::setPowerModeInternal.
173#if 0
Dominik Laskowski008bec02023-03-14 12:04:58 -0400174 // Hardware VSYNC should be disabled for newly registered displays.
Dominik Laskowski66295432023-03-14 12:25:36 -0400175 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId2, false)).Times(1);
176 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId3, false)).Times(1);
177#endif
Dominik Laskowski008bec02023-03-14 12:04:58 -0400178
179 mScheduler->registerDisplay(kDisplayId2,
180 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
181 kDisplay2Mode60->getId()));
182 mScheduler->registerDisplay(kDisplayId3,
183 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
184 kDisplay3Mode60->getId()));
Dominik Laskowski66295432023-03-14 12:25:36 -0400185
186 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId1)->getPendingHardwareVsyncState());
187 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId2)->getPendingHardwareVsyncState());
188 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId3)->getPendingHardwareVsyncState());
Dominik Laskowski008bec02023-03-14 12:04:58 -0400189}
190
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200191TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) {
192 // The layer is registered at creation time and deregistered at destruction time.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700193 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700194
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200195 // recordLayerHistory should be a noop
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(0u, mScheduler->getNumActiveLayers());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700200
Rachel Lee6a9731d2022-06-06 17:08:14 -0700201 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500202 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700203
204 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700205 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700206
ramindani69b58e82022-09-26 16:48:36 -0700207 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700208 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
209 /*updateAttachedChoreographer*/ false);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700210}
211
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200212TEST_F(SchedulerTest, updateDisplayModes) {
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700213 ASSERT_EQ(0u, mScheduler->layerHistorySize());
Dominik Laskowski068173d2021-08-11 17:22:59 -0700214 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700215 ASSERT_EQ(1u, mScheduler->layerHistorySize());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200216
Dominik Laskowski596a2562022-10-28 11:26:12 -0400217 // Replace `mSelector` with a new `RefreshRateSelector` that has different display modes.
218 mScheduler->registerDisplay(kDisplayId1,
219 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
220 kDisplay1Mode60->getId()));
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200221
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700222 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700223 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0, 0,
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000224 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700225 ASSERT_EQ(1u, mScheduler->getNumActiveLayers());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200226}
227
Dominik Laskowski068173d2021-08-11 17:22:59 -0700228TEST_F(SchedulerTest, dispatchCachedReportedMode) {
229 mScheduler->clearCachedReportedMode();
230
Ady Abraham690f4612021-07-01 23:24:03 -0700231 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Dominik Laskowski068173d2021-08-11 17:22:59 -0700232 EXPECT_NO_FATAL_FAILURE(mScheduler->dispatchCachedReportedMode());
Ana Krulec6ddd2612020-09-24 13:06:33 -0700233}
234
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100235TEST_F(SchedulerTest, onNonPrimaryDisplayModeChanged_invalidParameters) {
Ady Abraham690f4612021-07-01 23:24:03 -0700236 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
237 .setId(DisplayModeId(111))
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400238 .setPhysicalDisplayId(kDisplayId1)
Ady Abraham690f4612021-07-01 23:24:03 -0700239 .setVsyncPeriod(111111)
240 .build();
Ana Krulec6ddd2612020-09-24 13:06:33 -0700241
242 // If the handle is incorrect, the function should return before
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100243 // onModeChange is called.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700244 ConnectionHandle invalidHandle = {.id = 123};
Ady Abrahamace3d052022-11-17 16:25:05 -0800245 EXPECT_NO_FATAL_FAILURE(
246 mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle,
247 {90_Hz, ftl::as_non_null(mode)}));
Ady Abraham690f4612021-07-01 23:24:03 -0700248 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Ana Krulec6ddd2612020-09-24 13:06:33 -0700249}
250
Ady Abraham899dcdb2021-06-15 16:56:21 -0700251TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700252 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms));
253 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms));
254 EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(120_Hz, 30ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800255
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700256 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 40ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800257
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700258 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Piquea1456c12023-05-17 12:11:15 -0700259
Lloyd Pique30db6402023-06-26 18:56:51 +0000260 const auto savedMinAcquiredBuffers = mFlinger.mutableMinAcquiredBuffers();
261 mFlinger.mutableMinAcquiredBuffers() = 2;
Lloyd Piquea1456c12023-05-17 12:11:15 -0700262 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Pique30db6402023-06-26 18:56:51 +0000263 mFlinger.mutableMinAcquiredBuffers() = savedMinAcquiredBuffers;
Ady Abraham564f9de2021-02-03 18:34:33 -0800264}
265
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200266MATCHER(Is120Hz, "") {
Ady Abrahamace3d052022-11-17 16:25:05 -0800267 return isApproxEqual(arg.front().mode.fps, 120_Hz);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200268}
269
270TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
Dominik Laskowski596a2562022-10-28 11:26:12 -0400271 mScheduler->registerDisplay(kDisplayId1,
272 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
273 kDisplay1Mode60->getId()));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200274
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800275 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
276 EXPECT_CALL(*layer, isVisible()).WillOnce(Return(true));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200277
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700278 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0, systemTime(),
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000279 LayerHistory::LayerUpdateType::Buffer);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200280
Rachel Lee6a9731d2022-06-06 17:08:14 -0700281 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500282 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200283
284 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700285 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200286
ramindani69b58e82022-09-26 16:48:36 -0700287 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(Is120Hz())).Times(1);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700288 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
289 /*updateAttachedChoreographer*/ false);
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800290
291 // No-op if layer requirements have not changed.
ramindani69b58e82022-09-26 16:48:36 -0700292 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700293 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
294 /*updateAttachedChoreographer*/ false);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200295}
296
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400297TEST_F(SchedulerTest, chooseDisplayModesSingleDisplay) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400298 mScheduler->registerDisplay(kDisplayId1,
299 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
300 kDisplay1Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700301
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400302 std::vector<RefreshRateSelector::LayerRequirement> layers =
303 std::vector<RefreshRateSelector::LayerRequirement>({{.weight = 1.f}, {.weight = 1.f}});
ramindani69b58e82022-09-26 16:48:36 -0700304 mScheduler->setContentRequirements(layers);
305 GlobalSignals globalSignals = {.idle = true};
306 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
307
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400308 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
309
310 auto modeChoices = mScheduler->chooseDisplayModes();
311 ASSERT_EQ(1u, modeChoices.size());
312
313 auto choice = modeChoices.get(kDisplayId1);
314 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800315 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700316
317 globalSignals = {.idle = false};
318 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400319
320 modeChoices = mScheduler->chooseDisplayModes();
321 ASSERT_EQ(1u, modeChoices.size());
322
323 choice = modeChoices.get(kDisplayId1);
324 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800325 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700326
327 globalSignals = {.touch = true};
328 mScheduler->replaceTouchTimer(10);
329 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700330
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400331 modeChoices = mScheduler->chooseDisplayModes();
332 ASSERT_EQ(1u, modeChoices.size());
333
334 choice = modeChoices.get(kDisplayId1);
335 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800336 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700337}
338
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400339TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400340 mScheduler->registerDisplay(kDisplayId1,
341 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
342 kDisplay1Mode60->getId()));
343 mScheduler->registerDisplay(kDisplayId2,
344 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
345 kDisplay2Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700346
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400347 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
348 TestableScheduler::DisplayModeChoiceMap expectedChoices;
ramindani69b58e82022-09-26 16:48:36 -0700349
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400350 {
351 const GlobalSignals globalSignals = {.idle = true};
352 expectedChoices =
353 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800354 DisplayModeChoice>(kDisplayId1,
355 FrameRateMode{60_Hz, kDisplay1Mode60},
356 globalSignals)(kDisplayId2,
357 FrameRateMode{60_Hz,
358 kDisplay2Mode60},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400359 globalSignals);
360
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400361 std::vector<RefreshRateSelector::LayerRequirement> layers = {{.weight = 1.f},
362 {.weight = 1.f}};
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400363 mScheduler->setContentRequirements(layers);
364 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
365
366 const auto actualChoices = mScheduler->chooseDisplayModes();
367 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700368 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400369 {
370 const GlobalSignals globalSignals = {.idle = false};
371 expectedChoices =
372 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800373 DisplayModeChoice>(kDisplayId1,
374 FrameRateMode{120_Hz, kDisplay1Mode120},
375 globalSignals)(kDisplayId2,
376 FrameRateMode{120_Hz,
377 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400378 globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700379
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400380 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700381
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400382 const auto actualChoices = mScheduler->chooseDisplayModes();
383 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700384 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400385 {
386 const GlobalSignals globalSignals = {.touch = true};
387 mScheduler->replaceTouchTimer(10);
388 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700389
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400390 expectedChoices =
391 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800392 DisplayModeChoice>(kDisplayId1,
393 FrameRateMode{120_Hz, kDisplay1Mode120},
394 globalSignals)(kDisplayId2,
395 FrameRateMode{120_Hz,
396 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400397 globalSignals);
398
399 const auto actualChoices = mScheduler->chooseDisplayModes();
400 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700401 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400402 {
ramindani22f2ead2023-04-21 10:27:11 -0700403 // The kDisplayId3 does not support 120Hz, The pacesetter display rate is chosen to be 120
404 // Hz. In this case only the display kDisplayId3 choose 60Hz as it does not support 120Hz.
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400405 mScheduler
406 ->registerDisplay(kDisplayId3,
407 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
408 kDisplay3Mode60->getId()));
Dominik Laskowski327d6092022-10-11 18:05:08 -0400409
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400410 const GlobalSignals globalSignals = {.touch = true};
411 mScheduler->replaceTouchTimer(10);
412 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani7c487282022-10-10 16:17:51 -0700413
Ady Abrahamace3d052022-11-17 16:25:05 -0800414 expectedChoices = ftl::init::map<
415 const PhysicalDisplayId&,
ramindani22f2ead2023-04-21 10:27:11 -0700416 DisplayModeChoice>(kDisplayId1, FrameRateMode{120_Hz, kDisplay1Mode120},
417 globalSignals)(kDisplayId2,
418 FrameRateMode{120_Hz, kDisplay2Mode120},
419 globalSignals)(kDisplayId3,
420 FrameRateMode{60_Hz,
421 kDisplay3Mode60},
422 globalSignals);
423
424 const auto actualChoices = mScheduler->chooseDisplayModes();
425 EXPECT_EQ(expectedChoices, actualChoices);
426 }
427 {
428 // We should choose 60Hz despite the touch signal as pacesetter only supports 60Hz
429 mScheduler->setPacesetterDisplay(kDisplayId3);
430 const GlobalSignals globalSignals = {.touch = true};
431 mScheduler->replaceTouchTimer(10);
432 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
433
434 expectedChoices = ftl::init::map<
435 const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800436 DisplayModeChoice>(kDisplayId1, FrameRateMode{60_Hz, kDisplay1Mode60},
437 globalSignals)(kDisplayId2,
438 FrameRateMode{60_Hz, kDisplay2Mode60},
439 globalSignals)(kDisplayId3,
440 FrameRateMode{60_Hz,
441 kDisplay3Mode60},
442 globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400443
444 const auto actualChoices = mScheduler->chooseDisplayModes();
445 EXPECT_EQ(expectedChoices, actualChoices);
ramindani7c487282022-10-10 16:17:51 -0700446 }
ramindani69b58e82022-09-26 16:48:36 -0700447}
448
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400449TEST_F(SchedulerTest, onFrameSignalMultipleDisplays) {
450 mScheduler->registerDisplay(kDisplayId1,
451 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
452 kDisplay1Mode60->getId()));
453 mScheduler->registerDisplay(kDisplayId2,
454 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
455 kDisplay2Mode60->getId()));
456
457 using VsyncIds = std::vector<std::pair<PhysicalDisplayId, VsyncId>>;
458
459 struct Compositor final : ICompositor {
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500460 explicit Compositor(TestableScheduler& scheduler) : scheduler(scheduler) {}
461
462 TestableScheduler& scheduler;
463
464 struct {
465 PhysicalDisplayId commit;
466 PhysicalDisplayId composite;
467 } pacesetterIds;
468
469 struct {
470 VsyncIds commit;
471 VsyncIds composite;
472 } vsyncIds;
473
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400474 bool committed = true;
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500475 bool changePacesetter = false;
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400476
477 void configure() override {}
478
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500479 bool commit(PhysicalDisplayId pacesetterId,
480 const scheduler::FrameTargets& targets) override {
481 pacesetterIds.commit = pacesetterId;
482
483 vsyncIds.commit.clear();
484 vsyncIds.composite.clear();
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400485
486 for (const auto& [id, target] : targets) {
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500487 vsyncIds.commit.emplace_back(id, target->vsyncId());
488 }
489
490 if (changePacesetter) {
491 scheduler.setPacesetterDisplay(kDisplayId2);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400492 }
493
494 return committed;
495 }
496
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500497 CompositeResultsPerDisplay composite(PhysicalDisplayId pacesetterId,
498 const scheduler::FrameTargeters& targeters) override {
499 pacesetterIds.composite = pacesetterId;
500
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400501 CompositeResultsPerDisplay results;
502
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500503 for (const auto& [id, targeter] : targeters) {
504 vsyncIds.composite.emplace_back(id, targeter->target().vsyncId());
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400505 results.try_emplace(id,
506 CompositeResult{.compositionCoverage =
507 CompositionCoverage::Hwc});
508 }
509
510 return results;
511 }
512
513 void sample() override {}
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500514 } compositor(*mScheduler);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400515
516 mScheduler->doFrameSignal(compositor, VsyncId(42));
517
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500518 const auto makeVsyncIds = [](VsyncId vsyncId, bool swap = false) -> VsyncIds {
519 if (swap) {
520 return {{kDisplayId2, vsyncId}, {kDisplayId1, vsyncId}};
521 } else {
522 return {{kDisplayId1, vsyncId}, {kDisplayId2, vsyncId}};
523 }
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400524 };
525
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500526 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
527 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
528 EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.commit);
529 EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.composite);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400530
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500531 // FrameTargets should be updated despite the skipped commit.
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400532 compositor.committed = false;
533 mScheduler->doFrameSignal(compositor, VsyncId(43));
534
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500535 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
536 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
537 EXPECT_EQ(makeVsyncIds(VsyncId(43)), compositor.vsyncIds.commit);
538 EXPECT_TRUE(compositor.vsyncIds.composite.empty());
539
540 // The pacesetter may change during commit.
541 compositor.committed = true;
542 compositor.changePacesetter = true;
543 mScheduler->doFrameSignal(compositor, VsyncId(44));
544
545 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
546 EXPECT_EQ(kDisplayId2, compositor.pacesetterIds.composite);
547 EXPECT_EQ(makeVsyncIds(VsyncId(44)), compositor.vsyncIds.commit);
548 EXPECT_EQ(makeVsyncIds(VsyncId(44), true), compositor.vsyncIds.composite);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400549}
550
Ady Abraham822ecbd2023-07-07 16:16:09 -0700551class AttachedChoreographerTest : public SchedulerTest {
552protected:
553 void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
554 Fps expectedChoreographerFps);
555};
556
557TEST_F(AttachedChoreographerTest, registerSingle) {
558 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
559
560 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
561
562 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
563 const sp<IDisplayEventConnection> connection =
564 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
565
566 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
567 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
568 EXPECT_EQ(1u,
569 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
570 EXPECT_FALSE(
571 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
572}
573
574TEST_F(AttachedChoreographerTest, registerMultipleOnSameLayer) {
575 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
576
577 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
578 const auto handle = layer->getHandle();
579
580 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
581
582 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_))
583 .WillOnce(Return(0))
584 .WillOnce(Return(0));
585
586 const auto mockConnection1 = sp<MockEventThreadConnection>::make(mEventThread);
587 const auto mockConnection2 = sp<MockEventThreadConnection>::make(mEventThread);
588 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
589 .WillOnce(Return(mockConnection1))
590 .WillOnce(Return(mockConnection2));
591
592 const sp<IDisplayEventConnection> connection1 =
593 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
594 const sp<IDisplayEventConnection> connection2 =
595 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
596
597 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
598 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
599 EXPECT_EQ(2u,
600 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
601 EXPECT_FALSE(
602 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
603}
604
605TEST_F(AttachedChoreographerTest, registerMultipleOnDifferentLayers) {
606 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
607
608 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
609 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
610
611 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
612 const sp<IDisplayEventConnection> connection1 =
613 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer1->getHandle());
614 const sp<IDisplayEventConnection> connection2 =
615 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer2->getHandle());
616
617 EXPECT_EQ(2u, mScheduler->mutableAttachedChoreographers().size());
618
619 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer1->getSequence()));
620 EXPECT_EQ(1u,
621 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()]
622 .connections.size());
623 EXPECT_FALSE(
624 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()].frameRate.isValid());
625
626 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer2->getSequence()));
627 EXPECT_EQ(1u,
628 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()]
629 .connections.size());
630 EXPECT_FALSE(
631 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()].frameRate.isValid());
632}
633
634TEST_F(AttachedChoreographerTest, removedWhenConnectionIsGone) {
635 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
636
637 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
638
639 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
640
641 sp<IDisplayEventConnection> connection =
642 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
643
644 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
645 EXPECT_EQ(1u,
646 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
647
648 // The connection is used all over this test, so it is quite hard to release it from here.
649 // Instead, we just do a small shortcut.
650 {
651 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
652 sp<MockEventThreadConnection> mockConnection =
653 sp<MockEventThreadConnection>::make(mEventThread);
654 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.clear();
655 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.emplace(
656 mockConnection);
657 }
658
659 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
660 LayerHierarchy hierarchy(&layerState);
661 mScheduler->updateAttachedChoreographers(hierarchy, 60_Hz);
662 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
663}
664
665TEST_F(AttachedChoreographerTest, removedWhenLayerIsGone) {
666 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
667
668 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
669
670 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
671 const sp<IDisplayEventConnection> connection =
672 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
673
674 layer.clear();
675 mFlinger.mutableLayersPendingRemoval().clear();
676 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
677}
678
679void AttachedChoreographerTest::frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility,
680 Fps displayFps,
681 Fps expectedChoreographerFps) {
682 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
683
684 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
685 sp<IDisplayEventConnection> connection =
686 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
687
688 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
689 LayerHierarchy hierarchy(&layerState);
690
691 layerState.frameRate = layerFps.getValue();
692 layerState.frameRateCompatibility = frameRateCompatibility;
693
694 mScheduler->updateAttachedChoreographers(hierarchy, displayFps);
695
696 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
697 EXPECT_EQ(expectedChoreographerFps,
698 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
699 EXPECT_EQ(expectedChoreographerFps, mEventThreadConnection->frameRate);
700}
701
702TEST_F(AttachedChoreographerTest, setsFrameRateDefault) {
703 Fps layerFps = 30_Hz;
704 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
705 Fps displayFps = 60_Hz;
706 Fps expectedChoreographerFps = 30_Hz;
707
708 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
709
710 layerFps = Fps::fromValue(32.7f);
711 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
712}
713
714TEST_F(AttachedChoreographerTest, setsFrameRateExact) {
715 Fps layerFps = 30_Hz;
716 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_EXACT;
717 Fps displayFps = 60_Hz;
718 Fps expectedChoreographerFps = 30_Hz;
719
720 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
721
722 layerFps = Fps::fromValue(32.7f);
723 expectedChoreographerFps = {};
724 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
725}
726
727TEST_F(AttachedChoreographerTest, setsFrameRateExactOrMultiple) {
728 Fps layerFps = 30_Hz;
729 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
730 Fps displayFps = 60_Hz;
731 Fps expectedChoreographerFps = 30_Hz;
732
733 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
734
735 layerFps = Fps::fromValue(32.7f);
736 expectedChoreographerFps = {};
737 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
738}
739
740TEST_F(AttachedChoreographerTest, setsFrameRateParent) {
741 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
742 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
743
744 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
745 sp<IDisplayEventConnection> connection =
746 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
747
748 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
749 LayerHierarchy parentHierarchy(&parentState);
750
751 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
752 LayerHierarchy hierarchy(&layerState);
753 parentHierarchy.mChildren.push_back(
754 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
755
756 layerState.frameRate = (30_Hz).getValue();
757 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
758
759 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
760
761 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
762
763 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
764}
765
766TEST_F(AttachedChoreographerTest, setsFrameRateParent2Children) {
767 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
768 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
769 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
770
771 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
772 sp<IDisplayEventConnection> connection =
773 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
774
775 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
776 LayerHierarchy parentHierarchy(&parentState);
777
778 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
779 LayerHierarchy layer1Hierarchy(&layer1State);
780 parentHierarchy.mChildren.push_back(
781 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
782
783 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
784 LayerHierarchy layer2Hierarchy(&layer2State);
785 parentHierarchy.mChildren.push_back(
786 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
787
788 layer1State.frameRate = (30_Hz).getValue();
789 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
790
791 layer2State.frameRate = (20_Hz).getValue();
792 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
793
794 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
795
796 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
797
798 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
799}
800
801TEST_F(AttachedChoreographerTest, setsFrameRateParentConflictingChildren) {
802 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
803 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
804 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
805
806 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
807 sp<IDisplayEventConnection> connection =
808 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
809
810 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
811 LayerHierarchy parentHierarchy(&parentState);
812
813 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
814 LayerHierarchy layer1Hierarchy(&layer1State);
815 parentHierarchy.mChildren.push_back(
816 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
817
818 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
819 LayerHierarchy layer2Hierarchy(&layer2State);
820 parentHierarchy.mChildren.push_back(
821 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
822
823 layer1State.frameRate = (30_Hz).getValue();
824 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
825
826 layer2State.frameRate = (25_Hz).getValue();
827 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
828
829 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
830
831 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
832
833 EXPECT_EQ(Fps(), mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
834}
835
836TEST_F(AttachedChoreographerTest, setsFrameRateChild) {
837 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
838 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
839
840 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
841 sp<IDisplayEventConnection> connection =
842 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
843
844 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
845 LayerHierarchy parentHierarchy(&parentState);
846
847 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
848 LayerHierarchy hierarchy(&layerState);
849 parentHierarchy.mChildren.push_back(
850 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
851
852 parentState.frameRate = (30_Hz).getValue();
853 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
854
855 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
856
857 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
858
859 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
860}
861
862TEST_F(AttachedChoreographerTest, setsFrameRateChildNotOverriddenByParent) {
863 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
864 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
865
866 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
867 sp<IDisplayEventConnection> connection =
868 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
869
870 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
871 LayerHierarchy parentHierarchy(&parentState);
872
873 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
874 LayerHierarchy hierarchy(&layerState);
875 parentHierarchy.mChildren.push_back(
876 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
877
878 parentState.frameRate = (30_Hz).getValue();
879 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
880
881 layerState.frameRate = (60_Hz).getValue();
882 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
883
884 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
885
886 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
887
888 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
889}
890
Dominik Laskowski068173d2021-08-11 17:22:59 -0700891} // namespace android::scheduler