blob: 16d4b59250b9adcd33f48119d73f6987aaf696b9 [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;
437 composer_state.state.bufferData.acquireFence = std::move(fence);
438 composer_state.state.layerId = layerId;
439 composer_state.state.bufferData.flags = BufferData::BufferDataChange::fenceChanged;
440 composer_state.state.flags = stateFlags;
441 return composer_state;
442 }
443
Valerie Haud251afb2019-03-29 14:19:02 -0700444 bool mHasListenerCallbacks = false;
445 std::vector<ListenerCallbacks> mCallbacks;
446 int mTransactionNumber = 0;
447};
448
449TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000450 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Dominik Laskowski46f3e3b2021-08-10 11:44:24 -0700451 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700452
Valerie Haud251afb2019-03-29 14:19:02 -0700453 TransactionInfo transactionA; // transaction to go on pending queue
454 setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000455 /*desiredPresentTime*/ s2ns(1), false, FrameTimelineInfo{});
456 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700457 transactionA.displays, transactionA.flags, transactionA.applyToken,
458 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800459 transactionA.isAutoTimestamp, transactionA.uncacheBuffer,
460 mHasListenerCallbacks, mCallbacks, transactionA.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700461
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000462 auto& transactionQueue = mFlinger.getTransactionQueue();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000463 ASSERT_EQ(1u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700464
Arthur Hung58144272021-01-16 03:43:53 +0000465 auto& transactionState = transactionQueue.front();
Valerie Haud251afb2019-03-29 14:19:02 -0700466 checkEqual(transactionA, transactionState);
467
468 // because flushing uses the cached expected present time, we send an empty
469 // transaction here (sending a null applyToken to fake it as from a
470 // different process) to re-query and reset the cached expected present time
471 TransactionInfo empty;
472 empty.applyToken = sp<IBinder>();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000473 mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
474 empty.applyToken, empty.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800475 empty.desiredPresentTime, empty.isAutoTimestamp,
476 empty.uncacheBuffer, mHasListenerCallbacks, mCallbacks, empty.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700477
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000478 // flush transaction queue should flush as desiredPresentTime has
Valerie Haud251afb2019-03-29 14:19:02 -0700479 // passed
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000480 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700481
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000482 EXPECT_EQ(0u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700483}
484
485TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_Synchronous) {
486 NotPlacedOnTransactionQueue(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
487}
488
489TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_Animation) {
490 NotPlacedOnTransactionQueue(ISurfaceComposer::eAnimation, /*syncInputWindows*/ false);
491}
492
493TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_SyncInputWindows) {
494 NotPlacedOnTransactionQueue(/*flags*/ 0, /*syncInputWindows*/ true);
495}
496
497TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_Synchronous) {
498 PlaceOnTransactionQueue(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
499}
500
501TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_Animation) {
502 PlaceOnTransactionQueue(ISurfaceComposer::eAnimation, /*syncInputWindows*/ false);
503}
504
505TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_SyncInputWindows) {
506 PlaceOnTransactionQueue(/*flags*/ 0, /*syncInputWindows*/ true);
507}
508
509TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_Synchronous) {
510 BlockedByPriorTransaction(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
511}
512
513TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_Animation) {
514 BlockedByPriorTransaction(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
515}
516
517TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_SyncInputWindows) {
518 BlockedByPriorTransaction(/*flags*/ 0, /*syncInputWindows*/ true);
519}
520
Valerie Hau09e60052019-12-15 14:51:15 -0800521TEST_F(TransactionApplicationTest, FromHandle) {
522 sp<IBinder> badHandle;
523 auto ret = mFlinger.fromHandle(badHandle);
Alec Mouri9a02eda2020-04-21 17:39:34 -0700524 EXPECT_EQ(nullptr, ret.promote().get());
Valerie Hau09e60052019-12-15 14:51:15 -0800525}
ramindani4d48f902021-09-20 21:07:45 +0000526
527TEST_F(TransactionApplicationTest, Flush_RemovesSingleSignaledFromTheQueue_LatchUnsignaled_Auto) {
528 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
529 Flush_removesFromTheQueue(
530 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
531}
532
533TEST_F(TransactionApplicationTest, Flush_RemovesSingleUnSignaledFromTheQueue_LatchUnsignaled_Auto) {
534 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
535 Flush_removesFromTheQueue(
536 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
537}
538
539TEST_F(TransactionApplicationTest,
540 Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange_LatchUnsignaled_Auto) {
541 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
542 Flush_keepsInTheQueue(createComposerStateVector(
543 createComposerState(/*layerId*/ 1, mFenceUnsignaled, layer_state_t::eCropChanged)));
544}
545
546TEST_F(TransactionApplicationTest,
547 Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed_LatchUnsignaled_Auto) {
548 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
549 Flush_keepsInTheQueue(createComposerStateVector(
550 createComposerState(/*layerId*/ 1, mFenceUnsignaled,
551 layer_state_t::eCropChanged | layer_state_t::eBufferChanged)));
552}
553
554TEST_F(TransactionApplicationTest,
555 Flush_KeepsInTheQueueSameApplyTokenMultiState_LatchUnsignaled_Auto) {
556 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
557 Flush_keepsInTheQueue(
558 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
559 createComposerState(/*layerId*/ 1, mFenceSignaled)));
560}
561
562TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueue_MultipleStateTransaction_Auto) {
563 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
564 Flush_keepsInTheQueue(
565 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
566 createComposerState(/*layerId*/ 2, mFenceSignaled)));
567}
568
569TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Auto) {
570 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
571 Flush_removesSignaledFromTheQueue(createComposerStateVector(
572 createComposerState(/*layerId*/ 1, mFenceSignaled)),
573 createComposerStateVector(
574 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
575}
576
577TEST_F(TransactionApplicationTest, Flush_RemoveSignaledWithUnsignaledIntact_LatchUnsignaled_Auto) {
578 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
579 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
580 createComposerState(/*layerId*/ 1, mFenceSignaled)),
581 createComposerStateVector(
582 createComposerState(/*layerId*/ 2, mFenceUnsignaled)));
583 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
584}
585
586TEST_F(TransactionApplicationTest,
587 Flush_KeepsTransactionInTheQueueSameApplyToken_LatchUnsignaled_Auto) {
588 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
589 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
590 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
591 createComposerStateVector(
592 createComposerState(/*layerId*/ 2, mFenceSignaled)),
593 /*updateApplyToken*/ false);
594 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
595}
596
597TEST_F(TransactionApplicationTest, Flush_KeepsTransactionInTheQueue_LatchUnsignaled_Auto) {
598 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
599 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
600 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
601 createComposerStateVector(
602 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
603 /*updateApplyToken*/ true,
604 /*pendingTransactionQueueSize*/ 2u);
605 EXPECT_EQ(0ul, mFlinger.getTransactionCommittedSignals().size());
606}
607
608TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Disabled) {
609 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
610 Flush_removesFromTheQueue(
611 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
612}
613
614TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueue_LatchUnsignaled_Disabled) {
615 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
616 Flush_keepsInTheQueue(
617 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
618}
619
620TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueueSameLayerId_LatchUnsignaled_Disabled) {
621 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
622 Flush_keepsInTheQueue(
623 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
624 createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
625}
626
627TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueueDifferentLayerId_LatchUnsignaled_Disabled) {
628 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
629 Flush_keepsInTheQueue(
630 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
631 createComposerState(/*layerId*/ 2, mFenceUnsignaled)));
632}
633
634TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnSignaled_Disabled) {
635 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
636 Flush_removesSignaledFromTheQueue(createComposerStateVector(
637 createComposerState(/*layerId*/ 1, mFenceSignaled)),
638 createComposerStateVector(
639 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
640}
641
642TEST_F(TransactionApplicationTest,
643 Flush_KeepInTheQueueDifferentApplyToken_LatchUnsignaled_Disabled) {
644 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
645 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
646 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
647 createComposerStateVector(
648 createComposerState(/*layerId*/ 2, mFenceSignaled)));
649 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
650}
651
652TEST_F(TransactionApplicationTest, Flush_KeepInTheQueueSameApplyToken_LatchUnsignaled_Disabled) {
653 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
654 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
655 createComposerState(/*layerId*/ 1, mFenceSignaled)),
656 createComposerStateVector(
657 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
658 /*updateApplyToken*/ false);
659 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
660}
661
662TEST_F(TransactionApplicationTest, Flush_KeepInTheUnsignaledTheQueue_LatchUnsignaled_Disabled) {
663 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
664 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
665 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
666 createComposerStateVector(
667 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
668 /*updateApplyToken*/ false);
669 EXPECT_EQ(0ul, mFlinger.getTransactionCommittedSignals().size());
670}
671
672TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Always) {
673 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
674 Flush_removesFromTheQueue(
675 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
676}
677
678TEST_F(TransactionApplicationTest, Flush_RemovesFromTheQueue_LatchUnsignaled_Always) {
679 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
680 Flush_removesFromTheQueue(
681 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
682}
683
684TEST_F(TransactionApplicationTest, Flush_RemovesFromTheQueueSameLayerId_LatchUnsignaled_Always) {
685 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
686 Flush_removesFromTheQueue(
687 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
688 createComposerState(/*layerId*/ 1, mFenceSignaled)));
689}
690
691TEST_F(TransactionApplicationTest,
692 Flush_RemovesFromTheQueueDifferentLayerId_LatchUnsignaled_Always) {
693 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
694 Flush_removesFromTheQueue(
695 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
696 createComposerState(/*layerId*/ 2, mFenceSignaled)));
697}
698
699TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnSignaled_Always) {
700 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
701 Flush_removesSignaledFromTheQueue(createComposerStateVector(
702 createComposerState(/*layerId*/ 1, mFenceSignaled)),
703 createComposerStateVector(
704 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
705}
706
707TEST_F(TransactionApplicationTest,
708 Flush_RemovesFromTheQueueDifferentApplyToken_LatchUnsignaled_Always) {
709 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
710 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
711 createComposerState(/*layerId*/ 1, mFenceSignaled)),
712 createComposerStateVector(
713 createComposerState(/*layerId*/ 2,
714 mFenceUnsignaled)));
715}
716
717TEST_F(TransactionApplicationTest,
718 Flush_RemovesUnsignaledFromTheQueueSameApplyToken_LatchUnsignaled_Always) {
719 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
720 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
721 createComposerState(/*layerId*/ 1,
722 mFenceUnsignaled)),
723 createComposerStateVector(
724 createComposerState(/*layerId*/ 2, mFenceSignaled)),
725 /*updateApplyToken*/ false);
726}
727
728TEST_F(TransactionApplicationTest, Flush_RemovesUnsignaledFromTheQueue_LatchUnsignaled_Always) {
729 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
730 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
731 createComposerState(/*layerId*/ 1,
732 mFenceUnsignaled)),
733 createComposerStateVector(
734 createComposerState(/*layerId*/ 2,
735 mFenceUnsignaled)));
736}
737
Valerie Haud251afb2019-03-29 14:19:02 -0700738} // namespace android