blob: dbb7c6ce634792b34e88a16b3243a2faf910bb72 [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
18#define LOG_TAG "CompositionTest"
19
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);
76 static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1));
Valerie Haud251afb2019-03-29 14:19:02 -070077 };
78
Vishnu Nair6b591152021-10-08 11:45:14 -070079 void checkEqual(TransactionInfo info, TransactionState state) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100080 EXPECT_EQ(0u, info.states.size());
81 EXPECT_EQ(0u, state.states.size());
Valerie Haud251afb2019-03-29 14:19:02 -070082
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100083 EXPECT_EQ(0u, info.displays.size());
84 EXPECT_EQ(0u, state.displays.size());
Valerie Haud251afb2019-03-29 14:19:02 -070085 EXPECT_EQ(info.flags, state.flags);
86 EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime);
87 }
88
Patrick Williams641f7f22022-06-22 19:25:35 +000089 void setupSingle(TransactionInfo& transaction, uint32_t flags, int64_t desiredPresentTime,
90 bool isAutoTimestamp, const FrameTimelineInfo& frameTimelineInfo) {
Valerie Haud251afb2019-03-29 14:19:02 -070091 mTransactionNumber++;
Vishnu Nair1523dad2022-09-29 16:05:18 -070092 transaction.flags |= flags;
Valerie Haud251afb2019-03-29 14:19:02 -070093 transaction.desiredPresentTime = desiredPresentTime;
Ady Abrahamf0c56492020-12-17 18:04:15 -080094 transaction.isAutoTimestamp = isAutoTimestamp;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -100095 transaction.frameTimelineInfo = frameTimelineInfo;
Valerie Haud251afb2019-03-29 14:19:02 -070096 }
97
Patrick Williams641f7f22022-06-22 19:25:35 +000098 void NotPlacedOnTransactionQueue(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +000099 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700100 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700101 TransactionInfo transaction;
Patrick Williams641f7f22022-06-22 19:25:35 +0000102 setupSingle(transaction, flags,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800103 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000104 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700105 nsecs_t applicationTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000106 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700107 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700108 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800109 transaction.desiredPresentTime, transaction.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000110 transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800111 transaction.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700112
Patrick Williams641f7f22022-06-22 19:25:35 +0000113 // If transaction is synchronous, SF applyTransactionState should time out (5s) wating for
114 // SF to commit the transaction. If this is animation, it should not time out waiting.
Valerie Haud251afb2019-03-29 14:19:02 -0700115 nsecs_t returnedTime = systemTime();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700116 EXPECT_LE(returnedTime, applicationTime + TRANSACTION_TIMEOUT);
Arthur Hung58144272021-01-16 03:43:53 +0000117 // Each transaction should have been placed on the transaction queue
Vishnu Nair60d902e2022-07-20 02:55:37 +0000118 auto& transactionQueue = mFlinger.getTransactionQueue();
119 EXPECT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700120 }
121
Patrick Williams641f7f22022-06-22 19:25:35 +0000122 void PlaceOnTransactionQueue(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000123 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700124 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700125
126 // first check will see desired present time has not passed,
127 // but afterwards it will look like the desired present time has passed
128 nsecs_t time = systemTime();
Valerie Haud251afb2019-03-29 14:19:02 -0700129 TransactionInfo transaction;
Patrick Williams641f7f22022-06-22 19:25:35 +0000130 setupSingle(transaction, flags, /*desiredPresentTime*/ time + s2ns(1), false,
131 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700132 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000133 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700134 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700135 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800136 transaction.desiredPresentTime, transaction.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000137 transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800138 transaction.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700139
140 nsecs_t returnedTime = systemTime();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700141 EXPECT_LE(returnedTime, applicationSentTime + TRANSACTION_TIMEOUT);
Valerie Haud251afb2019-03-29 14:19:02 -0700142 // This transaction should have been placed on the transaction queue
Vishnu Nair60d902e2022-07-20 02:55:37 +0000143 auto& transactionQueue = mFlinger.getTransactionQueue();
144 EXPECT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700145 }
146
Patrick Williams641f7f22022-06-22 19:25:35 +0000147 void BlockedByPriorTransaction(uint32_t flags) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000148 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700149 nsecs_t time = systemTime();
Patrick Williams641f7f22022-06-22 19:25:35 +0000150 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(2);
151
Valerie Haud251afb2019-03-29 14:19:02 -0700152 // transaction that should go on the pending thread
153 TransactionInfo transactionA;
Patrick Williams641f7f22022-06-22 19:25:35 +0000154 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ time + s2ns(1), false,
155 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700156
157 // transaction that would not have gone on the pending thread if not
158 // blocked
159 TransactionInfo transactionB;
Patrick Williams641f7f22022-06-22 19:25:35 +0000160 setupSingle(transactionB, flags, /*desiredPresentTime*/ systemTime(),
161 /*isAutoTimestamp*/ true, FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700162
163 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000164 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700165 transactionA.displays, transactionA.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700166 transactionA.applyToken, transactionA.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800167 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000168 transactionA.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800169 transactionA.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700170
171 // This thread should not have been blocked by the above transaction
172 // (5s is the timeout period that applyTransactionState waits for SF to
173 // commit the transaction)
Vishnu Nair1523dad2022-09-29 16:05:18 -0700174 EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
Arthur Hung58144272021-01-16 03:43:53 +0000175 // transaction that would goes to pending transaciton queue.
176 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700177
178 applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000179 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700180 transactionB.displays, transactionB.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700181 transactionB.applyToken, transactionB.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800182 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000183 transactionB.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800184 transactionB.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700185
186 // this thread should have been blocked by the above transaction
187 // if this is an animation, this thread should be blocked for 5s
188 // in setTransactionState waiting for transactionA to flush. Otherwise,
189 // the transaction should be placed on the pending queue
Vishnu Nair1523dad2022-09-29 16:05:18 -0700190 EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
Valerie Haud251afb2019-03-29 14:19:02 -0700191
Arthur Hung58144272021-01-16 03:43:53 +0000192 // transaction that would goes to pending transaciton queue.
193 mFlinger.flushTransactionQueues();
194
Ady Abrahame46243a2021-02-23 19:33:49 -0800195 // check that the transaction was applied.
Arthur Hung58144272021-01-16 03:43:53 +0000196 auto transactionQueue = mFlinger.getPendingTransactionQueue();
Ady Abrahame46243a2021-02-23 19:33:49 -0800197 EXPECT_EQ(0u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700198 }
199
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500200 void modulateVsync() {
201 static_cast<void>(
Dominik Laskowski14956dc2023-02-22 13:43:57 -0500202 mFlinger.mutableScheduler().vsyncModulator().onRefreshRateChangeInitiated());
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500203 }
204
Valerie Haud251afb2019-03-29 14:19:02 -0700205 bool mHasListenerCallbacks = false;
206 std::vector<ListenerCallbacks> mCallbacks;
207 int mTransactionNumber = 0;
208};
209
Vishnu Nair60d902e2022-07-20 02:55:37 +0000210TEST_F(TransactionApplicationTest, AddToPendingQueue) {
211 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700212 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700213
Valerie Haud251afb2019-03-29 14:19:02 -0700214 TransactionInfo transactionA; // transaction to go on pending queue
Patrick Williams641f7f22022-06-22 19:25:35 +0000215 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
216 FrameTimelineInfo{});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000217 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700218 transactionA.displays, transactionA.flags, transactionA.applyToken,
219 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000220 transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800221 mHasListenerCallbacks, mCallbacks, transactionA.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700222
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000223 auto& transactionQueue = mFlinger.getTransactionQueue();
Vishnu Nair60d902e2022-07-20 02:55:37 +0000224 ASSERT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700225
Vishnu Nair60d902e2022-07-20 02:55:37 +0000226 auto transactionState = transactionQueue.pop().value();
Valerie Haud251afb2019-03-29 14:19:02 -0700227 checkEqual(transactionA, transactionState);
Vishnu Nair60d902e2022-07-20 02:55:37 +0000228}
229
230TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
231 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
232 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
233
234 TransactionInfo transactionA; // transaction to go on pending queue
235 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
236 FrameTimelineInfo{});
237 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
238 transactionA.displays, transactionA.flags, transactionA.applyToken,
239 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000240 transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
Vishnu Nair60d902e2022-07-20 02:55:37 +0000241 mHasListenerCallbacks, mCallbacks, transactionA.id);
242
243 auto& transactionQueue = mFlinger.getTransactionQueue();
244 ASSERT_FALSE(transactionQueue.isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700245
246 // because flushing uses the cached expected present time, we send an empty
247 // transaction here (sending a null applyToken to fake it as from a
248 // different process) to re-query and reset the cached expected present time
249 TransactionInfo empty;
250 empty.applyToken = sp<IBinder>();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000251 mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
252 empty.applyToken, empty.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800253 empty.desiredPresentTime, empty.isAutoTimestamp,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000254 empty.uncacheBuffers, mHasListenerCallbacks, mCallbacks, empty.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700255
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000256 // flush transaction queue should flush as desiredPresentTime has
Valerie Haud251afb2019-03-29 14:19:02 -0700257 // passed
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000258 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700259
Vishnu Nair60d902e2022-07-20 02:55:37 +0000260 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Valerie Haud251afb2019-03-29 14:19:02 -0700261}
262
Valerie Haud251afb2019-03-29 14:19:02 -0700263TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_SyncInputWindows) {
Patrick Williams641f7f22022-06-22 19:25:35 +0000264 NotPlacedOnTransactionQueue(/*flags*/ 0);
Valerie Haud251afb2019-03-29 14:19:02 -0700265}
266
Valerie Haud251afb2019-03-29 14:19:02 -0700267TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_SyncInputWindows) {
Patrick Williams641f7f22022-06-22 19:25:35 +0000268 PlaceOnTransactionQueue(/*flags*/ 0);
Valerie Haud251afb2019-03-29 14:19:02 -0700269}
270
Valerie Hau09e60052019-12-15 14:51:15 -0800271TEST_F(TransactionApplicationTest, FromHandle) {
272 sp<IBinder> badHandle;
273 auto ret = mFlinger.fromHandle(badHandle);
Vishnu Nair07e2a482022-10-18 19:18:16 +0000274 EXPECT_EQ(nullptr, ret.get());
Valerie Hau09e60052019-12-15 14:51:15 -0800275}
ramindani4d48f902021-09-20 21:07:45 +0000276
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700277class FakeExternalTexture : public renderengine::ExternalTexture {
278 const sp<GraphicBuffer> mEmptyBuffer = nullptr;
279 uint32_t mWidth;
280 uint32_t mHeight;
281 uint64_t mId;
282 PixelFormat mPixelFormat;
283 uint64_t mUsage;
284
285public:
286 FakeExternalTexture(BufferData& bufferData)
287 : mWidth(bufferData.getWidth()),
288 mHeight(bufferData.getHeight()),
289 mId(bufferData.getId()),
290 mPixelFormat(bufferData.getPixelFormat()),
291 mUsage(bufferData.getUsage()) {}
292 const sp<GraphicBuffer>& getBuffer() const { return mEmptyBuffer; }
293 bool hasSameBuffer(const renderengine::ExternalTexture& other) const override {
294 return getId() == other.getId();
295 }
296 uint32_t getWidth() const override { return mWidth; }
297 uint32_t getHeight() const override { return mHeight; }
298 uint64_t getId() const override { return mId; }
299 PixelFormat getPixelFormat() const override { return mPixelFormat; }
300 uint64_t getUsage() const override { return mUsage; }
301 void remapBuffer() override {}
302 ~FakeExternalTexture() = default;
303};
304
Ady Abraham9dada822022-02-03 10:26:59 -0800305class LatchUnsignaledTest : public TransactionApplicationTest {
306public:
307 void TearDown() override {
308 // Clear all transaction queues to release all transactions we sent
309 // in the tests. Otherwise, gmock complains about memory leaks.
Vishnu Nair60d902e2022-07-20 02:55:37 +0000310 while (!mFlinger.getTransactionQueue().isEmpty()) {
311 mFlinger.getTransactionQueue().pop();
312 }
Ady Abraham9dada822022-02-03 10:26:59 -0800313 mFlinger.getPendingTransactionQueue().clear();
Ady Abraham9dada822022-02-03 10:26:59 -0800314 mFlinger.commitTransactionsLocked(eTransactionMask);
315 mFlinger.mutableCurrentState().layersSortedByZ.clear();
316 mFlinger.mutableDrawingState().layersSortedByZ.clear();
317 }
318
319 static sp<Fence> fence(Fence::Status status) {
320 const auto fence = sp<mock::MockFence>::make();
321 EXPECT_CALL(*fence, getStatus()).WillRepeatedly(Return(status));
322 return fence;
323 }
324
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000325 ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what,
326 std::optional<sp<IBinder>> layerHandle = std::nullopt) {
Ady Abraham9dada822022-02-03 10:26:59 -0800327 ComposerState state;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700328 state.state.bufferData =
329 std::make_shared<fake::BufferData>(/* bufferId */ 123L, /* width */ 1,
330 /* height */ 2, /* pixelFormat */ 0,
331 /* outUsage */ 0);
Ady Abraham9dada822022-02-03 10:26:59 -0800332 state.state.bufferData->acquireFence = std::move(fence);
333 state.state.layerId = layerId;
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000334 state.state.surface = layerHandle.value_or(
Patrick Williams83f36b22022-09-14 17:57:35 +0000335 sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000336 ->getHandle());
Ady Abraham9dada822022-02-03 10:26:59 -0800337 state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
338
339 state.state.what = what;
340 if (what & layer_state_t::eCropChanged) {
341 state.state.crop = Rect(1, 2, 3, 4);
342 }
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000343 if (what & layer_state_t::eFlagsChanged) {
344 state.state.flags = layer_state_t::eEnableBackpressure;
345 state.state.mask = layer_state_t::eEnableBackpressure;
346 }
347
Ady Abraham9dada822022-02-03 10:26:59 -0800348 return state;
349 }
350
351 TransactionInfo createTransactionInfo(const sp<IBinder>& applyToken,
352 const std::vector<ComposerState>& states) {
353 TransactionInfo transaction;
Vishnu Nair1523dad2022-09-29 16:05:18 -0700354 const uint32_t kFlags = 0;
Ady Abraham9dada822022-02-03 10:26:59 -0800355 const nsecs_t kDesiredPresentTime = systemTime();
356 const bool kIsAutoTimestamp = true;
357 const auto kFrameTimelineInfo = FrameTimelineInfo{};
358
Patrick Williams641f7f22022-06-22 19:25:35 +0000359 setupSingle(transaction, kFlags, kDesiredPresentTime, kIsAutoTimestamp, kFrameTimelineInfo);
Ady Abraham9dada822022-02-03 10:26:59 -0800360 transaction.applyToken = applyToken;
361 for (const auto& state : states) {
362 transaction.states.push_back(state);
363 }
364
365 return transaction;
366 }
367
368 void setTransactionStates(const std::vector<TransactionInfo>& transactions,
Ady Abraham9dada822022-02-03 10:26:59 -0800369 size_t expectedTransactionsPending) {
Vishnu Nair60d902e2022-07-20 02:55:37 +0000370 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Ady Abraham9dada822022-02-03 10:26:59 -0800371 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
372
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000373 for (auto transaction : transactions) {
374 std::vector<ResolvedComposerState> resolvedStates;
375 resolvedStates.reserve(transaction.states.size());
376 for (auto& state : transaction.states) {
Vishnu Nair7ee4f462023-04-19 09:54:09 -0700377 ResolvedComposerState resolvedState;
378 resolvedState.state = std::move(state.state);
379 resolvedState.externalTexture =
380 std::make_shared<FakeExternalTexture>(*resolvedState.state.bufferData);
381 resolvedStates.emplace_back(resolvedState);
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000382 }
383
384 TransactionState transactionState(transaction.frameTimelineInfo, resolvedStates,
385 transaction.displays, transaction.flags,
386 transaction.applyToken,
387 transaction.inputWindowCommands,
388 transaction.desiredPresentTime,
Patrick Williams6c6dd3b2023-02-13 22:53:06 +0000389 transaction.isAutoTimestamp, {}, systemTime(), 0,
Vishnu Nair40fff5c2022-11-04 02:46:28 +0000390 mHasListenerCallbacks, mCallbacks, getpid(),
391 static_cast<int>(getuid()), transaction.id);
392 mFlinger.setTransactionStateInternal(transactionState);
Ady Abraham9dada822022-02-03 10:26:59 -0800393 }
394 mFlinger.flushTransactionQueues();
Vishnu Nair60d902e2022-07-20 02:55:37 +0000395 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700396 EXPECT_EQ(expectedTransactionsPending, mFlinger.getPendingTransactionCount());
Ady Abraham9dada822022-02-03 10:26:59 -0800397 }
398};
399
400class LatchUnsignaledAutoSingleLayerTest : public LatchUnsignaledTest {
401public:
402 void SetUp() override {
403 LatchUnsignaledTest::SetUp();
404 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::AutoSingleLayer;
405 }
406};
407
408TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleSignaledFromTheQueue) {
409 const sp<IBinder> kApplyToken =
410 IInterface::asBinder(TransactionCompletedListener::getIInstance());
411 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800412 const auto kExpectedTransactionsPending = 0u;
413
414 const auto signaledTransaction =
415 createTransactionInfo(kApplyToken,
416 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
417 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700418 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000419}
420
Ady Abraham9dada822022-02-03 10:26:59 -0800421TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleUnSignaledFromTheQueue) {
422 const sp<IBinder> kApplyToken =
423 IInterface::asBinder(TransactionCompletedListener::getIInstance());
424 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800425 const auto kExpectedTransactionsPending = 0u;
426
427 const auto unsignaledTransaction =
428 createTransactionInfo(kApplyToken,
429 {
430 createComposerState(kLayerId,
431 fence(Fence::Status::Unsignaled),
432 layer_state_t::eBufferChanged),
433 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700434 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000435}
436
Ady Abraham9dada822022-02-03 10:26:59 -0800437TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange) {
438 const sp<IBinder> kApplyToken =
439 IInterface::asBinder(TransactionCompletedListener::getIInstance());
440 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800441 const auto kExpectedTransactionsPending = 1u;
442
443 const auto unsignaledTransaction =
444 createTransactionInfo(kApplyToken,
445 {
446 createComposerState(kLayerId,
447 fence(Fence::Status::Unsignaled),
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700448 layer_state_t::eCropChanged |
449 layer_state_t::
450 eBufferChanged),
Ady Abraham9dada822022-02-03 10:26:59 -0800451 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700452 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000453}
454
Ady Abraham9dada822022-02-03 10:26:59 -0800455TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed) {
456 const sp<IBinder> kApplyToken =
457 IInterface::asBinder(TransactionCompletedListener::getIInstance());
458 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800459 const auto kExpectedTransactionsPending = 1u;
460
461 const auto unsignaledTransaction =
462 createTransactionInfo(kApplyToken,
463 {
464 createComposerState(kLayerId,
465 fence(Fence::Status::Unsignaled),
466 layer_state_t::eCropChanged |
467 layer_state_t::
468 eBufferChanged),
469 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700470 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000471}
472
Ady Abraham9dada822022-02-03 10:26:59 -0800473TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueueSameApplyTokenMultiState) {
474 const sp<IBinder> kApplyToken =
475 IInterface::asBinder(TransactionCompletedListener::getIInstance());
476 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800477 const auto kExpectedTransactionsPending = 1u;
478
479 const auto mixedTransaction =
480 createTransactionInfo(kApplyToken,
481 {
482 createComposerState(kLayerId,
483 fence(Fence::Status::Unsignaled),
484 layer_state_t::eBufferChanged),
485 createComposerState(kLayerId,
486 fence(Fence::Status::Signaled),
487 layer_state_t::eBufferChanged),
488 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700489 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000490}
491
Ady Abraham9dada822022-02-03 10:26:59 -0800492TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueue_MultipleStateTransaction) {
493 const sp<IBinder> kApplyToken =
494 IInterface::asBinder(TransactionCompletedListener::getIInstance());
495 const auto kLayerId1 = 1;
496 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800497 const auto kExpectedTransactionsPending = 1u;
498
499 const auto mixedTransaction =
500 createTransactionInfo(kApplyToken,
501 {
502 createComposerState(kLayerId1,
503 fence(Fence::Status::Unsignaled),
504 layer_state_t::eBufferChanged),
505 createComposerState(kLayerId2,
506 fence(Fence::Status::Signaled),
507 layer_state_t::eBufferChanged),
508 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700509 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000510}
511
Ady Abraham9dada822022-02-03 10:26:59 -0800512TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSignaledFromTheQueue) {
513 const sp<IBinder> kApplyToken =
514 IInterface::asBinder(TransactionCompletedListener::getIInstance());
515 const auto kLayerId1 = 1;
516 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800517 const auto kExpectedTransactionsPending = 0u;
518
519 const auto signaledTransaction =
520 createTransactionInfo(kApplyToken,
521 {
522 createComposerState(kLayerId1,
523 fence(Fence::Status::Signaled),
524 layer_state_t::eBufferChanged),
525 });
526 const auto signaledTransaction2 =
527 createTransactionInfo(kApplyToken,
528 {
529 createComposerState(kLayerId2,
530 fence(Fence::Status::Signaled),
531 layer_state_t::eBufferChanged),
532 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700533 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000534}
535
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800536TEST_F(LatchUnsignaledAutoSingleLayerTest,
537 UnsignaledNotAppliedWhenThereAreSignaled_UnsignaledFirst) {
Ady Abraham9dada822022-02-03 10:26:59 -0800538 const sp<IBinder> kApplyToken1 =
539 IInterface::asBinder(TransactionCompletedListener::getIInstance());
540 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800541 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
Ady Abraham9dada822022-02-03 10:26:59 -0800542 const auto kLayerId1 = 1;
543 const auto kLayerId2 = 2;
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800544 const auto kExpectedTransactionsPending = 1u;
545
546 const auto unsignaledTransaction =
547 createTransactionInfo(kApplyToken1,
548 {
549 createComposerState(kLayerId1,
550 fence(Fence::Status::Unsignaled),
551 layer_state_t::eBufferChanged),
552 });
553
554 const auto signaledTransaction =
555 createTransactionInfo(kApplyToken2,
556 {
557 createComposerState(kLayerId2,
558 fence(Fence::Status::Signaled),
559 layer_state_t::eBufferChanged),
560 });
561 const auto signaledTransaction2 =
562 createTransactionInfo(kApplyToken3,
563 {
564 createComposerState(kLayerId2,
565 fence(Fence::Status::Signaled),
566 layer_state_t::eBufferChanged),
567 });
568
569 setTransactionStates({unsignaledTransaction, signaledTransaction, signaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700570 kExpectedTransactionsPending);
Ady Abrahame1bfaac2022-02-22 21:32:08 -0800571}
572
Ady Abraham9dada822022-02-03 10:26:59 -0800573TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueueSameApplyToken) {
574 const sp<IBinder> kApplyToken =
575 IInterface::asBinder(TransactionCompletedListener::getIInstance());
576 const auto kLayerId1 = 1;
577 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800578 const auto kExpectedTransactionsPending = 1u;
579
580 const auto unsignaledTransaction =
581 createTransactionInfo(kApplyToken,
582 {
583 createComposerState(kLayerId1,
584 fence(Fence::Status::Unsignaled),
585 layer_state_t::eBufferChanged),
586 });
587 const auto signaledTransaction =
588 createTransactionInfo(kApplyToken,
589 {
590 createComposerState(kLayerId2,
591 fence(Fence::Status::Signaled),
592 layer_state_t::eBufferChanged),
593 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700594 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800595 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000596}
597
Ady Abraham9dada822022-02-03 10:26:59 -0800598TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueue) {
599 const sp<IBinder> kApplyToken1 =
600 IInterface::asBinder(TransactionCompletedListener::getIInstance());
601 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
602 const auto kLayerId1 = 1;
603 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800604 const auto kExpectedTransactionsPending = 1u;
605
606 const auto unsignaledTransaction =
607 createTransactionInfo(kApplyToken1,
608 {
609 createComposerState(kLayerId1,
610 fence(Fence::Status::Unsignaled),
611 layer_state_t::eBufferChanged),
612 });
613 const auto unsignaledTransaction2 =
614 createTransactionInfo(kApplyToken2,
615 {
616 createComposerState(kLayerId2,
617 fence(Fence::Status::Unsignaled),
618 layer_state_t::eBufferChanged),
619 });
620 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700621 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000622}
623
Ady Abraham2739e832022-02-14 17:42:00 -0800624TEST_F(LatchUnsignaledAutoSingleLayerTest, DontLatchUnsignaledWhenEarlyOffset) {
625 const sp<IBinder> kApplyToken =
626 IInterface::asBinder(TransactionCompletedListener::getIInstance());
627 const auto kLayerId = 1;
Ady Abraham2739e832022-02-14 17:42:00 -0800628 const auto kExpectedTransactionsPending = 1u;
629
630 const auto unsignaledTransaction =
631 createTransactionInfo(kApplyToken,
632 {
633 createComposerState(kLayerId,
634 fence(Fence::Status::Unsignaled),
635 layer_state_t::eBufferChanged),
636 });
637
Dominik Laskowski1c99a002023-01-20 17:10:36 -0500638 modulateVsync();
Vishnu Nair1523dad2022-09-29 16:05:18 -0700639 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
Ady Abraham2739e832022-02-14 17:42:00 -0800640}
641
Vishnu Nairf01a6f12023-04-03 22:34:17 +0000642TEST_F(LatchUnsignaledAutoSingleLayerTest, UnsignaledNotAppliedWhenThereAreSignaled_SignaledFirst) {
643 const sp<IBinder> kApplyToken1 =
644 IInterface::asBinder(TransactionCompletedListener::getIInstance());
645 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
646 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
647 const auto kLayerId1 = 1;
648 const auto kLayerId2 = 2;
649 const auto kExpectedTransactionsPending = 1u;
650
651 const auto signaledTransaction =
652 createTransactionInfo(kApplyToken1,
653 {
654 createComposerState(kLayerId1,
655 fence(Fence::Status::Signaled),
656 layer_state_t::eBufferChanged),
657 });
658 const auto signaledTransaction2 =
659 createTransactionInfo(kApplyToken2,
660 {
661 createComposerState(kLayerId1,
662 fence(Fence::Status::Signaled),
663 layer_state_t::eBufferChanged),
664 });
665 const auto unsignaledTransaction =
666 createTransactionInfo(kApplyToken3,
667 {
668 createComposerState(kLayerId2,
669 fence(Fence::Status::Unsignaled),
670 layer_state_t::eBufferChanged),
671 });
672
673 setTransactionStates({signaledTransaction, signaledTransaction2, unsignaledTransaction},
674 kExpectedTransactionsPending);
675}
676
Ady Abraham9dada822022-02-03 10:26:59 -0800677class LatchUnsignaledDisabledTest : public LatchUnsignaledTest {
678public:
679 void SetUp() override {
680 LatchUnsignaledTest::SetUp();
681 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
682 }
683};
684
685TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue) {
686 const sp<IBinder> kApplyToken =
687 IInterface::asBinder(TransactionCompletedListener::getIInstance());
688 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800689 const auto kExpectedTransactionsPending = 0u;
690
691 const auto signaledTransaction =
692 createTransactionInfo(kApplyToken,
693 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
694 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700695 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000696}
697
Ady Abraham9dada822022-02-03 10:26:59 -0800698TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueue) {
699 const sp<IBinder> kApplyToken =
700 IInterface::asBinder(TransactionCompletedListener::getIInstance());
701 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800702 const auto kExpectedTransactionsPending = 1u;
703
704 const auto unsignaledTransaction =
705 createTransactionInfo(kApplyToken,
706 {
707 createComposerState(kLayerId,
708 fence(Fence::Status::Unsignaled),
709 layer_state_t::eBufferChanged),
710 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700711 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000712}
713
Ady Abraham9dada822022-02-03 10:26:59 -0800714TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueSameLayerId) {
715 const sp<IBinder> kApplyToken =
716 IInterface::asBinder(TransactionCompletedListener::getIInstance());
717 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800718 const auto kExpectedTransactionsPending = 1u;
719
720 const auto unsignaledTransaction =
721 createTransactionInfo(kApplyToken,
722 {
723 createComposerState(kLayerId,
724 fence(Fence::Status::Unsignaled),
725 layer_state_t::eBufferChanged),
726 createComposerState(kLayerId,
727 fence(Fence::Status::Unsignaled),
728 layer_state_t::eBufferChanged),
729 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700730 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000731}
732
Ady Abraham9dada822022-02-03 10:26:59 -0800733TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueDifferentLayerId) {
734 const sp<IBinder> kApplyToken =
735 IInterface::asBinder(TransactionCompletedListener::getIInstance());
736 const auto kLayerId1 = 1;
737 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800738 const auto kExpectedTransactionsPending = 1u;
739
740 const auto unsignaledTransaction =
741 createTransactionInfo(kApplyToken,
742 {
743 createComposerState(kLayerId1,
744 fence(Fence::Status::Unsignaled),
745 layer_state_t::eBufferChanged),
746 createComposerState(kLayerId2,
747 fence(Fence::Status::Unsignaled),
748 layer_state_t::eBufferChanged),
749 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700750 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000751}
752
Ady Abraham9dada822022-02-03 10:26:59 -0800753TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue_MultipleLayers) {
754 const sp<IBinder> kApplyToken =
755 IInterface::asBinder(TransactionCompletedListener::getIInstance());
756 const auto kLayerId1 = 1;
757 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800758 const auto kExpectedTransactionsPending = 0u;
759
760 const auto signaledTransaction =
761 createTransactionInfo(kApplyToken,
762 {
763 createComposerState(kLayerId1,
764 fence(Fence::Status::Signaled),
765 layer_state_t::eBufferChanged),
766 });
767 const auto signaledTransaction2 =
768 createTransactionInfo(kApplyToken,
769 {
770 createComposerState(kLayerId2,
771 fence(Fence::Status::Signaled),
772 layer_state_t::eBufferChanged),
773 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700774 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000775}
776
Ady Abraham9dada822022-02-03 10:26:59 -0800777TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueDifferentApplyToken) {
778 const sp<IBinder> kApplyToken1 =
779 IInterface::asBinder(TransactionCompletedListener::getIInstance());
780 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
781 const auto kLayerId1 = 1;
782 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800783 const auto kExpectedTransactionsPending = 1u;
784
785 const auto unsignaledTransaction =
786 createTransactionInfo(kApplyToken1,
787 {
788 createComposerState(kLayerId1,
789 fence(Fence::Status::Unsignaled),
790 layer_state_t::eBufferChanged),
791 });
792 const auto signaledTransaction =
793 createTransactionInfo(kApplyToken2,
794 {
795 createComposerState(kLayerId2,
796 fence(Fence::Status::Signaled),
797 layer_state_t::eBufferChanged),
798 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700799 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800800 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000801}
802
Ady Abraham9dada822022-02-03 10:26:59 -0800803TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueSameApplyToken) {
804 const sp<IBinder> kApplyToken =
805 IInterface::asBinder(TransactionCompletedListener::getIInstance());
806 const auto kLayerId1 = 1;
807 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800808 const auto kExpectedTransactionsPending = 1u;
809
810 const auto signaledTransaction =
811 createTransactionInfo(kApplyToken,
812 {
813 createComposerState(kLayerId1,
814 fence(Fence::Status::Signaled),
815 layer_state_t::eBufferChanged),
816 });
817 const auto unsignaledTransaction =
818 createTransactionInfo(kApplyToken,
819 {
820 createComposerState(kLayerId2,
821 fence(Fence::Status::Unsignaled),
822 layer_state_t::eBufferChanged),
823 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700824 setTransactionStates({signaledTransaction, unsignaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800825 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000826}
827
Ady Abraham9dada822022-02-03 10:26:59 -0800828TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheUnsignaledTheQueue) {
829 const sp<IBinder> kApplyToken =
830 IInterface::asBinder(TransactionCompletedListener::getIInstance());
831 const auto kLayerId1 = 1;
832 const auto kLayerId2 = 2;
Vishnu Nair59f6d2d2022-10-05 16:59:56 -0700833 const auto kExpectedTransactionsPending = 2u;
Ady Abraham9dada822022-02-03 10:26:59 -0800834
835 const auto unsignaledTransaction =
836 createTransactionInfo(kApplyToken,
837 {
838 createComposerState(kLayerId1,
839 fence(Fence::Status::Unsignaled),
840 layer_state_t::eBufferChanged),
841 });
842 const auto unsignaledTransaction2 =
843 createTransactionInfo(kApplyToken,
844 {
845 createComposerState(kLayerId2,
846 fence(Fence::Status::Unsignaled),
847 layer_state_t::eBufferChanged),
848 });
849 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -0700850 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000851}
852
Ady Abraham9dada822022-02-03 10:26:59 -0800853class LatchUnsignaledAlwaysTest : public LatchUnsignaledTest {
854public:
855 void SetUp() override {
856 LatchUnsignaledTest::SetUp();
857 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
858 }
859};
860
861TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesSignaledFromTheQueue) {
862 const sp<IBinder> kApplyToken =
863 IInterface::asBinder(TransactionCompletedListener::getIInstance());
864 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800865 const auto kExpectedTransactionsPending = 0u;
866
867 const auto signaledTransaction =
868 createTransactionInfo(kApplyToken,
869 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
870 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700871 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000872}
873
Ady Abraham9dada822022-02-03 10:26:59 -0800874TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueue) {
875 const sp<IBinder> kApplyToken =
876 IInterface::asBinder(TransactionCompletedListener::getIInstance());
877 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800878 const auto kExpectedTransactionsPending = 0u;
879
880 const auto unsignaledTransaction =
881 createTransactionInfo(kApplyToken,
882 {createComposerState(kLayerId, fence(Fence::Status::Unsignaled),
883 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700884 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000885}
886
Ady Abraham9dada822022-02-03 10:26:59 -0800887TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueueSameLayerId) {
888 const sp<IBinder> kApplyToken =
889 IInterface::asBinder(TransactionCompletedListener::getIInstance());
890 const auto kLayerId = 1;
Ady Abraham9dada822022-02-03 10:26:59 -0800891 const auto kExpectedTransactionsPending = 0u;
892
893 const auto mixedTransaction =
894 createTransactionInfo(kApplyToken,
895 {createComposerState(kLayerId, fence(Fence::Status::Unsignaled),
896 layer_state_t::eBufferChanged),
897 createComposerState(kLayerId, fence(Fence::Status::Signaled),
898 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700899 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000900}
901
Ady Abraham9dada822022-02-03 10:26:59 -0800902TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueueDifferentLayerId) {
903 const sp<IBinder> kApplyToken =
904 IInterface::asBinder(TransactionCompletedListener::getIInstance());
905 const auto kLayerId1 = 1;
906 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800907 const auto kExpectedTransactionsPending = 0u;
908
909 const auto mixedTransaction =
910 createTransactionInfo(kApplyToken,
911 {createComposerState(kLayerId1, fence(Fence::Status::Unsignaled),
912 layer_state_t::eBufferChanged),
913 createComposerState(kLayerId2, fence(Fence::Status::Signaled),
914 layer_state_t::eBufferChanged)});
Vishnu Nair1523dad2022-09-29 16:05:18 -0700915 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000916}
917
Ady Abraham9dada822022-02-03 10:26:59 -0800918TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesSignaledFromTheQueue_MultipleLayers) {
919 const sp<IBinder> kApplyToken =
920 IInterface::asBinder(TransactionCompletedListener::getIInstance());
921 const auto kLayerId1 = 1;
922 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800923 const auto kExpectedTransactionsPending = 0u;
924
925 const auto signaledTransaction =
926 createTransactionInfo(kApplyToken,
927 {
928 createComposerState(kLayerId1,
929 fence(Fence::Status::Signaled),
930 layer_state_t::eBufferChanged),
931 });
932 const auto signaledTransaction2 =
933 createTransactionInfo(kApplyToken,
934 {
935 createComposerState(kLayerId2,
936 fence(Fence::Status::Signaled),
937 layer_state_t::eBufferChanged),
938 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700939 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000940}
941
Ady Abraham9dada822022-02-03 10:26:59 -0800942TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueueDifferentApplyToken) {
943 const sp<IBinder> kApplyToken1 =
944 IInterface::asBinder(TransactionCompletedListener::getIInstance());
945 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
946 const auto kLayerId1 = 1;
947 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800948 const auto kExpectedTransactionsPending = 0u;
949
950 const auto signaledTransaction =
951 createTransactionInfo(kApplyToken1,
952 {
953 createComposerState(kLayerId1,
954 fence(Fence::Status::Signaled),
955 layer_state_t::eBufferChanged),
956 });
957 const auto unsignaledTransaction =
958 createTransactionInfo(kApplyToken2,
959 {
960 createComposerState(kLayerId2,
961 fence(Fence::Status::Unsignaled),
962 layer_state_t::eBufferChanged),
963 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700964 setTransactionStates({signaledTransaction, unsignaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800965 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000966}
967
Ady Abraham9dada822022-02-03 10:26:59 -0800968TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesUnsignaledFromTheQueueSameApplyToken) {
969 const sp<IBinder> kApplyToken =
970 IInterface::asBinder(TransactionCompletedListener::getIInstance());
971 const auto kLayerId1 = 1;
972 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800973 const auto kExpectedTransactionsPending = 0u;
974
975 const auto unsignaledTransaction =
976 createTransactionInfo(kApplyToken,
977 {
978 createComposerState(kLayerId1,
979 fence(Fence::Status::Unsignaled),
980 layer_state_t::eBufferChanged),
981 });
982 const auto signaledTransaction =
983 createTransactionInfo(kApplyToken,
984 {
985 createComposerState(kLayerId2,
986 fence(Fence::Status::Signaled),
987 layer_state_t::eBufferChanged),
988 });
Vishnu Nair1523dad2022-09-29 16:05:18 -0700989 setTransactionStates({unsignaledTransaction, signaledTransaction},
Ady Abraham9dada822022-02-03 10:26:59 -0800990 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +0000991}
992
Ady Abraham9dada822022-02-03 10:26:59 -0800993TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesUnsignaledFromTheQueue) {
994 const sp<IBinder> kApplyToken1 =
995 IInterface::asBinder(TransactionCompletedListener::getIInstance());
996 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
997 const auto kLayerId1 = 1;
998 const auto kLayerId2 = 2;
Ady Abraham9dada822022-02-03 10:26:59 -0800999 const auto kExpectedTransactionsPending = 0u;
1000
1001 const auto unsignaledTransaction =
1002 createTransactionInfo(kApplyToken1,
1003 {
1004 createComposerState(kLayerId1,
1005 fence(Fence::Status::Unsignaled),
1006 layer_state_t::eBufferChanged),
1007 });
1008 const auto unsignaledTransaction2 =
1009 createTransactionInfo(kApplyToken2,
1010 {
1011 createComposerState(kLayerId2,
1012 fence(Fence::Status::Unsignaled),
1013 layer_state_t::eBufferChanged),
1014 });
1015 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
Vishnu Nair1523dad2022-09-29 16:05:18 -07001016 kExpectedTransactionsPending);
ramindani4d48f902021-09-20 21:07:45 +00001017}
1018
Vishnu Nairf01a6f12023-04-03 22:34:17 +00001019TEST_F(LatchUnsignaledAlwaysTest, RespectsBackPressureFlag) {
1020 const sp<IBinder> kApplyToken1 =
1021 IInterface::asBinder(TransactionCompletedListener::getIInstance());
1022 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
1023 const auto kLayerId1 = 1;
1024 const auto kExpectedTransactionsPending = 1u;
1025 auto layer =
1026 sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}));
1027 auto layerHandle = layer->getHandle();
1028 const auto setBackPressureFlagTransaction =
1029 createTransactionInfo(kApplyToken1,
1030 {createComposerState(kLayerId1, fence(Fence::Status::Unsignaled),
1031 layer_state_t::eBufferChanged |
1032 layer_state_t::eFlagsChanged,
1033 {layerHandle})});
1034 setTransactionStates({setBackPressureFlagTransaction}, 0u);
1035
1036 const auto unsignaledTransaction =
1037 createTransactionInfo(kApplyToken1,
1038 {
1039 createComposerState(kLayerId1,
1040 fence(Fence::Status::Unsignaled),
1041 layer_state_t::eBufferChanged,
1042 {layerHandle}),
1043 });
1044 const auto unsignaledTransaction2 =
1045 createTransactionInfo(kApplyToken1,
1046 {
1047 createComposerState(kLayerId1,
1048 fence(Fence::Status::Unsignaled),
1049 layer_state_t::eBufferChanged,
1050 {layerHandle}),
1051 });
1052 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
1053 kExpectedTransactionsPending);
1054}
1055
Ady Abraham2739e832022-02-14 17:42:00 -08001056TEST_F(LatchUnsignaledAlwaysTest, LatchUnsignaledWhenEarlyOffset) {
1057 const sp<IBinder> kApplyToken =
1058 IInterface::asBinder(TransactionCompletedListener::getIInstance());
1059 const auto kLayerId = 1;
Ady Abraham2739e832022-02-14 17:42:00 -08001060 const auto kExpectedTransactionsPending = 0u;
1061
1062 const auto unsignaledTransaction =
1063 createTransactionInfo(kApplyToken,
1064 {
1065 createComposerState(kLayerId,
1066 fence(Fence::Status::Unsignaled),
1067 layer_state_t::eBufferChanged),
1068 });
1069
Dominik Laskowski1c99a002023-01-20 17:10:36 -05001070 modulateVsync();
Vishnu Nair1523dad2022-09-29 16:05:18 -07001071 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
Ady Abraham2739e832022-02-14 17:42:00 -08001072}
1073
Vishnu Nair59f6d2d2022-10-05 16:59:56 -07001074TEST(TransactionHandlerTest, QueueTransaction) {
1075 TransactionHandler handler;
1076 TransactionState transaction;
1077 transaction.applyToken = sp<BBinder>::make();
1078 transaction.id = 42;
1079 handler.queueTransaction(std::move(transaction));
1080 std::vector<TransactionState> transactionsReadyToBeApplied = handler.flushTransactions();
1081
1082 EXPECT_EQ(transactionsReadyToBeApplied.size(), 1u);
1083 EXPECT_EQ(transactionsReadyToBeApplied.front().id, 42u);
1084}
1085
Valerie Haud251afb2019-03-29 14:19:02 -07001086} // namespace android