blob: 1f2a1edb779723f76c3168525731e2ab0e404137 [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
20#include <compositionengine/Display.h>
21#include <compositionengine/mock/DisplaySurface.h>
22#include <gmock/gmock.h>
23#include <gtest/gtest.h>
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070024#include <gui/LayerState.h>
Valerie Haud251afb2019-03-29 14:19:02 -070025#include <gui/SurfaceComposerClient.h>
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070026#include <gui/fake/BufferData.h>
Valerie Haud251afb2019-03-29 14:19:02 -070027#include <log/log.h>
ramindani4d48f902021-09-20 21:07:45 +000028#include <ui/MockFence.h>
Valerie Haud251afb2019-03-29 14:19:02 -070029#include <utils/String8.h>
Vishnu Nair59f6d2d2022-10-05 16:59:56 -070030#include <vector>
31#include <binder/Binder.h>
Dominik Laskowski068173d2021-08-11 17:22:59 -070032
Vishnu Naira61e4fb2022-10-18 18:29:37 +000033#include "FrontEnd/TransactionHandler.h"
Valerie Haud251afb2019-03-29 14:19:02 -070034#include "TestableSurfaceFlinger.h"
Vishnu Nair40fff5c2022-11-04 02:46:28 +000035#include "TransactionState.h"
Valerie Haud251afb2019-03-29 14:19:02 -070036
37namespace android {
38
39using testing::_;
40using testing::Return;
41
Vishnu Nairaf6d2972022-11-18 06:26:38 +000042using frontend::TransactionHandler;
43
Vishnu Nair1523dad2022-09-29 16:05:18 -070044constexpr nsecs_t TRANSACTION_TIMEOUT = s2ns(5);
Valerie Haud251afb2019-03-29 14:19:02 -070045class TransactionApplicationTest : public testing::Test {
46public:
47 TransactionApplicationTest() {
48 const ::testing::TestInfo* const test_info =
49 ::testing::UnitTest::GetInstance()->current_test_info();
50 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
51
Dominik Laskowskiaee9a622023-02-11 14:24:19 -050052 mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
53 mFlinger.setupMockScheduler();
54 mFlinger.flinger()->addTransactionReadyFilters();
Valerie Haud251afb2019-03-29 14:19:02 -070055 }
56
57 ~TransactionApplicationTest() {
58 const ::testing::TestInfo* const test_info =
59 ::testing::UnitTest::GetInstance()->current_test_info();
60 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
61 }
62
Valerie Haud251afb2019-03-29 14:19:02 -070063 TestableSurfaceFlinger mFlinger;
64
Valerie Haud251afb2019-03-29 14:19:02 -070065 struct TransactionInfo {
66 Vector<ComposerState> states;
67 Vector<DisplayState> displays;
68 uint32_t flags = 0;
69 sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
70 InputWindowCommands inputWindowCommands;
Ady Abrahamf0c56492020-12-17 18:04:15 -080071 int64_t desiredPresentTime = 0;
72 bool isAutoTimestamp = true;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100073 FrameTimelineInfo frameTimelineInfo;
Patrick Williams6c6dd3b2023-02-13 22:53:06 +000074 std::vector<client_cache_t> uncacheBuffers;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100075 uint64_t id = static_cast<uint64_t>(-1);
Pablo Gamito23780be2023-04-18 08:30:00 +000076 std::vector<uint64_t> mergedTransactionIds;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100077 static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1));
Valerie Haud251afb2019-03-29 14:19:02 -070078 };
79
Vishnu Nair6b591152021-10-08 11:45:14 -070080 void checkEqual(TransactionInfo info, TransactionState state) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100081 EXPECT_EQ(0u, info.states.size());
82 EXPECT_EQ(0u, state.states.size());
Valerie Haud251afb2019-03-29 14:19:02 -070083
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100084 EXPECT_EQ(0u, info.displays.size());
85 EXPECT_EQ(0u, state.displays.size());
Valerie Haud251afb2019-03-29 14:19:02 -070086 EXPECT_EQ(info.flags, state.flags);
87 EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime);
88 }
89
Patrick Williams641f7f22022-06-22 19:25:35 +000090 void setupSingle(TransactionInfo& transaction, uint32_t flags, int64_t desiredPresentTime,
91 bool isAutoTimestamp, const FrameTimelineInfo& frameTimelineInfo) {
Valerie Haud251afb2019-03-29 14:19:02 -070092 mTransactionNumber++;
Vishnu Nair1523dad2022-09-29 16:05:18 -070093 transaction.flags |= flags;
Valerie Haud251afb2019-03-29 14:19:02 -070094 transaction.desiredPresentTime = desiredPresentTime;
Ady Abrahamf0c56492020-12-17 18:04:15 -080095 transaction.isAutoTimestamp = isAutoTimestamp;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100096 transaction.frameTimelineInfo = frameTimelineInfo;
Valerie Haud251afb2019-03-29 14:19:02 -070097 }
98
Patrick Williams641f7f22022-06-22 19:25:35 +000099 void NotPlacedOnTransactionQueue(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000100 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700101 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700102 TransactionInfo transaction;
Patrick Williams641f7f22022-06-22 19:25:35 +0000103 setupSingle(transaction, flags,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800104 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000105 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700106 nsecs_t applicationTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000107 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700108 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700109 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800110 transaction.desiredPresentTime, transaction.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000111 transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000112 transaction.id, transaction.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700113
Patrick Williams641f7f22022-06-22 19:25:35 +0000114 // If transaction is synchronous, SF applyTransactionState should time out (5s) wating for
115 // SF to commit the transaction. If this is animation, it should not time out waiting.
Valerie Haud251afb2019-03-29 14:19:02 -0700116 nsecs_t returnedTime = systemTime();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700117 EXPECT_LE(returnedTime, applicationTime + TRANSACTION_TIMEOUT);
Arthur Hung58144272021-01-16 03:43:53 +0000118 // Each transaction should have been placed on the transaction queue
Vishnu Nair60d902e2022-07-20 02:55:37 +0000119 auto& transactionQueue = mFlinger.getTransactionQueue();
120 EXPECT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700121 }
122
Patrick Williams641f7f22022-06-22 19:25:35 +0000123 void PlaceOnTransactionQueue(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000124 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700125 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700126
127 // first check will see desired present time has not passed,
128 // but afterwards it will look like the desired present time has passed
129 nsecs_t time = systemTime();
Valerie Haud251afb2019-03-29 14:19:02 -0700130 TransactionInfo transaction;
Patrick Williams641f7f22022-06-22 19:25:35 +0000131 setupSingle(transaction, flags, /*desiredPresentTime*/ time + s2ns(1), false,
132 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700133 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000134 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700135 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700136 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800137 transaction.desiredPresentTime, transaction.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000138 transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000139 transaction.id, transaction.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700140
141 nsecs_t returnedTime = systemTime();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700142 EXPECT_LE(returnedTime, applicationSentTime + TRANSACTION_TIMEOUT);
Valerie Haud251afb2019-03-29 14:19:02 -0700143 // This transaction should have been placed on the transaction queue
Vishnu Nair60d902e2022-07-20 02:55:37 +0000144 auto& transactionQueue = mFlinger.getTransactionQueue();
145 EXPECT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700146 }
147
Patrick Williams641f7f22022-06-22 19:25:35 +0000148 void BlockedByPriorTransaction(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000149 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700150 nsecs_t time = systemTime();
Patrick Williams641f7f22022-06-22 19:25:35 +0000151 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(2);
152
Valerie Haud251afb2019-03-29 14:19:02 -0700153 // transaction that should go on the pending thread
154 TransactionInfo transactionA;
Patrick Williams641f7f22022-06-22 19:25:35 +0000155 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ time + s2ns(1), false,
156 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700157
158 // transaction that would not have gone on the pending thread if not
159 // blocked
160 TransactionInfo transactionB;
Patrick Williams641f7f22022-06-22 19:25:35 +0000161 setupSingle(transactionB, flags, /*desiredPresentTime*/ systemTime(),
162 /*isAutoTimestamp*/ true, FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700163
164 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000165 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700166 transactionA.displays, transactionA.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700167 transactionA.applyToken, transactionA.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800168 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000169 transactionA.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000170 transactionA.id, transactionA.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700171
172 // This thread should not have been blocked by the above transaction
173 // (5s is the timeout period that applyTransactionState waits for SF to
174 // commit the transaction)
Vishnu Nair1523dad2022-09-29 16:05:18 -0700175 EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
Arthur Hung58144272021-01-16 03:43:53 +0000176 // transaction that would goes to pending transaciton queue.
177 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700178
179 applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000180 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700181 transactionB.displays, transactionB.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700182 transactionB.applyToken, transactionB.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800183 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000184 transactionB.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Pablo Gamito23780be2023-04-18 08:30:00 +0000185 transactionB.id, transactionB.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700186
187 // this thread should have been blocked by the above transaction
188 // if this is an animation, this thread should be blocked for 5s
189 // in setTransactionState waiting for transactionA to flush. Otherwise,
190 // the transaction should be placed on the pending queue
Vishnu Nair1523dad2022-09-29 16:05:18 -0700191 EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
Valerie Haud251afb2019-03-29 14:19:02 -0700192
Arthur Hung58144272021-01-16 03:43:53 +0000193 // transaction that would goes to pending transaciton queue.
194 mFlinger.flushTransactionQueues();
195
Ady Abrahame46243a2021-02-23 19:33:49 -0800196 // check that the transaction was applied.
Arthur Hung58144272021-01-16 03:43:53 +0000197 auto transactionQueue = mFlinger.getPendingTransactionQueue();
Ady Abrahame46243a2021-02-23 19:33:49 -0800198 EXPECT_EQ(0u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700199 }
200
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500201 void modulateVsync() {
202 static_cast<void>(
Dominik Laskowski14956dc2023-02-22 13:43:57 -0500203 mFlinger.mutableScheduler().vsyncModulator().onRefreshRateChangeInitiated());
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500204 }
205
Valerie Haud251afb2019-03-29 14:19:02 -0700206 bool mHasListenerCallbacks = false;
207 std::vector<ListenerCallbacks> mCallbacks;
208 int mTransactionNumber = 0;
209};
210
Vishnu Nair60d902e2022-07-20 02:55:37 +0000211TEST_F(TransactionApplicationTest, AddToPendingQueue) {
212 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700213 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700214
Valerie Haud251afb2019-03-29 14:19:02 -0700215 TransactionInfo transactionA; // transaction to go on pending queue
Patrick Williams641f7f22022-06-22 19:25:35 +0000216 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
217 FrameTimelineInfo{});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000218 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700219 transactionA.displays, transactionA.flags, transactionA.applyToken,
220 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000221 transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
Pablo Gamito23780be2023-04-18 08:30:00 +0000222 mHasListenerCallbacks, mCallbacks, transactionA.id,
223 transactionA.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700224
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000225 auto& transactionQueue = mFlinger.getTransactionQueue();
Vishnu Nair60d902e2022-07-20 02:55:37 +0000226 ASSERT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700227
Vishnu Nair60d902e2022-07-20 02:55:37 +0000228 auto transactionState = transactionQueue.pop().value();
Valerie Haud251afb2019-03-29 14:19:02 -0700229 checkEqual(transactionA, transactionState);
Vishnu Nair60d902e2022-07-20 02:55:37 +0000230}
231
232TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
233 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
234 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
235
236 TransactionInfo transactionA; // transaction to go on pending queue
237 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
238 FrameTimelineInfo{});
239 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
240 transactionA.displays, transactionA.flags, transactionA.applyToken,
241 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000242 transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
Pablo Gamito23780be2023-04-18 08:30:00 +0000243 mHasListenerCallbacks, mCallbacks, transactionA.id,
244 transactionA.mergedTransactionIds);
Vishnu Nair60d902e2022-07-20 02:55:37 +0000245
246 auto& transactionQueue = mFlinger.getTransactionQueue();
247 ASSERT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700248
249 // because flushing uses the cached expected present time, we send an empty
250 // transaction here (sending a null applyToken to fake it as from a
251 // different process) to re-query and reset the cached expected present time
252 TransactionInfo empty;
253 empty.applyToken = sp<IBinder>();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000254 mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
255 empty.applyToken, empty.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800256 empty.desiredPresentTime, empty.isAutoTimestamp,
Pablo Gamito23780be2023-04-18 08:30:00 +0000257 empty.uncacheBuffers, mHasListenerCallbacks, mCallbacks, empty.id,
258 empty.mergedTransactionIds);
Valerie Haud251afb2019-03-29 14:19:02 -0700259
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000260 // flush transaction queue should flush as desiredPresentTime has
Valerie Haud251afb2019-03-29 14:19:02 -0700261 // passed
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000262 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700263
Vishnu Nair60d902e2022-07-20 02:55:37 +0000264 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700265}
266
Valerie Haud251afb2019-03-29 14:19:02 -0700267TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_SyncInputWindows) {
Patrick Williams641f7f22022-06-22 19:25:35 +0000268 NotPlacedOnTransactionQueue(/*flags*/ 0);
Valerie Haud251afb2019-03-29 14:19:02 -0700269}
270
Valerie Haud251afb2019-03-29 14:19:02 -0700271TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_SyncInputWindows) {
Patrick Williams641f7f22022-06-22 19:25:35 +0000272 PlaceOnTransactionQueue(/*flags*/ 0);
Valerie Haud251afb2019-03-29 14:19:02 -0700273}
274
Valerie Hau09e60052019-12-15 14:51:15 -0800275TEST_F(TransactionApplicationTest, FromHandle) {
276 sp<IBinder> badHandle;
277 auto ret = mFlinger.fromHandle(badHandle);
Vishnu Nair07e2a482022-10-18 19:18:16 +0000278 EXPECT_EQ(nullptr, ret.get());
Valerie Hau09e60052019-12-15 14:51:15 -0800279}
ramindani4d48f902021-09-20 21:07:45 +0000280
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700281class FakeExternalTexture : public renderengine::ExternalTexture {
282 const sp<GraphicBuffer> mEmptyBuffer = nullptr;
283 uint32_t mWidth;
284 uint32_t mHeight;
285 uint64_t mId;
286 PixelFormat mPixelFormat;
287 uint64_t mUsage;
288
289public:
290 FakeExternalTexture(BufferData& bufferData)
291 : mWidth(bufferData.getWidth()),
292 mHeight(bufferData.getHeight()),
293 mId(bufferData.getId()),
294 mPixelFormat(bufferData.getPixelFormat()),
295 mUsage(bufferData.getUsage()) {}
296 const sp<GraphicBuffer>& getBuffer() const { return mEmptyBuffer; }
297 bool hasSameBuffer(const renderengine::ExternalTexture& other) const override {
298 return getId() == other.getId();
299 }
300 uint32_t getWidth() const override { return mWidth; }
301 uint32_t getHeight() const override { return mHeight; }
302 uint64_t getId() const override { return mId; }
303 PixelFormat getPixelFormat() const override { return mPixelFormat; }
304 uint64_t getUsage() const override { return mUsage; }
305 void remapBuffer() override {}
306 ~FakeExternalTexture() = default;
307};
308
Patrick Williams1cd73f82023-07-31 15:54:48 -0500309TEST_F(TransactionApplicationTest, ApplyTokensUseDifferentQueues) {
310 auto applyToken1 = sp<BBinder>::make();
311 auto applyToken2 = sp<BBinder>::make();
312
313 // Transaction 1 has a buffer with an unfired fence. It should not be ready to be applied.
314 TransactionState transaction1;
315 transaction1.applyToken = applyToken1;
316 transaction1.id = 42069;
317 transaction1.states.emplace_back();
318 transaction1.states[0].state.what |= layer_state_t::eBufferChanged;
319 transaction1.states[0].state.bufferData =
320 std::make_shared<fake::BufferData>(/* bufferId */ 1, /* width */ 1, /* height */ 1,
321 /* pixelFormat */ 0, /* outUsage */ 0);
322 transaction1.states[0].externalTexture =
323 std::make_shared<FakeExternalTexture>(*transaction1.states[0].state.bufferData);
324 transaction1.states[0].state.surface =
325 sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
326 ->getHandle();
327 auto fence = sp<mock::MockFence>::make();
328 EXPECT_CALL(*fence, getStatus()).WillRepeatedly(Return(Fence::Status::Unsignaled));
329 transaction1.states[0].state.bufferData->acquireFence = std::move(fence);
330 transaction1.states[0].state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
331 transaction1.isAutoTimestamp = true;
332
333 // Transaction 2 should be ready to be applied.
334 TransactionState transaction2;
335 transaction2.applyToken = applyToken2;
336 transaction2.id = 2;
337 transaction2.isAutoTimestamp = true;
338
339 mFlinger.setTransactionStateInternal(transaction1);
340 mFlinger.setTransactionStateInternal(transaction2);
341 mFlinger.flushTransactionQueues();
342 auto transactionQueues = mFlinger.getPendingTransactionQueue();
343
344 // Transaction 1 is still in its queue.
345 EXPECT_EQ(transactionQueues[applyToken1].size(), 1u);
346 // Transaction 2 has been dequeued.
347 EXPECT_EQ(transactionQueues[applyToken2].size(), 0u);
348}
349
Ady Abraham9dada822022-02-03 10:26:59 -0800350class LatchUnsignaledTest : public TransactionApplicationTest {
351public:
352 void TearDown() override {
353 // Clear all transaction queues to release all transactions we sent
354 // in the tests. Otherwise, gmock complains about memory leaks.
Vishnu Nair60d902e2022-07-20 02:55:37 +0000355 while (!mFlinger.getTransactionQueue().isEmpty()) {
356 mFlinger.getTransactionQueue().pop();
357 }
Ady Abraham9dada822022-02-03 10:26:59 -0800358 mFlinger.getPendingTransactionQueue().clear();
Ady Abraham9dada822022-02-03 10:26:59 -0800359 mFlinger.commitTransactionsLocked(eTransactionMask);
360 mFlinger.mutableCurrentState().layersSortedByZ.clear();
361 mFlinger.mutableDrawingState().layersSortedByZ.clear();
362 }
363
364 static sp<Fence> fence(Fence::Status status) {
365 const auto fence = sp<mock::MockFence>::make();
366 EXPECT_CALL(*fence, getStatus()).WillRepeatedly(Return(status));
367 return fence;
368 }
369
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000370 ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what,
371 std::optional<sp<IBinder>> layerHandle = std::nullopt) {
Ady Abraham9dada822022-02-03 10:26:59 -0800372 ComposerState state;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700373 state.state.bufferData =
374 std::make_shared<fake::BufferData>(/* bufferId */ 123L, /* width */ 1,
375 /* height */ 2, /* pixelFormat */ 0,
376 /* outUsage */ 0);
Ady Abraham9dada822022-02-03 10:26:59 -0800377 state.state.bufferData->acquireFence = std::move(fence);
378 state.state.layerId = layerId;
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000379 state.state.surface = layerHandle.value_or(
Patrick Williams83f36b22022-09-14 17:57:35 +0000380 sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000381 ->getHandle());
Ady Abraham9dada822022-02-03 10:26:59 -0800382 state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
383
384 state.state.what = what;
385 if (what & layer_state_t::eCropChanged) {
386 state.state.crop = Rect(1, 2, 3, 4);
387 }
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000388 if (what & layer_state_t::eFlagsChanged) {
389 state.state.flags = layer_state_t::eEnableBackpressure;
390 state.state.mask = layer_state_t::eEnableBackpressure;
391 }
392
Ady Abraham9dada822022-02-03 10:26:59 -0800393 return state;
394 }
395
396 TransactionInfo createTransactionInfo(const sp<IBinder>& applyToken,
397 const std::vector<ComposerState>& states) {
398 TransactionInfo transaction;
Vishnu Nair1523dad2022-09-29 16:05:18 -0700399 const uint32_t kFlags = 0;
Ady Abraham9dada822022-02-03 10:26:59 -0800400 const nsecs_t kDesiredPresentTime = systemTime();
401 const bool kIsAutoTimestamp = true;
402 const auto kFrameTimelineInfo = FrameTimelineInfo{};
403
Patrick Williams641f7f22022-06-22 19:25:35 +0000404 setupSingle(transaction, kFlags, kDesiredPresentTime, kIsAutoTimestamp, kFrameTimelineInfo);
Ady Abraham9dada822022-02-03 10:26:59 -0800405 transaction.applyToken = applyToken;
406 for (const auto& state : states) {
407 transaction.states.push_back(state);
408 }
409
410 return transaction;
411 }
412
413 void setTransactionStates(const std::vector<TransactionInfo>& transactions,
Ady Abraham9dada822022-02-03 10:26:59 -0800414 size_t expectedTransactionsPending) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000415 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Ady Abraham9dada822022-02-03 10:26:59 -0800416 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
417
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000418 for (auto transaction : transactions) {
419 std::vector<ResolvedComposerState> resolvedStates;
420 resolvedStates.reserve(transaction.states.size());
421 for (auto& state : transaction.states) {
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700422 ResolvedComposerState resolvedState;
423 resolvedState.state = std::move(state.state);
424 resolvedState.externalTexture =
425 std::make_shared<FakeExternalTexture>(*resolvedState.state.bufferData);
426 resolvedStates.emplace_back(resolvedState);
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000427 }
428
429 TransactionState transactionState(transaction.frameTimelineInfo, resolvedStates,
430 transaction.displays, transaction.flags,
431 transaction.applyToken,
432 transaction.inputWindowCommands,
433 transaction.desiredPresentTime,
Chavi Weingartenc78f53c2023-04-14 18:50:53 +0000434 transaction.isAutoTimestamp, {}, systemTime(),
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000435 mHasListenerCallbacks, mCallbacks, getpid(),
Pablo Gamito23780be2023-04-18 08:30:00 +0000436 static_cast<int>(getuid()), transaction.id,
437 transaction.mergedTransactionIds);
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000438 mFlinger.setTransactionStateInternal(transactionState);
Ady Abraham9dada822022-02-03 10:26:59 -0800439 }
440 mFlinger.flushTransactionQueues();
Vishnu Nair60d902e2022-07-20 02:55:37 +0000441 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700442 EXPECT_EQ(expectedTransactionsPending, mFlinger.getPendingTransactionCount());
Ady Abraham9dada822022-02-03 10:26:59 -0800443 }
444};
445
446class LatchUnsignaledAutoSingleLayerTest : public LatchUnsignaledTest {
447public:
448 void SetUp() override {
449 LatchUnsignaledTest::SetUp();
450 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::AutoSingleLayer;
451 }
452};
453
454TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleSignaledFromTheQueue) {
455 const sp<IBinder> kApplyToken =
456 IInterface::asBinder(TransactionCompletedListener::getIInstance());
457 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800458 const auto kExpectedTransactionsPending = 0u;
459
460 const auto signaledTransaction =
461 createTransactionInfo(kApplyToken,
462 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
463 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700464 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000465}
466
Ady Abraham9dada822022-02-03 10:26:59 -0800467TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleUnSignaledFromTheQueue) {
468 const sp<IBinder> kApplyToken =
469 IInterface::asBinder(TransactionCompletedListener::getIInstance());
470 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800471 const auto kExpectedTransactionsPending = 0u;
472
473 const auto unsignaledTransaction =
474 createTransactionInfo(kApplyToken,
475 {
476 createComposerState(kLayerId,
477 fence(Fence::Status::Unsignaled),
478 layer_state_t::eBufferChanged),
479 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700480 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000481}
482
Ady Abraham9dada822022-02-03 10:26:59 -0800483TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange) {
484 const sp<IBinder> kApplyToken =
485 IInterface::asBinder(TransactionCompletedListener::getIInstance());
486 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800487 const auto kExpectedTransactionsPending = 1u;
488
489 const auto unsignaledTransaction =
490 createTransactionInfo(kApplyToken,
491 {
492 createComposerState(kLayerId,
493 fence(Fence::Status::Unsignaled),
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700494 layer_state_t::eCropChanged |
495 layer_state_t::
496 eBufferChanged),
Ady Abraham9dada822022-02-03 10:26:59 -0800497 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700498 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000499}
500
Ady Abraham9dada822022-02-03 10:26:59 -0800501TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed) {
502 const sp<IBinder> kApplyToken =
503 IInterface::asBinder(TransactionCompletedListener::getIInstance());
504 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800505 const auto kExpectedTransactionsPending = 1u;
506
507 const auto unsignaledTransaction =
508 createTransactionInfo(kApplyToken,
509 {
510 createComposerState(kLayerId,
511 fence(Fence::Status::Unsignaled),
512 layer_state_t::eCropChanged |
513 layer_state_t::
514 eBufferChanged),
515 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700516 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000517}
518
Ady Abraham9dada822022-02-03 10:26:59 -0800519TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueueSameApplyTokenMultiState) {
520 const sp<IBinder> kApplyToken =
521 IInterface::asBinder(TransactionCompletedListener::getIInstance());
522 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800523 const auto kExpectedTransactionsPending = 1u;
524
525 const auto mixedTransaction =
526 createTransactionInfo(kApplyToken,
527 {
528 createComposerState(kLayerId,
529 fence(Fence::Status::Unsignaled),
530 layer_state_t::eBufferChanged),
531 createComposerState(kLayerId,
532 fence(Fence::Status::Signaled),
533 layer_state_t::eBufferChanged),
534 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700535 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000536}
537
Ady Abraham9dada822022-02-03 10:26:59 -0800538TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueue_MultipleStateTransaction) {
539 const sp<IBinder> kApplyToken =
540 IInterface::asBinder(TransactionCompletedListener::getIInstance());
541 const auto kLayerId1 = 1;
542 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800543 const auto kExpectedTransactionsPending = 1u;
544
545 const auto mixedTransaction =
546 createTransactionInfo(kApplyToken,
547 {
548 createComposerState(kLayerId1,
549 fence(Fence::Status::Unsignaled),
550 layer_state_t::eBufferChanged),
551 createComposerState(kLayerId2,
552 fence(Fence::Status::Signaled),
553 layer_state_t::eBufferChanged),
554 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700555 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000556}
557
Ady Abraham9dada822022-02-03 10:26:59 -0800558TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSignaledFromTheQueue) {
559 const sp<IBinder> kApplyToken =
560 IInterface::asBinder(TransactionCompletedListener::getIInstance());
561 const auto kLayerId1 = 1;
562 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800563 const auto kExpectedTransactionsPending = 0u;
564
565 const auto signaledTransaction =
566 createTransactionInfo(kApplyToken,
567 {
568 createComposerState(kLayerId1,
569 fence(Fence::Status::Signaled),
570 layer_state_t::eBufferChanged),
571 });
572 const auto signaledTransaction2 =
573 createTransactionInfo(kApplyToken,
574 {
575 createComposerState(kLayerId2,
576 fence(Fence::Status::Signaled),
577 layer_state_t::eBufferChanged),
578 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700579 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000580}
581
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800582TEST_F(LatchUnsignaledAutoSingleLayerTest,
583 UnsignaledNotAppliedWhenThereAreSignaled_UnsignaledFirst) {
Ady Abraham9dada822022-02-03 10:26:59 -0800584 const sp<IBinder> kApplyToken1 =
585 IInterface::asBinder(TransactionCompletedListener::getIInstance());
586 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800587 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
Ady Abraham9dada822022-02-03 10:26:59 -0800588 const auto kLayerId1 = 1;
589 const auto kLayerId2 = 2;
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800590 const auto kExpectedTransactionsPending = 1u;
591
592 const auto unsignaledTransaction =
593 createTransactionInfo(kApplyToken1,
594 {
595 createComposerState(kLayerId1,
596 fence(Fence::Status::Unsignaled),
597 layer_state_t::eBufferChanged),
598 });
599
600 const auto signaledTransaction =
601 createTransactionInfo(kApplyToken2,
602 {
603 createComposerState(kLayerId2,
604 fence(Fence::Status::Signaled),
605 layer_state_t::eBufferChanged),
606 });
607 const auto signaledTransaction2 =
608 createTransactionInfo(kApplyToken3,
609 {
610 createComposerState(kLayerId2,
611 fence(Fence::Status::Signaled),
612 layer_state_t::eBufferChanged),
613 });
614
615 setTransactionStates({unsignaledTransaction, signaledTransaction, signaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700616 kExpectedTransactionsPending);
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800617}
618
Ady Abraham9dada822022-02-03 10:26:59 -0800619TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueueSameApplyToken) {
620 const sp<IBinder> kApplyToken =
621 IInterface::asBinder(TransactionCompletedListener::getIInstance());
622 const auto kLayerId1 = 1;
623 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800624 const auto kExpectedTransactionsPending = 1u;
625
626 const auto unsignaledTransaction =
627 createTransactionInfo(kApplyToken,
628 {
629 createComposerState(kLayerId1,
630 fence(Fence::Status::Unsignaled),
631 layer_state_t::eBufferChanged),
632 });
633 const auto signaledTransaction =
634 createTransactionInfo(kApplyToken,
635 {
636 createComposerState(kLayerId2,
637 fence(Fence::Status::Signaled),
638 layer_state_t::eBufferChanged),
639 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700640 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800641 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000642}
643
Ady Abraham9dada822022-02-03 10:26:59 -0800644TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueue) {
645 const sp<IBinder> kApplyToken1 =
646 IInterface::asBinder(TransactionCompletedListener::getIInstance());
647 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
648 const auto kLayerId1 = 1;
649 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800650 const auto kExpectedTransactionsPending = 1u;
651
652 const auto unsignaledTransaction =
653 createTransactionInfo(kApplyToken1,
654 {
655 createComposerState(kLayerId1,
656 fence(Fence::Status::Unsignaled),
657 layer_state_t::eBufferChanged),
658 });
659 const auto unsignaledTransaction2 =
660 createTransactionInfo(kApplyToken2,
661 {
662 createComposerState(kLayerId2,
663 fence(Fence::Status::Unsignaled),
664 layer_state_t::eBufferChanged),
665 });
666 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700667 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000668}
669
Ady Abraham2739e832022-02-14 17:42:00 -0800670TEST_F(LatchUnsignaledAutoSingleLayerTest, DontLatchUnsignaledWhenEarlyOffset) {
671 const sp<IBinder> kApplyToken =
672 IInterface::asBinder(TransactionCompletedListener::getIInstance());
673 const auto kLayerId = 1;
Ady Abraham2739e832022-02-14 17:42:00 -0800674 const auto kExpectedTransactionsPending = 1u;
675
676 const auto unsignaledTransaction =
677 createTransactionInfo(kApplyToken,
678 {
679 createComposerState(kLayerId,
680 fence(Fence::Status::Unsignaled),
681 layer_state_t::eBufferChanged),
682 });
683
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500684 modulateVsync();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700685 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
Ady Abraham2739e832022-02-14 17:42:00 -0800686}
687
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000688TEST_F(LatchUnsignaledAutoSingleLayerTest, UnsignaledNotAppliedWhenThereAreSignaled_SignaledFirst) {
689 const sp<IBinder> kApplyToken1 =
690 IInterface::asBinder(TransactionCompletedListener::getIInstance());
691 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
692 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
693 const auto kLayerId1 = 1;
694 const auto kLayerId2 = 2;
695 const auto kExpectedTransactionsPending = 1u;
696
697 const auto signaledTransaction =
698 createTransactionInfo(kApplyToken1,
699 {
700 createComposerState(kLayerId1,
701 fence(Fence::Status::Signaled),
702 layer_state_t::eBufferChanged),
703 });
704 const auto signaledTransaction2 =
705 createTransactionInfo(kApplyToken2,
706 {
707 createComposerState(kLayerId1,
708 fence(Fence::Status::Signaled),
709 layer_state_t::eBufferChanged),
710 });
711 const auto unsignaledTransaction =
712 createTransactionInfo(kApplyToken3,
713 {
714 createComposerState(kLayerId2,
715 fence(Fence::Status::Unsignaled),
716 layer_state_t::eBufferChanged),
717 });
718
719 setTransactionStates({signaledTransaction, signaledTransaction2, unsignaledTransaction},
720 kExpectedTransactionsPending);
721}
722
Ady Abraham9dada822022-02-03 10:26:59 -0800723class LatchUnsignaledDisabledTest : public LatchUnsignaledTest {
724public:
725 void SetUp() override {
726 LatchUnsignaledTest::SetUp();
727 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
728 }
729};
730
731TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue) {
732 const sp<IBinder> kApplyToken =
733 IInterface::asBinder(TransactionCompletedListener::getIInstance());
734 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800735 const auto kExpectedTransactionsPending = 0u;
736
737 const auto signaledTransaction =
738 createTransactionInfo(kApplyToken,
739 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
740 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700741 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000742}
743
Ady Abraham9dada822022-02-03 10:26:59 -0800744TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueue) {
745 const sp<IBinder> kApplyToken =
746 IInterface::asBinder(TransactionCompletedListener::getIInstance());
747 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800748 const auto kExpectedTransactionsPending = 1u;
749
750 const auto unsignaledTransaction =
751 createTransactionInfo(kApplyToken,
752 {
753 createComposerState(kLayerId,
754 fence(Fence::Status::Unsignaled),
755 layer_state_t::eBufferChanged),
756 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700757 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000758}
759
Ady Abraham9dada822022-02-03 10:26:59 -0800760TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueSameLayerId) {
761 const sp<IBinder> kApplyToken =
762 IInterface::asBinder(TransactionCompletedListener::getIInstance());
763 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800764 const auto kExpectedTransactionsPending = 1u;
765
766 const auto unsignaledTransaction =
767 createTransactionInfo(kApplyToken,
768 {
769 createComposerState(kLayerId,
770 fence(Fence::Status::Unsignaled),
771 layer_state_t::eBufferChanged),
772 createComposerState(kLayerId,
773 fence(Fence::Status::Unsignaled),
774 layer_state_t::eBufferChanged),
775 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700776 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000777}
778
Ady Abraham9dada822022-02-03 10:26:59 -0800779TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueDifferentLayerId) {
780 const sp<IBinder> kApplyToken =
781 IInterface::asBinder(TransactionCompletedListener::getIInstance());
782 const auto kLayerId1 = 1;
783 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800784 const auto kExpectedTransactionsPending = 1u;
785
786 const auto unsignaledTransaction =
787 createTransactionInfo(kApplyToken,
788 {
789 createComposerState(kLayerId1,
790 fence(Fence::Status::Unsignaled),
791 layer_state_t::eBufferChanged),
792 createComposerState(kLayerId2,
793 fence(Fence::Status::Unsignaled),
794 layer_state_t::eBufferChanged),
795 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700796 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000797}
798
Ady Abraham9dada822022-02-03 10:26:59 -0800799TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue_MultipleLayers) {
800 const sp<IBinder> kApplyToken =
801 IInterface::asBinder(TransactionCompletedListener::getIInstance());
802 const auto kLayerId1 = 1;
803 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800804 const auto kExpectedTransactionsPending = 0u;
805
806 const auto signaledTransaction =
807 createTransactionInfo(kApplyToken,
808 {
809 createComposerState(kLayerId1,
810 fence(Fence::Status::Signaled),
811 layer_state_t::eBufferChanged),
812 });
813 const auto signaledTransaction2 =
814 createTransactionInfo(kApplyToken,
815 {
816 createComposerState(kLayerId2,
817 fence(Fence::Status::Signaled),
818 layer_state_t::eBufferChanged),
819 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700820 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000821}
822
Ady Abraham9dada822022-02-03 10:26:59 -0800823TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueDifferentApplyToken) {
824 const sp<IBinder> kApplyToken1 =
825 IInterface::asBinder(TransactionCompletedListener::getIInstance());
826 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
827 const auto kLayerId1 = 1;
828 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800829 const auto kExpectedTransactionsPending = 1u;
830
831 const auto unsignaledTransaction =
832 createTransactionInfo(kApplyToken1,
833 {
834 createComposerState(kLayerId1,
835 fence(Fence::Status::Unsignaled),
836 layer_state_t::eBufferChanged),
837 });
838 const auto signaledTransaction =
839 createTransactionInfo(kApplyToken2,
840 {
841 createComposerState(kLayerId2,
842 fence(Fence::Status::Signaled),
843 layer_state_t::eBufferChanged),
844 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700845 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800846 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000847}
848
Ady Abraham9dada822022-02-03 10:26:59 -0800849TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueSameApplyToken) {
850 const sp<IBinder> kApplyToken =
851 IInterface::asBinder(TransactionCompletedListener::getIInstance());
852 const auto kLayerId1 = 1;
853 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800854 const auto kExpectedTransactionsPending = 1u;
855
856 const auto signaledTransaction =
857 createTransactionInfo(kApplyToken,
858 {
859 createComposerState(kLayerId1,
860 fence(Fence::Status::Signaled),
861 layer_state_t::eBufferChanged),
862 });
863 const auto unsignaledTransaction =
864 createTransactionInfo(kApplyToken,
865 {
866 createComposerState(kLayerId2,
867 fence(Fence::Status::Unsignaled),
868 layer_state_t::eBufferChanged),
869 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700870 setTransactionStates({signaledTransaction, unsignaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800871 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000872}
873
Ady Abraham9dada822022-02-03 10:26:59 -0800874TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheUnsignaledTheQueue) {
875 const sp<IBinder> kApplyToken =
876 IInterface::asBinder(TransactionCompletedListener::getIInstance());
877 const auto kLayerId1 = 1;
878 const auto kLayerId2 = 2;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700879 const auto kExpectedTransactionsPending = 2u;
Ady Abraham9dada822022-02-03 10:26:59 -0800880
881 const auto unsignaledTransaction =
882 createTransactionInfo(kApplyToken,
883 {
884 createComposerState(kLayerId1,
885 fence(Fence::Status::Unsignaled),
886 layer_state_t::eBufferChanged),
887 });
888 const auto unsignaledTransaction2 =
889 createTransactionInfo(kApplyToken,
890 {
891 createComposerState(kLayerId2,
892 fence(Fence::Status::Unsignaled),
893 layer_state_t::eBufferChanged),
894 });
895 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700896 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000897}
898
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700899TEST(TransactionHandlerTest, QueueTransaction) {
900 TransactionHandler handler;
901 TransactionState transaction;
902 transaction.applyToken = sp<BBinder>::make();
903 transaction.id = 42;
904 handler.queueTransaction(std::move(transaction));
Vishnu Nair4d9cef92023-06-24 22:34:41 +0000905 handler.collectTransactions();
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700906 std::vector<TransactionState> transactionsReadyToBeApplied = handler.flushTransactions();
907
908 EXPECT_EQ(transactionsReadyToBeApplied.size(), 1u);
909 EXPECT_EQ(transactionsReadyToBeApplied.front().id, 42u);
910}
911
Pablo Gamito23780be2023-04-18 08:30:00 +0000912TEST(TransactionHandlerTest, TransactionsKeepTrackOfDirectMerges) {
913 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
914
915 uint64_t transaction2Id = transaction2.getId();
916 uint64_t transaction3Id = transaction3.getId();
917 EXPECT_NE(transaction2Id, transaction3Id);
918
919 transaction1.merge(std::move(transaction2));
920 transaction1.merge(std::move(transaction3));
921
922 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
923 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
924 EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction2Id);
925}
926
927TEST(TransactionHandlerTest, TransactionsKeepTrackOfIndirectMerges) {
928 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
929
930 uint64_t transaction2Id = transaction2.getId();
931 uint64_t transaction3Id = transaction3.getId();
932 uint64_t transaction4Id = transaction4.getId();
933 EXPECT_NE(transaction2Id, transaction3Id);
934 EXPECT_NE(transaction2Id, transaction4Id);
935 EXPECT_NE(transaction3Id, transaction4Id);
936
937 transaction4.merge(std::move(transaction2));
938 transaction4.merge(std::move(transaction3));
939
940 EXPECT_EQ(transaction4.getMergedTransactionIds().size(), 2u);
941 EXPECT_EQ(transaction4.getMergedTransactionIds()[0], transaction3Id);
942 EXPECT_EQ(transaction4.getMergedTransactionIds()[1], transaction2Id);
943
944 transaction1.merge(std::move(transaction4));
945
946 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 3u);
947 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction4Id);
948 EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction3Id);
949 EXPECT_EQ(transaction1.getMergedTransactionIds()[2], transaction2Id);
950}
951
952TEST(TransactionHandlerTest, TransactionMergesAreCleared) {
953 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
954
955 transaction1.merge(std::move(transaction2));
956 transaction1.merge(std::move(transaction3));
957
958 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
959
960 transaction1.clear();
961
962 EXPECT_EQ(transaction1.getMergedTransactionIds().empty(), true);
963}
964
965TEST(TransactionHandlerTest, TransactionMergesAreCapped) {
966 SurfaceComposerClient::Transaction transaction;
967 std::vector<uint64_t> mergedTransactionIds;
968
969 for (uint i = 0; i < 20u; i++) {
970 SurfaceComposerClient::Transaction transactionToMerge;
971 mergedTransactionIds.push_back(transactionToMerge.getId());
972 transaction.merge(std::move(transactionToMerge));
973 }
974
975 // Keeps latest 10 merges in order of merge recency
976 EXPECT_EQ(transaction.getMergedTransactionIds().size(), 10u);
977 for (uint i = 0; i < 10u; i++) {
978 EXPECT_EQ(transaction.getMergedTransactionIds()[i],
979 mergedTransactionIds[mergedTransactionIds.size() - 1 - i]);
980 }
981}
982
983TEST(TransactionHandlerTest, KeepsMergesFromMoreRecentMerge) {
984 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
985 std::vector<uint64_t> mergedTransactionIds1, mergedTransactionIds2, mergedTransactionIds3;
986 uint64_t transaction2Id = transaction2.getId();
987 uint64_t transaction3Id = transaction3.getId();
988
989 for (uint i = 0; i < 20u; i++) {
990 SurfaceComposerClient::Transaction transactionToMerge;
991 mergedTransactionIds1.push_back(transactionToMerge.getId());
992 transaction1.merge(std::move(transactionToMerge));
993 }
994
995 for (uint i = 0; i < 5u; i++) {
996 SurfaceComposerClient::Transaction transactionToMerge;
997 mergedTransactionIds2.push_back(transactionToMerge.getId());
998 transaction2.merge(std::move(transactionToMerge));
999 }
1000
1001 transaction1.merge(std::move(transaction2));
1002 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1003 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction2Id);
1004 for (uint i = 0; i < 5u; i++) {
1005 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1u],
1006 mergedTransactionIds2[mergedTransactionIds2.size() - 1 - i]);
1007 }
1008 for (uint i = 0; i < 4u; i++) {
1009 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 6u],
1010 mergedTransactionIds1[mergedTransactionIds1.size() - 1 - i]);
1011 }
1012
1013 for (uint i = 0; i < 20u; i++) {
1014 SurfaceComposerClient::Transaction transactionToMerge;
1015 mergedTransactionIds3.push_back(transactionToMerge.getId());
1016 transaction3.merge(std::move(transactionToMerge));
1017 }
1018
1019 transaction1.merge(std::move(transaction3));
1020 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1021 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
1022 for (uint i = 0; i < 9u; i++) {
1023 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1],
1024 mergedTransactionIds3[mergedTransactionIds3.size() - 1 - i]);
1025 }
1026}
1027
1028TEST(TransactionHandlerTest, CanAddTransactionWithFullMergedIds) {
1029 SurfaceComposerClient::Transaction transaction1, transaction2;
1030 for (uint i = 0; i < 20u; i++) {
1031 SurfaceComposerClient::Transaction transactionToMerge;
1032 transaction1.merge(std::move(transactionToMerge));
1033 }
1034
1035 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1036
1037 auto transaction1Id = transaction1.getId();
1038 transaction2.merge(std::move(transaction1));
1039 EXPECT_EQ(transaction2.getMergedTransactionIds().size(), 10u);
1040 auto mergedTransactionIds = transaction2.getMergedTransactionIds();
1041 EXPECT_TRUE(std::count(mergedTransactionIds.begin(), mergedTransactionIds.end(),
1042 transaction1Id) > 0);
1043}
1044
Valerie Haud251afb2019-03-29 14:19:02 -07001045} // namespace android