blob: 644b8c70c6d4d4ac47c1351aeabca683105400c8 [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
Ady Abraham9dada822022-02-03 10:26:59 -0800309class LatchUnsignaledTest : public TransactionApplicationTest {
310public:
311 void TearDown() override {
312 // Clear all transaction queues to release all transactions we sent
313 // in the tests. Otherwise, gmock complains about memory leaks.
Vishnu Nair60d902e2022-07-20 02:55:37 +0000314 while (!mFlinger.getTransactionQueue().isEmpty()) {
315 mFlinger.getTransactionQueue().pop();
316 }
Ady Abraham9dada822022-02-03 10:26:59 -0800317 mFlinger.getPendingTransactionQueue().clear();
Ady Abraham9dada822022-02-03 10:26:59 -0800318 mFlinger.commitTransactionsLocked(eTransactionMask);
319 mFlinger.mutableCurrentState().layersSortedByZ.clear();
320 mFlinger.mutableDrawingState().layersSortedByZ.clear();
321 }
322
323 static sp<Fence> fence(Fence::Status status) {
324 const auto fence = sp<mock::MockFence>::make();
325 EXPECT_CALL(*fence, getStatus()).WillRepeatedly(Return(status));
326 return fence;
327 }
328
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000329 ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what,
330 std::optional<sp<IBinder>> layerHandle = std::nullopt) {
Ady Abraham9dada822022-02-03 10:26:59 -0800331 ComposerState state;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700332 state.state.bufferData =
333 std::make_shared<fake::BufferData>(/* bufferId */ 123L, /* width */ 1,
334 /* height */ 2, /* pixelFormat */ 0,
335 /* outUsage */ 0);
Ady Abraham9dada822022-02-03 10:26:59 -0800336 state.state.bufferData->acquireFence = std::move(fence);
337 state.state.layerId = layerId;
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000338 state.state.surface = layerHandle.value_or(
Patrick Williams83f36b22022-09-14 17:57:35 +0000339 sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000340 ->getHandle());
Ady Abraham9dada822022-02-03 10:26:59 -0800341 state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
342
343 state.state.what = what;
344 if (what & layer_state_t::eCropChanged) {
345 state.state.crop = Rect(1, 2, 3, 4);
346 }
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000347 if (what & layer_state_t::eFlagsChanged) {
348 state.state.flags = layer_state_t::eEnableBackpressure;
349 state.state.mask = layer_state_t::eEnableBackpressure;
350 }
351
Ady Abraham9dada822022-02-03 10:26:59 -0800352 return state;
353 }
354
355 TransactionInfo createTransactionInfo(const sp<IBinder>& applyToken,
356 const std::vector<ComposerState>& states) {
357 TransactionInfo transaction;
Vishnu Nair1523dad2022-09-29 16:05:18 -0700358 const uint32_t kFlags = 0;
Ady Abraham9dada822022-02-03 10:26:59 -0800359 const nsecs_t kDesiredPresentTime = systemTime();
360 const bool kIsAutoTimestamp = true;
361 const auto kFrameTimelineInfo = FrameTimelineInfo{};
362
Patrick Williams641f7f22022-06-22 19:25:35 +0000363 setupSingle(transaction, kFlags, kDesiredPresentTime, kIsAutoTimestamp, kFrameTimelineInfo);
Ady Abraham9dada822022-02-03 10:26:59 -0800364 transaction.applyToken = applyToken;
365 for (const auto& state : states) {
366 transaction.states.push_back(state);
367 }
368
369 return transaction;
370 }
371
372 void setTransactionStates(const std::vector<TransactionInfo>& transactions,
Ady Abraham9dada822022-02-03 10:26:59 -0800373 size_t expectedTransactionsPending) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000374 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Ady Abraham9dada822022-02-03 10:26:59 -0800375 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
376
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000377 for (auto transaction : transactions) {
378 std::vector<ResolvedComposerState> resolvedStates;
379 resolvedStates.reserve(transaction.states.size());
380 for (auto& state : transaction.states) {
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700381 ResolvedComposerState resolvedState;
382 resolvedState.state = std::move(state.state);
383 resolvedState.externalTexture =
384 std::make_shared<FakeExternalTexture>(*resolvedState.state.bufferData);
385 resolvedStates.emplace_back(resolvedState);
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000386 }
387
388 TransactionState transactionState(transaction.frameTimelineInfo, resolvedStates,
389 transaction.displays, transaction.flags,
390 transaction.applyToken,
391 transaction.inputWindowCommands,
392 transaction.desiredPresentTime,
Chavi Weingartenc78f53c2023-04-14 18:50:53 +0000393 transaction.isAutoTimestamp, {}, systemTime(),
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000394 mHasListenerCallbacks, mCallbacks, getpid(),
Pablo Gamito23780be2023-04-18 08:30:00 +0000395 static_cast<int>(getuid()), transaction.id,
396 transaction.mergedTransactionIds);
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000397 mFlinger.setTransactionStateInternal(transactionState);
Ady Abraham9dada822022-02-03 10:26:59 -0800398 }
399 mFlinger.flushTransactionQueues();
Vishnu Nair60d902e2022-07-20 02:55:37 +0000400 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700401 EXPECT_EQ(expectedTransactionsPending, mFlinger.getPendingTransactionCount());
Ady Abraham9dada822022-02-03 10:26:59 -0800402 }
403};
404
405class LatchUnsignaledAutoSingleLayerTest : public LatchUnsignaledTest {
406public:
407 void SetUp() override {
408 LatchUnsignaledTest::SetUp();
409 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::AutoSingleLayer;
410 }
411};
412
413TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleSignaledFromTheQueue) {
414 const sp<IBinder> kApplyToken =
415 IInterface::asBinder(TransactionCompletedListener::getIInstance());
416 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800417 const auto kExpectedTransactionsPending = 0u;
418
419 const auto signaledTransaction =
420 createTransactionInfo(kApplyToken,
421 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
422 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700423 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000424}
425
Ady Abraham9dada822022-02-03 10:26:59 -0800426TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleUnSignaledFromTheQueue) {
427 const sp<IBinder> kApplyToken =
428 IInterface::asBinder(TransactionCompletedListener::getIInstance());
429 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800430 const auto kExpectedTransactionsPending = 0u;
431
432 const auto unsignaledTransaction =
433 createTransactionInfo(kApplyToken,
434 {
435 createComposerState(kLayerId,
436 fence(Fence::Status::Unsignaled),
437 layer_state_t::eBufferChanged),
438 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700439 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000440}
441
Ady Abraham9dada822022-02-03 10:26:59 -0800442TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange) {
443 const sp<IBinder> kApplyToken =
444 IInterface::asBinder(TransactionCompletedListener::getIInstance());
445 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800446 const auto kExpectedTransactionsPending = 1u;
447
448 const auto unsignaledTransaction =
449 createTransactionInfo(kApplyToken,
450 {
451 createComposerState(kLayerId,
452 fence(Fence::Status::Unsignaled),
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700453 layer_state_t::eCropChanged |
454 layer_state_t::
455 eBufferChanged),
Ady Abraham9dada822022-02-03 10:26:59 -0800456 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700457 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000458}
459
Ady Abraham9dada822022-02-03 10:26:59 -0800460TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed) {
461 const sp<IBinder> kApplyToken =
462 IInterface::asBinder(TransactionCompletedListener::getIInstance());
463 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800464 const auto kExpectedTransactionsPending = 1u;
465
466 const auto unsignaledTransaction =
467 createTransactionInfo(kApplyToken,
468 {
469 createComposerState(kLayerId,
470 fence(Fence::Status::Unsignaled),
471 layer_state_t::eCropChanged |
472 layer_state_t::
473 eBufferChanged),
474 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700475 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000476}
477
Ady Abraham9dada822022-02-03 10:26:59 -0800478TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueueSameApplyTokenMultiState) {
479 const sp<IBinder> kApplyToken =
480 IInterface::asBinder(TransactionCompletedListener::getIInstance());
481 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800482 const auto kExpectedTransactionsPending = 1u;
483
484 const auto mixedTransaction =
485 createTransactionInfo(kApplyToken,
486 {
487 createComposerState(kLayerId,
488 fence(Fence::Status::Unsignaled),
489 layer_state_t::eBufferChanged),
490 createComposerState(kLayerId,
491 fence(Fence::Status::Signaled),
492 layer_state_t::eBufferChanged),
493 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700494 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000495}
496
Ady Abraham9dada822022-02-03 10:26:59 -0800497TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueue_MultipleStateTransaction) {
498 const sp<IBinder> kApplyToken =
499 IInterface::asBinder(TransactionCompletedListener::getIInstance());
500 const auto kLayerId1 = 1;
501 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800502 const auto kExpectedTransactionsPending = 1u;
503
504 const auto mixedTransaction =
505 createTransactionInfo(kApplyToken,
506 {
507 createComposerState(kLayerId1,
508 fence(Fence::Status::Unsignaled),
509 layer_state_t::eBufferChanged),
510 createComposerState(kLayerId2,
511 fence(Fence::Status::Signaled),
512 layer_state_t::eBufferChanged),
513 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700514 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000515}
516
Ady Abraham9dada822022-02-03 10:26:59 -0800517TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSignaledFromTheQueue) {
518 const sp<IBinder> kApplyToken =
519 IInterface::asBinder(TransactionCompletedListener::getIInstance());
520 const auto kLayerId1 = 1;
521 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800522 const auto kExpectedTransactionsPending = 0u;
523
524 const auto signaledTransaction =
525 createTransactionInfo(kApplyToken,
526 {
527 createComposerState(kLayerId1,
528 fence(Fence::Status::Signaled),
529 layer_state_t::eBufferChanged),
530 });
531 const auto signaledTransaction2 =
532 createTransactionInfo(kApplyToken,
533 {
534 createComposerState(kLayerId2,
535 fence(Fence::Status::Signaled),
536 layer_state_t::eBufferChanged),
537 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700538 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000539}
540
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800541TEST_F(LatchUnsignaledAutoSingleLayerTest,
542 UnsignaledNotAppliedWhenThereAreSignaled_UnsignaledFirst) {
Ady Abraham9dada822022-02-03 10:26:59 -0800543 const sp<IBinder> kApplyToken1 =
544 IInterface::asBinder(TransactionCompletedListener::getIInstance());
545 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800546 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
Ady Abraham9dada822022-02-03 10:26:59 -0800547 const auto kLayerId1 = 1;
548 const auto kLayerId2 = 2;
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800549 const auto kExpectedTransactionsPending = 1u;
550
551 const auto unsignaledTransaction =
552 createTransactionInfo(kApplyToken1,
553 {
554 createComposerState(kLayerId1,
555 fence(Fence::Status::Unsignaled),
556 layer_state_t::eBufferChanged),
557 });
558
559 const auto signaledTransaction =
560 createTransactionInfo(kApplyToken2,
561 {
562 createComposerState(kLayerId2,
563 fence(Fence::Status::Signaled),
564 layer_state_t::eBufferChanged),
565 });
566 const auto signaledTransaction2 =
567 createTransactionInfo(kApplyToken3,
568 {
569 createComposerState(kLayerId2,
570 fence(Fence::Status::Signaled),
571 layer_state_t::eBufferChanged),
572 });
573
574 setTransactionStates({unsignaledTransaction, signaledTransaction, signaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700575 kExpectedTransactionsPending);
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800576}
577
Ady Abraham9dada822022-02-03 10:26:59 -0800578TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueueSameApplyToken) {
579 const sp<IBinder> kApplyToken =
580 IInterface::asBinder(TransactionCompletedListener::getIInstance());
581 const auto kLayerId1 = 1;
582 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800583 const auto kExpectedTransactionsPending = 1u;
584
585 const auto unsignaledTransaction =
586 createTransactionInfo(kApplyToken,
587 {
588 createComposerState(kLayerId1,
589 fence(Fence::Status::Unsignaled),
590 layer_state_t::eBufferChanged),
591 });
592 const auto signaledTransaction =
593 createTransactionInfo(kApplyToken,
594 {
595 createComposerState(kLayerId2,
596 fence(Fence::Status::Signaled),
597 layer_state_t::eBufferChanged),
598 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700599 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800600 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000601}
602
Ady Abraham9dada822022-02-03 10:26:59 -0800603TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueue) {
604 const sp<IBinder> kApplyToken1 =
605 IInterface::asBinder(TransactionCompletedListener::getIInstance());
606 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
607 const auto kLayerId1 = 1;
608 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800609 const auto kExpectedTransactionsPending = 1u;
610
611 const auto unsignaledTransaction =
612 createTransactionInfo(kApplyToken1,
613 {
614 createComposerState(kLayerId1,
615 fence(Fence::Status::Unsignaled),
616 layer_state_t::eBufferChanged),
617 });
618 const auto unsignaledTransaction2 =
619 createTransactionInfo(kApplyToken2,
620 {
621 createComposerState(kLayerId2,
622 fence(Fence::Status::Unsignaled),
623 layer_state_t::eBufferChanged),
624 });
625 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700626 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000627}
628
Ady Abraham2739e832022-02-14 17:42:00 -0800629TEST_F(LatchUnsignaledAutoSingleLayerTest, DontLatchUnsignaledWhenEarlyOffset) {
630 const sp<IBinder> kApplyToken =
631 IInterface::asBinder(TransactionCompletedListener::getIInstance());
632 const auto kLayerId = 1;
Ady Abraham2739e832022-02-14 17:42:00 -0800633 const auto kExpectedTransactionsPending = 1u;
634
635 const auto unsignaledTransaction =
636 createTransactionInfo(kApplyToken,
637 {
638 createComposerState(kLayerId,
639 fence(Fence::Status::Unsignaled),
640 layer_state_t::eBufferChanged),
641 });
642
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500643 modulateVsync();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700644 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
Ady Abraham2739e832022-02-14 17:42:00 -0800645}
646
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000647TEST_F(LatchUnsignaledAutoSingleLayerTest, UnsignaledNotAppliedWhenThereAreSignaled_SignaledFirst) {
648 const sp<IBinder> kApplyToken1 =
649 IInterface::asBinder(TransactionCompletedListener::getIInstance());
650 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
651 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
652 const auto kLayerId1 = 1;
653 const auto kLayerId2 = 2;
654 const auto kExpectedTransactionsPending = 1u;
655
656 const auto signaledTransaction =
657 createTransactionInfo(kApplyToken1,
658 {
659 createComposerState(kLayerId1,
660 fence(Fence::Status::Signaled),
661 layer_state_t::eBufferChanged),
662 });
663 const auto signaledTransaction2 =
664 createTransactionInfo(kApplyToken2,
665 {
666 createComposerState(kLayerId1,
667 fence(Fence::Status::Signaled),
668 layer_state_t::eBufferChanged),
669 });
670 const auto unsignaledTransaction =
671 createTransactionInfo(kApplyToken3,
672 {
673 createComposerState(kLayerId2,
674 fence(Fence::Status::Unsignaled),
675 layer_state_t::eBufferChanged),
676 });
677
678 setTransactionStates({signaledTransaction, signaledTransaction2, unsignaledTransaction},
679 kExpectedTransactionsPending);
680}
681
Ady Abraham9dada822022-02-03 10:26:59 -0800682class LatchUnsignaledDisabledTest : public LatchUnsignaledTest {
683public:
684 void SetUp() override {
685 LatchUnsignaledTest::SetUp();
686 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
687 }
688};
689
690TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue) {
691 const sp<IBinder> kApplyToken =
692 IInterface::asBinder(TransactionCompletedListener::getIInstance());
693 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800694 const auto kExpectedTransactionsPending = 0u;
695
696 const auto signaledTransaction =
697 createTransactionInfo(kApplyToken,
698 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
699 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700700 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000701}
702
Ady Abraham9dada822022-02-03 10:26:59 -0800703TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueue) {
704 const sp<IBinder> kApplyToken =
705 IInterface::asBinder(TransactionCompletedListener::getIInstance());
706 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800707 const auto kExpectedTransactionsPending = 1u;
708
709 const auto unsignaledTransaction =
710 createTransactionInfo(kApplyToken,
711 {
712 createComposerState(kLayerId,
713 fence(Fence::Status::Unsignaled),
714 layer_state_t::eBufferChanged),
715 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700716 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000717}
718
Ady Abraham9dada822022-02-03 10:26:59 -0800719TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueSameLayerId) {
720 const sp<IBinder> kApplyToken =
721 IInterface::asBinder(TransactionCompletedListener::getIInstance());
722 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800723 const auto kExpectedTransactionsPending = 1u;
724
725 const auto unsignaledTransaction =
726 createTransactionInfo(kApplyToken,
727 {
728 createComposerState(kLayerId,
729 fence(Fence::Status::Unsignaled),
730 layer_state_t::eBufferChanged),
731 createComposerState(kLayerId,
732 fence(Fence::Status::Unsignaled),
733 layer_state_t::eBufferChanged),
734 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700735 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000736}
737
Ady Abraham9dada822022-02-03 10:26:59 -0800738TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueDifferentLayerId) {
739 const sp<IBinder> kApplyToken =
740 IInterface::asBinder(TransactionCompletedListener::getIInstance());
741 const auto kLayerId1 = 1;
742 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800743 const auto kExpectedTransactionsPending = 1u;
744
745 const auto unsignaledTransaction =
746 createTransactionInfo(kApplyToken,
747 {
748 createComposerState(kLayerId1,
749 fence(Fence::Status::Unsignaled),
750 layer_state_t::eBufferChanged),
751 createComposerState(kLayerId2,
752 fence(Fence::Status::Unsignaled),
753 layer_state_t::eBufferChanged),
754 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700755 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000756}
757
Ady Abraham9dada822022-02-03 10:26:59 -0800758TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue_MultipleLayers) {
759 const sp<IBinder> kApplyToken =
760 IInterface::asBinder(TransactionCompletedListener::getIInstance());
761 const auto kLayerId1 = 1;
762 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800763 const auto kExpectedTransactionsPending = 0u;
764
765 const auto signaledTransaction =
766 createTransactionInfo(kApplyToken,
767 {
768 createComposerState(kLayerId1,
769 fence(Fence::Status::Signaled),
770 layer_state_t::eBufferChanged),
771 });
772 const auto signaledTransaction2 =
773 createTransactionInfo(kApplyToken,
774 {
775 createComposerState(kLayerId2,
776 fence(Fence::Status::Signaled),
777 layer_state_t::eBufferChanged),
778 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700779 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000780}
781
Ady Abraham9dada822022-02-03 10:26:59 -0800782TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueDifferentApplyToken) {
783 const sp<IBinder> kApplyToken1 =
784 IInterface::asBinder(TransactionCompletedListener::getIInstance());
785 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
786 const auto kLayerId1 = 1;
787 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800788 const auto kExpectedTransactionsPending = 1u;
789
790 const auto unsignaledTransaction =
791 createTransactionInfo(kApplyToken1,
792 {
793 createComposerState(kLayerId1,
794 fence(Fence::Status::Unsignaled),
795 layer_state_t::eBufferChanged),
796 });
797 const auto signaledTransaction =
798 createTransactionInfo(kApplyToken2,
799 {
800 createComposerState(kLayerId2,
801 fence(Fence::Status::Signaled),
802 layer_state_t::eBufferChanged),
803 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700804 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800805 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000806}
807
Ady Abraham9dada822022-02-03 10:26:59 -0800808TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueSameApplyToken) {
809 const sp<IBinder> kApplyToken =
810 IInterface::asBinder(TransactionCompletedListener::getIInstance());
811 const auto kLayerId1 = 1;
812 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800813 const auto kExpectedTransactionsPending = 1u;
814
815 const auto signaledTransaction =
816 createTransactionInfo(kApplyToken,
817 {
818 createComposerState(kLayerId1,
819 fence(Fence::Status::Signaled),
820 layer_state_t::eBufferChanged),
821 });
822 const auto unsignaledTransaction =
823 createTransactionInfo(kApplyToken,
824 {
825 createComposerState(kLayerId2,
826 fence(Fence::Status::Unsignaled),
827 layer_state_t::eBufferChanged),
828 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700829 setTransactionStates({signaledTransaction, unsignaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800830 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000831}
832
Ady Abraham9dada822022-02-03 10:26:59 -0800833TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheUnsignaledTheQueue) {
834 const sp<IBinder> kApplyToken =
835 IInterface::asBinder(TransactionCompletedListener::getIInstance());
836 const auto kLayerId1 = 1;
837 const auto kLayerId2 = 2;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700838 const auto kExpectedTransactionsPending = 2u;
Ady Abraham9dada822022-02-03 10:26:59 -0800839
840 const auto unsignaledTransaction =
841 createTransactionInfo(kApplyToken,
842 {
843 createComposerState(kLayerId1,
844 fence(Fence::Status::Unsignaled),
845 layer_state_t::eBufferChanged),
846 });
847 const auto unsignaledTransaction2 =
848 createTransactionInfo(kApplyToken,
849 {
850 createComposerState(kLayerId2,
851 fence(Fence::Status::Unsignaled),
852 layer_state_t::eBufferChanged),
853 });
854 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700855 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000856}
857
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700858TEST(TransactionHandlerTest, QueueTransaction) {
859 TransactionHandler handler;
860 TransactionState transaction;
861 transaction.applyToken = sp<BBinder>::make();
862 transaction.id = 42;
863 handler.queueTransaction(std::move(transaction));
Vishnu Nair4d9cef92023-06-24 22:34:41 +0000864 handler.collectTransactions();
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700865 std::vector<TransactionState> transactionsReadyToBeApplied = handler.flushTransactions();
866
867 EXPECT_EQ(transactionsReadyToBeApplied.size(), 1u);
868 EXPECT_EQ(transactionsReadyToBeApplied.front().id, 42u);
869}
870
Pablo Gamito23780be2023-04-18 08:30:00 +0000871TEST(TransactionHandlerTest, TransactionsKeepTrackOfDirectMerges) {
872 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
873
874 uint64_t transaction2Id = transaction2.getId();
875 uint64_t transaction3Id = transaction3.getId();
876 EXPECT_NE(transaction2Id, transaction3Id);
877
878 transaction1.merge(std::move(transaction2));
879 transaction1.merge(std::move(transaction3));
880
881 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
882 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
883 EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction2Id);
884}
885
886TEST(TransactionHandlerTest, TransactionsKeepTrackOfIndirectMerges) {
887 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
888
889 uint64_t transaction2Id = transaction2.getId();
890 uint64_t transaction3Id = transaction3.getId();
891 uint64_t transaction4Id = transaction4.getId();
892 EXPECT_NE(transaction2Id, transaction3Id);
893 EXPECT_NE(transaction2Id, transaction4Id);
894 EXPECT_NE(transaction3Id, transaction4Id);
895
896 transaction4.merge(std::move(transaction2));
897 transaction4.merge(std::move(transaction3));
898
899 EXPECT_EQ(transaction4.getMergedTransactionIds().size(), 2u);
900 EXPECT_EQ(transaction4.getMergedTransactionIds()[0], transaction3Id);
901 EXPECT_EQ(transaction4.getMergedTransactionIds()[1], transaction2Id);
902
903 transaction1.merge(std::move(transaction4));
904
905 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 3u);
906 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction4Id);
907 EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction3Id);
908 EXPECT_EQ(transaction1.getMergedTransactionIds()[2], transaction2Id);
909}
910
911TEST(TransactionHandlerTest, TransactionMergesAreCleared) {
912 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
913
914 transaction1.merge(std::move(transaction2));
915 transaction1.merge(std::move(transaction3));
916
917 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
918
919 transaction1.clear();
920
921 EXPECT_EQ(transaction1.getMergedTransactionIds().empty(), true);
922}
923
924TEST(TransactionHandlerTest, TransactionMergesAreCapped) {
925 SurfaceComposerClient::Transaction transaction;
926 std::vector<uint64_t> mergedTransactionIds;
927
928 for (uint i = 0; i < 20u; i++) {
929 SurfaceComposerClient::Transaction transactionToMerge;
930 mergedTransactionIds.push_back(transactionToMerge.getId());
931 transaction.merge(std::move(transactionToMerge));
932 }
933
934 // Keeps latest 10 merges in order of merge recency
935 EXPECT_EQ(transaction.getMergedTransactionIds().size(), 10u);
936 for (uint i = 0; i < 10u; i++) {
937 EXPECT_EQ(transaction.getMergedTransactionIds()[i],
938 mergedTransactionIds[mergedTransactionIds.size() - 1 - i]);
939 }
940}
941
942TEST(TransactionHandlerTest, KeepsMergesFromMoreRecentMerge) {
943 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
944 std::vector<uint64_t> mergedTransactionIds1, mergedTransactionIds2, mergedTransactionIds3;
945 uint64_t transaction2Id = transaction2.getId();
946 uint64_t transaction3Id = transaction3.getId();
947
948 for (uint i = 0; i < 20u; i++) {
949 SurfaceComposerClient::Transaction transactionToMerge;
950 mergedTransactionIds1.push_back(transactionToMerge.getId());
951 transaction1.merge(std::move(transactionToMerge));
952 }
953
954 for (uint i = 0; i < 5u; i++) {
955 SurfaceComposerClient::Transaction transactionToMerge;
956 mergedTransactionIds2.push_back(transactionToMerge.getId());
957 transaction2.merge(std::move(transactionToMerge));
958 }
959
960 transaction1.merge(std::move(transaction2));
961 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
962 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction2Id);
963 for (uint i = 0; i < 5u; i++) {
964 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1u],
965 mergedTransactionIds2[mergedTransactionIds2.size() - 1 - i]);
966 }
967 for (uint i = 0; i < 4u; i++) {
968 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 6u],
969 mergedTransactionIds1[mergedTransactionIds1.size() - 1 - i]);
970 }
971
972 for (uint i = 0; i < 20u; i++) {
973 SurfaceComposerClient::Transaction transactionToMerge;
974 mergedTransactionIds3.push_back(transactionToMerge.getId());
975 transaction3.merge(std::move(transactionToMerge));
976 }
977
978 transaction1.merge(std::move(transaction3));
979 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
980 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
981 for (uint i = 0; i < 9u; i++) {
982 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1],
983 mergedTransactionIds3[mergedTransactionIds3.size() - 1 - i]);
984 }
985}
986
987TEST(TransactionHandlerTest, CanAddTransactionWithFullMergedIds) {
988 SurfaceComposerClient::Transaction transaction1, transaction2;
989 for (uint i = 0; i < 20u; i++) {
990 SurfaceComposerClient::Transaction transactionToMerge;
991 transaction1.merge(std::move(transactionToMerge));
992 }
993
994 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
995
996 auto transaction1Id = transaction1.getId();
997 transaction2.merge(std::move(transaction1));
998 EXPECT_EQ(transaction2.getMergedTransactionIds().size(), 10u);
999 auto mergedTransactionIds = transaction2.getMergedTransactionIds();
1000 EXPECT_TRUE(std::count(mergedTransactionIds.begin(), mergedTransactionIds.end(),
1001 transaction1Id) > 0);
1002}
1003
Valerie Haud251afb2019-03-29 14:19:02 -07001004} // namespace android