blob: 405f79d290e1ec8d39e6c7f5eefc79cfd343f089 [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);
Alec Mouri717bcb62020-02-10 17:07:19 -0800161
162 static constexpr size_t kEventConnections = 5;
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700163 EXPECT_CALL(*mEventThread, getEventThreadConnectionCount()).WillOnce(Return(kEventConnections));
Ady Abrahama0a16272021-03-03 15:23:35 -0800164 EXPECT_EQ(kEventConnections, mScheduler->getEventThreadConnectionCount(mConnectionHandle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700165}
Dominik Laskowski98041832019-08-01 18:35:59 -0700166
Dominik Laskowski66295432023-03-14 12:25:36 -0400167TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) {
Dominik Laskowski008bec02023-03-14 12:04:58 -0400168 // Hardware VSYNC should not change if the display is already registered.
Dominik Laskowski66295432023-03-14 12:25:36 -0400169 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId1, false)).Times(0);
Dominik Laskowski008bec02023-03-14 12:04:58 -0400170 mScheduler->registerDisplay(kDisplayId1,
171 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
172 kDisplay1Mode60->getId()));
173
Dominik Laskowski66295432023-03-14 12:25:36 -0400174 // TODO(b/241285191): Restore once VsyncSchedule::getPendingHardwareVsyncState is called by
175 // Scheduler::setDisplayPowerMode rather than SF::setPowerModeInternal.
176#if 0
Dominik Laskowski008bec02023-03-14 12:04:58 -0400177 // Hardware VSYNC should be disabled for newly registered displays.
Dominik Laskowski66295432023-03-14 12:25:36 -0400178 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId2, false)).Times(1);
179 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId3, false)).Times(1);
180#endif
Dominik Laskowski008bec02023-03-14 12:04:58 -0400181
182 mScheduler->registerDisplay(kDisplayId2,
183 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
184 kDisplay2Mode60->getId()));
185 mScheduler->registerDisplay(kDisplayId3,
186 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
187 kDisplay3Mode60->getId()));
Dominik Laskowski66295432023-03-14 12:25:36 -0400188
189 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId1)->getPendingHardwareVsyncState());
190 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId2)->getPendingHardwareVsyncState());
191 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId3)->getPendingHardwareVsyncState());
Dominik Laskowski008bec02023-03-14 12:04:58 -0400192}
193
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200194TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) {
195 // The layer is registered at creation time and deregistered at destruction time.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700196 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700197
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200198 // recordLayerHistory should be a noop
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700199 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000200 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
201 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700202 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700203
Rachel Lee6a9731d2022-06-06 17:08:14 -0700204 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500205 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700206
207 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700208 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700209
ramindani69b58e82022-09-26 16:48:36 -0700210 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700211 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
212 /*updateAttachedChoreographer*/ false);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700213}
214
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200215TEST_F(SchedulerTest, updateDisplayModes) {
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700216 ASSERT_EQ(0u, mScheduler->layerHistorySize());
Dominik Laskowski068173d2021-08-11 17:22:59 -0700217 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700218 ASSERT_EQ(1u, mScheduler->layerHistorySize());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200219
Dominik Laskowski596a2562022-10-28 11:26:12 -0400220 // Replace `mSelector` with a new `RefreshRateSelector` that has different display modes.
221 mScheduler->registerDisplay(kDisplayId1,
222 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
223 kDisplay1Mode60->getId()));
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200224
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700225 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000226 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
227 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700228 ASSERT_EQ(1u, mScheduler->getNumActiveLayers());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200229}
230
Dominik Laskowski068173d2021-08-11 17:22:59 -0700231TEST_F(SchedulerTest, dispatchCachedReportedMode) {
232 mScheduler->clearCachedReportedMode();
233
Ady Abraham690f4612021-07-01 23:24:03 -0700234 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Dominik Laskowski068173d2021-08-11 17:22:59 -0700235 EXPECT_NO_FATAL_FAILURE(mScheduler->dispatchCachedReportedMode());
Ana Krulec6ddd2612020-09-24 13:06:33 -0700236}
237
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100238TEST_F(SchedulerTest, onNonPrimaryDisplayModeChanged_invalidParameters) {
Ady Abraham690f4612021-07-01 23:24:03 -0700239 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
240 .setId(DisplayModeId(111))
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400241 .setPhysicalDisplayId(kDisplayId1)
Ady Abraham690f4612021-07-01 23:24:03 -0700242 .setVsyncPeriod(111111)
243 .build();
Ana Krulec6ddd2612020-09-24 13:06:33 -0700244
245 // If the handle is incorrect, the function should return before
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100246 // onModeChange is called.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700247 ConnectionHandle invalidHandle = {.id = 123};
Ady Abrahamace3d052022-11-17 16:25:05 -0800248 EXPECT_NO_FATAL_FAILURE(
249 mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle,
250 {90_Hz, ftl::as_non_null(mode)}));
Ady Abraham690f4612021-07-01 23:24:03 -0700251 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Ana Krulec6ddd2612020-09-24 13:06:33 -0700252}
253
Ady Abraham899dcdb2021-06-15 16:56:21 -0700254TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700255 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms));
256 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms));
257 EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(120_Hz, 30ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800258
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700259 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 40ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800260
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700261 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Piquea1456c12023-05-17 12:11:15 -0700262
Lloyd Pique30db6402023-06-26 18:56:51 +0000263 const auto savedMinAcquiredBuffers = mFlinger.mutableMinAcquiredBuffers();
264 mFlinger.mutableMinAcquiredBuffers() = 2;
Lloyd Piquea1456c12023-05-17 12:11:15 -0700265 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Pique30db6402023-06-26 18:56:51 +0000266 mFlinger.mutableMinAcquiredBuffers() = savedMinAcquiredBuffers;
Ady Abraham564f9de2021-02-03 18:34:33 -0800267}
268
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200269MATCHER(Is120Hz, "") {
Ady Abrahamace3d052022-11-17 16:25:05 -0800270 return isApproxEqual(arg.front().mode.fps, 120_Hz);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200271}
272
273TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
Dominik Laskowski596a2562022-10-28 11:26:12 -0400274 mScheduler->registerDisplay(kDisplayId1,
275 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
276 kDisplay1Mode60->getId()));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200277
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800278 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
279 EXPECT_CALL(*layer, isVisible()).WillOnce(Return(true));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200280
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000281 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
282 LayerHistory::LayerUpdateType::Buffer);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200283
Rachel Lee6a9731d2022-06-06 17:08:14 -0700284 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500285 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200286
287 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700288 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200289
ramindani69b58e82022-09-26 16:48:36 -0700290 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(Is120Hz())).Times(1);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700291 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
292 /*updateAttachedChoreographer*/ false);
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800293
294 // No-op if layer requirements have not changed.
ramindani69b58e82022-09-26 16:48:36 -0700295 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700296 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
297 /*updateAttachedChoreographer*/ false);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200298}
299
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400300TEST_F(SchedulerTest, chooseDisplayModesSingleDisplay) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400301 mScheduler->registerDisplay(kDisplayId1,
302 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
303 kDisplay1Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700304
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400305 std::vector<RefreshRateSelector::LayerRequirement> layers =
306 std::vector<RefreshRateSelector::LayerRequirement>({{.weight = 1.f}, {.weight = 1.f}});
ramindani69b58e82022-09-26 16:48:36 -0700307 mScheduler->setContentRequirements(layers);
308 GlobalSignals globalSignals = {.idle = true};
309 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
310
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400311 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
312
313 auto modeChoices = mScheduler->chooseDisplayModes();
314 ASSERT_EQ(1u, modeChoices.size());
315
316 auto choice = modeChoices.get(kDisplayId1);
317 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800318 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700319
320 globalSignals = {.idle = false};
321 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400322
323 modeChoices = mScheduler->chooseDisplayModes();
324 ASSERT_EQ(1u, modeChoices.size());
325
326 choice = modeChoices.get(kDisplayId1);
327 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800328 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700329
330 globalSignals = {.touch = true};
331 mScheduler->replaceTouchTimer(10);
332 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700333
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400334 modeChoices = mScheduler->chooseDisplayModes();
335 ASSERT_EQ(1u, modeChoices.size());
336
337 choice = modeChoices.get(kDisplayId1);
338 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800339 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700340}
341
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400342TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400343 mScheduler->registerDisplay(kDisplayId1,
344 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
345 kDisplay1Mode60->getId()));
346 mScheduler->registerDisplay(kDisplayId2,
347 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
348 kDisplay2Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700349
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400350 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
351 TestableScheduler::DisplayModeChoiceMap expectedChoices;
ramindani69b58e82022-09-26 16:48:36 -0700352
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400353 {
354 const GlobalSignals globalSignals = {.idle = true};
355 expectedChoices =
356 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800357 DisplayModeChoice>(kDisplayId1,
358 FrameRateMode{60_Hz, kDisplay1Mode60},
359 globalSignals)(kDisplayId2,
360 FrameRateMode{60_Hz,
361 kDisplay2Mode60},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400362 globalSignals);
363
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400364 std::vector<RefreshRateSelector::LayerRequirement> layers = {{.weight = 1.f},
365 {.weight = 1.f}};
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400366 mScheduler->setContentRequirements(layers);
367 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
368
369 const auto actualChoices = mScheduler->chooseDisplayModes();
370 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700371 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400372 {
373 const GlobalSignals globalSignals = {.idle = false};
374 expectedChoices =
375 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800376 DisplayModeChoice>(kDisplayId1,
377 FrameRateMode{120_Hz, kDisplay1Mode120},
378 globalSignals)(kDisplayId2,
379 FrameRateMode{120_Hz,
380 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400381 globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700382
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400383 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700384
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400385 const auto actualChoices = mScheduler->chooseDisplayModes();
386 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700387 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400388 {
389 const GlobalSignals globalSignals = {.touch = true};
390 mScheduler->replaceTouchTimer(10);
391 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700392
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400393 expectedChoices =
394 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800395 DisplayModeChoice>(kDisplayId1,
396 FrameRateMode{120_Hz, kDisplay1Mode120},
397 globalSignals)(kDisplayId2,
398 FrameRateMode{120_Hz,
399 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400400 globalSignals);
401
402 const auto actualChoices = mScheduler->chooseDisplayModes();
403 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700404 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400405 {
ramindani22f2ead2023-04-21 10:27:11 -0700406 // The kDisplayId3 does not support 120Hz, The pacesetter display rate is chosen to be 120
407 // Hz. In this case only the display kDisplayId3 choose 60Hz as it does not support 120Hz.
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400408 mScheduler
409 ->registerDisplay(kDisplayId3,
410 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
411 kDisplay3Mode60->getId()));
Dominik Laskowski327d6092022-10-11 18:05:08 -0400412
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400413 const GlobalSignals globalSignals = {.touch = true};
414 mScheduler->replaceTouchTimer(10);
415 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani7c487282022-10-10 16:17:51 -0700416
Ady Abrahamace3d052022-11-17 16:25:05 -0800417 expectedChoices = ftl::init::map<
418 const PhysicalDisplayId&,
ramindani22f2ead2023-04-21 10:27:11 -0700419 DisplayModeChoice>(kDisplayId1, FrameRateMode{120_Hz, kDisplay1Mode120},
420 globalSignals)(kDisplayId2,
421 FrameRateMode{120_Hz, kDisplay2Mode120},
422 globalSignals)(kDisplayId3,
423 FrameRateMode{60_Hz,
424 kDisplay3Mode60},
425 globalSignals);
426
427 const auto actualChoices = mScheduler->chooseDisplayModes();
428 EXPECT_EQ(expectedChoices, actualChoices);
429 }
430 {
431 // We should choose 60Hz despite the touch signal as pacesetter only supports 60Hz
432 mScheduler->setPacesetterDisplay(kDisplayId3);
433 const GlobalSignals globalSignals = {.touch = true};
434 mScheduler->replaceTouchTimer(10);
435 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
436
437 expectedChoices = ftl::init::map<
438 const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800439 DisplayModeChoice>(kDisplayId1, FrameRateMode{60_Hz, kDisplay1Mode60},
440 globalSignals)(kDisplayId2,
441 FrameRateMode{60_Hz, kDisplay2Mode60},
442 globalSignals)(kDisplayId3,
443 FrameRateMode{60_Hz,
444 kDisplay3Mode60},
445 globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400446
447 const auto actualChoices = mScheduler->chooseDisplayModes();
448 EXPECT_EQ(expectedChoices, actualChoices);
ramindani7c487282022-10-10 16:17:51 -0700449 }
ramindani69b58e82022-09-26 16:48:36 -0700450}
451
Ady Abraham822ecbd2023-07-07 16:16:09 -0700452class AttachedChoreographerTest : public SchedulerTest {
453protected:
454 void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
455 Fps expectedChoreographerFps);
456};
457
458TEST_F(AttachedChoreographerTest, registerSingle) {
459 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
460
461 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
462
463 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
464 const sp<IDisplayEventConnection> connection =
465 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
466
467 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
468 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
469 EXPECT_EQ(1u,
470 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
471 EXPECT_FALSE(
472 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
473}
474
475TEST_F(AttachedChoreographerTest, registerMultipleOnSameLayer) {
476 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
477
478 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
479 const auto handle = layer->getHandle();
480
481 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
482
483 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_))
484 .WillOnce(Return(0))
485 .WillOnce(Return(0));
486
487 const auto mockConnection1 = sp<MockEventThreadConnection>::make(mEventThread);
488 const auto mockConnection2 = sp<MockEventThreadConnection>::make(mEventThread);
489 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
490 .WillOnce(Return(mockConnection1))
491 .WillOnce(Return(mockConnection2));
492
493 const sp<IDisplayEventConnection> connection1 =
494 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
495 const sp<IDisplayEventConnection> connection2 =
496 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
497
498 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
499 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
500 EXPECT_EQ(2u,
501 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
502 EXPECT_FALSE(
503 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
504}
505
506TEST_F(AttachedChoreographerTest, registerMultipleOnDifferentLayers) {
507 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
508
509 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
510 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
511
512 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
513 const sp<IDisplayEventConnection> connection1 =
514 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer1->getHandle());
515 const sp<IDisplayEventConnection> connection2 =
516 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer2->getHandle());
517
518 EXPECT_EQ(2u, mScheduler->mutableAttachedChoreographers().size());
519
520 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer1->getSequence()));
521 EXPECT_EQ(1u,
522 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()]
523 .connections.size());
524 EXPECT_FALSE(
525 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()].frameRate.isValid());
526
527 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer2->getSequence()));
528 EXPECT_EQ(1u,
529 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()]
530 .connections.size());
531 EXPECT_FALSE(
532 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()].frameRate.isValid());
533}
534
535TEST_F(AttachedChoreographerTest, removedWhenConnectionIsGone) {
536 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
537
538 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
539
540 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
541
542 sp<IDisplayEventConnection> connection =
543 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
544
545 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
546 EXPECT_EQ(1u,
547 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
548
549 // The connection is used all over this test, so it is quite hard to release it from here.
550 // Instead, we just do a small shortcut.
551 {
552 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
553 sp<MockEventThreadConnection> mockConnection =
554 sp<MockEventThreadConnection>::make(mEventThread);
555 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.clear();
556 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.emplace(
557 mockConnection);
558 }
559
560 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
561 LayerHierarchy hierarchy(&layerState);
562 mScheduler->updateAttachedChoreographers(hierarchy, 60_Hz);
563 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
564}
565
566TEST_F(AttachedChoreographerTest, removedWhenLayerIsGone) {
567 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
568
569 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
570
571 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
572 const sp<IDisplayEventConnection> connection =
573 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
574
575 layer.clear();
576 mFlinger.mutableLayersPendingRemoval().clear();
577 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
578}
579
580void AttachedChoreographerTest::frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility,
581 Fps displayFps,
582 Fps expectedChoreographerFps) {
583 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
584
585 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
586 sp<IDisplayEventConnection> connection =
587 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
588
589 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
590 LayerHierarchy hierarchy(&layerState);
591
592 layerState.frameRate = layerFps.getValue();
593 layerState.frameRateCompatibility = frameRateCompatibility;
594
595 mScheduler->updateAttachedChoreographers(hierarchy, displayFps);
596
597 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
598 EXPECT_EQ(expectedChoreographerFps,
599 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
600 EXPECT_EQ(expectedChoreographerFps, mEventThreadConnection->frameRate);
601}
602
603TEST_F(AttachedChoreographerTest, setsFrameRateDefault) {
604 Fps layerFps = 30_Hz;
605 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
606 Fps displayFps = 60_Hz;
607 Fps expectedChoreographerFps = 30_Hz;
608
609 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
610
611 layerFps = Fps::fromValue(32.7f);
612 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
613}
614
615TEST_F(AttachedChoreographerTest, setsFrameRateExact) {
616 Fps layerFps = 30_Hz;
617 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_EXACT;
618 Fps displayFps = 60_Hz;
619 Fps expectedChoreographerFps = 30_Hz;
620
621 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
622
623 layerFps = Fps::fromValue(32.7f);
624 expectedChoreographerFps = {};
625 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
626}
627
628TEST_F(AttachedChoreographerTest, setsFrameRateExactOrMultiple) {
629 Fps layerFps = 30_Hz;
630 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
631 Fps displayFps = 60_Hz;
632 Fps expectedChoreographerFps = 30_Hz;
633
634 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
635
636 layerFps = Fps::fromValue(32.7f);
637 expectedChoreographerFps = {};
638 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
639}
640
641TEST_F(AttachedChoreographerTest, setsFrameRateParent) {
642 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
643 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
644
645 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
646 sp<IDisplayEventConnection> connection =
647 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
648
649 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
650 LayerHierarchy parentHierarchy(&parentState);
651
652 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
653 LayerHierarchy hierarchy(&layerState);
654 parentHierarchy.mChildren.push_back(
655 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
656
657 layerState.frameRate = (30_Hz).getValue();
658 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
659
660 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
661
662 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
663
664 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
665}
666
667TEST_F(AttachedChoreographerTest, setsFrameRateParent2Children) {
668 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
669 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
670 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
671
672 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
673 sp<IDisplayEventConnection> connection =
674 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
675
676 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
677 LayerHierarchy parentHierarchy(&parentState);
678
679 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
680 LayerHierarchy layer1Hierarchy(&layer1State);
681 parentHierarchy.mChildren.push_back(
682 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
683
684 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
685 LayerHierarchy layer2Hierarchy(&layer2State);
686 parentHierarchy.mChildren.push_back(
687 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
688
689 layer1State.frameRate = (30_Hz).getValue();
690 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
691
692 layer2State.frameRate = (20_Hz).getValue();
693 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
694
695 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
696
697 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
698
699 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
700}
701
702TEST_F(AttachedChoreographerTest, setsFrameRateParentConflictingChildren) {
703 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
704 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
705 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
706
707 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
708 sp<IDisplayEventConnection> connection =
709 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
710
711 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
712 LayerHierarchy parentHierarchy(&parentState);
713
714 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
715 LayerHierarchy layer1Hierarchy(&layer1State);
716 parentHierarchy.mChildren.push_back(
717 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
718
719 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
720 LayerHierarchy layer2Hierarchy(&layer2State);
721 parentHierarchy.mChildren.push_back(
722 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
723
724 layer1State.frameRate = (30_Hz).getValue();
725 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
726
727 layer2State.frameRate = (25_Hz).getValue();
728 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
729
730 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
731
732 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
733
734 EXPECT_EQ(Fps(), mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
735}
736
737TEST_F(AttachedChoreographerTest, setsFrameRateChild) {
738 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
739 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
740
741 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
742 sp<IDisplayEventConnection> connection =
743 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
744
745 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
746 LayerHierarchy parentHierarchy(&parentState);
747
748 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
749 LayerHierarchy hierarchy(&layerState);
750 parentHierarchy.mChildren.push_back(
751 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
752
753 parentState.frameRate = (30_Hz).getValue();
754 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
755
756 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
757
758 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
759
760 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
761}
762
763TEST_F(AttachedChoreographerTest, setsFrameRateChildNotOverriddenByParent) {
764 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
765 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
766
767 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
768 sp<IDisplayEventConnection> connection =
769 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
770
771 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
772 LayerHierarchy parentHierarchy(&parentState);
773
774 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
775 LayerHierarchy hierarchy(&layerState);
776 parentHierarchy.mChildren.push_back(
777 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
778
779 parentState.frameRate = (30_Hz).getValue();
780 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
781
782 layerState.frameRate = (60_Hz).getValue();
783 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
784
785 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
786
787 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
788
789 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
790}
791
Dominik Laskowski068173d2021-08-11 17:22:59 -0700792} // namespace android::scheduler