blob: 173f9417b919685f2c0634c4b2e156cab7859330 [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
Ady Abraham822ecbd2023-07-07 16:16:09 -0700447class AttachedChoreographerTest : public SchedulerTest {
448protected:
449 void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
450 Fps expectedChoreographerFps);
451};
452
453TEST_F(AttachedChoreographerTest, registerSingle) {
454 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
455
456 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
457
458 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
459 const sp<IDisplayEventConnection> connection =
460 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
461
462 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
463 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
464 EXPECT_EQ(1u,
465 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
466 EXPECT_FALSE(
467 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
468}
469
470TEST_F(AttachedChoreographerTest, registerMultipleOnSameLayer) {
471 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
472
473 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
474 const auto handle = layer->getHandle();
475
476 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
477
478 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_))
479 .WillOnce(Return(0))
480 .WillOnce(Return(0));
481
482 const auto mockConnection1 = sp<MockEventThreadConnection>::make(mEventThread);
483 const auto mockConnection2 = sp<MockEventThreadConnection>::make(mEventThread);
484 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
485 .WillOnce(Return(mockConnection1))
486 .WillOnce(Return(mockConnection2));
487
488 const sp<IDisplayEventConnection> connection1 =
489 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
490 const sp<IDisplayEventConnection> connection2 =
491 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
492
493 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
494 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
495 EXPECT_EQ(2u,
496 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
497 EXPECT_FALSE(
498 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
499}
500
501TEST_F(AttachedChoreographerTest, registerMultipleOnDifferentLayers) {
502 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
503
504 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
505 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
506
507 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
508 const sp<IDisplayEventConnection> connection1 =
509 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer1->getHandle());
510 const sp<IDisplayEventConnection> connection2 =
511 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer2->getHandle());
512
513 EXPECT_EQ(2u, mScheduler->mutableAttachedChoreographers().size());
514
515 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer1->getSequence()));
516 EXPECT_EQ(1u,
517 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()]
518 .connections.size());
519 EXPECT_FALSE(
520 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()].frameRate.isValid());
521
522 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer2->getSequence()));
523 EXPECT_EQ(1u,
524 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()]
525 .connections.size());
526 EXPECT_FALSE(
527 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()].frameRate.isValid());
528}
529
530TEST_F(AttachedChoreographerTest, removedWhenConnectionIsGone) {
531 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
532
533 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
534
535 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
536
537 sp<IDisplayEventConnection> connection =
538 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
539
540 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
541 EXPECT_EQ(1u,
542 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
543
544 // The connection is used all over this test, so it is quite hard to release it from here.
545 // Instead, we just do a small shortcut.
546 {
547 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
548 sp<MockEventThreadConnection> mockConnection =
549 sp<MockEventThreadConnection>::make(mEventThread);
550 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.clear();
551 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.emplace(
552 mockConnection);
553 }
554
555 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
556 LayerHierarchy hierarchy(&layerState);
557 mScheduler->updateAttachedChoreographers(hierarchy, 60_Hz);
558 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
559}
560
561TEST_F(AttachedChoreographerTest, removedWhenLayerIsGone) {
562 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
563
564 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
565
566 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
567 const sp<IDisplayEventConnection> connection =
568 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
569
570 layer.clear();
571 mFlinger.mutableLayersPendingRemoval().clear();
572 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
573}
574
575void AttachedChoreographerTest::frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility,
576 Fps displayFps,
577 Fps expectedChoreographerFps) {
578 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
579
580 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
581 sp<IDisplayEventConnection> connection =
582 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
583
584 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
585 LayerHierarchy hierarchy(&layerState);
586
587 layerState.frameRate = layerFps.getValue();
588 layerState.frameRateCompatibility = frameRateCompatibility;
589
590 mScheduler->updateAttachedChoreographers(hierarchy, displayFps);
591
592 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
593 EXPECT_EQ(expectedChoreographerFps,
594 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
595 EXPECT_EQ(expectedChoreographerFps, mEventThreadConnection->frameRate);
596}
597
598TEST_F(AttachedChoreographerTest, setsFrameRateDefault) {
599 Fps layerFps = 30_Hz;
600 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
601 Fps displayFps = 60_Hz;
602 Fps expectedChoreographerFps = 30_Hz;
603
604 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
605
606 layerFps = Fps::fromValue(32.7f);
607 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
608}
609
610TEST_F(AttachedChoreographerTest, setsFrameRateExact) {
611 Fps layerFps = 30_Hz;
612 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_EXACT;
613 Fps displayFps = 60_Hz;
614 Fps expectedChoreographerFps = 30_Hz;
615
616 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
617
618 layerFps = Fps::fromValue(32.7f);
619 expectedChoreographerFps = {};
620 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
621}
622
623TEST_F(AttachedChoreographerTest, setsFrameRateExactOrMultiple) {
624 Fps layerFps = 30_Hz;
625 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
626 Fps displayFps = 60_Hz;
627 Fps expectedChoreographerFps = 30_Hz;
628
629 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
630
631 layerFps = Fps::fromValue(32.7f);
632 expectedChoreographerFps = {};
633 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
634}
635
636TEST_F(AttachedChoreographerTest, setsFrameRateParent) {
637 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
638 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
639
640 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
641 sp<IDisplayEventConnection> connection =
642 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
643
644 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
645 LayerHierarchy parentHierarchy(&parentState);
646
647 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
648 LayerHierarchy hierarchy(&layerState);
649 parentHierarchy.mChildren.push_back(
650 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
651
652 layerState.frameRate = (30_Hz).getValue();
653 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
654
655 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
656
657 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
658
659 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
660}
661
662TEST_F(AttachedChoreographerTest, setsFrameRateParent2Children) {
663 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
664 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
665 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
666
667 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
668 sp<IDisplayEventConnection> connection =
669 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
670
671 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
672 LayerHierarchy parentHierarchy(&parentState);
673
674 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
675 LayerHierarchy layer1Hierarchy(&layer1State);
676 parentHierarchy.mChildren.push_back(
677 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
678
679 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
680 LayerHierarchy layer2Hierarchy(&layer2State);
681 parentHierarchy.mChildren.push_back(
682 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
683
684 layer1State.frameRate = (30_Hz).getValue();
685 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
686
687 layer2State.frameRate = (20_Hz).getValue();
688 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
689
690 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
691
692 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
693
694 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
695}
696
697TEST_F(AttachedChoreographerTest, setsFrameRateParentConflictingChildren) {
698 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
699 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
700 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
701
702 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
703 sp<IDisplayEventConnection> connection =
704 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
705
706 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
707 LayerHierarchy parentHierarchy(&parentState);
708
709 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
710 LayerHierarchy layer1Hierarchy(&layer1State);
711 parentHierarchy.mChildren.push_back(
712 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
713
714 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
715 LayerHierarchy layer2Hierarchy(&layer2State);
716 parentHierarchy.mChildren.push_back(
717 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
718
719 layer1State.frameRate = (30_Hz).getValue();
720 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
721
722 layer2State.frameRate = (25_Hz).getValue();
723 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
724
725 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
726
727 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
728
729 EXPECT_EQ(Fps(), mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
730}
731
732TEST_F(AttachedChoreographerTest, setsFrameRateChild) {
733 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
734 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
735
736 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
737 sp<IDisplayEventConnection> connection =
738 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
739
740 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
741 LayerHierarchy parentHierarchy(&parentState);
742
743 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
744 LayerHierarchy hierarchy(&layerState);
745 parentHierarchy.mChildren.push_back(
746 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
747
748 parentState.frameRate = (30_Hz).getValue();
749 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
750
751 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
752
753 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
754
755 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
756}
757
758TEST_F(AttachedChoreographerTest, setsFrameRateChildNotOverriddenByParent) {
759 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
760 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
761
762 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
763 sp<IDisplayEventConnection> connection =
764 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
765
766 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
767 LayerHierarchy parentHierarchy(&parentState);
768
769 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
770 LayerHierarchy hierarchy(&layerState);
771 parentHierarchy.mChildren.push_back(
772 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
773
774 parentState.frameRate = (30_Hz).getValue();
775 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
776
777 layerState.frameRate = (60_Hz).getValue();
778 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
779
780 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
781
782 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
783
784 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
785}
786
Dominik Laskowski068173d2021-08-11 17:22:59 -0700787} // namespace android::scheduler