blob: fab1f6d451ac94f8114e52b2107cfc027d8f1f78 [file] [log] [blame]
Valerie Haud251afb2019-03-29 14:19:02 -07001/*
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
17#undef LOG_TAG
Ying Wei1fd9bfc2023-06-29 16:47:00 +000018#define LOG_TAG "TransactionApplicationTest"
Valerie Haud251afb2019-03-29 14:19:02 -070019
Vishnu Nair0a51a872024-07-22 23:08:39 +000020#include <binder/Binder.h>
Ady Abrahambb1ad762024-03-27 18:31:28 -070021#include <common/test/FlagUtils.h>
Valerie Haud251afb2019-03-29 14:19:02 -070022#include <compositionengine/Display.h>
23#include <compositionengine/mock/DisplaySurface.h>
24#include <gmock/gmock.h>
25#include <gtest/gtest.h>
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070026#include <gui/LayerState.h>
Valerie Haud251afb2019-03-29 14:19:02 -070027#include <gui/SurfaceComposerClient.h>
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070028#include <gui/fake/BufferData.h>
Valerie Haud251afb2019-03-29 14:19:02 -070029#include <log/log.h>
Vishnu Nair0a51a872024-07-22 23:08:39 +000030#include <renderengine/mock/RenderEngine.h>
ramindani4d48f902021-09-20 21:07:45 +000031#include <ui/MockFence.h>
Valerie Haud251afb2019-03-29 14:19:02 -070032#include <utils/String8.h>
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070033#include <vector>
Dominik Laskowski068173d2021-08-11 17:22:59 -070034
Vishnu Naira61e4fb2022-10-18 18:29:37 +000035#include "FrontEnd/TransactionHandler.h"
Valerie Haud251afb2019-03-29 14:19:02 -070036#include "TestableSurfaceFlinger.h"
Vishnu Nair40fff5c2022-11-04 02:46:28 +000037#include "TransactionState.h"
Valerie Haud251afb2019-03-29 14:19:02 -070038
Ady Abrahambb1ad762024-03-27 18:31:28 -070039#include <com_android_graphics_surfaceflinger_flags.h>
40
Valerie Haud251afb2019-03-29 14:19:02 -070041namespace android {
42
Ady Abrahambb1ad762024-03-27 18:31:28 -070043using namespace com::android::graphics::surfaceflinger;
Valerie Haud251afb2019-03-29 14:19:02 -070044using testing::_;
45using testing::Return;
46
Vishnu Nairaf6d2972022-11-18 06:26:38 +000047using frontend::TransactionHandler;
48
Vishnu Nair1523dad2022-09-29 16:05:18 -070049constexpr nsecs_t TRANSACTION_TIMEOUT = s2ns(5);
Valerie Haud251afb2019-03-29 14:19:02 -070050class TransactionApplicationTest : public testing::Test {
51public:
52 TransactionApplicationTest() {
53 const ::testing::TestInfo* const test_info =
54 ::testing::UnitTest::GetInstance()->current_test_info();
55 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
56
Dominik Laskowskiaee9a622023-02-11 14:24:19 -050057 mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
58 mFlinger.setupMockScheduler();
Vishnu Nair0a51a872024-07-22 23:08:39 +000059 mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
Dominik Laskowskiaee9a622023-02-11 14:24:19 -050060 mFlinger.flinger()->addTransactionReadyFilters();
Valerie Haud251afb2019-03-29 14:19:02 -070061 }
62
63 ~TransactionApplicationTest() {
64 const ::testing::TestInfo* const test_info =
65 ::testing::UnitTest::GetInstance()->current_test_info();
66 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
67 }
68
Valerie Haud251afb2019-03-29 14:19:02 -070069 TestableSurfaceFlinger mFlinger;
Vishnu Nair0a51a872024-07-22 23:08:39 +000070 renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
Valerie Haud251afb2019-03-29 14:19:02 -070071
Valerie Haud251afb2019-03-29 14:19:02 -070072 struct TransactionInfo {
73 Vector<ComposerState> states;
74 Vector<DisplayState> displays;
75 uint32_t flags = 0;
76 sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
77 InputWindowCommands inputWindowCommands;
Ady Abrahamf0c56492020-12-17 18:04:15 -080078 int64_t desiredPresentTime = 0;
79 bool isAutoTimestamp = true;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100080 FrameTimelineInfo frameTimelineInfo;
Patrick Williams6c6dd3b2023-02-13 22:53:06 +000081 std::vector<client_cache_t> uncacheBuffers;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100082 uint64_t id = static_cast<uint64_t>(-1);
Pablo Gamito23780be2023-04-18 08:30:00 +000083 std::vector<uint64_t> mergedTransactionIds;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100084 static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1));
Valerie Haud251afb2019-03-29 14:19:02 -070085 };
86
Vishnu Nair6b591152021-10-08 11:45:14 -070087 void checkEqual(TransactionInfo info, TransactionState state) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100088 EXPECT_EQ(0u, info.states.size());
89 EXPECT_EQ(0u, state.states.size());
Valerie Haud251afb2019-03-29 14:19:02 -070090
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100091 EXPECT_EQ(0u, info.displays.size());
92 EXPECT_EQ(0u, state.displays.size());
Valerie Haud251afb2019-03-29 14:19:02 -070093 EXPECT_EQ(info.flags, state.flags);
94 EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime);
95 }
96
Patrick Williams641f7f22022-06-22 19:25:35 +000097 void setupSingle(TransactionInfo& transaction, uint32_t flags, int64_t desiredPresentTime,
98 bool isAutoTimestamp, const FrameTimelineInfo& frameTimelineInfo) {
Valerie Haud251afb2019-03-29 14:19:02 -070099 mTransactionNumber++;
Vishnu Nair1523dad2022-09-29 16:05:18 -0700100 transaction.flags |= flags;
Valerie Haud251afb2019-03-29 14:19:02 -0700101 transaction.desiredPresentTime = desiredPresentTime;
Ady Abrahamf0c56492020-12-17 18:04:15 -0800102 transaction.isAutoTimestamp = isAutoTimestamp;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000103 transaction.frameTimelineInfo = frameTimelineInfo;
Valerie Haud251afb2019-03-29 14:19:02 -0700104 }
105
Patrick Williams641f7f22022-06-22 19:25:35 +0000106 void NotPlacedOnTransactionQueue(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000107 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Ady Abraham9953e062024-07-24 22:56:22 -0700108 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700109 TransactionInfo transaction;
Patrick Williams641f7f22022-06-22 19:25:35 +0000110 setupSingle(transaction, flags,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800111 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000112 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700113 nsecs_t applicationTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000114 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700115 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700116 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800117 transaction.desiredPresentTime, transaction.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000118 transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000119 transaction.id, transaction.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700120
Patrick Williams641f7f22022-06-22 19:25:35 +0000121 // If transaction is synchronous, SF applyTransactionState should time out (5s) wating for
122 // SF to commit the transaction. If this is animation, it should not time out waiting.
Valerie Haud251afb2019-03-29 14:19:02 -0700123 nsecs_t returnedTime = systemTime();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700124 EXPECT_LE(returnedTime, applicationTime + TRANSACTION_TIMEOUT);
Arthur Hung58144272021-01-16 03:43:53 +0000125 // Each transaction should have been placed on the transaction queue
Vishnu Nair60d902e2022-07-20 02:55:37 +0000126 auto& transactionQueue = mFlinger.getTransactionQueue();
127 EXPECT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700128 }
129
Patrick Williams641f7f22022-06-22 19:25:35 +0000130 void PlaceOnTransactionQueue(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000131 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Ady Abraham9953e062024-07-24 22:56:22 -0700132 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700133
134 // first check will see desired present time has not passed,
135 // but afterwards it will look like the desired present time has passed
136 nsecs_t time = systemTime();
Valerie Haud251afb2019-03-29 14:19:02 -0700137 TransactionInfo transaction;
Patrick Williams641f7f22022-06-22 19:25:35 +0000138 setupSingle(transaction, flags, /*desiredPresentTime*/ time + s2ns(1), false,
139 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700140 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000141 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700142 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700143 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800144 transaction.desiredPresentTime, transaction.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000145 transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000146 transaction.id, transaction.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700147
148 nsecs_t returnedTime = systemTime();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700149 EXPECT_LE(returnedTime, applicationSentTime + TRANSACTION_TIMEOUT);
Valerie Haud251afb2019-03-29 14:19:02 -0700150 // This transaction should have been placed on the transaction queue
Vishnu Nair60d902e2022-07-20 02:55:37 +0000151 auto& transactionQueue = mFlinger.getTransactionQueue();
152 EXPECT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700153 }
154
Patrick Williams641f7f22022-06-22 19:25:35 +0000155 void BlockedByPriorTransaction(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000156 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700157 nsecs_t time = systemTime();
Ady Abraham9953e062024-07-24 22:56:22 -0700158 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(2);
Patrick Williams641f7f22022-06-22 19:25:35 +0000159
Valerie Haud251afb2019-03-29 14:19:02 -0700160 // transaction that should go on the pending thread
161 TransactionInfo transactionA;
Patrick Williams641f7f22022-06-22 19:25:35 +0000162 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ time + s2ns(1), false,
163 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700164
165 // transaction that would not have gone on the pending thread if not
166 // blocked
167 TransactionInfo transactionB;
Patrick Williams641f7f22022-06-22 19:25:35 +0000168 setupSingle(transactionB, flags, /*desiredPresentTime*/ systemTime(),
169 /*isAutoTimestamp*/ true, FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700170
171 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000172 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700173 transactionA.displays, transactionA.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700174 transactionA.applyToken, transactionA.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800175 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000176 transactionA.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000177 transactionA.id, transactionA.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700178
179 // This thread should not have been blocked by the above transaction
180 // (5s is the timeout period that applyTransactionState waits for SF to
181 // commit the transaction)
Vishnu Nair1523dad2022-09-29 16:05:18 -0700182 EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
Arthur Hung58144272021-01-16 03:43:53 +0000183 // transaction that would goes to pending transaciton queue.
184 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700185
186 applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000187 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700188 transactionB.displays, transactionB.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700189 transactionB.applyToken, transactionB.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800190 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000191 transactionB.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000192 transactionB.id, transactionB.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700193
194 // this thread should have been blocked by the above transaction
195 // if this is an animation, this thread should be blocked for 5s
196 // in setTransactionState waiting for transactionA to flush. Otherwise,
197 // the transaction should be placed on the pending queue
Vishnu Nair1523dad2022-09-29 16:05:18 -0700198 EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
Valerie Haud251afb2019-03-29 14:19:02 -0700199
Arthur Hung58144272021-01-16 03:43:53 +0000200 // transaction that would goes to pending transaciton queue.
201 mFlinger.flushTransactionQueues();
202
Ady Abrahame46243a2021-02-23 19:33:49 -0800203 // check that the transaction was applied.
Arthur Hung58144272021-01-16 03:43:53 +0000204 auto transactionQueue = mFlinger.getPendingTransactionQueue();
Ady Abrahame46243a2021-02-23 19:33:49 -0800205 EXPECT_EQ(0u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700206 }
207
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500208 void modulateVsync() {
209 static_cast<void>(
Dominik Laskowski14956dc2023-02-22 13:43:57 -0500210 mFlinger.mutableScheduler().vsyncModulator().onRefreshRateChangeInitiated());
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500211 }
212
Valerie Haud251afb2019-03-29 14:19:02 -0700213 bool mHasListenerCallbacks = false;
214 std::vector<ListenerCallbacks> mCallbacks;
215 int mTransactionNumber = 0;
216};
217
Vishnu Nair60d902e2022-07-20 02:55:37 +0000218TEST_F(TransactionApplicationTest, AddToPendingQueue) {
219 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Ady Abraham9953e062024-07-24 22:56:22 -0700220 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700221
Valerie Haud251afb2019-03-29 14:19:02 -0700222 TransactionInfo transactionA; // transaction to go on pending queue
Patrick Williams641f7f22022-06-22 19:25:35 +0000223 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
224 FrameTimelineInfo{});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000225 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700226 transactionA.displays, transactionA.flags, transactionA.applyToken,
227 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000228 transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
Pablo Gamito23780be2023-04-18 08:30:00 +0000229 mHasListenerCallbacks, mCallbacks, transactionA.id,
230 transactionA.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700231
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000232 auto& transactionQueue = mFlinger.getTransactionQueue();
Vishnu Nair60d902e2022-07-20 02:55:37 +0000233 ASSERT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700234
Vishnu Nair60d902e2022-07-20 02:55:37 +0000235 auto transactionState = transactionQueue.pop().value();
Valerie Haud251afb2019-03-29 14:19:02 -0700236 checkEqual(transactionA, transactionState);
Vishnu Nair60d902e2022-07-20 02:55:37 +0000237}
238
239TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
240 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Ady Abraham9953e062024-07-24 22:56:22 -0700241 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame(_)).Times(1);
Vishnu Nair60d902e2022-07-20 02:55:37 +0000242
243 TransactionInfo transactionA; // transaction to go on pending queue
244 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
245 FrameTimelineInfo{});
246 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
247 transactionA.displays, transactionA.flags, transactionA.applyToken,
248 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000249 transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
Pablo Gamito23780be2023-04-18 08:30:00 +0000250 mHasListenerCallbacks, mCallbacks, transactionA.id,
251 transactionA.mergedTransactionIds);
Vishnu Nair60d902e2022-07-20 02:55:37 +0000252
253 auto& transactionQueue = mFlinger.getTransactionQueue();
254 ASSERT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700255
256 // because flushing uses the cached expected present time, we send an empty
257 // transaction here (sending a null applyToken to fake it as from a
258 // different process) to re-query and reset the cached expected present time
259 TransactionInfo empty;
260 empty.applyToken = sp<IBinder>();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000261 mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
262 empty.applyToken, empty.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800263 empty.desiredPresentTime, empty.isAutoTimestamp,
Pablo Gamito23780be2023-04-18 08:30:00 +0000264 empty.uncacheBuffers, mHasListenerCallbacks, mCallbacks, empty.id,
265 empty.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700266
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000267 // flush transaction queue should flush as desiredPresentTime has
Valerie Haud251afb2019-03-29 14:19:02 -0700268 // passed
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000269 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700270
Vishnu Nair60d902e2022-07-20 02:55:37 +0000271 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700272}
273
Valerie Haud251afb2019-03-29 14:19:02 -0700274TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_SyncInputWindows) {
Patrick Williams641f7f22022-06-22 19:25:35 +0000275 NotPlacedOnTransactionQueue(/*flags*/ 0);
Valerie Haud251afb2019-03-29 14:19:02 -0700276}
277
Valerie Haud251afb2019-03-29 14:19:02 -0700278TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_SyncInputWindows) {
Patrick Williams641f7f22022-06-22 19:25:35 +0000279 PlaceOnTransactionQueue(/*flags*/ 0);
Valerie Haud251afb2019-03-29 14:19:02 -0700280}
281
Valerie Hau09e60052019-12-15 14:51:15 -0800282TEST_F(TransactionApplicationTest, FromHandle) {
283 sp<IBinder> badHandle;
284 auto ret = mFlinger.fromHandle(badHandle);
Vishnu Nair07e2a482022-10-18 19:18:16 +0000285 EXPECT_EQ(nullptr, ret.get());
Valerie Hau09e60052019-12-15 14:51:15 -0800286}
ramindani4d48f902021-09-20 21:07:45 +0000287
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700288class FakeExternalTexture : public renderengine::ExternalTexture {
289 const sp<GraphicBuffer> mEmptyBuffer = nullptr;
290 uint32_t mWidth;
291 uint32_t mHeight;
292 uint64_t mId;
293 PixelFormat mPixelFormat;
294 uint64_t mUsage;
295
296public:
297 FakeExternalTexture(BufferData& bufferData)
298 : mWidth(bufferData.getWidth()),
299 mHeight(bufferData.getHeight()),
300 mId(bufferData.getId()),
301 mPixelFormat(bufferData.getPixelFormat()),
302 mUsage(bufferData.getUsage()) {}
303 const sp<GraphicBuffer>& getBuffer() const { return mEmptyBuffer; }
304 bool hasSameBuffer(const renderengine::ExternalTexture& other) const override {
305 return getId() == other.getId();
306 }
307 uint32_t getWidth() const override { return mWidth; }
308 uint32_t getHeight() const override { return mHeight; }
309 uint64_t getId() const override { return mId; }
310 PixelFormat getPixelFormat() const override { return mPixelFormat; }
311 uint64_t getUsage() const override { return mUsage; }
312 void remapBuffer() override {}
313 ~FakeExternalTexture() = default;
314};
315
Patrick Williams1cd73f82023-07-31 15:54:48 -0500316TEST_F(TransactionApplicationTest, ApplyTokensUseDifferentQueues) {
317 auto applyToken1 = sp<BBinder>::make();
318 auto applyToken2 = sp<BBinder>::make();
319
320 // Transaction 1 has a buffer with an unfired fence. It should not be ready to be applied.
321 TransactionState transaction1;
322 transaction1.applyToken = applyToken1;
323 transaction1.id = 42069;
324 transaction1.states.emplace_back();
325 transaction1.states[0].state.what |= layer_state_t::eBufferChanged;
326 transaction1.states[0].state.bufferData =
327 std::make_shared<fake::BufferData>(/* bufferId */ 1, /* width */ 1, /* height */ 1,
328 /* pixelFormat */ 0, /* outUsage */ 0);
Vishnu Nair0a51a872024-07-22 23:08:39 +0000329 mFlinger.addLayer(1);
330 bool out;
331 mFlinger.updateLayerSnapshots(VsyncId{1}, 0, /* transactionsFlushed */ true, out);
Patrick Williams1cd73f82023-07-31 15:54:48 -0500332 transaction1.states[0].externalTexture =
333 std::make_shared<FakeExternalTexture>(*transaction1.states[0].state.bufferData);
Vishnu Nair0a51a872024-07-22 23:08:39 +0000334 transaction1.states[0].state.surface = mFlinger.getLegacyLayer(1)->getHandle();
Patrick Williams1cd73f82023-07-31 15:54:48 -0500335 auto fence = sp<mock::MockFence>::make();
336 EXPECT_CALL(*fence, getStatus()).WillRepeatedly(Return(Fence::Status::Unsignaled));
337 transaction1.states[0].state.bufferData->acquireFence = std::move(fence);
338 transaction1.states[0].state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
Vishnu Nair0a51a872024-07-22 23:08:39 +0000339 transaction1.states[0].layerId = 1;
Patrick Williams1cd73f82023-07-31 15:54:48 -0500340 transaction1.isAutoTimestamp = true;
341
342 // Transaction 2 should be ready to be applied.
343 TransactionState transaction2;
344 transaction2.applyToken = applyToken2;
345 transaction2.id = 2;
346 transaction2.isAutoTimestamp = true;
347
348 mFlinger.setTransactionStateInternal(transaction1);
349 mFlinger.setTransactionStateInternal(transaction2);
350 mFlinger.flushTransactionQueues();
351 auto transactionQueues = mFlinger.getPendingTransactionQueue();
352
353 // Transaction 1 is still in its queue.
354 EXPECT_EQ(transactionQueues[applyToken1].size(), 1u);
355 // Transaction 2 has been dequeued.
356 EXPECT_EQ(transactionQueues[applyToken2].size(), 0u);
357}
358
Ady Abraham9dada822022-02-03 10:26:59 -0800359class LatchUnsignaledTest : public TransactionApplicationTest {
360public:
361 void TearDown() override {
362 // Clear all transaction queues to release all transactions we sent
363 // in the tests. Otherwise, gmock complains about memory leaks.
Vishnu Nair60d902e2022-07-20 02:55:37 +0000364 while (!mFlinger.getTransactionQueue().isEmpty()) {
365 mFlinger.getTransactionQueue().pop();
366 }
Ady Abraham9dada822022-02-03 10:26:59 -0800367 mFlinger.getPendingTransactionQueue().clear();
Ady Abraham9dada822022-02-03 10:26:59 -0800368 mFlinger.commitTransactionsLocked(eTransactionMask);
Vishnu Nair0a51a872024-07-22 23:08:39 +0000369 mFlinger.destroyAllLayerHandles();
Ady Abraham9dada822022-02-03 10:26:59 -0800370 }
371
372 static sp<Fence> fence(Fence::Status status) {
373 const auto fence = sp<mock::MockFence>::make();
374 EXPECT_CALL(*fence, getStatus()).WillRepeatedly(Return(status));
375 return fence;
376 }
377
Vishnu Nair0a51a872024-07-22 23:08:39 +0000378 ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what) {
Ady Abraham9dada822022-02-03 10:26:59 -0800379 ComposerState state;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700380 state.state.bufferData =
381 std::make_shared<fake::BufferData>(/* bufferId */ 123L, /* width */ 1,
382 /* height */ 2, /* pixelFormat */ 0,
383 /* outUsage */ 0);
Ady Abraham9dada822022-02-03 10:26:59 -0800384 state.state.bufferData->acquireFence = std::move(fence);
385 state.state.layerId = layerId;
Ady Abraham9dada822022-02-03 10:26:59 -0800386 state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
387
388 state.state.what = what;
389 if (what & layer_state_t::eCropChanged) {
390 state.state.crop = Rect(1, 2, 3, 4);
391 }
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000392 if (what & layer_state_t::eFlagsChanged) {
393 state.state.flags = layer_state_t::eEnableBackpressure;
394 state.state.mask = layer_state_t::eEnableBackpressure;
395 }
396
Ady Abraham9dada822022-02-03 10:26:59 -0800397 return state;
398 }
399
400 TransactionInfo createTransactionInfo(const sp<IBinder>& applyToken,
401 const std::vector<ComposerState>& states) {
402 TransactionInfo transaction;
Vishnu Nair1523dad2022-09-29 16:05:18 -0700403 const uint32_t kFlags = 0;
Ady Abraham9dada822022-02-03 10:26:59 -0800404 const nsecs_t kDesiredPresentTime = systemTime();
405 const bool kIsAutoTimestamp = true;
406 const auto kFrameTimelineInfo = FrameTimelineInfo{};
407
Patrick Williams641f7f22022-06-22 19:25:35 +0000408 setupSingle(transaction, kFlags, kDesiredPresentTime, kIsAutoTimestamp, kFrameTimelineInfo);
Ady Abraham9dada822022-02-03 10:26:59 -0800409 transaction.applyToken = applyToken;
410 for (const auto& state : states) {
411 transaction.states.push_back(state);
412 }
413
414 return transaction;
415 }
416
417 void setTransactionStates(const std::vector<TransactionInfo>& transactions,
Ady Abraham9dada822022-02-03 10:26:59 -0800418 size_t expectedTransactionsPending) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000419 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Ady Abraham9dada822022-02-03 10:26:59 -0800420 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
Vishnu Nair0a51a872024-07-22 23:08:39 +0000421 std::unordered_set<uint32_t> createdLayers;
422 for (auto transaction : transactions) {
423 for (auto& state : transaction.states) {
424 auto layerId = static_cast<uint32_t>(state.state.layerId);
425 if (createdLayers.find(layerId) == createdLayers.end()) {
426 mFlinger.addLayer(layerId);
427 createdLayers.insert(layerId);
428 }
429 }
430 }
431 bool unused;
432 bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0,
433 /*transactionsFlushed=*/true, unused);
Ady Abraham9dada822022-02-03 10:26:59 -0800434
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000435 for (auto transaction : transactions) {
436 std::vector<ResolvedComposerState> resolvedStates;
437 resolvedStates.reserve(transaction.states.size());
438 for (auto& state : transaction.states) {
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700439 ResolvedComposerState resolvedState;
440 resolvedState.state = std::move(state.state);
441 resolvedState.externalTexture =
442 std::make_shared<FakeExternalTexture>(*resolvedState.state.bufferData);
Vishnu Nair0a51a872024-07-22 23:08:39 +0000443 resolvedState.layerId = static_cast<uint32_t>(state.state.layerId);
444 resolvedState.state.surface =
445 mFlinger.getLegacyLayer(resolvedState.layerId)->getHandle();
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700446 resolvedStates.emplace_back(resolvedState);
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000447 }
448
449 TransactionState transactionState(transaction.frameTimelineInfo, resolvedStates,
450 transaction.displays, transaction.flags,
451 transaction.applyToken,
452 transaction.inputWindowCommands,
453 transaction.desiredPresentTime,
Chavi Weingartenc78f53c2023-04-14 18:50:53 +0000454 transaction.isAutoTimestamp, {}, systemTime(),
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000455 mHasListenerCallbacks, mCallbacks, getpid(),
Pablo Gamito23780be2023-04-18 08:30:00 +0000456 static_cast<int>(getuid()), transaction.id,
457 transaction.mergedTransactionIds);
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000458 mFlinger.setTransactionStateInternal(transactionState);
Ady Abraham9dada822022-02-03 10:26:59 -0800459 }
460 mFlinger.flushTransactionQueues();
Vishnu Nair60d902e2022-07-20 02:55:37 +0000461 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700462 EXPECT_EQ(expectedTransactionsPending, mFlinger.getPendingTransactionCount());
Ady Abraham9dada822022-02-03 10:26:59 -0800463 }
464};
465
466class LatchUnsignaledAutoSingleLayerTest : public LatchUnsignaledTest {
467public:
468 void SetUp() override {
469 LatchUnsignaledTest::SetUp();
470 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::AutoSingleLayer;
471 }
472};
473
474TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleSignaledFromTheQueue) {
475 const sp<IBinder> kApplyToken =
476 IInterface::asBinder(TransactionCompletedListener::getIInstance());
Vishnu Nair0a51a872024-07-22 23:08:39 +0000477 const auto kLayerId = 10;
Ady Abraham9dada822022-02-03 10:26:59 -0800478 const auto kExpectedTransactionsPending = 0u;
Ady Abraham9dada822022-02-03 10:26:59 -0800479 const auto signaledTransaction =
480 createTransactionInfo(kApplyToken,
481 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
482 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700483 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000484}
485
Ady Abraham9dada822022-02-03 10:26:59 -0800486TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleUnSignaledFromTheQueue) {
487 const sp<IBinder> kApplyToken =
488 IInterface::asBinder(TransactionCompletedListener::getIInstance());
489 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800490 const auto kExpectedTransactionsPending = 0u;
491
492 const auto unsignaledTransaction =
493 createTransactionInfo(kApplyToken,
494 {
495 createComposerState(kLayerId,
496 fence(Fence::Status::Unsignaled),
497 layer_state_t::eBufferChanged),
498 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700499 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000500}
501
Ady Abraham9dada822022-02-03 10:26:59 -0800502TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange) {
503 const sp<IBinder> kApplyToken =
504 IInterface::asBinder(TransactionCompletedListener::getIInstance());
505 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800506 const auto kExpectedTransactionsPending = 1u;
507
508 const auto unsignaledTransaction =
509 createTransactionInfo(kApplyToken,
510 {
511 createComposerState(kLayerId,
512 fence(Fence::Status::Unsignaled),
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700513 layer_state_t::eCropChanged |
514 layer_state_t::
515 eBufferChanged),
Ady Abraham9dada822022-02-03 10:26:59 -0800516 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700517 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000518}
519
Ady Abrahambb1ad762024-03-27 18:31:28 -0700520TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_AutoRefreshChanged) {
521 SET_FLAG_FOR_TEST(flags::latch_unsignaled_with_auto_refresh_changed, false);
522 const sp<IBinder> kApplyToken =
523 IInterface::asBinder(TransactionCompletedListener::getIInstance());
524 const auto kLayerId = 1;
525 const auto kExpectedTransactionsPending = 1u;
526
527 const auto unsignaledTransaction =
528 createTransactionInfo(kApplyToken,
529 {
530 createComposerState(kLayerId,
531 fence(Fence::Status::Unsignaled),
532 layer_state_t::eAutoRefreshChanged |
533 layer_state_t::
534 eBufferChanged),
535 });
536 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
537}
538
539TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesUnSignaledInTheQueue_AutoRefreshChanged) {
540 SET_FLAG_FOR_TEST(flags::latch_unsignaled_with_auto_refresh_changed, true);
541 const sp<IBinder> kApplyToken =
542 IInterface::asBinder(TransactionCompletedListener::getIInstance());
543 const auto kLayerId = 1;
544 const auto kExpectedTransactionsPending = 0u;
545
546 const auto unsignaledTransaction =
547 createTransactionInfo(kApplyToken,
548 {
549 createComposerState(kLayerId,
550 fence(Fence::Status::Unsignaled),
551 layer_state_t::eAutoRefreshChanged |
552 layer_state_t::
553 eBufferChanged),
554 });
555 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
556}
557
Ady Abraham9dada822022-02-03 10:26:59 -0800558TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed) {
559 const sp<IBinder> kApplyToken =
560 IInterface::asBinder(TransactionCompletedListener::getIInstance());
561 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800562 const auto kExpectedTransactionsPending = 1u;
563
564 const auto unsignaledTransaction =
565 createTransactionInfo(kApplyToken,
566 {
567 createComposerState(kLayerId,
568 fence(Fence::Status::Unsignaled),
569 layer_state_t::eCropChanged |
570 layer_state_t::
571 eBufferChanged),
572 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700573 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000574}
575
Ady Abraham9dada822022-02-03 10:26:59 -0800576TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueueSameApplyTokenMultiState) {
577 const sp<IBinder> kApplyToken =
578 IInterface::asBinder(TransactionCompletedListener::getIInstance());
579 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800580 const auto kExpectedTransactionsPending = 1u;
581
582 const auto mixedTransaction =
583 createTransactionInfo(kApplyToken,
584 {
585 createComposerState(kLayerId,
586 fence(Fence::Status::Unsignaled),
587 layer_state_t::eBufferChanged),
588 createComposerState(kLayerId,
589 fence(Fence::Status::Signaled),
590 layer_state_t::eBufferChanged),
591 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700592 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000593}
594
Ady Abraham9dada822022-02-03 10:26:59 -0800595TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueue_MultipleStateTransaction) {
596 const sp<IBinder> kApplyToken =
597 IInterface::asBinder(TransactionCompletedListener::getIInstance());
598 const auto kLayerId1 = 1;
599 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800600 const auto kExpectedTransactionsPending = 1u;
601
602 const auto mixedTransaction =
603 createTransactionInfo(kApplyToken,
604 {
605 createComposerState(kLayerId1,
606 fence(Fence::Status::Unsignaled),
607 layer_state_t::eBufferChanged),
608 createComposerState(kLayerId2,
609 fence(Fence::Status::Signaled),
610 layer_state_t::eBufferChanged),
611 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700612 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000613}
614
Ady Abraham9dada822022-02-03 10:26:59 -0800615TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSignaledFromTheQueue) {
616 const sp<IBinder> kApplyToken =
617 IInterface::asBinder(TransactionCompletedListener::getIInstance());
618 const auto kLayerId1 = 1;
619 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800620 const auto kExpectedTransactionsPending = 0u;
621
622 const auto signaledTransaction =
623 createTransactionInfo(kApplyToken,
624 {
625 createComposerState(kLayerId1,
626 fence(Fence::Status::Signaled),
627 layer_state_t::eBufferChanged),
628 });
629 const auto signaledTransaction2 =
630 createTransactionInfo(kApplyToken,
631 {
632 createComposerState(kLayerId2,
633 fence(Fence::Status::Signaled),
634 layer_state_t::eBufferChanged),
635 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700636 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000637}
638
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800639TEST_F(LatchUnsignaledAutoSingleLayerTest,
640 UnsignaledNotAppliedWhenThereAreSignaled_UnsignaledFirst) {
Ady Abraham9dada822022-02-03 10:26:59 -0800641 const sp<IBinder> kApplyToken1 =
642 IInterface::asBinder(TransactionCompletedListener::getIInstance());
643 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800644 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
Ady Abraham9dada822022-02-03 10:26:59 -0800645 const auto kLayerId1 = 1;
646 const auto kLayerId2 = 2;
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800647 const auto kExpectedTransactionsPending = 1u;
648
649 const auto unsignaledTransaction =
650 createTransactionInfo(kApplyToken1,
651 {
652 createComposerState(kLayerId1,
653 fence(Fence::Status::Unsignaled),
654 layer_state_t::eBufferChanged),
655 });
656
657 const auto signaledTransaction =
658 createTransactionInfo(kApplyToken2,
659 {
660 createComposerState(kLayerId2,
661 fence(Fence::Status::Signaled),
662 layer_state_t::eBufferChanged),
663 });
664 const auto signaledTransaction2 =
665 createTransactionInfo(kApplyToken3,
666 {
667 createComposerState(kLayerId2,
668 fence(Fence::Status::Signaled),
669 layer_state_t::eBufferChanged),
670 });
671
672 setTransactionStates({unsignaledTransaction, signaledTransaction, signaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700673 kExpectedTransactionsPending);
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800674}
675
Ady Abraham9dada822022-02-03 10:26:59 -0800676TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueueSameApplyToken) {
677 const sp<IBinder> kApplyToken =
678 IInterface::asBinder(TransactionCompletedListener::getIInstance());
679 const auto kLayerId1 = 1;
680 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800681 const auto kExpectedTransactionsPending = 1u;
682
683 const auto unsignaledTransaction =
684 createTransactionInfo(kApplyToken,
685 {
686 createComposerState(kLayerId1,
687 fence(Fence::Status::Unsignaled),
688 layer_state_t::eBufferChanged),
689 });
690 const auto signaledTransaction =
691 createTransactionInfo(kApplyToken,
692 {
693 createComposerState(kLayerId2,
694 fence(Fence::Status::Signaled),
695 layer_state_t::eBufferChanged),
696 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700697 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800698 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000699}
700
Ady Abraham9dada822022-02-03 10:26:59 -0800701TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueue) {
702 const sp<IBinder> kApplyToken1 =
703 IInterface::asBinder(TransactionCompletedListener::getIInstance());
704 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
705 const auto kLayerId1 = 1;
706 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800707 const auto kExpectedTransactionsPending = 1u;
708
709 const auto unsignaledTransaction =
710 createTransactionInfo(kApplyToken1,
711 {
712 createComposerState(kLayerId1,
713 fence(Fence::Status::Unsignaled),
714 layer_state_t::eBufferChanged),
715 });
716 const auto unsignaledTransaction2 =
717 createTransactionInfo(kApplyToken2,
718 {
719 createComposerState(kLayerId2,
720 fence(Fence::Status::Unsignaled),
721 layer_state_t::eBufferChanged),
722 });
723 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700724 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000725}
726
Ady Abraham2739e832022-02-14 17:42:00 -0800727TEST_F(LatchUnsignaledAutoSingleLayerTest, DontLatchUnsignaledWhenEarlyOffset) {
728 const sp<IBinder> kApplyToken =
729 IInterface::asBinder(TransactionCompletedListener::getIInstance());
730 const auto kLayerId = 1;
Ady Abraham2739e832022-02-14 17:42:00 -0800731 const auto kExpectedTransactionsPending = 1u;
732
733 const auto unsignaledTransaction =
734 createTransactionInfo(kApplyToken,
735 {
736 createComposerState(kLayerId,
737 fence(Fence::Status::Unsignaled),
738 layer_state_t::eBufferChanged),
739 });
740
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500741 modulateVsync();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700742 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
Ady Abraham2739e832022-02-14 17:42:00 -0800743}
744
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000745TEST_F(LatchUnsignaledAutoSingleLayerTest, UnsignaledNotAppliedWhenThereAreSignaled_SignaledFirst) {
746 const sp<IBinder> kApplyToken1 =
747 IInterface::asBinder(TransactionCompletedListener::getIInstance());
748 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
749 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
750 const auto kLayerId1 = 1;
751 const auto kLayerId2 = 2;
752 const auto kExpectedTransactionsPending = 1u;
753
754 const auto signaledTransaction =
755 createTransactionInfo(kApplyToken1,
756 {
757 createComposerState(kLayerId1,
758 fence(Fence::Status::Signaled),
759 layer_state_t::eBufferChanged),
760 });
761 const auto signaledTransaction2 =
762 createTransactionInfo(kApplyToken2,
763 {
764 createComposerState(kLayerId1,
765 fence(Fence::Status::Signaled),
766 layer_state_t::eBufferChanged),
767 });
768 const auto unsignaledTransaction =
769 createTransactionInfo(kApplyToken3,
770 {
771 createComposerState(kLayerId2,
772 fence(Fence::Status::Unsignaled),
773 layer_state_t::eBufferChanged),
774 });
775
776 setTransactionStates({signaledTransaction, signaledTransaction2, unsignaledTransaction},
777 kExpectedTransactionsPending);
778}
779
Ady Abraham9dada822022-02-03 10:26:59 -0800780class LatchUnsignaledDisabledTest : public LatchUnsignaledTest {
781public:
782 void SetUp() override {
783 LatchUnsignaledTest::SetUp();
784 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
785 }
786};
787
788TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue) {
789 const sp<IBinder> kApplyToken =
790 IInterface::asBinder(TransactionCompletedListener::getIInstance());
Vishnu Nair0a51a872024-07-22 23:08:39 +0000791 const auto kLayerId = 10;
Ady Abraham9dada822022-02-03 10:26:59 -0800792 const auto kExpectedTransactionsPending = 0u;
793
794 const auto signaledTransaction =
795 createTransactionInfo(kApplyToken,
796 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
797 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700798 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000799}
800
Ady Abraham9dada822022-02-03 10:26:59 -0800801TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueue) {
802 const sp<IBinder> kApplyToken =
803 IInterface::asBinder(TransactionCompletedListener::getIInstance());
804 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800805 const auto kExpectedTransactionsPending = 1u;
806
807 const auto unsignaledTransaction =
808 createTransactionInfo(kApplyToken,
809 {
810 createComposerState(kLayerId,
811 fence(Fence::Status::Unsignaled),
812 layer_state_t::eBufferChanged),
813 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700814 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000815}
816
Ady Abraham9dada822022-02-03 10:26:59 -0800817TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueSameLayerId) {
818 const sp<IBinder> kApplyToken =
819 IInterface::asBinder(TransactionCompletedListener::getIInstance());
820 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800821 const auto kExpectedTransactionsPending = 1u;
822
823 const auto unsignaledTransaction =
824 createTransactionInfo(kApplyToken,
825 {
826 createComposerState(kLayerId,
827 fence(Fence::Status::Unsignaled),
828 layer_state_t::eBufferChanged),
829 createComposerState(kLayerId,
830 fence(Fence::Status::Unsignaled),
831 layer_state_t::eBufferChanged),
832 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700833 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000834}
835
Ady Abraham9dada822022-02-03 10:26:59 -0800836TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueDifferentLayerId) {
837 const sp<IBinder> kApplyToken =
838 IInterface::asBinder(TransactionCompletedListener::getIInstance());
839 const auto kLayerId1 = 1;
840 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800841 const auto kExpectedTransactionsPending = 1u;
842
843 const auto unsignaledTransaction =
844 createTransactionInfo(kApplyToken,
845 {
846 createComposerState(kLayerId1,
847 fence(Fence::Status::Unsignaled),
848 layer_state_t::eBufferChanged),
849 createComposerState(kLayerId2,
850 fence(Fence::Status::Unsignaled),
851 layer_state_t::eBufferChanged),
852 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700853 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000854}
855
Ady Abraham9dada822022-02-03 10:26:59 -0800856TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue_MultipleLayers) {
857 const sp<IBinder> kApplyToken =
858 IInterface::asBinder(TransactionCompletedListener::getIInstance());
859 const auto kLayerId1 = 1;
860 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800861 const auto kExpectedTransactionsPending = 0u;
862
863 const auto signaledTransaction =
864 createTransactionInfo(kApplyToken,
865 {
866 createComposerState(kLayerId1,
867 fence(Fence::Status::Signaled),
868 layer_state_t::eBufferChanged),
869 });
870 const auto signaledTransaction2 =
871 createTransactionInfo(kApplyToken,
872 {
873 createComposerState(kLayerId2,
874 fence(Fence::Status::Signaled),
875 layer_state_t::eBufferChanged),
876 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700877 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000878}
879
Ady Abraham9dada822022-02-03 10:26:59 -0800880TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueDifferentApplyToken) {
881 const sp<IBinder> kApplyToken1 =
882 IInterface::asBinder(TransactionCompletedListener::getIInstance());
883 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
884 const auto kLayerId1 = 1;
885 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800886 const auto kExpectedTransactionsPending = 1u;
887
888 const auto unsignaledTransaction =
889 createTransactionInfo(kApplyToken1,
890 {
891 createComposerState(kLayerId1,
892 fence(Fence::Status::Unsignaled),
893 layer_state_t::eBufferChanged),
894 });
895 const auto signaledTransaction =
896 createTransactionInfo(kApplyToken2,
897 {
898 createComposerState(kLayerId2,
899 fence(Fence::Status::Signaled),
900 layer_state_t::eBufferChanged),
901 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700902 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800903 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000904}
905
Ady Abraham9dada822022-02-03 10:26:59 -0800906TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueSameApplyToken) {
907 const sp<IBinder> kApplyToken =
908 IInterface::asBinder(TransactionCompletedListener::getIInstance());
909 const auto kLayerId1 = 1;
910 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800911 const auto kExpectedTransactionsPending = 1u;
912
913 const auto signaledTransaction =
914 createTransactionInfo(kApplyToken,
915 {
916 createComposerState(kLayerId1,
917 fence(Fence::Status::Signaled),
918 layer_state_t::eBufferChanged),
919 });
920 const auto unsignaledTransaction =
921 createTransactionInfo(kApplyToken,
922 {
923 createComposerState(kLayerId2,
924 fence(Fence::Status::Unsignaled),
925 layer_state_t::eBufferChanged),
926 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700927 setTransactionStates({signaledTransaction, unsignaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800928 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000929}
930
Ady Abraham9dada822022-02-03 10:26:59 -0800931TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheUnsignaledTheQueue) {
932 const sp<IBinder> kApplyToken =
933 IInterface::asBinder(TransactionCompletedListener::getIInstance());
934 const auto kLayerId1 = 1;
935 const auto kLayerId2 = 2;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700936 const auto kExpectedTransactionsPending = 2u;
Ady Abraham9dada822022-02-03 10:26:59 -0800937
938 const auto unsignaledTransaction =
939 createTransactionInfo(kApplyToken,
940 {
941 createComposerState(kLayerId1,
942 fence(Fence::Status::Unsignaled),
943 layer_state_t::eBufferChanged),
944 });
945 const auto unsignaledTransaction2 =
946 createTransactionInfo(kApplyToken,
947 {
948 createComposerState(kLayerId2,
949 fence(Fence::Status::Unsignaled),
950 layer_state_t::eBufferChanged),
951 });
952 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700953 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000954}
955
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700956TEST(TransactionHandlerTest, QueueTransaction) {
957 TransactionHandler handler;
958 TransactionState transaction;
959 transaction.applyToken = sp<BBinder>::make();
960 transaction.id = 42;
961 handler.queueTransaction(std::move(transaction));
Vishnu Nair4d9cef92023-06-24 22:34:41 +0000962 handler.collectTransactions();
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700963 std::vector<TransactionState> transactionsReadyToBeApplied = handler.flushTransactions();
964
965 EXPECT_EQ(transactionsReadyToBeApplied.size(), 1u);
966 EXPECT_EQ(transactionsReadyToBeApplied.front().id, 42u);
967}
968
Pablo Gamito23780be2023-04-18 08:30:00 +0000969TEST(TransactionHandlerTest, TransactionsKeepTrackOfDirectMerges) {
970 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
971
972 uint64_t transaction2Id = transaction2.getId();
973 uint64_t transaction3Id = transaction3.getId();
974 EXPECT_NE(transaction2Id, transaction3Id);
975
976 transaction1.merge(std::move(transaction2));
977 transaction1.merge(std::move(transaction3));
978
979 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
980 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
981 EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction2Id);
982}
983
984TEST(TransactionHandlerTest, TransactionsKeepTrackOfIndirectMerges) {
985 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
986
987 uint64_t transaction2Id = transaction2.getId();
988 uint64_t transaction3Id = transaction3.getId();
989 uint64_t transaction4Id = transaction4.getId();
990 EXPECT_NE(transaction2Id, transaction3Id);
991 EXPECT_NE(transaction2Id, transaction4Id);
992 EXPECT_NE(transaction3Id, transaction4Id);
993
994 transaction4.merge(std::move(transaction2));
995 transaction4.merge(std::move(transaction3));
996
997 EXPECT_EQ(transaction4.getMergedTransactionIds().size(), 2u);
998 EXPECT_EQ(transaction4.getMergedTransactionIds()[0], transaction3Id);
999 EXPECT_EQ(transaction4.getMergedTransactionIds()[1], transaction2Id);
1000
1001 transaction1.merge(std::move(transaction4));
1002
1003 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 3u);
1004 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction4Id);
1005 EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction3Id);
1006 EXPECT_EQ(transaction1.getMergedTransactionIds()[2], transaction2Id);
1007}
1008
1009TEST(TransactionHandlerTest, TransactionMergesAreCleared) {
1010 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
1011
1012 transaction1.merge(std::move(transaction2));
1013 transaction1.merge(std::move(transaction3));
1014
1015 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
1016
1017 transaction1.clear();
1018
1019 EXPECT_EQ(transaction1.getMergedTransactionIds().empty(), true);
1020}
1021
1022TEST(TransactionHandlerTest, TransactionMergesAreCapped) {
1023 SurfaceComposerClient::Transaction transaction;
1024 std::vector<uint64_t> mergedTransactionIds;
1025
1026 for (uint i = 0; i < 20u; i++) {
1027 SurfaceComposerClient::Transaction transactionToMerge;
1028 mergedTransactionIds.push_back(transactionToMerge.getId());
1029 transaction.merge(std::move(transactionToMerge));
1030 }
1031
1032 // Keeps latest 10 merges in order of merge recency
1033 EXPECT_EQ(transaction.getMergedTransactionIds().size(), 10u);
1034 for (uint i = 0; i < 10u; i++) {
1035 EXPECT_EQ(transaction.getMergedTransactionIds()[i],
1036 mergedTransactionIds[mergedTransactionIds.size() - 1 - i]);
1037 }
1038}
1039
1040TEST(TransactionHandlerTest, KeepsMergesFromMoreRecentMerge) {
1041 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
1042 std::vector<uint64_t> mergedTransactionIds1, mergedTransactionIds2, mergedTransactionIds3;
1043 uint64_t transaction2Id = transaction2.getId();
1044 uint64_t transaction3Id = transaction3.getId();
1045
1046 for (uint i = 0; i < 20u; i++) {
1047 SurfaceComposerClient::Transaction transactionToMerge;
1048 mergedTransactionIds1.push_back(transactionToMerge.getId());
1049 transaction1.merge(std::move(transactionToMerge));
1050 }
1051
1052 for (uint i = 0; i < 5u; i++) {
1053 SurfaceComposerClient::Transaction transactionToMerge;
1054 mergedTransactionIds2.push_back(transactionToMerge.getId());
1055 transaction2.merge(std::move(transactionToMerge));
1056 }
1057
1058 transaction1.merge(std::move(transaction2));
1059 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1060 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction2Id);
1061 for (uint i = 0; i < 5u; i++) {
1062 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1u],
1063 mergedTransactionIds2[mergedTransactionIds2.size() - 1 - i]);
1064 }
1065 for (uint i = 0; i < 4u; i++) {
1066 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 6u],
1067 mergedTransactionIds1[mergedTransactionIds1.size() - 1 - i]);
1068 }
1069
1070 for (uint i = 0; i < 20u; i++) {
1071 SurfaceComposerClient::Transaction transactionToMerge;
1072 mergedTransactionIds3.push_back(transactionToMerge.getId());
1073 transaction3.merge(std::move(transactionToMerge));
1074 }
1075
1076 transaction1.merge(std::move(transaction3));
1077 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1078 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
1079 for (uint i = 0; i < 9u; i++) {
1080 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1],
1081 mergedTransactionIds3[mergedTransactionIds3.size() - 1 - i]);
1082 }
1083}
1084
1085TEST(TransactionHandlerTest, CanAddTransactionWithFullMergedIds) {
1086 SurfaceComposerClient::Transaction transaction1, transaction2;
1087 for (uint i = 0; i < 20u; i++) {
1088 SurfaceComposerClient::Transaction transactionToMerge;
1089 transaction1.merge(std::move(transactionToMerge));
1090 }
1091
1092 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1093
1094 auto transaction1Id = transaction1.getId();
1095 transaction2.merge(std::move(transaction1));
1096 EXPECT_EQ(transaction2.getMergedTransactionIds().size(), 10u);
1097 auto mergedTransactionIds = transaction2.getMergedTransactionIds();
1098 EXPECT_TRUE(std::count(mergedTransactionIds.begin(), mergedTransactionIds.end(),
1099 transaction1Id) > 0);
1100}
1101
Valerie Haud251afb2019-03-29 14:19:02 -07001102} // namespace android