blob: 69866894634b2fc195160d4e06da0796889328c4 [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
ramindani0491e642023-11-16 17:42:14 -080017#include <common/test/FlagUtils.h>
Leon Scroggins III67388622023-02-06 20:36:20 -050018#include <ftl/fake_guard.h>
Ana Krulec0c8cd522018-08-31 12:27:28 -070019#include <gmock/gmock.h>
20#include <gtest/gtest.h>
Ana Krulec0c8cd522018-08-31 12:27:28 -070021#include <log/log.h>
22
Ana Krulece588e312018-09-18 12:32:24 -070023#include <mutex>
24
Ana Krulec0c8cd522018-08-31 12:27:28 -070025#include "Scheduler/EventThread.h"
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040026#include "Scheduler/RefreshRateSelector.h"
ramindani0491e642023-11-16 17:42:14 -080027#include "Scheduler/VSyncPredictor.h"
Dominik Laskowski98041832019-08-01 18:35:59 -070028#include "TestableScheduler.h"
Dominik Laskowski983f2b52020-06-25 16:54:06 -070029#include "TestableSurfaceFlinger.h"
Dominik Laskowskib0054a22022-03-03 09:03:06 -080030#include "mock/DisplayHardware/MockDisplayMode.h"
Ana Krulec0c8cd522018-08-31 12:27:28 -070031#include "mock/MockEventThread.h"
Dominik Laskowski983f2b52020-06-25 16:54:06 -070032#include "mock/MockLayer.h"
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070033#include "mock/MockSchedulerCallback.h"
Ana Krulec0c8cd522018-08-31 12:27:28 -070034
Ady Abraham822ecbd2023-07-07 16:16:09 -070035#include <FrontEnd/LayerHierarchy.h>
36
ramindani0491e642023-11-16 17:42:14 -080037#include <com_android_graphics_surfaceflinger_flags.h>
Ady Abraham822ecbd2023-07-07 16:16:09 -070038#include "FpsOps.h"
39
ramindani0491e642023-11-16 17:42:14 -080040using namespace com::android::graphics::surfaceflinger;
41
Dominik Laskowski068173d2021-08-11 17:22:59 -070042namespace android::scheduler {
43
Dominik Laskowskib0054a22022-03-03 09:03:06 -080044using android::mock::createDisplayMode;
ramindani0491e642023-11-16 17:42:14 -080045using android::mock::createVrrDisplayMode;
Dominik Laskowskib0054a22022-03-03 09:03:06 -080046
Ana Krulec0c8cd522018-08-31 12:27:28 -070047using testing::_;
48using testing::Return;
49
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070050namespace {
Ana Krulec0c8cd522018-08-31 12:27:28 -070051
Dominik Laskowski068173d2021-08-11 17:22:59 -070052using MockEventThread = android::mock::EventThread;
53using MockLayer = android::mock::MockLayer;
54
Ady Abraham822ecbd2023-07-07 16:16:09 -070055using LayerHierarchy = surfaceflinger::frontend::LayerHierarchy;
56using LayerHierarchyBuilder = surfaceflinger::frontend::LayerHierarchyBuilder;
57using RequestedLayerState = surfaceflinger::frontend::RequestedLayerState;
58
Ana Krulec0c8cd522018-08-31 12:27:28 -070059class SchedulerTest : public testing::Test {
60protected:
Ana Krulec85c39af2018-12-26 17:29:57 -080061 class MockEventThreadConnection : public android::EventThreadConnection {
Ana Krulec0c8cd522018-08-31 12:27:28 -070062 public:
Ana Krulec85c39af2018-12-26 17:29:57 -080063 explicit MockEventThreadConnection(EventThread* eventThread)
Ady Abrahamf2851612023-09-25 17:19:00 -070064 : EventThreadConnection(eventThread, /*callingUid*/ static_cast<uid_t>(0)) {}
Ana Krulec0c8cd522018-08-31 12:27:28 -070065 ~MockEventThreadConnection() = default;
66
Huihong Luo6fac5232021-11-22 16:05:23 -080067 MOCK_METHOD1(stealReceiveChannel, binder::Status(gui::BitTube* outChannel));
68 MOCK_METHOD1(setVsyncRate, binder::Status(int count));
69 MOCK_METHOD0(requestNextVsync, binder::Status());
Ana Krulec0c8cd522018-08-31 12:27:28 -070070 };
71
Ana Krulec0c8cd522018-08-31 12:27:28 -070072 SchedulerTest();
Ana Krulec0c8cd522018-08-31 12:27:28 -070073
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040074 static constexpr PhysicalDisplayId kDisplayId1 = PhysicalDisplayId::fromPort(255u);
Ady Abrahamace3d052022-11-17 16:25:05 -080075 static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode60 =
76 ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(0), 60_Hz));
77 static inline const ftl::NonNull<DisplayModePtr> kDisplay1Mode120 =
78 ftl::as_non_null(createDisplayMode(kDisplayId1, DisplayModeId(1), 120_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040079 static inline const DisplayModes kDisplay1Modes = makeModes(kDisplay1Mode60, kDisplay1Mode120);
80
81 static constexpr PhysicalDisplayId kDisplayId2 = PhysicalDisplayId::fromPort(254u);
Ady Abrahamace3d052022-11-17 16:25:05 -080082 static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode60 =
83 ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(0), 60_Hz));
84 static inline const ftl::NonNull<DisplayModePtr> kDisplay2Mode120 =
85 ftl::as_non_null(createDisplayMode(kDisplayId2, DisplayModeId(1), 120_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040086 static inline const DisplayModes kDisplay2Modes = makeModes(kDisplay2Mode60, kDisplay2Mode120);
87
88 static constexpr PhysicalDisplayId kDisplayId3 = PhysicalDisplayId::fromPort(253u);
Ady Abrahamace3d052022-11-17 16:25:05 -080089 static inline const ftl::NonNull<DisplayModePtr> kDisplay3Mode60 =
90 ftl::as_non_null(createDisplayMode(kDisplayId3, DisplayModeId(0), 60_Hz));
Dominik Laskowski530d6bd2022-10-10 16:55:54 -040091 static inline const DisplayModes kDisplay3Modes = makeModes(kDisplay3Mode60);
Marin Shalamanov2cde1002021-06-08 19:50:10 +020092
Dominik Laskowskid82e0f02022-10-26 15:23:04 -040093 std::shared_ptr<RefreshRateSelector> mSelector =
94 std::make_shared<RefreshRateSelector>(makeModes(kDisplay1Mode60),
95 kDisplay1Mode60->getId());
Dominik Laskowski983f2b52020-06-25 16:54:06 -070096
Dominik Laskowski8b01cc02020-07-14 19:02:41 -070097 mock::SchedulerCallback mSchedulerCallback;
ramindanid4354a92023-10-02 15:11:09 -070098 mock::VsyncTrackerCallback mVsyncTrackerCallback;
Leon Scroggins III823d4ca2023-12-12 16:57:34 -050099 TestableSurfaceFlinger mFlinger;
ramindanid4354a92023-10-02 15:11:09 -0700100 TestableScheduler* mScheduler =
Leon Scroggins III823d4ca2023-12-12 16:57:34 -0500101 new TestableScheduler{mSelector, mFlinger, mSchedulerCallback, mVsyncTrackerCallback};
Vishnu Naira0292282023-12-16 14:32:00 -0800102 surfaceflinger::frontend::LayerHierarchyBuilder mLayerHierarchyBuilder;
Dominik Laskowski98041832019-08-01 18:35:59 -0700103
Dominik Laskowski068173d2021-08-11 17:22:59 -0700104 ConnectionHandle mConnectionHandle;
105 MockEventThread* mEventThread;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700106 sp<MockEventThreadConnection> mEventThreadConnection;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700107};
108
109SchedulerTest::SchedulerTest() {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700110 auto eventThread = std::make_unique<MockEventThread>();
Ana Krulec0c8cd522018-08-31 12:27:28 -0700111 mEventThread = eventThread.get();
Ana Krulec85c39af2018-12-26 17:29:57 -0800112 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
113
Ady Abrahamd11bade2022-08-01 16:18:03 -0700114 mEventThreadConnection = sp<MockEventThreadConnection>::make(mEventThread);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700115
116 // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
117 // sure that call gets executed and returns an EventThread::Connection object.
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700118 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
Ana Krulec0c8cd522018-08-31 12:27:28 -0700119 .WillRepeatedly(Return(mEventThreadConnection));
120
Ady Abrahama0a16272021-03-03 15:23:35 -0800121 mConnectionHandle = mScheduler->createConnection(std::move(eventThread));
Dominik Laskowski98041832019-08-01 18:35:59 -0700122 EXPECT_TRUE(mConnectionHandle);
Ady Abrahama0a16272021-03-03 15:23:35 -0800123
124 mFlinger.resetScheduler(mScheduler);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700125}
126
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700127} // namespace
Ana Krulec0c8cd522018-08-31 12:27:28 -0700128
Ana Krulec0c8cd522018-08-31 12:27:28 -0700129TEST_F(SchedulerTest, invalidConnectionHandle) {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700130 ConnectionHandle handle;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700131
Ady Abrahama0a16272021-03-03 15:23:35 -0800132 const sp<IDisplayEventConnection> connection = mScheduler->createDisplayEventConnection(handle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700133
Dominik Laskowski98041832019-08-01 18:35:59 -0700134 EXPECT_FALSE(connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800135 EXPECT_FALSE(mScheduler->getEventConnection(handle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700136
137 // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads.
138 EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400139 mScheduler->onHotplugReceived(handle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700140
Dominik Laskowski98041832019-08-01 18:35:59 -0700141 std::string output;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700142 EXPECT_CALL(*mEventThread, dump(_)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800143 mScheduler->dump(handle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700144 EXPECT_TRUE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700145
Ady Abraham9c53ee72020-07-22 21:16:18 -0700146 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800147 mScheduler->setDuration(handle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700148}
149
150TEST_F(SchedulerTest, validConnectionHandle) {
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700151 const sp<IDisplayEventConnection> connection =
Ady Abrahama0a16272021-03-03 15:23:35 -0800152 mScheduler->createDisplayEventConnection(mConnectionHandle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700153
Dominik Laskowski98041832019-08-01 18:35:59 -0700154 ASSERT_EQ(mEventThreadConnection, connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800155 EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700156
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400157 EXPECT_CALL(*mEventThread, onHotplugReceived(kDisplayId1, false)).Times(1);
158 mScheduler->onHotplugReceived(mConnectionHandle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700159
Dominik Laskowski98041832019-08-01 18:35:59 -0700160 std::string output("dump");
161 EXPECT_CALL(*mEventThread, dump(output)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800162 mScheduler->dump(mConnectionHandle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700163 EXPECT_FALSE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700164
Ady Abraham9c53ee72020-07-22 21:16:18 -0700165 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800166 mScheduler->setDuration(mConnectionHandle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700167}
Dominik Laskowski98041832019-08-01 18:35:59 -0700168
Dominik Laskowski66295432023-03-14 12:25:36 -0400169TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) {
Dominik Laskowski008bec02023-03-14 12:04:58 -0400170 // Hardware VSYNC should not change if the display is already registered.
Dominik Laskowski66295432023-03-14 12:25:36 -0400171 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId1, false)).Times(0);
Dominik Laskowski008bec02023-03-14 12:04:58 -0400172 mScheduler->registerDisplay(kDisplayId1,
173 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
174 kDisplay1Mode60->getId()));
175
Dominik Laskowski66295432023-03-14 12:25:36 -0400176 // TODO(b/241285191): Restore once VsyncSchedule::getPendingHardwareVsyncState is called by
177 // Scheduler::setDisplayPowerMode rather than SF::setPowerModeInternal.
178#if 0
Dominik Laskowski008bec02023-03-14 12:04:58 -0400179 // Hardware VSYNC should be disabled for newly registered displays.
Dominik Laskowski66295432023-03-14 12:25:36 -0400180 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId2, false)).Times(1);
181 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId3, false)).Times(1);
182#endif
Dominik Laskowski008bec02023-03-14 12:04:58 -0400183
184 mScheduler->registerDisplay(kDisplayId2,
185 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
186 kDisplay2Mode60->getId()));
187 mScheduler->registerDisplay(kDisplayId3,
188 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
189 kDisplay3Mode60->getId()));
Dominik Laskowski66295432023-03-14 12:25:36 -0400190
191 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId1)->getPendingHardwareVsyncState());
192 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId2)->getPendingHardwareVsyncState());
193 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId3)->getPendingHardwareVsyncState());
Dominik Laskowski008bec02023-03-14 12:04:58 -0400194}
195
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200196TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) {
197 // The layer is registered at creation time and deregistered at destruction time.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700198 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700199
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200200 // recordLayerHistory should be a noop
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700201 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700202 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0, 0,
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000203 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700204 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700205
Rachel Lee6a9731d2022-06-06 17:08:14 -0700206 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500207 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700208
209 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700210 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700211
ramindani69b58e82022-09-26 16:48:36 -0700212 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700213 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
214 /*updateAttachedChoreographer*/ false);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700215}
216
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200217TEST_F(SchedulerTest, updateDisplayModes) {
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700218 ASSERT_EQ(0u, mScheduler->layerHistorySize());
Dominik Laskowski068173d2021-08-11 17:22:59 -0700219 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700220 ASSERT_EQ(1u, mScheduler->layerHistorySize());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200221
Dominik Laskowski596a2562022-10-28 11:26:12 -0400222 // Replace `mSelector` with a new `RefreshRateSelector` that has different display modes.
223 mScheduler->registerDisplay(kDisplayId1,
224 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
225 kDisplay1Mode60->getId()));
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200226
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700227 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700228 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0, 0,
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000229 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700230 ASSERT_EQ(1u, mScheduler->getNumActiveLayers());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200231}
232
Dominik Laskowski068173d2021-08-11 17:22:59 -0700233TEST_F(SchedulerTest, dispatchCachedReportedMode) {
234 mScheduler->clearCachedReportedMode();
235
Ady Abraham690f4612021-07-01 23:24:03 -0700236 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Dominik Laskowski068173d2021-08-11 17:22:59 -0700237 EXPECT_NO_FATAL_FAILURE(mScheduler->dispatchCachedReportedMode());
Ana Krulec6ddd2612020-09-24 13:06:33 -0700238}
239
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100240TEST_F(SchedulerTest, onNonPrimaryDisplayModeChanged_invalidParameters) {
Ady Abraham690f4612021-07-01 23:24:03 -0700241 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
242 .setId(DisplayModeId(111))
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400243 .setPhysicalDisplayId(kDisplayId1)
Ady Abraham690f4612021-07-01 23:24:03 -0700244 .setVsyncPeriod(111111)
245 .build();
Ana Krulec6ddd2612020-09-24 13:06:33 -0700246
247 // If the handle is incorrect, the function should return before
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100248 // onModeChange is called.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700249 ConnectionHandle invalidHandle = {.id = 123};
Ady Abrahamace3d052022-11-17 16:25:05 -0800250 EXPECT_NO_FATAL_FAILURE(
251 mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle,
252 {90_Hz, ftl::as_non_null(mode)}));
Ady Abraham690f4612021-07-01 23:24:03 -0700253 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Ana Krulec6ddd2612020-09-24 13:06:33 -0700254}
255
Ady Abraham899dcdb2021-06-15 16:56:21 -0700256TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700257 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms));
258 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms));
259 EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(120_Hz, 30ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800260
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700261 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 40ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800262
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700263 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Piquea1456c12023-05-17 12:11:15 -0700264
Lloyd Pique30db6402023-06-26 18:56:51 +0000265 const auto savedMinAcquiredBuffers = mFlinger.mutableMinAcquiredBuffers();
266 mFlinger.mutableMinAcquiredBuffers() = 2;
Lloyd Piquea1456c12023-05-17 12:11:15 -0700267 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Pique30db6402023-06-26 18:56:51 +0000268 mFlinger.mutableMinAcquiredBuffers() = savedMinAcquiredBuffers;
Ady Abraham564f9de2021-02-03 18:34:33 -0800269}
270
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200271MATCHER(Is120Hz, "") {
Ady Abrahamace3d052022-11-17 16:25:05 -0800272 return isApproxEqual(arg.front().mode.fps, 120_Hz);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200273}
274
275TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
Dominik Laskowski596a2562022-10-28 11:26:12 -0400276 mScheduler->registerDisplay(kDisplayId1,
277 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
278 kDisplay1Mode60->getId()));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200279
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800280 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
281 EXPECT_CALL(*layer, isVisible()).WillOnce(Return(true));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200282
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700283 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0, systemTime(),
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000284 LayerHistory::LayerUpdateType::Buffer);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200285
Rachel Lee6a9731d2022-06-06 17:08:14 -0700286 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500287 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200288
289 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700290 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200291
ramindani69b58e82022-09-26 16:48:36 -0700292 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(Is120Hz())).Times(1);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700293 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
294 /*updateAttachedChoreographer*/ false);
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800295
296 // No-op if layer requirements have not changed.
ramindani69b58e82022-09-26 16:48:36 -0700297 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700298 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
299 /*updateAttachedChoreographer*/ false);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200300}
301
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400302TEST_F(SchedulerTest, chooseDisplayModesSingleDisplay) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400303 mScheduler->registerDisplay(kDisplayId1,
304 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
305 kDisplay1Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700306
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400307 std::vector<RefreshRateSelector::LayerRequirement> layers =
308 std::vector<RefreshRateSelector::LayerRequirement>({{.weight = 1.f}, {.weight = 1.f}});
ramindani69b58e82022-09-26 16:48:36 -0700309 mScheduler->setContentRequirements(layers);
310 GlobalSignals globalSignals = {.idle = true};
311 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
312
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400313 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
314
315 auto modeChoices = mScheduler->chooseDisplayModes();
316 ASSERT_EQ(1u, modeChoices.size());
317
318 auto choice = modeChoices.get(kDisplayId1);
319 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800320 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700321
322 globalSignals = {.idle = false};
323 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400324
325 modeChoices = mScheduler->chooseDisplayModes();
326 ASSERT_EQ(1u, modeChoices.size());
327
328 choice = modeChoices.get(kDisplayId1);
329 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800330 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700331
332 globalSignals = {.touch = true};
333 mScheduler->replaceTouchTimer(10);
334 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700335
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400336 modeChoices = mScheduler->chooseDisplayModes();
337 ASSERT_EQ(1u, modeChoices.size());
338
339 choice = modeChoices.get(kDisplayId1);
340 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800341 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700342}
343
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400344TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400345 mScheduler->registerDisplay(kDisplayId1,
346 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
347 kDisplay1Mode60->getId()));
348 mScheduler->registerDisplay(kDisplayId2,
349 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
350 kDisplay2Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700351
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400352 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
353 TestableScheduler::DisplayModeChoiceMap expectedChoices;
ramindani69b58e82022-09-26 16:48:36 -0700354
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400355 {
356 const GlobalSignals globalSignals = {.idle = true};
357 expectedChoices =
358 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800359 DisplayModeChoice>(kDisplayId1,
360 FrameRateMode{60_Hz, kDisplay1Mode60},
361 globalSignals)(kDisplayId2,
362 FrameRateMode{60_Hz,
363 kDisplay2Mode60},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400364 globalSignals);
365
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400366 std::vector<RefreshRateSelector::LayerRequirement> layers = {{.weight = 1.f},
367 {.weight = 1.f}};
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400368 mScheduler->setContentRequirements(layers);
369 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
370
371 const auto actualChoices = mScheduler->chooseDisplayModes();
372 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700373 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400374 {
375 const GlobalSignals globalSignals = {.idle = false};
376 expectedChoices =
377 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800378 DisplayModeChoice>(kDisplayId1,
379 FrameRateMode{120_Hz, kDisplay1Mode120},
380 globalSignals)(kDisplayId2,
381 FrameRateMode{120_Hz,
382 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400383 globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700384
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400385 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700386
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400387 const auto actualChoices = mScheduler->chooseDisplayModes();
388 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700389 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400390 {
391 const GlobalSignals globalSignals = {.touch = true};
392 mScheduler->replaceTouchTimer(10);
393 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700394
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400395 expectedChoices =
396 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800397 DisplayModeChoice>(kDisplayId1,
398 FrameRateMode{120_Hz, kDisplay1Mode120},
399 globalSignals)(kDisplayId2,
400 FrameRateMode{120_Hz,
401 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400402 globalSignals);
403
404 const auto actualChoices = mScheduler->chooseDisplayModes();
405 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700406 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400407 {
ramindani22f2ead2023-04-21 10:27:11 -0700408 // The kDisplayId3 does not support 120Hz, The pacesetter display rate is chosen to be 120
409 // Hz. In this case only the display kDisplayId3 choose 60Hz as it does not support 120Hz.
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400410 mScheduler
411 ->registerDisplay(kDisplayId3,
412 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
413 kDisplay3Mode60->getId()));
Dominik Laskowski327d6092022-10-11 18:05:08 -0400414
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400415 const GlobalSignals globalSignals = {.touch = true};
416 mScheduler->replaceTouchTimer(10);
417 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani7c487282022-10-10 16:17:51 -0700418
Ady Abrahamace3d052022-11-17 16:25:05 -0800419 expectedChoices = ftl::init::map<
420 const PhysicalDisplayId&,
ramindani22f2ead2023-04-21 10:27:11 -0700421 DisplayModeChoice>(kDisplayId1, FrameRateMode{120_Hz, kDisplay1Mode120},
422 globalSignals)(kDisplayId2,
423 FrameRateMode{120_Hz, kDisplay2Mode120},
424 globalSignals)(kDisplayId3,
425 FrameRateMode{60_Hz,
426 kDisplay3Mode60},
427 globalSignals);
428
429 const auto actualChoices = mScheduler->chooseDisplayModes();
430 EXPECT_EQ(expectedChoices, actualChoices);
431 }
432 {
433 // We should choose 60Hz despite the touch signal as pacesetter only supports 60Hz
434 mScheduler->setPacesetterDisplay(kDisplayId3);
435 const GlobalSignals globalSignals = {.touch = true};
436 mScheduler->replaceTouchTimer(10);
437 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
438
439 expectedChoices = ftl::init::map<
440 const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800441 DisplayModeChoice>(kDisplayId1, FrameRateMode{60_Hz, kDisplay1Mode60},
442 globalSignals)(kDisplayId2,
443 FrameRateMode{60_Hz, kDisplay2Mode60},
444 globalSignals)(kDisplayId3,
445 FrameRateMode{60_Hz,
446 kDisplay3Mode60},
447 globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400448
449 const auto actualChoices = mScheduler->chooseDisplayModes();
450 EXPECT_EQ(expectedChoices, actualChoices);
ramindani7c487282022-10-10 16:17:51 -0700451 }
ramindani69b58e82022-09-26 16:48:36 -0700452}
453
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400454TEST_F(SchedulerTest, onFrameSignalMultipleDisplays) {
455 mScheduler->registerDisplay(kDisplayId1,
456 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
457 kDisplay1Mode60->getId()));
458 mScheduler->registerDisplay(kDisplayId2,
459 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
460 kDisplay2Mode60->getId()));
461
462 using VsyncIds = std::vector<std::pair<PhysicalDisplayId, VsyncId>>;
463
464 struct Compositor final : ICompositor {
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500465 explicit Compositor(TestableScheduler& scheduler) : scheduler(scheduler) {}
466
467 TestableScheduler& scheduler;
468
469 struct {
470 PhysicalDisplayId commit;
471 PhysicalDisplayId composite;
472 } pacesetterIds;
473
474 struct {
475 VsyncIds commit;
476 VsyncIds composite;
477 } vsyncIds;
478
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400479 bool committed = true;
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500480 bool changePacesetter = false;
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400481
482 void configure() override {}
483
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500484 bool commit(PhysicalDisplayId pacesetterId,
485 const scheduler::FrameTargets& targets) override {
486 pacesetterIds.commit = pacesetterId;
487
488 vsyncIds.commit.clear();
489 vsyncIds.composite.clear();
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400490
491 for (const auto& [id, target] : targets) {
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500492 vsyncIds.commit.emplace_back(id, target->vsyncId());
493 }
494
495 if (changePacesetter) {
496 scheduler.setPacesetterDisplay(kDisplayId2);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400497 }
498
499 return committed;
500 }
501
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500502 CompositeResultsPerDisplay composite(PhysicalDisplayId pacesetterId,
503 const scheduler::FrameTargeters& targeters) override {
504 pacesetterIds.composite = pacesetterId;
505
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400506 CompositeResultsPerDisplay results;
507
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500508 for (const auto& [id, targeter] : targeters) {
509 vsyncIds.composite.emplace_back(id, targeter->target().vsyncId());
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400510 results.try_emplace(id,
511 CompositeResult{.compositionCoverage =
512 CompositionCoverage::Hwc});
513 }
514
515 return results;
516 }
517
518 void sample() override {}
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500519 } compositor(*mScheduler);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400520
521 mScheduler->doFrameSignal(compositor, VsyncId(42));
522
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500523 const auto makeVsyncIds = [](VsyncId vsyncId, bool swap = false) -> VsyncIds {
524 if (swap) {
525 return {{kDisplayId2, vsyncId}, {kDisplayId1, vsyncId}};
526 } else {
527 return {{kDisplayId1, vsyncId}, {kDisplayId2, vsyncId}};
528 }
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400529 };
530
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500531 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
532 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
533 EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.commit);
534 EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.composite);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400535
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500536 // FrameTargets should be updated despite the skipped commit.
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400537 compositor.committed = false;
538 mScheduler->doFrameSignal(compositor, VsyncId(43));
539
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500540 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
541 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
542 EXPECT_EQ(makeVsyncIds(VsyncId(43)), compositor.vsyncIds.commit);
543 EXPECT_TRUE(compositor.vsyncIds.composite.empty());
544
545 // The pacesetter may change during commit.
546 compositor.committed = true;
547 compositor.changePacesetter = true;
548 mScheduler->doFrameSignal(compositor, VsyncId(44));
549
550 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
551 EXPECT_EQ(kDisplayId2, compositor.pacesetterIds.composite);
552 EXPECT_EQ(makeVsyncIds(VsyncId(44)), compositor.vsyncIds.commit);
553 EXPECT_EQ(makeVsyncIds(VsyncId(44), true), compositor.vsyncIds.composite);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400554}
555
ramindani0491e642023-11-16 17:42:14 -0800556TEST_F(SchedulerTest, nextFrameIntervalTest) {
557 SET_FLAG_FOR_TEST(flags::vrr_config, true);
558
559 static constexpr size_t kHistorySize = 10;
560 static constexpr size_t kMinimumSamplesForPrediction = 6;
561 static constexpr size_t kOutlierTolerancePercent = 25;
562 const auto refreshRate = Fps::fromPeriodNsecs(500);
563 auto frameRate = Fps::fromPeriodNsecs(1000);
564
565 const ftl::NonNull<DisplayModePtr> kMode = ftl::as_non_null(
566 createVrrDisplayMode(DisplayModeId(0), refreshRate,
567 hal::VrrConfig{.minFrameIntervalNs = static_cast<int32_t>(
568 frameRate.getPeriodNsecs())}));
569 std::shared_ptr<VSyncPredictor> vrrTracker =
570 std::make_shared<VSyncPredictor>(kMode, kHistorySize, kMinimumSamplesForPrediction,
571 kOutlierTolerancePercent, mVsyncTrackerCallback);
572 std::shared_ptr<RefreshRateSelector> vrrSelectorPtr =
573 std::make_shared<RefreshRateSelector>(makeModes(kMode), kMode->getId());
574 TestableScheduler scheduler{std::make_unique<android::mock::VsyncController>(),
575 vrrTracker,
576 vrrSelectorPtr,
Leon Scroggins III823d4ca2023-12-12 16:57:34 -0500577 mFlinger.getFactory(),
578 mFlinger.getTimeStats(),
ramindani0491e642023-11-16 17:42:14 -0800579 mSchedulerCallback,
580 mVsyncTrackerCallback};
581
582 scheduler.registerDisplay(kMode->getPhysicalDisplayId(), vrrSelectorPtr, vrrTracker);
583 vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
584 scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate);
585 vrrTracker->addVsyncTimestamp(0);
586
ramindani0491e642023-11-16 17:42:14 -0800587 EXPECT_EQ(Fps::fromPeriodNsecs(1000),
588 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abraham4335afd2023-12-18 19:10:47 -0800589 TimePoint::fromNs(1000)));
ramindani0491e642023-11-16 17:42:14 -0800590 EXPECT_EQ(Fps::fromPeriodNsecs(1000),
591 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abraham4335afd2023-12-18 19:10:47 -0800592 TimePoint::fromNs(2000)));
ramindani0491e642023-11-16 17:42:14 -0800593
Ady Abraham4335afd2023-12-18 19:10:47 -0800594 // Not crossing the min frame period
595 EXPECT_EQ(Fps::fromPeriodNsecs(1500),
596 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
597 TimePoint::fromNs(2500)));
ramindani0491e642023-11-16 17:42:14 -0800598 // Change render rate
599 frameRate = Fps::fromPeriodNsecs(2000);
600 vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
601 scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate);
602
603 EXPECT_EQ(Fps::fromPeriodNsecs(2000),
604 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abraham4335afd2023-12-18 19:10:47 -0800605 TimePoint::fromNs(2000)));
ramindani0491e642023-11-16 17:42:14 -0800606 EXPECT_EQ(Fps::fromPeriodNsecs(2000),
607 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abraham4335afd2023-12-18 19:10:47 -0800608 TimePoint::fromNs(4000)));
ramindani0491e642023-11-16 17:42:14 -0800609}
610
Leon Scroggins III792ea802023-11-27 17:32:51 -0500611TEST_F(SchedulerTest, resyncAllToHardwareVsync) FTL_FAKE_GUARD(kMainThreadContext) {
612 // resyncAllToHardwareVsync will result in requesting hardware VSYNC on both displays, since
613 // they are both on.
614 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
615 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, true)).Times(1);
616
617 mScheduler->registerDisplay(kDisplayId2,
618 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
619 kDisplay2Mode60->getId()));
620 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
621 mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON);
622
623 static constexpr bool kDisallow = true;
624 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
625 mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
626
627 static constexpr bool kAllowToEnable = true;
628 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
629}
630
631TEST_F(SchedulerTest, resyncAllDoNotAllow) FTL_FAKE_GUARD(kMainThreadContext) {
632 // Without setting allowToEnable to true, resyncAllToHardwareVsync does not
633 // result in requesting hardware VSYNC.
634 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, _)).Times(0);
635
636 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
637
638 static constexpr bool kDisallow = true;
639 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
640
641 static constexpr bool kAllowToEnable = false;
642 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
643}
644
645TEST_F(SchedulerTest, resyncAllSkipsOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) {
646 SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
647
648 // resyncAllToHardwareVsync will result in requesting hardware VSYNC on display 1, which is on,
649 // but not on display 2, which is off.
650 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
651 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, _)).Times(0);
652
653 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
654
655 mScheduler->registerDisplay(kDisplayId2,
656 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
657 kDisplay2Mode60->getId()));
658 ASSERT_EQ(hal::PowerMode::OFF, mScheduler->getDisplayPowerMode(kDisplayId2));
659
660 static constexpr bool kDisallow = true;
661 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
662 mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
663
664 static constexpr bool kAllowToEnable = true;
665 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
666}
667
668TEST_F(SchedulerTest, resyncAllLegacyAppliesToOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) {
669 SET_FLAG_FOR_TEST(flags::multithreaded_present, false);
670
671 // In the legacy code, prior to the flag, resync applied to OFF displays.
672 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
673 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, true)).Times(1);
674
675 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
676
677 mScheduler->registerDisplay(kDisplayId2,
678 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
679 kDisplay2Mode60->getId()));
680 ASSERT_EQ(hal::PowerMode::OFF, mScheduler->getDisplayPowerMode(kDisplayId2));
681
682 static constexpr bool kDisallow = true;
683 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
684 mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
685
686 static constexpr bool kAllowToEnable = true;
687 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
688}
689
Ady Abraham822ecbd2023-07-07 16:16:09 -0700690class AttachedChoreographerTest : public SchedulerTest {
691protected:
692 void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
693 Fps expectedChoreographerFps);
694};
695
696TEST_F(AttachedChoreographerTest, registerSingle) {
697 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
698
699 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
700
701 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
702 const sp<IDisplayEventConnection> connection =
703 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
704
705 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
706 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
707 EXPECT_EQ(1u,
708 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
709 EXPECT_FALSE(
710 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
711}
712
713TEST_F(AttachedChoreographerTest, registerMultipleOnSameLayer) {
714 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
715
716 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
717 const auto handle = layer->getHandle();
718
719 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
720
721 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_))
722 .WillOnce(Return(0))
723 .WillOnce(Return(0));
724
725 const auto mockConnection1 = sp<MockEventThreadConnection>::make(mEventThread);
726 const auto mockConnection2 = sp<MockEventThreadConnection>::make(mEventThread);
727 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
728 .WillOnce(Return(mockConnection1))
729 .WillOnce(Return(mockConnection2));
730
731 const sp<IDisplayEventConnection> connection1 =
732 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
733 const sp<IDisplayEventConnection> connection2 =
734 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
735
736 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
737 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
738 EXPECT_EQ(2u,
739 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
740 EXPECT_FALSE(
741 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
742}
743
744TEST_F(AttachedChoreographerTest, registerMultipleOnDifferentLayers) {
745 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
746
747 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
748 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
749
750 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
751 const sp<IDisplayEventConnection> connection1 =
752 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer1->getHandle());
753 const sp<IDisplayEventConnection> connection2 =
754 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer2->getHandle());
755
756 EXPECT_EQ(2u, mScheduler->mutableAttachedChoreographers().size());
757
758 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer1->getSequence()));
759 EXPECT_EQ(1u,
760 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()]
761 .connections.size());
762 EXPECT_FALSE(
763 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()].frameRate.isValid());
764
765 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer2->getSequence()));
766 EXPECT_EQ(1u,
767 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()]
768 .connections.size());
769 EXPECT_FALSE(
770 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()].frameRate.isValid());
771}
772
773TEST_F(AttachedChoreographerTest, removedWhenConnectionIsGone) {
774 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
775
776 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
777
778 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
779
780 sp<IDisplayEventConnection> connection =
781 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
782
783 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
784 EXPECT_EQ(1u,
785 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
786
787 // The connection is used all over this test, so it is quite hard to release it from here.
788 // Instead, we just do a small shortcut.
789 {
790 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
791 sp<MockEventThreadConnection> mockConnection =
792 sp<MockEventThreadConnection>::make(mEventThread);
793 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.clear();
794 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.emplace(
795 mockConnection);
796 }
797
798 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
799 LayerHierarchy hierarchy(&layerState);
800 mScheduler->updateAttachedChoreographers(hierarchy, 60_Hz);
801 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
802}
803
804TEST_F(AttachedChoreographerTest, removedWhenLayerIsGone) {
805 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
806
807 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
808
809 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
810 const sp<IDisplayEventConnection> connection =
811 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
812
813 layer.clear();
814 mFlinger.mutableLayersPendingRemoval().clear();
815 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
816}
817
818void AttachedChoreographerTest::frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility,
819 Fps displayFps,
820 Fps expectedChoreographerFps) {
821 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
822
823 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
824 sp<IDisplayEventConnection> connection =
825 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
826
827 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
828 LayerHierarchy hierarchy(&layerState);
829
830 layerState.frameRate = layerFps.getValue();
831 layerState.frameRateCompatibility = frameRateCompatibility;
832
833 mScheduler->updateAttachedChoreographers(hierarchy, displayFps);
834
835 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
836 EXPECT_EQ(expectedChoreographerFps,
837 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
838 EXPECT_EQ(expectedChoreographerFps, mEventThreadConnection->frameRate);
839}
840
841TEST_F(AttachedChoreographerTest, setsFrameRateDefault) {
842 Fps layerFps = 30_Hz;
843 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
844 Fps displayFps = 60_Hz;
845 Fps expectedChoreographerFps = 30_Hz;
846
847 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
848
849 layerFps = Fps::fromValue(32.7f);
850 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
851}
852
853TEST_F(AttachedChoreographerTest, setsFrameRateExact) {
854 Fps layerFps = 30_Hz;
855 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_EXACT;
856 Fps displayFps = 60_Hz;
857 Fps expectedChoreographerFps = 30_Hz;
858
859 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
860
861 layerFps = Fps::fromValue(32.7f);
862 expectedChoreographerFps = {};
863 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
864}
865
866TEST_F(AttachedChoreographerTest, setsFrameRateExactOrMultiple) {
867 Fps layerFps = 30_Hz;
868 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
869 Fps displayFps = 60_Hz;
870 Fps expectedChoreographerFps = 30_Hz;
871
872 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
873
874 layerFps = Fps::fromValue(32.7f);
875 expectedChoreographerFps = {};
876 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
877}
878
879TEST_F(AttachedChoreographerTest, setsFrameRateParent) {
880 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
881 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
882
883 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
884 sp<IDisplayEventConnection> connection =
885 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
886
887 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
888 LayerHierarchy parentHierarchy(&parentState);
889
890 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
891 LayerHierarchy hierarchy(&layerState);
892 parentHierarchy.mChildren.push_back(
893 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
894
895 layerState.frameRate = (30_Hz).getValue();
896 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
897
898 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
899
900 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
901
902 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
903}
904
905TEST_F(AttachedChoreographerTest, setsFrameRateParent2Children) {
906 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
907 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
908 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
909
910 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
911 sp<IDisplayEventConnection> connection =
912 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
913
914 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
915 LayerHierarchy parentHierarchy(&parentState);
916
917 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
918 LayerHierarchy layer1Hierarchy(&layer1State);
919 parentHierarchy.mChildren.push_back(
920 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
921
922 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
923 LayerHierarchy layer2Hierarchy(&layer2State);
924 parentHierarchy.mChildren.push_back(
925 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
926
927 layer1State.frameRate = (30_Hz).getValue();
928 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
929
930 layer2State.frameRate = (20_Hz).getValue();
931 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
932
933 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
934
935 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
936
937 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
938}
939
940TEST_F(AttachedChoreographerTest, setsFrameRateParentConflictingChildren) {
941 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
942 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
943 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
944
945 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
946 sp<IDisplayEventConnection> connection =
947 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
948
949 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
950 LayerHierarchy parentHierarchy(&parentState);
951
952 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
953 LayerHierarchy layer1Hierarchy(&layer1State);
954 parentHierarchy.mChildren.push_back(
955 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
956
957 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
958 LayerHierarchy layer2Hierarchy(&layer2State);
959 parentHierarchy.mChildren.push_back(
960 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
961
962 layer1State.frameRate = (30_Hz).getValue();
963 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
964
965 layer2State.frameRate = (25_Hz).getValue();
966 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
967
968 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
969
970 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
971
972 EXPECT_EQ(Fps(), mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
973}
974
975TEST_F(AttachedChoreographerTest, setsFrameRateChild) {
976 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
977 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
978
979 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
980 sp<IDisplayEventConnection> connection =
981 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
982
983 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
984 LayerHierarchy parentHierarchy(&parentState);
985
986 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
987 LayerHierarchy hierarchy(&layerState);
988 parentHierarchy.mChildren.push_back(
989 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
990
991 parentState.frameRate = (30_Hz).getValue();
992 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
993
994 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
995
996 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
997
998 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
999}
1000
1001TEST_F(AttachedChoreographerTest, setsFrameRateChildNotOverriddenByParent) {
1002 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
1003 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
1004
1005 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
1006 sp<IDisplayEventConnection> connection =
1007 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
1008
1009 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
1010 LayerHierarchy parentHierarchy(&parentState);
1011
1012 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
1013 LayerHierarchy hierarchy(&layerState);
1014 parentHierarchy.mChildren.push_back(
1015 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
1016
1017 parentState.frameRate = (30_Hz).getValue();
1018 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1019
1020 layerState.frameRate = (60_Hz).getValue();
1021 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1022
1023 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1024
1025 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
1026
1027 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
1028}
1029
Dominik Laskowski068173d2021-08-11 17:22:59 -07001030} // namespace android::scheduler