blob: 1ce0309683ccc942aed3a3490e8a3f6b1c1ed6e9 [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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017
Valerie Haud251afb2019-03-29 14:19:02 -070018#undef LOG_TAG
19#define LOG_TAG "CompositionTest"
20
21#include <compositionengine/Display.h>
22#include <compositionengine/mock/DisplaySurface.h>
23#include <gmock/gmock.h>
24#include <gtest/gtest.h>
25#include <gui/SurfaceComposerClient.h>
26#include <log/log.h>
ramindani4d48f902021-09-20 21:07:45 +000027#include <ui/MockFence.h>
Valerie Haud251afb2019-03-29 14:19:02 -070028#include <utils/String8.h>
Dominik Laskowski068173d2021-08-11 17:22:59 -070029
Valerie Haud251afb2019-03-29 14:19:02 -070030#include "TestableSurfaceFlinger.h"
Valerie Haud251afb2019-03-29 14:19:02 -070031#include "mock/MockEventThread.h"
Ady Abraham8cb21882020-08-26 18:22:05 -070032#include "mock/MockVsyncController.h"
Valerie Haud251afb2019-03-29 14:19:02 -070033
34namespace android {
35
36using testing::_;
37using testing::Return;
38
39using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
40
41class TransactionApplicationTest : public testing::Test {
42public:
43 TransactionApplicationTest() {
44 const ::testing::TestInfo* const test_info =
45 ::testing::UnitTest::GetInstance()->current_test_info();
46 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
47
Valerie Haud251afb2019-03-29 14:19:02 -070048 setupScheduler();
49 }
50
51 ~TransactionApplicationTest() {
52 const ::testing::TestInfo* const test_info =
53 ::testing::UnitTest::GetInstance()->current_test_info();
54 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
55 }
56
57 void setupScheduler() {
58 auto eventThread = std::make_unique<mock::EventThread>();
59 auto sfEventThread = std::make_unique<mock::EventThread>();
60
61 EXPECT_CALL(*eventThread, registerDisplayEventConnection(_));
62 EXPECT_CALL(*eventThread, createEventConnection(_, _))
Ady Abraham62f216c2020-10-13 19:07:23 -070063 .WillOnce(Return(new EventThreadConnection(eventThread.get(), /*callingUid=*/0,
64 ResyncCallback())));
Valerie Haud251afb2019-03-29 14:19:02 -070065
66 EXPECT_CALL(*sfEventThread, registerDisplayEventConnection(_));
67 EXPECT_CALL(*sfEventThread, createEventConnection(_, _))
Ady Abraham62f216c2020-10-13 19:07:23 -070068 .WillOnce(Return(new EventThreadConnection(sfEventThread.get(), /*callingUid=*/0,
69 ResyncCallback())));
Valerie Haud251afb2019-03-29 14:19:02 -070070
Ady Abraham8cb21882020-08-26 18:22:05 -070071 EXPECT_CALL(*mVSyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
72 EXPECT_CALL(*mVSyncTracker, currentPeriod())
Marin Shalamanov045b7002021-01-07 16:56:24 +010073 .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
Valerie Haud251afb2019-03-29 14:19:02 -070074
ramindani4d48f902021-09-20 21:07:45 +000075 EXPECT_CALL(*mFenceUnsignaled, getStatus())
76 .WillRepeatedly(Return(Fence::Status::Unsignaled));
77 EXPECT_CALL(*mFenceUnsignaled2, getStatus())
78 .WillRepeatedly(Return(Fence::Status::Unsignaled));
79 EXPECT_CALL(*mFenceSignaled, getStatus()).WillRepeatedly(Return(Fence::Status::Signaled));
80 EXPECT_CALL(*mFenceSignaled2, getStatus()).WillRepeatedly(Return(Fence::Status::Signaled));
81
Ady Abraham3efa3942021-06-24 19:01:25 -070082 mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
Ady Abraham8cb21882020-08-26 18:22:05 -070083 mFlinger.setupScheduler(std::unique_ptr<mock::VsyncController>(mVsyncController),
84 std::unique_ptr<mock::VSyncTracker>(mVSyncTracker),
Valerie Haud251afb2019-03-29 14:19:02 -070085 std::move(eventThread), std::move(sfEventThread));
86 }
87
Valerie Haud251afb2019-03-29 14:19:02 -070088 TestableSurfaceFlinger mFlinger;
89
Ady Abraham8cb21882020-08-26 18:22:05 -070090 mock::VsyncController* mVsyncController = new mock::VsyncController();
91 mock::VSyncTracker* mVSyncTracker = new mock::VSyncTracker();
ramindani4d48f902021-09-20 21:07:45 +000092 mock::MockFence* mFenceUnsignaled = new mock::MockFence();
93 mock::MockFence* mFenceSignaled = new mock::MockFence();
94 mock::MockFence* mFenceUnsignaled2 = new mock::MockFence();
95 mock::MockFence* mFenceSignaled2 = new mock::MockFence();
Valerie Haud251afb2019-03-29 14:19:02 -070096
97 struct TransactionInfo {
98 Vector<ComposerState> states;
99 Vector<DisplayState> displays;
100 uint32_t flags = 0;
101 sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
102 InputWindowCommands inputWindowCommands;
Ady Abrahamf0c56492020-12-17 18:04:15 -0800103 int64_t desiredPresentTime = 0;
104 bool isAutoTimestamp = true;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000105 FrameTimelineInfo frameTimelineInfo;
Valerie Haud251afb2019-03-29 14:19:02 -0700106 client_cache_t uncacheBuffer;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000107 uint64_t id = static_cast<uint64_t>(-1);
108 static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1));
Valerie Haud251afb2019-03-29 14:19:02 -0700109 };
110
Vishnu Nair6b591152021-10-08 11:45:14 -0700111 void checkEqual(TransactionInfo info, TransactionState state) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000112 EXPECT_EQ(0u, info.states.size());
113 EXPECT_EQ(0u, state.states.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700114
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000115 EXPECT_EQ(0u, info.displays.size());
116 EXPECT_EQ(0u, state.displays.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700117 EXPECT_EQ(info.flags, state.flags);
118 EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime);
119 }
120
121 void setupSingle(TransactionInfo& transaction, uint32_t flags, bool syncInputWindows,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800122 int64_t desiredPresentTime, bool isAutoTimestamp,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000123 const FrameTimelineInfo& frameTimelineInfo) {
Valerie Haud251afb2019-03-29 14:19:02 -0700124 mTransactionNumber++;
125 transaction.flags |= flags; // ISurfaceComposer::eSynchronous;
126 transaction.inputWindowCommands.syncInputWindows = syncInputWindows;
127 transaction.desiredPresentTime = desiredPresentTime;
Ady Abrahamf0c56492020-12-17 18:04:15 -0800128 transaction.isAutoTimestamp = isAutoTimestamp;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000129 transaction.frameTimelineInfo = frameTimelineInfo;
Valerie Haud251afb2019-03-29 14:19:02 -0700130 }
131
ramindani4d48f902021-09-20 21:07:45 +0000132 void setupSingleWithComposer(TransactionInfo& transaction, uint32_t flags,
133 bool syncInputWindows, int64_t desiredPresentTime,
134 bool isAutoTimestamp, const FrameTimelineInfo& frameTimelineInfo,
135 const Vector<ComposerState>* states) {
136 setupSingle(transaction, flags, syncInputWindows, desiredPresentTime, isAutoTimestamp,
137 frameTimelineInfo);
138 transaction.states = *states;
139 }
140
Valerie Haud251afb2019-03-29 14:19:02 -0700141 void NotPlacedOnTransactionQueue(uint32_t flags, bool syncInputWindows) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000142 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700143 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700144 TransactionInfo transaction;
145 setupSingle(transaction, flags, syncInputWindows,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800146 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000147 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700148 nsecs_t applicationTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000149 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700150 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700151 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800152 transaction.desiredPresentTime, transaction.isAutoTimestamp,
153 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
154 transaction.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700155
Valerie Haud251afb2019-03-29 14:19:02 -0700156 // If transaction is synchronous or syncs input windows, SF
157 // applyTransactionState should time out (5s) wating for SF to commit
158 // the transaction or to receive a signal that syncInputWindows has
159 // completed. If this is animation, it should not time out waiting.
160 nsecs_t returnedTime = systemTime();
161 if (flags & ISurfaceComposer::eSynchronous || syncInputWindows) {
162 EXPECT_GE(returnedTime, applicationTime + s2ns(5));
163 } else {
164 EXPECT_LE(returnedTime, applicationTime + s2ns(5));
165 }
Arthur Hung58144272021-01-16 03:43:53 +0000166 // Each transaction should have been placed on the transaction queue
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000167 auto transactionQueue = mFlinger.getTransactionQueue();
Arthur Hung58144272021-01-16 03:43:53 +0000168 EXPECT_EQ(1u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700169 }
170
171 void PlaceOnTransactionQueue(uint32_t flags, bool syncInputWindows) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000172 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700173 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700174
175 // first check will see desired present time has not passed,
176 // but afterwards it will look like the desired present time has passed
177 nsecs_t time = systemTime();
Valerie Haud251afb2019-03-29 14:19:02 -0700178 TransactionInfo transaction;
179 setupSingle(transaction, flags, syncInputWindows,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000180 /*desiredPresentTime*/ time + s2ns(1), false, FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700181 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000182 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700183 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700184 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800185 transaction.desiredPresentTime, transaction.isAutoTimestamp,
186 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
187 transaction.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700188
189 nsecs_t returnedTime = systemTime();
Ady Abrahame46243a2021-02-23 19:33:49 -0800190 if ((flags & ISurfaceComposer::eSynchronous) || syncInputWindows) {
191 EXPECT_GE(systemTime(), applicationSentTime + s2ns(5));
192 } else {
193 EXPECT_LE(returnedTime, applicationSentTime + s2ns(5));
194 }
Valerie Haud251afb2019-03-29 14:19:02 -0700195 // This transaction should have been placed on the transaction queue
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000196 auto transactionQueue = mFlinger.getTransactionQueue();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000197 EXPECT_EQ(1u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700198 }
199
200 void BlockedByPriorTransaction(uint32_t flags, bool syncInputWindows) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000201 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Valerie Haud251afb2019-03-29 14:19:02 -0700202 nsecs_t time = systemTime();
Ady Abrahame46243a2021-02-23 19:33:49 -0800203 if (!syncInputWindows) {
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700204 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(2);
Ady Abrahame46243a2021-02-23 19:33:49 -0800205 } else {
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700206 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Ady Abrahame46243a2021-02-23 19:33:49 -0800207 }
Valerie Haud251afb2019-03-29 14:19:02 -0700208 // transaction that should go on the pending thread
209 TransactionInfo transactionA;
210 setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000211 /*desiredPresentTime*/ time + s2ns(1), false, FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700212
213 // transaction that would not have gone on the pending thread if not
214 // blocked
215 TransactionInfo transactionB;
216 setupSingle(transactionB, flags, syncInputWindows,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800217 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000218 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700219
220 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000221 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700222 transactionA.displays, transactionA.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700223 transactionA.applyToken, transactionA.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800224 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
225 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
226 transactionA.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700227
228 // This thread should not have been blocked by the above transaction
229 // (5s is the timeout period that applyTransactionState waits for SF to
230 // commit the transaction)
231 EXPECT_LE(systemTime(), applicationSentTime + s2ns(5));
Arthur Hung58144272021-01-16 03:43:53 +0000232 // transaction that would goes to pending transaciton queue.
233 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700234
235 applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000236 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700237 transactionB.displays, transactionB.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700238 transactionB.applyToken, transactionB.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800239 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
240 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
241 transactionB.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700242
243 // this thread should have been blocked by the above transaction
244 // if this is an animation, this thread should be blocked for 5s
245 // in setTransactionState waiting for transactionA to flush. Otherwise,
246 // the transaction should be placed on the pending queue
Ady Abrahame46243a2021-02-23 19:33:49 -0800247 if (flags & (ISurfaceComposer::eAnimation | ISurfaceComposer::eSynchronous) ||
248 syncInputWindows) {
Valerie Haud251afb2019-03-29 14:19:02 -0700249 EXPECT_GE(systemTime(), applicationSentTime + s2ns(5));
250 } else {
251 EXPECT_LE(systemTime(), applicationSentTime + s2ns(5));
252 }
253
Arthur Hung58144272021-01-16 03:43:53 +0000254 // transaction that would goes to pending transaciton queue.
255 mFlinger.flushTransactionQueues();
256
Ady Abrahame46243a2021-02-23 19:33:49 -0800257 // check that the transaction was applied.
Arthur Hung58144272021-01-16 03:43:53 +0000258 auto transactionQueue = mFlinger.getPendingTransactionQueue();
Ady Abrahame46243a2021-02-23 19:33:49 -0800259 EXPECT_EQ(0u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700260 }
261
ramindani4d48f902021-09-20 21:07:45 +0000262 void Flush_removesUnsignaledFromTheQueue(Vector<ComposerState> state1,
263 Vector<ComposerState> state2,
264 bool updateApplyToken = true) {
265 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
266
267 TransactionInfo transactionA;
268 setupSingleWithComposer(transactionA, ISurfaceComposer::eSynchronous,
269 /*syncInputWindows*/ false,
270 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
271 FrameTimelineInfo{}, &state1);
272
273 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
274 transactionA.displays, transactionA.flags,
275 transactionA.applyToken, transactionA.inputWindowCommands,
276 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
277 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
278 transactionA.id);
279
280 TransactionInfo transactionB;
281 if (updateApplyToken) {
282 transactionB.applyToken = sp<IBinder>();
283 }
284 setupSingleWithComposer(transactionB, ISurfaceComposer::eSynchronous,
285 /*syncInputWindows*/ false,
286 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
287 FrameTimelineInfo{}, &state2);
288 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
289 transactionB.displays, transactionB.flags,
290 transactionB.applyToken, transactionB.inputWindowCommands,
291 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
292 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
293 transactionB.id);
294
295 mFlinger.flushTransactionQueues();
296 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
297 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
298 EXPECT_EQ(2ul, mFlinger.getTransactionCommittedSignals().size());
299 }
300
301 void Flush_removesFromTheQueue(const Vector<ComposerState>& state) {
302 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
303 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
304
305 TransactionInfo transaction;
306 setupSingleWithComposer(transaction, ISurfaceComposer::eSynchronous,
307 /*syncInputWindows*/ false,
308 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
309 FrameTimelineInfo{}, &state);
310
311 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
312 transaction.displays, transaction.flags,
313 transaction.applyToken, transaction.inputWindowCommands,
314 transaction.desiredPresentTime, transaction.isAutoTimestamp,
315 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
316 transaction.id);
317
318 mFlinger.flushTransactionQueues();
319 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
320 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
321 EXPECT_EQ(1u, mFlinger.getTransactionCommittedSignals().size());
322 }
323
324 void Flush_keepsInTheQueue(const Vector<ComposerState>& state) {
325 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
326 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
327
328 TransactionInfo transaction;
329 setupSingleWithComposer(transaction, ISurfaceComposer::eSynchronous,
330 /*syncInputWindows*/ false,
331 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
332 FrameTimelineInfo{}, &state);
333
334 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
335 transaction.displays, transaction.flags,
336 transaction.applyToken, transaction.inputWindowCommands,
337 transaction.desiredPresentTime, transaction.isAutoTimestamp,
338 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
339 transaction.id);
340
341 mFlinger.flushTransactionQueues();
342 EXPECT_EQ(1u, mFlinger.getPendingTransactionQueue().size());
343 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
344 EXPECT_EQ(0ul, mFlinger.getTransactionCommittedSignals().size());
345 }
346
347 void Flush_KeepsUnsignaledInTheQueue(const Vector<ComposerState>& state1,
348 const Vector<ComposerState>& state2,
349 bool updateApplyToken = true,
350 uint32_t pendingTransactionQueueSize = 1u) {
351 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
352 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
353 auto time = systemTime();
354 TransactionInfo transactionA;
355 TransactionInfo transactionB;
356 setupSingleWithComposer(transactionA, ISurfaceComposer::eSynchronous,
357 /*syncInputWindows*/ false,
358 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
359 FrameTimelineInfo{}, &state1);
360 setupSingleWithComposer(transactionB, ISurfaceComposer::eSynchronous,
361 /*syncInputWindows*/ false,
362 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
363 FrameTimelineInfo{}, &state2);
364 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
365 transactionA.displays, transactionA.flags,
366 transactionA.applyToken, transactionA.inputWindowCommands,
367 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
368 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
369 transactionA.id);
370 if (updateApplyToken) {
371 transactionB.applyToken = sp<IBinder>();
372 }
373 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
374 transactionB.displays, transactionB.flags,
375 transactionB.applyToken, transactionB.inputWindowCommands,
376 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
377 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
378 transactionB.id);
379
380 mFlinger.flushTransactionQueues();
381 EXPECT_EQ(pendingTransactionQueueSize, mFlinger.getPendingTransactionQueue().size());
382 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
383 }
384
385 void Flush_removesSignaledFromTheQueue(const Vector<ComposerState>& state1,
386 const Vector<ComposerState>& state2) {
387 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
388 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
389
390 auto time = systemTime();
391 TransactionInfo transactionA;
392 TransactionInfo transactionB;
393 setupSingleWithComposer(transactionA, ISurfaceComposer::eSynchronous,
394 /*syncInputWindows*/ false,
395 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
396 FrameTimelineInfo{}, &state1);
397 setupSingleWithComposer(transactionB, ISurfaceComposer::eSynchronous,
398 /*syncInputWindows*/ false,
399 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
400 FrameTimelineInfo{}, &state2);
401 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
402 transactionA.displays, transactionA.flags,
403 transactionA.applyToken, transactionA.inputWindowCommands,
404 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
405 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
406 transactionA.id);
407 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
408 transactionB.displays, transactionB.flags,
409 transactionB.applyToken, transactionB.inputWindowCommands,
410 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
411 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
412 transactionB.id);
413
414 mFlinger.flushTransactionQueues();
415 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
416 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
417 EXPECT_EQ(2ul, mFlinger.getTransactionCommittedSignals().size());
418 }
419
420 static Vector<ComposerState> createComposerStateVector(const ComposerState& state1,
421 const ComposerState& state2) {
422 Vector<ComposerState> states;
423 states.push_back(state1);
424 states.push_back(state2);
425 return states;
426 }
427
428 static Vector<ComposerState> createComposerStateVector(const ComposerState& state) {
429 Vector<ComposerState> states;
430 states.push_back(state);
431 return states;
432 }
433
434 static ComposerState createComposerState(int layerId, sp<Fence> fence,
435 uint32_t stateFlags = layer_state_t::eBufferChanged) {
436 ComposerState composer_state;
Vishnu Nair9f0835e2022-01-07 09:33:19 -0800437 composer_state.state.bufferData = std::make_shared<BufferData>();
438 composer_state.state.bufferData->acquireFence = std::move(fence);
ramindani4d48f902021-09-20 21:07:45 +0000439 composer_state.state.layerId = layerId;
Vishnu Nair9f0835e2022-01-07 09:33:19 -0800440 composer_state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
ramindani4d48f902021-09-20 21:07:45 +0000441 composer_state.state.flags = stateFlags;
442 return composer_state;
443 }
444
Valerie Haud251afb2019-03-29 14:19:02 -0700445 bool mHasListenerCallbacks = false;
446 std::vector<ListenerCallbacks> mCallbacks;
447 int mTransactionNumber = 0;
448};
449
450TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000451 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700452 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700453
Valerie Haud251afb2019-03-29 14:19:02 -0700454 TransactionInfo transactionA; // transaction to go on pending queue
455 setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000456 /*desiredPresentTime*/ s2ns(1), false, FrameTimelineInfo{});
457 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700458 transactionA.displays, transactionA.flags, transactionA.applyToken,
459 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800460 transactionA.isAutoTimestamp, transactionA.uncacheBuffer,
461 mHasListenerCallbacks, mCallbacks, transactionA.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700462
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000463 auto& transactionQueue = mFlinger.getTransactionQueue();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000464 ASSERT_EQ(1u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700465
Arthur Hung58144272021-01-16 03:43:53 +0000466 auto& transactionState = transactionQueue.front();
Valerie Haud251afb2019-03-29 14:19:02 -0700467 checkEqual(transactionA, transactionState);
468
469 // because flushing uses the cached expected present time, we send an empty
470 // transaction here (sending a null applyToken to fake it as from a
471 // different process) to re-query and reset the cached expected present time
472 TransactionInfo empty;
473 empty.applyToken = sp<IBinder>();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000474 mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
475 empty.applyToken, empty.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800476 empty.desiredPresentTime, empty.isAutoTimestamp,
477 empty.uncacheBuffer, mHasListenerCallbacks, mCallbacks, empty.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700478
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000479 // flush transaction queue should flush as desiredPresentTime has
Valerie Haud251afb2019-03-29 14:19:02 -0700480 // passed
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000481 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700482
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000483 EXPECT_EQ(0u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700484}
485
486TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_Synchronous) {
487 NotPlacedOnTransactionQueue(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
488}
489
490TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_Animation) {
491 NotPlacedOnTransactionQueue(ISurfaceComposer::eAnimation, /*syncInputWindows*/ false);
492}
493
494TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_SyncInputWindows) {
495 NotPlacedOnTransactionQueue(/*flags*/ 0, /*syncInputWindows*/ true);
496}
497
498TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_Synchronous) {
499 PlaceOnTransactionQueue(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
500}
501
502TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_Animation) {
503 PlaceOnTransactionQueue(ISurfaceComposer::eAnimation, /*syncInputWindows*/ false);
504}
505
506TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_SyncInputWindows) {
507 PlaceOnTransactionQueue(/*flags*/ 0, /*syncInputWindows*/ true);
508}
509
510TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_Synchronous) {
511 BlockedByPriorTransaction(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
512}
513
514TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_Animation) {
515 BlockedByPriorTransaction(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
516}
517
518TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_SyncInputWindows) {
519 BlockedByPriorTransaction(/*flags*/ 0, /*syncInputWindows*/ true);
520}
521
Valerie Hau09e60052019-12-15 14:51:15 -0800522TEST_F(TransactionApplicationTest, FromHandle) {
523 sp<IBinder> badHandle;
524 auto ret = mFlinger.fromHandle(badHandle);
Alec Mouri9a02eda2020-04-21 17:39:34 -0700525 EXPECT_EQ(nullptr, ret.promote().get());
Valerie Hau09e60052019-12-15 14:51:15 -0800526}
ramindani4d48f902021-09-20 21:07:45 +0000527
528TEST_F(TransactionApplicationTest, Flush_RemovesSingleSignaledFromTheQueue_LatchUnsignaled_Auto) {
529 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
530 Flush_removesFromTheQueue(
531 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
532}
533
534TEST_F(TransactionApplicationTest, Flush_RemovesSingleUnSignaledFromTheQueue_LatchUnsignaled_Auto) {
535 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
536 Flush_removesFromTheQueue(
537 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
538}
539
540TEST_F(TransactionApplicationTest,
541 Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange_LatchUnsignaled_Auto) {
542 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
543 Flush_keepsInTheQueue(createComposerStateVector(
544 createComposerState(/*layerId*/ 1, mFenceUnsignaled, layer_state_t::eCropChanged)));
545}
546
547TEST_F(TransactionApplicationTest,
548 Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed_LatchUnsignaled_Auto) {
549 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
550 Flush_keepsInTheQueue(createComposerStateVector(
551 createComposerState(/*layerId*/ 1, mFenceUnsignaled,
552 layer_state_t::eCropChanged | layer_state_t::eBufferChanged)));
553}
554
555TEST_F(TransactionApplicationTest,
556 Flush_KeepsInTheQueueSameApplyTokenMultiState_LatchUnsignaled_Auto) {
557 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
558 Flush_keepsInTheQueue(
559 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
560 createComposerState(/*layerId*/ 1, mFenceSignaled)));
561}
562
563TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueue_MultipleStateTransaction_Auto) {
564 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
565 Flush_keepsInTheQueue(
566 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
567 createComposerState(/*layerId*/ 2, mFenceSignaled)));
568}
569
570TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Auto) {
571 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
572 Flush_removesSignaledFromTheQueue(createComposerStateVector(
573 createComposerState(/*layerId*/ 1, mFenceSignaled)),
574 createComposerStateVector(
575 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
576}
577
578TEST_F(TransactionApplicationTest, Flush_RemoveSignaledWithUnsignaledIntact_LatchUnsignaled_Auto) {
579 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
580 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
581 createComposerState(/*layerId*/ 1, mFenceSignaled)),
582 createComposerStateVector(
583 createComposerState(/*layerId*/ 2, mFenceUnsignaled)));
584 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
585}
586
587TEST_F(TransactionApplicationTest,
588 Flush_KeepsTransactionInTheQueueSameApplyToken_LatchUnsignaled_Auto) {
589 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
590 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
591 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
592 createComposerStateVector(
593 createComposerState(/*layerId*/ 2, mFenceSignaled)),
594 /*updateApplyToken*/ false);
595 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
596}
597
598TEST_F(TransactionApplicationTest, Flush_KeepsTransactionInTheQueue_LatchUnsignaled_Auto) {
599 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
600 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
601 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
602 createComposerStateVector(
603 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
604 /*updateApplyToken*/ true,
605 /*pendingTransactionQueueSize*/ 2u);
606 EXPECT_EQ(0ul, mFlinger.getTransactionCommittedSignals().size());
607}
608
609TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Disabled) {
610 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
611 Flush_removesFromTheQueue(
612 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
613}
614
615TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueue_LatchUnsignaled_Disabled) {
616 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
617 Flush_keepsInTheQueue(
618 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
619}
620
621TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueueSameLayerId_LatchUnsignaled_Disabled) {
622 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
623 Flush_keepsInTheQueue(
624 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
625 createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
626}
627
628TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueueDifferentLayerId_LatchUnsignaled_Disabled) {
629 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
630 Flush_keepsInTheQueue(
631 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
632 createComposerState(/*layerId*/ 2, mFenceUnsignaled)));
633}
634
635TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnSignaled_Disabled) {
636 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
637 Flush_removesSignaledFromTheQueue(createComposerStateVector(
638 createComposerState(/*layerId*/ 1, mFenceSignaled)),
639 createComposerStateVector(
640 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
641}
642
643TEST_F(TransactionApplicationTest,
644 Flush_KeepInTheQueueDifferentApplyToken_LatchUnsignaled_Disabled) {
645 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
646 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
647 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
648 createComposerStateVector(
649 createComposerState(/*layerId*/ 2, mFenceSignaled)));
650 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
651}
652
653TEST_F(TransactionApplicationTest, Flush_KeepInTheQueueSameApplyToken_LatchUnsignaled_Disabled) {
654 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
655 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
656 createComposerState(/*layerId*/ 1, mFenceSignaled)),
657 createComposerStateVector(
658 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
659 /*updateApplyToken*/ false);
660 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
661}
662
663TEST_F(TransactionApplicationTest, Flush_KeepInTheUnsignaledTheQueue_LatchUnsignaled_Disabled) {
664 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
665 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
666 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
667 createComposerStateVector(
668 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
669 /*updateApplyToken*/ false);
670 EXPECT_EQ(0ul, mFlinger.getTransactionCommittedSignals().size());
671}
672
673TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Always) {
674 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
675 Flush_removesFromTheQueue(
676 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
677}
678
679TEST_F(TransactionApplicationTest, Flush_RemovesFromTheQueue_LatchUnsignaled_Always) {
680 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
681 Flush_removesFromTheQueue(
682 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
683}
684
685TEST_F(TransactionApplicationTest, Flush_RemovesFromTheQueueSameLayerId_LatchUnsignaled_Always) {
686 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
687 Flush_removesFromTheQueue(
688 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
689 createComposerState(/*layerId*/ 1, mFenceSignaled)));
690}
691
692TEST_F(TransactionApplicationTest,
693 Flush_RemovesFromTheQueueDifferentLayerId_LatchUnsignaled_Always) {
694 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
695 Flush_removesFromTheQueue(
696 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
697 createComposerState(/*layerId*/ 2, mFenceSignaled)));
698}
699
700TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnSignaled_Always) {
701 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
702 Flush_removesSignaledFromTheQueue(createComposerStateVector(
703 createComposerState(/*layerId*/ 1, mFenceSignaled)),
704 createComposerStateVector(
705 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
706}
707
708TEST_F(TransactionApplicationTest,
709 Flush_RemovesFromTheQueueDifferentApplyToken_LatchUnsignaled_Always) {
710 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
711 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
712 createComposerState(/*layerId*/ 1, mFenceSignaled)),
713 createComposerStateVector(
714 createComposerState(/*layerId*/ 2,
715 mFenceUnsignaled)));
716}
717
718TEST_F(TransactionApplicationTest,
719 Flush_RemovesUnsignaledFromTheQueueSameApplyToken_LatchUnsignaled_Always) {
720 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
721 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
722 createComposerState(/*layerId*/ 1,
723 mFenceUnsignaled)),
724 createComposerStateVector(
725 createComposerState(/*layerId*/ 2, mFenceSignaled)),
726 /*updateApplyToken*/ false);
727}
728
729TEST_F(TransactionApplicationTest, Flush_RemovesUnsignaledFromTheQueue_LatchUnsignaled_Always) {
730 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
731 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
732 createComposerState(/*layerId*/ 1,
733 mFenceUnsignaled)),
734 createComposerStateVector(
735 createComposerState(/*layerId*/ 2,
736 mFenceUnsignaled)));
737}
738
Valerie Haud251afb2019-03-29 14:19:02 -0700739} // namespace android