blob: b0595257a92d4d21a4f9a2c0edd2552c12d29ea3 [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;
Leon Scroggins III823d4ca2023-12-12 16:57:34 -050098 TestableSurfaceFlinger mFlinger;
ramindaniae645822024-01-11 10:57:29 -080099 TestableScheduler* mScheduler = new TestableScheduler{mSelector, mFlinger, mSchedulerCallback};
Vishnu Naira0292282023-12-16 14:32:00 -0800100 surfaceflinger::frontend::LayerHierarchyBuilder mLayerHierarchyBuilder;
Dominik Laskowski98041832019-08-01 18:35:59 -0700101
Dominik Laskowski068173d2021-08-11 17:22:59 -0700102 ConnectionHandle mConnectionHandle;
103 MockEventThread* mEventThread;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700104 sp<MockEventThreadConnection> mEventThreadConnection;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700105};
106
107SchedulerTest::SchedulerTest() {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700108 auto eventThread = std::make_unique<MockEventThread>();
Ana Krulec0c8cd522018-08-31 12:27:28 -0700109 mEventThread = eventThread.get();
Ana Krulec85c39af2018-12-26 17:29:57 -0800110 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
111
Ady Abrahamd11bade2022-08-01 16:18:03 -0700112 mEventThreadConnection = sp<MockEventThreadConnection>::make(mEventThread);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700113
114 // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
115 // sure that call gets executed and returns an EventThread::Connection object.
Ady Abraham0f4a1b12019-06-04 16:04:04 -0700116 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
Ana Krulec0c8cd522018-08-31 12:27:28 -0700117 .WillRepeatedly(Return(mEventThreadConnection));
118
Ady Abrahama0a16272021-03-03 15:23:35 -0800119 mConnectionHandle = mScheduler->createConnection(std::move(eventThread));
Dominik Laskowski98041832019-08-01 18:35:59 -0700120 EXPECT_TRUE(mConnectionHandle);
Ady Abrahama0a16272021-03-03 15:23:35 -0800121
122 mFlinger.resetScheduler(mScheduler);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700123}
124
Dominik Laskowski8b01cc02020-07-14 19:02:41 -0700125} // namespace
Ana Krulec0c8cd522018-08-31 12:27:28 -0700126
Ana Krulec0c8cd522018-08-31 12:27:28 -0700127TEST_F(SchedulerTest, invalidConnectionHandle) {
Dominik Laskowski068173d2021-08-11 17:22:59 -0700128 ConnectionHandle handle;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700129
Ady Abrahama0a16272021-03-03 15:23:35 -0800130 const sp<IDisplayEventConnection> connection = mScheduler->createDisplayEventConnection(handle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700131
Dominik Laskowski98041832019-08-01 18:35:59 -0700132 EXPECT_FALSE(connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800133 EXPECT_FALSE(mScheduler->getEventConnection(handle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700134
135 // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads.
136 EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400137 mScheduler->onHotplugReceived(handle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700138
Dominik Laskowski98041832019-08-01 18:35:59 -0700139 std::string output;
Ana Krulec0c8cd522018-08-31 12:27:28 -0700140 EXPECT_CALL(*mEventThread, dump(_)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800141 mScheduler->dump(handle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700142 EXPECT_TRUE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700143
Ady Abraham9c53ee72020-07-22 21:16:18 -0700144 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(0);
Ady Abrahama0a16272021-03-03 15:23:35 -0800145 mScheduler->setDuration(handle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700146}
147
148TEST_F(SchedulerTest, validConnectionHandle) {
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700149 const sp<IDisplayEventConnection> connection =
Ady Abrahama0a16272021-03-03 15:23:35 -0800150 mScheduler->createDisplayEventConnection(mConnectionHandle);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700151
Dominik Laskowski98041832019-08-01 18:35:59 -0700152 ASSERT_EQ(mEventThreadConnection, connection);
Ady Abrahama0a16272021-03-03 15:23:35 -0800153 EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle));
Ana Krulec0c8cd522018-08-31 12:27:28 -0700154
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400155 EXPECT_CALL(*mEventThread, onHotplugReceived(kDisplayId1, false)).Times(1);
156 mScheduler->onHotplugReceived(mConnectionHandle, kDisplayId1, false);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700157
Dominik Laskowski98041832019-08-01 18:35:59 -0700158 std::string output("dump");
159 EXPECT_CALL(*mEventThread, dump(output)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800160 mScheduler->dump(mConnectionHandle, output);
Dominik Laskowski98041832019-08-01 18:35:59 -0700161 EXPECT_FALSE(output.empty());
Ana Krulec0c8cd522018-08-31 12:27:28 -0700162
Ady Abraham9c53ee72020-07-22 21:16:18 -0700163 EXPECT_CALL(*mEventThread, setDuration(10ns, 20ns)).Times(1);
Ady Abrahama0a16272021-03-03 15:23:35 -0800164 mScheduler->setDuration(mConnectionHandle, 10ns, 20ns);
Ana Krulec0c8cd522018-08-31 12:27:28 -0700165}
Dominik Laskowski98041832019-08-01 18:35:59 -0700166
Dominik Laskowski66295432023-03-14 12:25:36 -0400167TEST_F(SchedulerTest, registerDisplay) FTL_FAKE_GUARD(kMainThreadContext) {
Dominik Laskowski008bec02023-03-14 12:04:58 -0400168 // Hardware VSYNC should not change if the display is already registered.
Dominik Laskowski66295432023-03-14 12:25:36 -0400169 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId1, false)).Times(0);
Dominik Laskowski008bec02023-03-14 12:04:58 -0400170 mScheduler->registerDisplay(kDisplayId1,
171 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
172 kDisplay1Mode60->getId()));
173
Dominik Laskowski66295432023-03-14 12:25:36 -0400174 // TODO(b/241285191): Restore once VsyncSchedule::getPendingHardwareVsyncState is called by
175 // Scheduler::setDisplayPowerMode rather than SF::setPowerModeInternal.
176#if 0
Dominik Laskowski008bec02023-03-14 12:04:58 -0400177 // Hardware VSYNC should be disabled for newly registered displays.
Dominik Laskowski66295432023-03-14 12:25:36 -0400178 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId2, false)).Times(1);
179 EXPECT_CALL(mSchedulerCallback, requestHardwareVsync(kDisplayId3, false)).Times(1);
180#endif
Dominik Laskowski008bec02023-03-14 12:04:58 -0400181
182 mScheduler->registerDisplay(kDisplayId2,
183 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
184 kDisplay2Mode60->getId()));
185 mScheduler->registerDisplay(kDisplayId3,
186 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
187 kDisplay3Mode60->getId()));
Dominik Laskowski66295432023-03-14 12:25:36 -0400188
189 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId1)->getPendingHardwareVsyncState());
190 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId2)->getPendingHardwareVsyncState());
191 EXPECT_FALSE(mScheduler->getVsyncSchedule(kDisplayId3)->getPendingHardwareVsyncState());
Dominik Laskowski008bec02023-03-14 12:04:58 -0400192}
193
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200194TEST_F(SchedulerTest, chooseRefreshRateForContentIsNoopWhenModeSwitchingIsNotSupported) {
195 // The layer is registered at creation time and deregistered at destruction time.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700196 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700197
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200198 // recordLayerHistory should be a noop
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700199 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700200 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0, 0,
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000201 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700202 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700203
Rachel Lee6a9731d2022-06-06 17:08:14 -0700204 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500205 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700206
207 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700208 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700209
ramindani69b58e82022-09-26 16:48:36 -0700210 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700211 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
212 /*updateAttachedChoreographer*/ false);
Dominik Laskowski983f2b52020-06-25 16:54:06 -0700213}
214
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200215TEST_F(SchedulerTest, updateDisplayModes) {
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700216 ASSERT_EQ(0u, mScheduler->layerHistorySize());
Dominik Laskowski068173d2021-08-11 17:22:59 -0700217 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700218 ASSERT_EQ(1u, mScheduler->layerHistorySize());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200219
Dominik Laskowski596a2562022-10-28 11:26:12 -0400220 // Replace `mSelector` with a new `RefreshRateSelector` that has different display modes.
221 mScheduler->registerDisplay(kDisplayId1,
222 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
223 kDisplay1Mode60->getId()));
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200224
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700225 ASSERT_EQ(0u, mScheduler->getNumActiveLayers());
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700226 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0, 0,
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000227 LayerHistory::LayerUpdateType::Buffer);
Dominik Laskowski9c93d602021-10-07 19:38:26 -0700228 ASSERT_EQ(1u, mScheduler->getNumActiveLayers());
Marin Shalamanov2cde1002021-06-08 19:50:10 +0200229}
230
Dominik Laskowski068173d2021-08-11 17:22:59 -0700231TEST_F(SchedulerTest, dispatchCachedReportedMode) {
232 mScheduler->clearCachedReportedMode();
233
Ady Abraham690f4612021-07-01 23:24:03 -0700234 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Dominik Laskowski068173d2021-08-11 17:22:59 -0700235 EXPECT_NO_FATAL_FAILURE(mScheduler->dispatchCachedReportedMode());
Ana Krulec6ddd2612020-09-24 13:06:33 -0700236}
237
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100238TEST_F(SchedulerTest, onNonPrimaryDisplayModeChanged_invalidParameters) {
Ady Abraham690f4612021-07-01 23:24:03 -0700239 const auto mode = DisplayMode::Builder(hal::HWConfigId(0))
240 .setId(DisplayModeId(111))
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400241 .setPhysicalDisplayId(kDisplayId1)
Ady Abraham690f4612021-07-01 23:24:03 -0700242 .setVsyncPeriod(111111)
243 .build();
Ana Krulec6ddd2612020-09-24 13:06:33 -0700244
245 // If the handle is incorrect, the function should return before
Marin Shalamanova7fe3042021-01-29 21:02:08 +0100246 // onModeChange is called.
Dominik Laskowski068173d2021-08-11 17:22:59 -0700247 ConnectionHandle invalidHandle = {.id = 123};
Ady Abrahamace3d052022-11-17 16:25:05 -0800248 EXPECT_NO_FATAL_FAILURE(
249 mScheduler->onNonPrimaryDisplayModeChanged(invalidHandle,
250 {90_Hz, ftl::as_non_null(mode)}));
Ady Abraham690f4612021-07-01 23:24:03 -0700251 EXPECT_CALL(*mEventThread, onModeChanged(_)).Times(0);
Ana Krulec6ddd2612020-09-24 13:06:33 -0700252}
253
Ady Abraham899dcdb2021-06-15 16:56:21 -0700254TEST_F(SchedulerTest, calculateMaxAcquiredBufferCount) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700255 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 30ms));
256 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(90_Hz, 30ms));
257 EXPECT_EQ(3, mFlinger.calculateMaxAcquiredBufferCount(120_Hz, 30ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800258
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700259 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 40ms));
Ady Abraham564f9de2021-02-03 18:34:33 -0800260
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700261 EXPECT_EQ(1, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Piquea1456c12023-05-17 12:11:15 -0700262
Lloyd Pique30db6402023-06-26 18:56:51 +0000263 const auto savedMinAcquiredBuffers = mFlinger.mutableMinAcquiredBuffers();
264 mFlinger.mutableMinAcquiredBuffers() = 2;
Lloyd Piquea1456c12023-05-17 12:11:15 -0700265 EXPECT_EQ(2, mFlinger.calculateMaxAcquiredBufferCount(60_Hz, 10ms));
Lloyd Pique30db6402023-06-26 18:56:51 +0000266 mFlinger.mutableMinAcquiredBuffers() = savedMinAcquiredBuffers;
Ady Abraham564f9de2021-02-03 18:34:33 -0800267}
268
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200269MATCHER(Is120Hz, "") {
Ady Abrahamace3d052022-11-17 16:25:05 -0800270 return isApproxEqual(arg.front().mode.fps, 120_Hz);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200271}
272
273TEST_F(SchedulerTest, chooseRefreshRateForContentSelectsMaxRefreshRate) {
Dominik Laskowski596a2562022-10-28 11:26:12 -0400274 mScheduler->registerDisplay(kDisplayId1,
275 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
276 kDisplay1Mode60->getId()));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200277
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800278 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
279 EXPECT_CALL(*layer, isVisible()).WillOnce(Return(true));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200280
Vishnu Nair47b7bb42023-09-29 16:27:33 -0700281 mScheduler->recordLayerHistory(layer->getSequence(), layer->getLayerProps(), 0, systemTime(),
Vishnu Nairef68d6d2023-02-28 06:18:27 +0000282 LayerHistory::LayerUpdateType::Buffer);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200283
Rachel Lee6a9731d2022-06-06 17:08:14 -0700284 constexpr hal::PowerMode kPowerModeOn = hal::PowerMode::ON;
Leon Scroggins III67388622023-02-06 20:36:20 -0500285 FTL_FAKE_GUARD(kMainThreadContext, mScheduler->setDisplayPowerMode(kDisplayId1, kPowerModeOn));
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200286
287 constexpr uint32_t kDisplayArea = 999'999;
Ady Abrahamed3290f2021-05-17 15:12:14 -0700288 mScheduler->onActiveDisplayAreaChanged(kDisplayArea);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200289
ramindani69b58e82022-09-26 16:48:36 -0700290 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(Is120Hz())).Times(1);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700291 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
292 /*updateAttachedChoreographer*/ false);
Dominik Laskowski0c41ffa2021-12-24 16:45:12 -0800293
294 // No-op if layer requirements have not changed.
ramindani69b58e82022-09-26 16:48:36 -0700295 EXPECT_CALL(mSchedulerCallback, requestDisplayModes(_)).Times(0);
Ady Abraham822ecbd2023-07-07 16:16:09 -0700296 mScheduler->chooseRefreshRateForContent(/*LayerHierarchy*/ nullptr,
297 /*updateAttachedChoreographer*/ false);
Marin Shalamanov4c7831e2021-06-08 20:44:06 +0200298}
299
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400300TEST_F(SchedulerTest, chooseDisplayModesSingleDisplay) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400301 mScheduler->registerDisplay(kDisplayId1,
302 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
303 kDisplay1Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700304
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400305 std::vector<RefreshRateSelector::LayerRequirement> layers =
306 std::vector<RefreshRateSelector::LayerRequirement>({{.weight = 1.f}, {.weight = 1.f}});
ramindani69b58e82022-09-26 16:48:36 -0700307 mScheduler->setContentRequirements(layers);
308 GlobalSignals globalSignals = {.idle = true};
309 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
310
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400311 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
312
313 auto modeChoices = mScheduler->chooseDisplayModes();
314 ASSERT_EQ(1u, modeChoices.size());
315
316 auto choice = modeChoices.get(kDisplayId1);
317 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800318 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700319
320 globalSignals = {.idle = false};
321 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400322
323 modeChoices = mScheduler->chooseDisplayModes();
324 ASSERT_EQ(1u, modeChoices.size());
325
326 choice = modeChoices.get(kDisplayId1);
327 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800328 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700329
330 globalSignals = {.touch = true};
331 mScheduler->replaceTouchTimer(10);
332 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700333
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400334 modeChoices = mScheduler->chooseDisplayModes();
335 ASSERT_EQ(1u, modeChoices.size());
336
337 choice = modeChoices.get(kDisplayId1);
338 ASSERT_TRUE(choice);
Ady Abrahamace3d052022-11-17 16:25:05 -0800339 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, globalSignals));
ramindani69b58e82022-09-26 16:48:36 -0700340}
341
Rachel Lee6ed96c92024-02-07 14:37:38 -0800342TEST_F(SchedulerTest, chooseDisplayModesSingleDisplayHighHintTouchSignal) {
343 mScheduler->registerDisplay(kDisplayId1,
344 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
345 kDisplay1Mode60->getId()));
346
347 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
348
349 std::vector<RefreshRateSelector::LayerRequirement> layers =
350 std::vector<RefreshRateSelector::LayerRequirement>({{.weight = 1.f}, {.weight = 1.f}});
351 auto& lr1 = layers[0];
352 auto& lr2 = layers[1];
353
354 // Scenario that is similar to game. Expects no touch boost.
355 lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
356 lr1.frameRateCategory = FrameRateCategory::HighHint;
357 lr1.name = "ExplicitCategory HighHint";
358 lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitDefault;
359 lr2.desiredRefreshRate = 30_Hz;
360 lr2.name = "30Hz ExplicitDefault";
361 mScheduler->setContentRequirements(layers);
362 auto modeChoices = mScheduler->chooseDisplayModes();
363 ASSERT_EQ(1u, modeChoices.size());
364 auto choice = modeChoices.get(kDisplayId1);
365 ASSERT_TRUE(choice);
366 EXPECT_EQ(choice->get(), DisplayModeChoice({60_Hz, kDisplay1Mode60}, {.touch = false}));
367
368 // Scenario that is similar to video playback and interaction. Expects touch boost.
369 lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
370 lr1.frameRateCategory = FrameRateCategory::HighHint;
371 lr1.name = "ExplicitCategory HighHint";
372 lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitExactOrMultiple;
373 lr2.desiredRefreshRate = 30_Hz;
374 lr2.name = "30Hz ExplicitExactOrMultiple";
375 mScheduler->setContentRequirements(layers);
376 modeChoices = mScheduler->chooseDisplayModes();
377 ASSERT_EQ(1u, modeChoices.size());
378 choice = modeChoices.get(kDisplayId1);
379 ASSERT_TRUE(choice);
380 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, {.touch = true}));
381
382 // Scenario with explicit category and HighHint. Expects touch boost.
383 lr1.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
384 lr1.frameRateCategory = FrameRateCategory::HighHint;
385 lr1.name = "ExplicitCategory HighHint";
386 lr2.vote = RefreshRateSelector::LayerVoteType::ExplicitCategory;
387 lr2.frameRateCategory = FrameRateCategory::Low;
388 lr2.name = "ExplicitCategory Low";
389 mScheduler->setContentRequirements(layers);
390 modeChoices = mScheduler->chooseDisplayModes();
391 ASSERT_EQ(1u, modeChoices.size());
392 choice = modeChoices.get(kDisplayId1);
393 ASSERT_TRUE(choice);
394 EXPECT_EQ(choice->get(), DisplayModeChoice({120_Hz, kDisplay1Mode120}, {.touch = true}));
395}
396
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400397TEST_F(SchedulerTest, chooseDisplayModesMultipleDisplays) {
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400398 mScheduler->registerDisplay(kDisplayId1,
399 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
400 kDisplay1Mode60->getId()));
401 mScheduler->registerDisplay(kDisplayId2,
402 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
403 kDisplay2Mode60->getId()));
ramindani69b58e82022-09-26 16:48:36 -0700404
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400405 using DisplayModeChoice = TestableScheduler::DisplayModeChoice;
406 TestableScheduler::DisplayModeChoiceMap expectedChoices;
ramindani69b58e82022-09-26 16:48:36 -0700407
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400408 {
409 const GlobalSignals globalSignals = {.idle = true};
410 expectedChoices =
411 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800412 DisplayModeChoice>(kDisplayId1,
413 FrameRateMode{60_Hz, kDisplay1Mode60},
414 globalSignals)(kDisplayId2,
415 FrameRateMode{60_Hz,
416 kDisplay2Mode60},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400417 globalSignals);
418
Dominik Laskowskid82e0f02022-10-26 15:23:04 -0400419 std::vector<RefreshRateSelector::LayerRequirement> layers = {{.weight = 1.f},
420 {.weight = 1.f}};
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400421 mScheduler->setContentRequirements(layers);
422 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
423
424 const auto actualChoices = mScheduler->chooseDisplayModes();
425 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700426 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400427 {
428 const GlobalSignals globalSignals = {.idle = false};
429 expectedChoices =
430 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800431 DisplayModeChoice>(kDisplayId1,
432 FrameRateMode{120_Hz, kDisplay1Mode120},
433 globalSignals)(kDisplayId2,
434 FrameRateMode{120_Hz,
435 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400436 globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700437
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400438 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700439
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400440 const auto actualChoices = mScheduler->chooseDisplayModes();
441 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700442 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400443 {
444 const GlobalSignals globalSignals = {.touch = true};
445 mScheduler->replaceTouchTimer(10);
446 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani69b58e82022-09-26 16:48:36 -0700447
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400448 expectedChoices =
449 ftl::init::map<const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800450 DisplayModeChoice>(kDisplayId1,
451 FrameRateMode{120_Hz, kDisplay1Mode120},
452 globalSignals)(kDisplayId2,
453 FrameRateMode{120_Hz,
454 kDisplay2Mode120},
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400455 globalSignals);
456
457 const auto actualChoices = mScheduler->chooseDisplayModes();
458 EXPECT_EQ(expectedChoices, actualChoices);
ramindani69b58e82022-09-26 16:48:36 -0700459 }
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400460 {
ramindani22f2ead2023-04-21 10:27:11 -0700461 // The kDisplayId3 does not support 120Hz, The pacesetter display rate is chosen to be 120
462 // Hz. In this case only the display kDisplayId3 choose 60Hz as it does not support 120Hz.
Dominik Laskowskib5a094b2022-10-27 12:00:12 -0400463 mScheduler
464 ->registerDisplay(kDisplayId3,
465 std::make_shared<RefreshRateSelector>(kDisplay3Modes,
466 kDisplay3Mode60->getId()));
Dominik Laskowski327d6092022-10-11 18:05:08 -0400467
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400468 const GlobalSignals globalSignals = {.touch = true};
469 mScheduler->replaceTouchTimer(10);
470 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
ramindani7c487282022-10-10 16:17:51 -0700471
Ady Abrahamace3d052022-11-17 16:25:05 -0800472 expectedChoices = ftl::init::map<
473 const PhysicalDisplayId&,
ramindani22f2ead2023-04-21 10:27:11 -0700474 DisplayModeChoice>(kDisplayId1, FrameRateMode{120_Hz, kDisplay1Mode120},
475 globalSignals)(kDisplayId2,
476 FrameRateMode{120_Hz, kDisplay2Mode120},
477 globalSignals)(kDisplayId3,
478 FrameRateMode{60_Hz,
479 kDisplay3Mode60},
480 globalSignals);
481
482 const auto actualChoices = mScheduler->chooseDisplayModes();
483 EXPECT_EQ(expectedChoices, actualChoices);
484 }
485 {
486 // We should choose 60Hz despite the touch signal as pacesetter only supports 60Hz
487 mScheduler->setPacesetterDisplay(kDisplayId3);
488 const GlobalSignals globalSignals = {.touch = true};
489 mScheduler->replaceTouchTimer(10);
490 mScheduler->setTouchStateAndIdleTimerPolicy(globalSignals);
491
492 expectedChoices = ftl::init::map<
493 const PhysicalDisplayId&,
Ady Abrahamace3d052022-11-17 16:25:05 -0800494 DisplayModeChoice>(kDisplayId1, FrameRateMode{60_Hz, kDisplay1Mode60},
495 globalSignals)(kDisplayId2,
496 FrameRateMode{60_Hz, kDisplay2Mode60},
497 globalSignals)(kDisplayId3,
498 FrameRateMode{60_Hz,
499 kDisplay3Mode60},
500 globalSignals);
Dominik Laskowski530d6bd2022-10-10 16:55:54 -0400501
502 const auto actualChoices = mScheduler->chooseDisplayModes();
503 EXPECT_EQ(expectedChoices, actualChoices);
ramindani7c487282022-10-10 16:17:51 -0700504 }
ramindani69b58e82022-09-26 16:48:36 -0700505}
506
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400507TEST_F(SchedulerTest, onFrameSignalMultipleDisplays) {
508 mScheduler->registerDisplay(kDisplayId1,
509 std::make_shared<RefreshRateSelector>(kDisplay1Modes,
510 kDisplay1Mode60->getId()));
511 mScheduler->registerDisplay(kDisplayId2,
512 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
513 kDisplay2Mode60->getId()));
514
515 using VsyncIds = std::vector<std::pair<PhysicalDisplayId, VsyncId>>;
516
517 struct Compositor final : ICompositor {
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500518 explicit Compositor(TestableScheduler& scheduler) : scheduler(scheduler) {}
519
520 TestableScheduler& scheduler;
521
522 struct {
523 PhysicalDisplayId commit;
524 PhysicalDisplayId composite;
525 } pacesetterIds;
526
527 struct {
528 VsyncIds commit;
529 VsyncIds composite;
530 } vsyncIds;
531
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400532 bool committed = true;
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500533 bool changePacesetter = false;
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400534
535 void configure() override {}
536
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500537 bool commit(PhysicalDisplayId pacesetterId,
538 const scheduler::FrameTargets& targets) override {
539 pacesetterIds.commit = pacesetterId;
540
541 vsyncIds.commit.clear();
542 vsyncIds.composite.clear();
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400543
544 for (const auto& [id, target] : targets) {
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500545 vsyncIds.commit.emplace_back(id, target->vsyncId());
546 }
547
548 if (changePacesetter) {
549 scheduler.setPacesetterDisplay(kDisplayId2);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400550 }
551
552 return committed;
553 }
554
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500555 CompositeResultsPerDisplay composite(PhysicalDisplayId pacesetterId,
556 const scheduler::FrameTargeters& targeters) override {
557 pacesetterIds.composite = pacesetterId;
558
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400559 CompositeResultsPerDisplay results;
560
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500561 for (const auto& [id, targeter] : targeters) {
562 vsyncIds.composite.emplace_back(id, targeter->target().vsyncId());
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400563 results.try_emplace(id,
564 CompositeResult{.compositionCoverage =
565 CompositionCoverage::Hwc});
566 }
567
568 return results;
569 }
570
571 void sample() override {}
ramindaniae645822024-01-11 10:57:29 -0800572 void sendNotifyExpectedPresentHint(PhysicalDisplayId) override {}
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500573 } compositor(*mScheduler);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400574
575 mScheduler->doFrameSignal(compositor, VsyncId(42));
576
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500577 const auto makeVsyncIds = [](VsyncId vsyncId, bool swap = false) -> VsyncIds {
578 if (swap) {
579 return {{kDisplayId2, vsyncId}, {kDisplayId1, vsyncId}};
580 } else {
581 return {{kDisplayId1, vsyncId}, {kDisplayId2, vsyncId}};
582 }
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400583 };
584
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500585 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
586 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
587 EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.commit);
588 EXPECT_EQ(makeVsyncIds(VsyncId(42)), compositor.vsyncIds.composite);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400589
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500590 // FrameTargets should be updated despite the skipped commit.
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400591 compositor.committed = false;
592 mScheduler->doFrameSignal(compositor, VsyncId(43));
593
Dominik Laskowskifb4b7372023-11-22 09:56:54 -0500594 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
595 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.composite);
596 EXPECT_EQ(makeVsyncIds(VsyncId(43)), compositor.vsyncIds.commit);
597 EXPECT_TRUE(compositor.vsyncIds.composite.empty());
598
599 // The pacesetter may change during commit.
600 compositor.committed = true;
601 compositor.changePacesetter = true;
602 mScheduler->doFrameSignal(compositor, VsyncId(44));
603
604 EXPECT_EQ(kDisplayId1, compositor.pacesetterIds.commit);
605 EXPECT_EQ(kDisplayId2, compositor.pacesetterIds.composite);
606 EXPECT_EQ(makeVsyncIds(VsyncId(44)), compositor.vsyncIds.commit);
607 EXPECT_EQ(makeVsyncIds(VsyncId(44), true), compositor.vsyncIds.composite);
Dominik Laskowski50e2e4d2023-10-04 10:58:28 -0400608}
609
ramindani0491e642023-11-16 17:42:14 -0800610TEST_F(SchedulerTest, nextFrameIntervalTest) {
611 SET_FLAG_FOR_TEST(flags::vrr_config, true);
612
613 static constexpr size_t kHistorySize = 10;
614 static constexpr size_t kMinimumSamplesForPrediction = 6;
615 static constexpr size_t kOutlierTolerancePercent = 25;
616 const auto refreshRate = Fps::fromPeriodNsecs(500);
617 auto frameRate = Fps::fromPeriodNsecs(1000);
618
619 const ftl::NonNull<DisplayModePtr> kMode = ftl::as_non_null(
620 createVrrDisplayMode(DisplayModeId(0), refreshRate,
621 hal::VrrConfig{.minFrameIntervalNs = static_cast<int32_t>(
622 frameRate.getPeriodNsecs())}));
623 std::shared_ptr<VSyncPredictor> vrrTracker =
624 std::make_shared<VSyncPredictor>(kMode, kHistorySize, kMinimumSamplesForPrediction,
ramindaniae645822024-01-11 10:57:29 -0800625 kOutlierTolerancePercent);
ramindani0491e642023-11-16 17:42:14 -0800626 std::shared_ptr<RefreshRateSelector> vrrSelectorPtr =
627 std::make_shared<RefreshRateSelector>(makeModes(kMode), kMode->getId());
628 TestableScheduler scheduler{std::make_unique<android::mock::VsyncController>(),
629 vrrTracker,
630 vrrSelectorPtr,
Leon Scroggins III823d4ca2023-12-12 16:57:34 -0500631 mFlinger.getFactory(),
632 mFlinger.getTimeStats(),
ramindaniae645822024-01-11 10:57:29 -0800633 mSchedulerCallback};
ramindani0491e642023-11-16 17:42:14 -0800634
635 scheduler.registerDisplay(kMode->getPhysicalDisplayId(), vrrSelectorPtr, vrrTracker);
636 vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
637 scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate);
638 vrrTracker->addVsyncTimestamp(0);
639
ramindani0491e642023-11-16 17:42:14 -0800640 EXPECT_EQ(Fps::fromPeriodNsecs(1000),
641 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abraham4335afd2023-12-18 19:10:47 -0800642 TimePoint::fromNs(1000)));
ramindani0491e642023-11-16 17:42:14 -0800643 EXPECT_EQ(Fps::fromPeriodNsecs(1000),
644 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abraham4335afd2023-12-18 19:10:47 -0800645 TimePoint::fromNs(2000)));
ramindani0491e642023-11-16 17:42:14 -0800646
Ady Abraham4335afd2023-12-18 19:10:47 -0800647 // Not crossing the min frame period
648 EXPECT_EQ(Fps::fromPeriodNsecs(1500),
649 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
650 TimePoint::fromNs(2500)));
ramindani0491e642023-11-16 17:42:14 -0800651 // Change render rate
652 frameRate = Fps::fromPeriodNsecs(2000);
653 vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
654 scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate);
655
656 EXPECT_EQ(Fps::fromPeriodNsecs(2000),
657 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abraham4335afd2023-12-18 19:10:47 -0800658 TimePoint::fromNs(2000)));
ramindani0491e642023-11-16 17:42:14 -0800659 EXPECT_EQ(Fps::fromPeriodNsecs(2000),
660 scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
Ady Abraham4335afd2023-12-18 19:10:47 -0800661 TimePoint::fromNs(4000)));
ramindani0491e642023-11-16 17:42:14 -0800662}
663
Leon Scroggins III792ea802023-11-27 17:32:51 -0500664TEST_F(SchedulerTest, resyncAllToHardwareVsync) FTL_FAKE_GUARD(kMainThreadContext) {
665 // resyncAllToHardwareVsync will result in requesting hardware VSYNC on both displays, since
666 // they are both on.
667 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
668 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, true)).Times(1);
669
670 mScheduler->registerDisplay(kDisplayId2,
671 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
672 kDisplay2Mode60->getId()));
673 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
674 mScheduler->setDisplayPowerMode(kDisplayId2, hal::PowerMode::ON);
675
676 static constexpr bool kDisallow = true;
677 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
678 mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
679
680 static constexpr bool kAllowToEnable = true;
681 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
682}
683
684TEST_F(SchedulerTest, resyncAllDoNotAllow) FTL_FAKE_GUARD(kMainThreadContext) {
685 // Without setting allowToEnable to true, resyncAllToHardwareVsync does not
686 // result in requesting hardware VSYNC.
687 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, _)).Times(0);
688
689 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
690
691 static constexpr bool kDisallow = true;
692 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
693
694 static constexpr bool kAllowToEnable = false;
695 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
696}
697
698TEST_F(SchedulerTest, resyncAllSkipsOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) {
699 SET_FLAG_FOR_TEST(flags::multithreaded_present, true);
700
701 // resyncAllToHardwareVsync will result in requesting hardware VSYNC on display 1, which is on,
702 // but not on display 2, which is off.
703 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
704 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, _)).Times(0);
705
706 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
707
708 mScheduler->registerDisplay(kDisplayId2,
709 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
710 kDisplay2Mode60->getId()));
711 ASSERT_EQ(hal::PowerMode::OFF, mScheduler->getDisplayPowerMode(kDisplayId2));
712
713 static constexpr bool kDisallow = true;
714 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
715 mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
716
717 static constexpr bool kAllowToEnable = true;
718 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
719}
720
721TEST_F(SchedulerTest, resyncAllLegacyAppliesToOffDisplays) FTL_FAKE_GUARD(kMainThreadContext) {
722 SET_FLAG_FOR_TEST(flags::multithreaded_present, false);
723
724 // In the legacy code, prior to the flag, resync applied to OFF displays.
725 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId1, true)).Times(1);
726 EXPECT_CALL(mScheduler->mockRequestHardwareVsync, Call(kDisplayId2, true)).Times(1);
727
728 mScheduler->setDisplayPowerMode(kDisplayId1, hal::PowerMode::ON);
729
730 mScheduler->registerDisplay(kDisplayId2,
731 std::make_shared<RefreshRateSelector>(kDisplay2Modes,
732 kDisplay2Mode60->getId()));
733 ASSERT_EQ(hal::PowerMode::OFF, mScheduler->getDisplayPowerMode(kDisplayId2));
734
735 static constexpr bool kDisallow = true;
736 mScheduler->disableHardwareVsync(kDisplayId1, kDisallow);
737 mScheduler->disableHardwareVsync(kDisplayId2, kDisallow);
738
739 static constexpr bool kAllowToEnable = true;
740 mScheduler->resyncAllToHardwareVsync(kAllowToEnable);
741}
742
Ady Abraham822ecbd2023-07-07 16:16:09 -0700743class AttachedChoreographerTest : public SchedulerTest {
744protected:
745 void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
746 Fps expectedChoreographerFps);
747};
748
749TEST_F(AttachedChoreographerTest, registerSingle) {
750 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
751
752 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
753
754 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
755 const sp<IDisplayEventConnection> connection =
756 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
757
758 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
759 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
760 EXPECT_EQ(1u,
761 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
762 EXPECT_FALSE(
763 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
764}
765
766TEST_F(AttachedChoreographerTest, registerMultipleOnSameLayer) {
767 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
768
769 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
770 const auto handle = layer->getHandle();
771
772 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
773
774 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_))
775 .WillOnce(Return(0))
776 .WillOnce(Return(0));
777
778 const auto mockConnection1 = sp<MockEventThreadConnection>::make(mEventThread);
779 const auto mockConnection2 = sp<MockEventThreadConnection>::make(mEventThread);
780 EXPECT_CALL(*mEventThread, createEventConnection(_, _))
781 .WillOnce(Return(mockConnection1))
782 .WillOnce(Return(mockConnection2));
783
784 const sp<IDisplayEventConnection> connection1 =
785 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
786 const sp<IDisplayEventConnection> connection2 =
787 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, handle);
788
789 EXPECT_EQ(1u, mScheduler->mutableAttachedChoreographers().size());
790 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
791 EXPECT_EQ(2u,
792 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
793 EXPECT_FALSE(
794 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate.isValid());
795}
796
797TEST_F(AttachedChoreographerTest, registerMultipleOnDifferentLayers) {
798 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
799
800 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
801 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
802
803 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached).Times(2);
804 const sp<IDisplayEventConnection> connection1 =
805 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer1->getHandle());
806 const sp<IDisplayEventConnection> connection2 =
807 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer2->getHandle());
808
809 EXPECT_EQ(2u, mScheduler->mutableAttachedChoreographers().size());
810
811 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer1->getSequence()));
812 EXPECT_EQ(1u,
813 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()]
814 .connections.size());
815 EXPECT_FALSE(
816 mScheduler->mutableAttachedChoreographers()[layer1->getSequence()].frameRate.isValid());
817
818 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer2->getSequence()));
819 EXPECT_EQ(1u,
820 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()]
821 .connections.size());
822 EXPECT_FALSE(
823 mScheduler->mutableAttachedChoreographers()[layer2->getSequence()].frameRate.isValid());
824}
825
826TEST_F(AttachedChoreographerTest, removedWhenConnectionIsGone) {
827 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
828
829 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
830
831 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
832
833 sp<IDisplayEventConnection> connection =
834 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
835
836 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
837 EXPECT_EQ(1u,
838 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.size());
839
840 // The connection is used all over this test, so it is quite hard to release it from here.
841 // Instead, we just do a small shortcut.
842 {
843 EXPECT_CALL(*mEventThread, registerDisplayEventConnection(_)).WillOnce(Return(0));
844 sp<MockEventThreadConnection> mockConnection =
845 sp<MockEventThreadConnection>::make(mEventThread);
846 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.clear();
847 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].connections.emplace(
848 mockConnection);
849 }
850
851 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
852 LayerHierarchy hierarchy(&layerState);
853 mScheduler->updateAttachedChoreographers(hierarchy, 60_Hz);
854 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
855}
856
857TEST_F(AttachedChoreographerTest, removedWhenLayerIsGone) {
858 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
859
860 sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
861
862 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
863 const sp<IDisplayEventConnection> connection =
864 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
865
866 layer.clear();
867 mFlinger.mutableLayersPendingRemoval().clear();
868 EXPECT_TRUE(mScheduler->mutableAttachedChoreographers().empty());
869}
870
871void AttachedChoreographerTest::frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility,
872 Fps displayFps,
873 Fps expectedChoreographerFps) {
874 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
875
876 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
877 sp<IDisplayEventConnection> connection =
878 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
879
880 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
881 LayerHierarchy hierarchy(&layerState);
882
883 layerState.frameRate = layerFps.getValue();
884 layerState.frameRateCompatibility = frameRateCompatibility;
885
886 mScheduler->updateAttachedChoreographers(hierarchy, displayFps);
887
888 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
889 EXPECT_EQ(expectedChoreographerFps,
890 mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
891 EXPECT_EQ(expectedChoreographerFps, mEventThreadConnection->frameRate);
892}
893
894TEST_F(AttachedChoreographerTest, setsFrameRateDefault) {
895 Fps layerFps = 30_Hz;
896 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
897 Fps displayFps = 60_Hz;
898 Fps expectedChoreographerFps = 30_Hz;
899
900 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
901
902 layerFps = Fps::fromValue(32.7f);
903 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
904}
905
906TEST_F(AttachedChoreographerTest, setsFrameRateExact) {
907 Fps layerFps = 30_Hz;
908 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_EXACT;
909 Fps displayFps = 60_Hz;
910 Fps expectedChoreographerFps = 30_Hz;
911
912 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
913
914 layerFps = Fps::fromValue(32.7f);
915 expectedChoreographerFps = {};
916 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
917}
918
919TEST_F(AttachedChoreographerTest, setsFrameRateExactOrMultiple) {
920 Fps layerFps = 30_Hz;
921 int8_t frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
922 Fps displayFps = 60_Hz;
923 Fps expectedChoreographerFps = 30_Hz;
924
925 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
926
927 layerFps = Fps::fromValue(32.7f);
928 expectedChoreographerFps = {};
929 frameRateTestScenario(layerFps, frameRateCompatibility, displayFps, expectedChoreographerFps);
930}
931
932TEST_F(AttachedChoreographerTest, setsFrameRateParent) {
933 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
934 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
935
936 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
937 sp<IDisplayEventConnection> connection =
938 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
939
940 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
941 LayerHierarchy parentHierarchy(&parentState);
942
943 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
944 LayerHierarchy hierarchy(&layerState);
945 parentHierarchy.mChildren.push_back(
946 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
947
948 layerState.frameRate = (30_Hz).getValue();
949 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
950
951 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
952
953 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
954
955 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
956}
957
958TEST_F(AttachedChoreographerTest, setsFrameRateParent2Children) {
959 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
960 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
961 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
962
963 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
964 sp<IDisplayEventConnection> connection =
965 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
966
967 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
968 LayerHierarchy parentHierarchy(&parentState);
969
970 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
971 LayerHierarchy layer1Hierarchy(&layer1State);
972 parentHierarchy.mChildren.push_back(
973 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
974
975 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
976 LayerHierarchy layer2Hierarchy(&layer2State);
977 parentHierarchy.mChildren.push_back(
978 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
979
980 layer1State.frameRate = (30_Hz).getValue();
981 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
982
983 layer2State.frameRate = (20_Hz).getValue();
984 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
985
986 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
987
988 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
989
990 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
991}
992
993TEST_F(AttachedChoreographerTest, setsFrameRateParentConflictingChildren) {
994 const sp<MockLayer> layer1 = sp<MockLayer>::make(mFlinger.flinger());
995 const sp<MockLayer> layer2 = sp<MockLayer>::make(mFlinger.flinger());
996 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
997
998 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
999 sp<IDisplayEventConnection> connection =
1000 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, parent->getHandle());
1001
1002 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
1003 LayerHierarchy parentHierarchy(&parentState);
1004
1005 RequestedLayerState layer1State(LayerCreationArgs(layer1->getSequence()));
1006 LayerHierarchy layer1Hierarchy(&layer1State);
1007 parentHierarchy.mChildren.push_back(
1008 std::make_pair(&layer1Hierarchy, LayerHierarchy::Variant::Attached));
1009
1010 RequestedLayerState layer2State(LayerCreationArgs(layer1->getSequence()));
1011 LayerHierarchy layer2Hierarchy(&layer2State);
1012 parentHierarchy.mChildren.push_back(
1013 std::make_pair(&layer2Hierarchy, LayerHierarchy::Variant::Attached));
1014
1015 layer1State.frameRate = (30_Hz).getValue();
1016 layer1State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1017
1018 layer2State.frameRate = (25_Hz).getValue();
1019 layer2State.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1020
1021 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1022
1023 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(parent->getSequence()));
1024
1025 EXPECT_EQ(Fps(), mScheduler->mutableAttachedChoreographers()[parent->getSequence()].frameRate);
1026}
1027
1028TEST_F(AttachedChoreographerTest, setsFrameRateChild) {
1029 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
1030 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
1031
1032 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
1033 sp<IDisplayEventConnection> connection =
1034 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
1035
1036 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
1037 LayerHierarchy parentHierarchy(&parentState);
1038
1039 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
1040 LayerHierarchy hierarchy(&layerState);
1041 parentHierarchy.mChildren.push_back(
1042 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
1043
1044 parentState.frameRate = (30_Hz).getValue();
1045 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1046
1047 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1048
1049 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
1050
1051 EXPECT_EQ(30_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
1052}
1053
1054TEST_F(AttachedChoreographerTest, setsFrameRateChildNotOverriddenByParent) {
1055 const sp<MockLayer> layer = sp<MockLayer>::make(mFlinger.flinger());
1056 const sp<MockLayer> parent = sp<MockLayer>::make(mFlinger.flinger());
1057
1058 EXPECT_CALL(mSchedulerCallback, onChoreographerAttached);
1059 sp<IDisplayEventConnection> connection =
1060 mScheduler->createDisplayEventConnection(mConnectionHandle, {}, layer->getHandle());
1061
1062 RequestedLayerState parentState(LayerCreationArgs(parent->getSequence()));
1063 LayerHierarchy parentHierarchy(&parentState);
1064
1065 RequestedLayerState layerState(LayerCreationArgs(layer->getSequence()));
1066 LayerHierarchy hierarchy(&layerState);
1067 parentHierarchy.mChildren.push_back(
1068 std::make_pair(&hierarchy, LayerHierarchy::Variant::Attached));
1069
1070 parentState.frameRate = (30_Hz).getValue();
1071 parentState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1072
1073 layerState.frameRate = (60_Hz).getValue();
1074 layerState.frameRateCompatibility = ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT;
1075
1076 mScheduler->updateAttachedChoreographers(parentHierarchy, 120_Hz);
1077
1078 ASSERT_EQ(1u, mScheduler->mutableAttachedChoreographers().count(layer->getSequence()));
1079
1080 EXPECT_EQ(60_Hz, mScheduler->mutableAttachedChoreographers()[layer->getSequence()].frameRate);
1081}
1082
Dominik Laskowski068173d2021-08-11 17:22:59 -07001083} // namespace android::scheduler