blob: 0df41ed422ba093c55c228398df3f1f3a18425b8 [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;
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040092 TestableScheduler* mScheduler = new TestableScheduler{mSelector, mSchedulerCallback};
Ady Abraham822ecbd2023-07-07 16:16:09 -070093 surfaceflinger::frontend::LayerHierarchyBuilder mLayerHierarchyBuilder{{}};
Dominik Laskowski98041832019-08-01 18:35:59 -070094
Dominik Laskowski068173d2021-08-11 17:22:59 -070095 ConnectionHandle mConnectionHandle;
96 MockEventThread* mEventThread;
Ana Krulec0c8cd522018-08-31 12:27:28 -070097 sp<MockEventThreadConnection> mEventThreadConnection;
Ady Abraham564f9de2021-02-03 18:34:33 -080098
99 TestableSurfaceFlinger mFlinger;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700100};
101
102SchedulerTest::SchedulerTest() {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700103 auto eventThread = std::make_unique<MockEventThread>();
Ana Krulec0c8cd522018-08-31 12:27:28 -0700104 mEventThread = eventThread.get();
Ana Krulec85c39af2018-12-26 17:29:57 -0800105 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
106
Ady Abrahamd11bade2022-08-01 16:18:03 -0700107 mEventThreadConnection = sp<MockEventThreadConnection>::make(mEventThread);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700108
109 // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
110 // sure that call gets executed and returns an EventThread::Connection object.
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700111 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
Ana Krulec0c8cd522018-08-31 12:27:28 -0700112 .WillRepeatedly(Return(mEventThreadConnection));
113
Ady Abrahama0a16272021-03-03 15:23:35 -0800114 mConnectionHandle = mScheduler->createConnection(std::move(eventThread));
Dominik Laskowski98041832019-08-01 18:35:59 -0700115 EXPECT_TRUE(mConnectionHandle);
Ady Abrahama0a16272021-03-03 15:23:35 -0800116
117 mFlinger.resetScheduler(mScheduler);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700118}
119
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700120} // namespace
Ana Krulec0c8cd522018-08-31 12:27:28 -0700121
Ana Krulec0c8cd522018-08-31 12:27:28 -0700122TEST_F(SchedulerTest, invalidConnectionHandle) {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700123 ConnectionHandle handle;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700124
Ady Abrahama0a16272021-03-03 15:23:35 -0800125 const sp<IDisplayEventConnection> connection = mScheduler->createDisplayEventConnection(handle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700126
Dominik Laskowski98041832019-08-01 18:35:59 -0700127 EXPECT_FALSE(connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800128 EXPECT_FALSE(mScheduler->getEventConnection(handle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700129
130 // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads.
131 EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400132 mScheduler->onHotplugReceived(handle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700133
Dominik Laskowski98041832019-08-01 18:35:59 -0700134 std::string output;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700135 EXPECT_CALL(*mEventThread, dump(_)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800136 mScheduler->dump(handle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700137 EXPECT_TRUE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700138
Ady Abraham9c53ee72020-07-22 21:16:18 -0700139 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800140 mScheduler->setDuration(handle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700141}
142
143TEST_F(SchedulerTest, validConnectionHandle) {
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700144 const sp<IDisplayEventConnection> connection =
Ady Abrahama0a16272021-03-03 15:23:35 -0800145 mScheduler->createDisplayEventConnection(mConnectionHandle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700146
Dominik Laskowski98041832019-08-01 18:35:59 -0700147 ASSERT_EQ(mEventThreadConnection, connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800148 EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700149
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400150 EXPECT_CALL(*mEventThread, onHotplugReceived(kDisplayId1, false)).Times(1);
151 mScheduler->onHotplugReceived(mConnectionHandle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700152
Dominik Laskowski98041832019-08-01 18:35:59 -0700153 std::string output("dump");
154 EXPECT_CALL(*mEventThread, dump(output)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800155 mScheduler->dump(mConnectionHandle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700156 EXPECT_FALSE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700157
Ady Abraham9c53ee72020-07-22 21:16:18 -0700158 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800159 mScheduler->setDuration(mConnectionHandle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700160}
Dominik Laskowski98041832019-08-01 18:35:59 -0700161
Dominik Laskowski66295432023-03-14 12:25:36 -0400162TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) {
Dominik Laskowski008bec02023-03-14 12:04:58 -0400163 // Hardware VSYNC should not change if the display is already registered.
Dominik Laskowski66295432023-03-14 12:25:36 -0400164 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId1, false)).Times(0);
Dominik Laskowski008bec02023-03-14 12:04:58 -0400165 mScheduler->registerDisplay(kDisplayId1,
166 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
167 kDisplay1Mode60->getId()));
168
Dominik Laskowski66295432023-03-14 12:25:36 -0400169 // TODO(b/241285191): Restore once VsyncSchedule::getPendingHardwareVsyncState is called by
170 // Scheduler::setDisplayPowerMode rather than SF::setPowerModeInternal.
171#if 0
Dominik Laskowski008bec02023-03-14 12:04:58 -0400172 // Hardware VSYNC should be disabled for newly registered displays.
Dominik Laskowski66295432023-03-14 12:25:36 -0400173 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId2, false)).Times(1);
174 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId3, false)).Times(1);
175#endif
Dominik Laskowski008bec02023-03-14 12:04:58 -0400176
177 mScheduler->registerDisplay(kDisplayId2,
178 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
179 kDisplay2Mode60->getId()));
180 mScheduler->registerDisplay(kDisplayId3,
181 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
182 kDisplay3Mode60->getId()));
Dominik Laskowski66295432023-03-14 12:25:36 -0400183
184 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId1)->getPendingHardwareVsyncState());
185 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId2)->getPendingHardwareVsyncState());
186 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId3)->getPendingHardwareVsyncState());
Dominik Laskowski008bec02023-03-14 12:04:58 -0400187}
188
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200189TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) {
190 // The layer is registered at creation time and deregistered at destruction time.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700191 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700192
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200193 // recordLayerHistory should be a noop
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700194 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000195 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
196 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700197 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700198
Rachel Lee6a9731d2022-06-06 17:08:14 -0700199 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500200 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700201
202 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700203 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700204
ramindani69b58e82022-09-26 16:48:36 -0700205 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700206 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
207 /*updateAttachedChoreographer*/ false);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700208}
209
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200210TEST_F(SchedulerTest, updateDisplayModes) {
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700211 ASSERT_EQ(0u, mScheduler->layerHistorySize());
Dominik Laskowski068173d2021-08-11 17:22:59 -0700212 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700213 ASSERT_EQ(1u, mScheduler->layerHistorySize());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200214
Dominik Laskowski596a2562022-10-28 11:26:12 -0400215 // Replace `mSelector` with a new `RefreshRateSelector` that has different display modes.
216 mScheduler->registerDisplay(kDisplayId1,
217 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
218 kDisplay1Mode60->getId()));
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200219
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700220 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000221 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
222 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700223 ASSERT_EQ(1u, mScheduler->getNumActiveLayers());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200224}
225
Dominik Laskowski068173d2021-08-11 17:22:59 -0700226TEST_F(SchedulerTest, dispatchCachedReportedMode) {
227 mScheduler->clearCachedReportedMode();
228
Ady Abraham690f4612021-07-01 23:24:03 -0700229 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Dominik Laskowski068173d2021-08-11 17:22:59 -0700230 EXPECT_NO_FATAL_FAILURE(mScheduler->dispatchCachedReportedMode());
Ana Krulec6ddd2612020-09-24 13:06:33 -0700231}
232
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100233TEST_F(SchedulerTest, onNonPrimaryDisplayModeChanged_invalidParameters) {
Ady Abraham690f4612021-07-01 23:24:03 -0700234 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
235 .setId(DisplayModeId(111))
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400236 .setPhysicalDisplayId(kDisplayId1)
Ady Abraham690f4612021-07-01 23:24:03 -0700237 .setVsyncPeriod(111111)
238 .build();
Ana Krulec6ddd2612020-09-24 13:06:33 -0700239
240 // If the handle is incorrect, the function should return before
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100241 // onModeChange is called.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700242 ConnectionHandle invalidHandle = {.id = 123};
Ady Abrahamace3d052022-11-17 16:25:05 -0800243 EXPECT_NO_FATAL_FAILURE(
244 mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle,
245 {90_Hz, ftl::as_non_null(mode)}));
Ady Abraham690f4612021-07-01 23:24:03 -0700246 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Ana Krulec6ddd2612020-09-24 13:06:33 -0700247}
248
Ady Abraham899dcdb2021-06-15 16:56:21 -0700249TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700250 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms));
251 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms));
252 EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(120_Hz, 30ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800253
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700254 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 40ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800255
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700256 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Piquea1456c12023-05-17 12:11:15 -0700257
Lloyd Pique30db6402023-06-26 18:56:51 +0000258 const auto savedMinAcquiredBuffers = mFlinger.mutableMinAcquiredBuffers();
259 mFlinger.mutableMinAcquiredBuffers() = 2;
Lloyd Piquea1456c12023-05-17 12:11:15 -0700260 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Pique30db6402023-06-26 18:56:51 +0000261 mFlinger.mutableMinAcquiredBuffers() = savedMinAcquiredBuffers;
Ady Abraham564f9de2021-02-03 18:34:33 -0800262}
263
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200264MATCHER(Is120Hz, "") {
Ady Abrahamace3d052022-11-17 16:25:05 -0800265 return isApproxEqual(arg.front().mode.fps, 120_Hz);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200266}
267
268TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
Dominik Laskowski596a2562022-10-28 11:26:12 -0400269 mScheduler->registerDisplay(kDisplayId1,
270 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
271 kDisplay1Mode60->getId()));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200272
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800273 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
274 EXPECT_CALL(*layer, isVisible()).WillOnce(Return(true));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200275
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000276 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0,
277 LayerHistory::LayerUpdateType::Buffer);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200278
Rachel Lee6a9731d2022-06-06 17:08:14 -0700279 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500280 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200281
282 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700283 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200284
ramindani69b58e82022-09-26 16:48:36 -0700285 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(Is120Hz())).Times(1);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700286 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
287 /*updateAttachedChoreographer*/ false);
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800288
289 // No-op if layer requirements have not changed.
ramindani69b58e82022-09-26 16:48:36 -0700290 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700291 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
292 /*updateAttachedChoreographer*/ false);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200293}
294
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400295TEST_F(SchedulerTest, chooseDisplayModesSingleDisplay) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400296 mScheduler->registerDisplay(kDisplayId1,
297 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
298 kDisplay1Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700299
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400300 std::vector<RefreshRateSelector::LayerRequirement> layers =
301 std::vector<RefreshRateSelector::LayerRequirement>({{.weight = 1.f}, {.weight = 1.f}});
ramindani69b58e82022-09-26 16:48:36 -0700302 mScheduler->setContentRequirements(layers);
303 GlobalSignals globalSignals = {.idle = true};
304 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
305
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400306 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
307
308 auto modeChoices = mScheduler->chooseDisplayModes();
309 ASSERT_EQ(1u, modeChoices.size());
310
311 auto choice = modeChoices.get(kDisplayId1);
312 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800313 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700314
315 globalSignals = {.idle = false};
316 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400317
318 modeChoices = mScheduler->chooseDisplayModes();
319 ASSERT_EQ(1u, modeChoices.size());
320
321 choice = modeChoices.get(kDisplayId1);
322 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800323 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700324
325 globalSignals = {.touch = true};
326 mScheduler->replaceTouchTimer(10);
327 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700328
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400329 modeChoices = mScheduler->chooseDisplayModes();
330 ASSERT_EQ(1u, modeChoices.size());
331
332 choice = modeChoices.get(kDisplayId1);
333 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800334 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700335}
336
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400337TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400338 mScheduler->registerDisplay(kDisplayId1,
339 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
340 kDisplay1Mode60->getId()));
341 mScheduler->registerDisplay(kDisplayId2,
342 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
343 kDisplay2Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700344
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400345 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
346 TestableScheduler::DisplayModeChoiceMap expectedChoices;
ramindani69b58e82022-09-26 16:48:36 -0700347
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400348 {
349 const GlobalSignals globalSignals = {.idle = true};
350 expectedChoices =
351 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800352 DisplayModeChoice>(kDisplayId1,
353 FrameRateMode{60_Hz, kDisplay1Mode60},
354 globalSignals)(kDisplayId2,
355 FrameRateMode{60_Hz,
356 kDisplay2Mode60},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400357 globalSignals);
358
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400359 std::vector<RefreshRateSelector::LayerRequirement> layers = {{.weight = 1.f},
360 {.weight = 1.f}};
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400361 mScheduler->setContentRequirements(layers);
362 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
363
364 const auto actualChoices = mScheduler->chooseDisplayModes();
365 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700366 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400367 {
368 const GlobalSignals globalSignals = {.idle = false};
369 expectedChoices =
370 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800371 DisplayModeChoice>(kDisplayId1,
372 FrameRateMode{120_Hz, kDisplay1Mode120},
373 globalSignals)(kDisplayId2,
374 FrameRateMode{120_Hz,
375 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400376 globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700377
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400378 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700379
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400380 const auto actualChoices = mScheduler->chooseDisplayModes();
381 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700382 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400383 {
384 const GlobalSignals globalSignals = {.touch = true};
385 mScheduler->replaceTouchTimer(10);
386 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700387
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400388 expectedChoices =
389 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800390 DisplayModeChoice>(kDisplayId1,
391 FrameRateMode{120_Hz, kDisplay1Mode120},
392 globalSignals)(kDisplayId2,
393 FrameRateMode{120_Hz,
394 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400395 globalSignals);
396
397 const auto actualChoices = mScheduler->chooseDisplayModes();
398 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700399 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400400 {
ramindani22f2ead2023-04-21 10:27:11 -0700401 // The kDisplayId3 does not support 120Hz, The pacesetter display rate is chosen to be 120
402 // Hz. In this case only the display kDisplayId3 choose 60Hz as it does not support 120Hz.
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400403 mScheduler
404 ->registerDisplay(kDisplayId3,
405 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
406 kDisplay3Mode60->getId()));
Dominik Laskowski327d6092022-10-11 18:05:08 -0400407
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400408 const GlobalSignals globalSignals = {.touch = true};
409 mScheduler->replaceTouchTimer(10);
410 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani7c487282022-10-10 16:17:51 -0700411
Ady Abrahamace3d052022-11-17 16:25:05 -0800412 expectedChoices = ftl::init::map<
413 const PhysicalDisplayId&,
ramindani22f2ead2023-04-21 10:27:11 -0700414 DisplayModeChoice>(kDisplayId1, FrameRateMode{120_Hz, kDisplay1Mode120},
415 globalSignals)(kDisplayId2,
416 FrameRateMode{120_Hz, kDisplay2Mode120},
417 globalSignals)(kDisplayId3,
418 FrameRateMode{60_Hz,
419 kDisplay3Mode60},
420 globalSignals);
421
422 const auto actualChoices = mScheduler->chooseDisplayModes();
423 EXPECT_EQ(expectedChoices, actualChoices);
424 }
425 {
426 // We should choose 60Hz despite the touch signal as pacesetter only supports 60Hz
427 mScheduler->setPacesetterDisplay(kDisplayId3);
428 const GlobalSignals globalSignals = {.touch = true};
429 mScheduler->replaceTouchTimer(10);
430 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
431
432 expectedChoices = ftl::init::map<
433 const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800434 DisplayModeChoice>(kDisplayId1, FrameRateMode{60_Hz, kDisplay1Mode60},
435 globalSignals)(kDisplayId2,
436 FrameRateMode{60_Hz, kDisplay2Mode60},
437 globalSignals)(kDisplayId3,
438 FrameRateMode{60_Hz,
439 kDisplay3Mode60},
440 globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400441
442 const auto actualChoices = mScheduler->chooseDisplayModes();
443 EXPECT_EQ(expectedChoices, actualChoices);
ramindani7c487282022-10-10 16:17:51 -0700444 }
ramindani69b58e82022-09-26 16:48:36 -0700445}
446
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400447TEST_F(SchedulerTest, onFrameSignalMultipleDisplays) {
448 mScheduler->registerDisplay(kDisplayId1,
449 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
450 kDisplay1Mode60->getId()));
451 mScheduler->registerDisplay(kDisplayId2,
452 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
453 kDisplay2Mode60->getId()));
454
455 using VsyncIds = std::vector<std::pair<PhysicalDisplayId, VsyncId>>;
456
457 struct Compositor final : ICompositor {
458 VsyncIds vsyncIds;
459 bool committed = true;
460
461 void configure() override {}
462
463 bool commit(PhysicalDisplayId, const scheduler::FrameTargets& targets) override {
464 vsyncIds.clear();
465
466 for (const auto& [id, target] : targets) {
467 vsyncIds.emplace_back(id, target->vsyncId());
468 }
469
470 return committed;
471 }
472
473 CompositeResultsPerDisplay composite(PhysicalDisplayId,
474 const scheduler::FrameTargeters&) override {
475 CompositeResultsPerDisplay results;
476
477 for (const auto& [id, _] : vsyncIds) {
478 results.try_emplace(id,
479 CompositeResult{.compositionCoverage =
480 CompositionCoverage::Hwc});
481 }
482
483 return results;
484 }
485
486 void sample() override {}
487 } compositor;
488
489 mScheduler->doFrameSignal(compositor, VsyncId(42));
490
491 const auto makeVsyncIds = [](VsyncId vsyncId) -> VsyncIds {
492 return {{kDisplayId1, vsyncId}, {kDisplayId2, vsyncId}};
493 };
494
495 EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds);
496
497 compositor.committed = false;
498 mScheduler->doFrameSignal(compositor, VsyncId(43));
499
500 // FrameTargets should be updated despite the skipped commit.
501 EXPECT_EQ(makeVsyncIds(VsyncId(43)), compositor.vsyncIds);
502}
503
Ady Abraham822ecbd2023-07-07 16:16:09 -0700504class AttachedChoreographerTest : public SchedulerTest {
505protected:
506 void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
507 Fps expectedChoreographerFps);
508};
509
510TEST_F(AttachedChoreographerTest, registerSingle) {
511 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
512
513 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
514
515 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
516 const sp<IDisplayEventConnection> connection =
517 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
518
519 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
520 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
521 EXPECT_EQ(1u,
522 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
523 EXPECT_FALSE(
524 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
525}
526
527TEST_F(AttachedChoreographerTest, registerMultipleOnSameLayer) {
528 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
529
530 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
531 const auto handle = layer->getHandle();
532
533 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
534
535 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_))
536 .WillOnce(Return(0))
537 .WillOnce(Return(0));
538
539 const auto mockConnection1 = sp<MockEventThreadConnection>::make(mEventThread);
540 const auto mockConnection2 = sp<MockEventThreadConnection>::make(mEventThread);
541 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
542 .WillOnce(Return(mockConnection1))
543 .WillOnce(Return(mockConnection2));
544
545 const sp<IDisplayEventConnection> connection1 =
546 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
547 const sp<IDisplayEventConnection> connection2 =
548 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
549
550 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
551 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
552 EXPECT_EQ(2u,
553 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
554 EXPECT_FALSE(
555 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
556}
557
558TEST_F(AttachedChoreographerTest, registerMultipleOnDifferentLayers) {
559 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
560
561 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
562 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
563
564 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
565 const sp<IDisplayEventConnection> connection1 =
566 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer1->getHandle());
567 const sp<IDisplayEventConnection> connection2 =
568 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer2->getHandle());
569
570 EXPECT_EQ(2u, mScheduler->mutableAttachedChoreographers().size());
571
572 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer1->getSequence()));
573 EXPECT_EQ(1u,
574 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()]
575 .connections.size());
576 EXPECT_FALSE(
577 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()].frameRate.isValid());
578
579 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer2->getSequence()));
580 EXPECT_EQ(1u,
581 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()]
582 .connections.size());
583 EXPECT_FALSE(
584 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()].frameRate.isValid());
585}
586
587TEST_F(AttachedChoreographerTest, removedWhenConnectionIsGone) {
588 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
589
590 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
591
592 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
593
594 sp<IDisplayEventConnection> connection =
595 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
596
597 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
598 EXPECT_EQ(1u,
599 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
600
601 // The connection is used all over this test, so it is quite hard to release it from here.
602 // Instead, we just do a small shortcut.
603 {
604 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
605 sp<MockEventThreadConnection> mockConnection =
606 sp<MockEventThreadConnection>::make(mEventThread);
607 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.clear();
608 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.emplace(
609 mockConnection);
610 }
611
612 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
613 LayerHierarchy hierarchy(&layerState);
614 mScheduler->updateAttachedChoreographers(hierarchy, 60_Hz);
615 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
616}
617
618TEST_F(AttachedChoreographerTest, removedWhenLayerIsGone) {
619 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
620
621 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
622
623 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
624 const sp<IDisplayEventConnection> connection =
625 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
626
627 layer.clear();
628 mFlinger.mutableLayersPendingRemoval().clear();
629 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
630}
631
632void AttachedChoreographerTest::frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility,
633 Fps displayFps,
634 Fps expectedChoreographerFps) {
635 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
636
637 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
638 sp<IDisplayEventConnection> connection =
639 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
640
641 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
642 LayerHierarchy hierarchy(&layerState);
643
644 layerState.frameRate = layerFps.getValue();
645 layerState.frameRateCompatibility = frameRateCompatibility;
646
647 mScheduler->updateAttachedChoreographers(hierarchy, displayFps);
648
649 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
650 EXPECT_EQ(expectedChoreographerFps,
651 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
652 EXPECT_EQ(expectedChoreographerFps, mEventThreadConnection->frameRate);
653}
654
655TEST_F(AttachedChoreographerTest, setsFrameRateDefault) {
656 Fps layerFps = 30_Hz;
657 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
658 Fps displayFps = 60_Hz;
659 Fps expectedChoreographerFps = 30_Hz;
660
661 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
662
663 layerFps = Fps::fromValue(32.7f);
664 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
665}
666
667TEST_F(AttachedChoreographerTest, setsFrameRateExact) {
668 Fps layerFps = 30_Hz;
669 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_EXACT;
670 Fps displayFps = 60_Hz;
671 Fps expectedChoreographerFps = 30_Hz;
672
673 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
674
675 layerFps = Fps::fromValue(32.7f);
676 expectedChoreographerFps = {};
677 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
678}
679
680TEST_F(AttachedChoreographerTest, setsFrameRateExactOrMultiple) {
681 Fps layerFps = 30_Hz;
682 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
683 Fps displayFps = 60_Hz;
684 Fps expectedChoreographerFps = 30_Hz;
685
686 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
687
688 layerFps = Fps::fromValue(32.7f);
689 expectedChoreographerFps = {};
690 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
691}
692
693TEST_F(AttachedChoreographerTest, setsFrameRateParent) {
694 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
695 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
696
697 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
698 sp<IDisplayEventConnection> connection =
699 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
700
701 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
702 LayerHierarchy parentHierarchy(&parentState);
703
704 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
705 LayerHierarchy hierarchy(&layerState);
706 parentHierarchy.mChildren.push_back(
707 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
708
709 layerState.frameRate = (30_Hz).getValue();
710 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
711
712 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
713
714 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
715
716 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
717}
718
719TEST_F(AttachedChoreographerTest, setsFrameRateParent2Children) {
720 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
721 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
722 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
723
724 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
725 sp<IDisplayEventConnection> connection =
726 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
727
728 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
729 LayerHierarchy parentHierarchy(&parentState);
730
731 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
732 LayerHierarchy layer1Hierarchy(&layer1State);
733 parentHierarchy.mChildren.push_back(
734 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
735
736 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
737 LayerHierarchy layer2Hierarchy(&layer2State);
738 parentHierarchy.mChildren.push_back(
739 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
740
741 layer1State.frameRate = (30_Hz).getValue();
742 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
743
744 layer2State.frameRate = (20_Hz).getValue();
745 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
746
747 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
748
749 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
750
751 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
752}
753
754TEST_F(AttachedChoreographerTest, setsFrameRateParentConflictingChildren) {
755 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
756 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
757 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
758
759 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
760 sp<IDisplayEventConnection> connection =
761 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
762
763 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
764 LayerHierarchy parentHierarchy(&parentState);
765
766 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
767 LayerHierarchy layer1Hierarchy(&layer1State);
768 parentHierarchy.mChildren.push_back(
769 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
770
771 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
772 LayerHierarchy layer2Hierarchy(&layer2State);
773 parentHierarchy.mChildren.push_back(
774 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
775
776 layer1State.frameRate = (30_Hz).getValue();
777 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
778
779 layer2State.frameRate = (25_Hz).getValue();
780 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
781
782 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
783
784 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
785
786 EXPECT_EQ(Fps(), mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
787}
788
789TEST_F(AttachedChoreographerTest, setsFrameRateChild) {
790 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
791 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
792
793 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
794 sp<IDisplayEventConnection> connection =
795 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
796
797 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
798 LayerHierarchy parentHierarchy(&parentState);
799
800 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
801 LayerHierarchy hierarchy(&layerState);
802 parentHierarchy.mChildren.push_back(
803 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
804
805 parentState.frameRate = (30_Hz).getValue();
806 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
807
808 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
809
810 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
811
812 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
813}
814
815TEST_F(AttachedChoreographerTest, setsFrameRateChildNotOverriddenByParent) {
816 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
817 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
818
819 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
820 sp<IDisplayEventConnection> connection =
821 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
822
823 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
824 LayerHierarchy parentHierarchy(&parentState);
825
826 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
827 LayerHierarchy hierarchy(&layerState);
828 parentHierarchy.mChildren.push_back(
829 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
830
831 parentState.frameRate = (30_Hz).getValue();
832 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
833
834 layerState.frameRate = (60_Hz).getValue();
835 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
836
837 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
838
839 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
840
841 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
842}
843
Dominik Laskowski068173d2021-08-11 17:22:59 -0700844} // namespace android::scheduler