blob: 8caadfbf8522345bf7634ffdb82d98921bfceebc [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>
Valerie Haud251afb2019-03-29 14:19:02 -070029#include "TestableScheduler.h"
30#include "TestableSurfaceFlinger.h"
Valerie Haud251afb2019-03-29 14:19:02 -070031#include "mock/MockEventThread.h"
32#include "mock/MockMessageQueue.h"
Ady Abraham8cb21882020-08-26 18:22:05 -070033#include "mock/MockVsyncController.h"
Valerie Haud251afb2019-03-29 14:19:02 -070034
35namespace android {
36
37using testing::_;
38using testing::Return;
39
40using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
41
42class TransactionApplicationTest : public testing::Test {
43public:
44 TransactionApplicationTest() {
45 const ::testing::TestInfo* const test_info =
46 ::testing::UnitTest::GetInstance()->current_test_info();
47 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
48
49 mFlinger.mutableEventQueue().reset(mMessageQueue);
50 setupScheduler();
51 }
52
53 ~TransactionApplicationTest() {
54 const ::testing::TestInfo* const test_info =
55 ::testing::UnitTest::GetInstance()->current_test_info();
56 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
57 }
58
59 void setupScheduler() {
60 auto eventThread = std::make_unique<mock::EventThread>();
61 auto sfEventThread = std::make_unique<mock::EventThread>();
62
63 EXPECT_CALL(*eventThread, registerDisplayEventConnection(_));
64 EXPECT_CALL(*eventThread, createEventConnection(_, _))
Ady Abraham62f216c2020-10-13 19:07:23 -070065 .WillOnce(Return(new EventThreadConnection(eventThread.get(), /*callingUid=*/0,
66 ResyncCallback())));
Valerie Haud251afb2019-03-29 14:19:02 -070067
68 EXPECT_CALL(*sfEventThread, registerDisplayEventConnection(_));
69 EXPECT_CALL(*sfEventThread, createEventConnection(_, _))
Ady Abraham62f216c2020-10-13 19:07:23 -070070 .WillOnce(Return(new EventThreadConnection(sfEventThread.get(), /*callingUid=*/0,
71 ResyncCallback())));
Valerie Haud251afb2019-03-29 14:19:02 -070072
Ady Abraham8cb21882020-08-26 18:22:05 -070073 EXPECT_CALL(*mVSyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0));
74 EXPECT_CALL(*mVSyncTracker, currentPeriod())
Marin Shalamanov045b7002021-01-07 16:56:24 +010075 .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD));
Valerie Haud251afb2019-03-29 14:19:02 -070076
ramindani4d48f902021-09-20 21:07:45 +000077 EXPECT_CALL(*mFenceUnsignaled, getStatus())
78 .WillRepeatedly(Return(Fence::Status::Unsignaled));
79 EXPECT_CALL(*mFenceUnsignaled2, getStatus())
80 .WillRepeatedly(Return(Fence::Status::Unsignaled));
81 EXPECT_CALL(*mFenceSignaled, getStatus()).WillRepeatedly(Return(Fence::Status::Signaled));
82 EXPECT_CALL(*mFenceSignaled2, getStatus()).WillRepeatedly(Return(Fence::Status::Signaled));
83
Ady Abraham3efa3942021-06-24 19:01:25 -070084 mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
Ady Abraham8cb21882020-08-26 18:22:05 -070085 mFlinger.setupScheduler(std::unique_ptr<mock::VsyncController>(mVsyncController),
86 std::unique_ptr<mock::VSyncTracker>(mVSyncTracker),
Valerie Haud251afb2019-03-29 14:19:02 -070087 std::move(eventThread), std::move(sfEventThread));
88 }
89
90 TestableScheduler* mScheduler;
91 TestableSurfaceFlinger mFlinger;
92
93 std::unique_ptr<mock::EventThread> mEventThread = std::make_unique<mock::EventThread>();
Valerie Haud251afb2019-03-29 14:19:02 -070094
95 mock::MessageQueue* mMessageQueue = new mock::MessageQueue();
Ady Abraham8cb21882020-08-26 18:22:05 -070096 mock::VsyncController* mVsyncController = new mock::VsyncController();
97 mock::VSyncTracker* mVSyncTracker = new mock::VSyncTracker();
ramindani4d48f902021-09-20 21:07:45 +000098 mock::MockFence* mFenceUnsignaled = new mock::MockFence();
99 mock::MockFence* mFenceSignaled = new mock::MockFence();
100 mock::MockFence* mFenceUnsignaled2 = new mock::MockFence();
101 mock::MockFence* mFenceSignaled2 = new mock::MockFence();
Valerie Haud251afb2019-03-29 14:19:02 -0700102
103 struct TransactionInfo {
104 Vector<ComposerState> states;
105 Vector<DisplayState> displays;
106 uint32_t flags = 0;
107 sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
108 InputWindowCommands inputWindowCommands;
Ady Abrahamf0c56492020-12-17 18:04:15 -0800109 int64_t desiredPresentTime = 0;
110 bool isAutoTimestamp = true;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000111 FrameTimelineInfo frameTimelineInfo;
Valerie Haud251afb2019-03-29 14:19:02 -0700112 client_cache_t uncacheBuffer;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000113 uint64_t id = static_cast<uint64_t>(-1);
114 static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1));
Valerie Haud251afb2019-03-29 14:19:02 -0700115 };
116
Vishnu Nair6b591152021-10-08 11:45:14 -0700117 void checkEqual(TransactionInfo info, TransactionState state) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000118 EXPECT_EQ(0u, info.states.size());
119 EXPECT_EQ(0u, state.states.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700120
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000121 EXPECT_EQ(0u, info.displays.size());
122 EXPECT_EQ(0u, state.displays.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700123 EXPECT_EQ(info.flags, state.flags);
124 EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime);
125 }
126
127 void setupSingle(TransactionInfo& transaction, uint32_t flags, bool syncInputWindows,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800128 int64_t desiredPresentTime, bool isAutoTimestamp,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000129 const FrameTimelineInfo& frameTimelineInfo) {
Valerie Haud251afb2019-03-29 14:19:02 -0700130 mTransactionNumber++;
131 transaction.flags |= flags; // ISurfaceComposer::eSynchronous;
132 transaction.inputWindowCommands.syncInputWindows = syncInputWindows;
133 transaction.desiredPresentTime = desiredPresentTime;
Ady Abrahamf0c56492020-12-17 18:04:15 -0800134 transaction.isAutoTimestamp = isAutoTimestamp;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000135 transaction.frameTimelineInfo = frameTimelineInfo;
Valerie Haud251afb2019-03-29 14:19:02 -0700136 }
137
ramindani4d48f902021-09-20 21:07:45 +0000138 void setupSingleWithComposer(TransactionInfo& transaction, uint32_t flags,
139 bool syncInputWindows, int64_t desiredPresentTime,
140 bool isAutoTimestamp, const FrameTimelineInfo& frameTimelineInfo,
141 const Vector<ComposerState>* states) {
142 setupSingle(transaction, flags, syncInputWindows, desiredPresentTime, isAutoTimestamp,
143 frameTimelineInfo);
144 transaction.states = *states;
145 }
146
Valerie Haud251afb2019-03-29 14:19:02 -0700147 void NotPlacedOnTransactionQueue(uint32_t flags, bool syncInputWindows) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000148 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -0700149 EXPECT_CALL(*mMessageQueue, scheduleCommit()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700150 TransactionInfo transaction;
151 setupSingle(transaction, flags, syncInputWindows,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800152 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000153 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700154 nsecs_t applicationTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000155 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700156 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700157 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800158 transaction.desiredPresentTime, transaction.isAutoTimestamp,
159 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
160 transaction.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700161
Valerie Haud251afb2019-03-29 14:19:02 -0700162 // If transaction is synchronous or syncs input windows, SF
163 // applyTransactionState should time out (5s) wating for SF to commit
164 // the transaction or to receive a signal that syncInputWindows has
165 // completed. If this is animation, it should not time out waiting.
166 nsecs_t returnedTime = systemTime();
167 if (flags & ISurfaceComposer::eSynchronous || syncInputWindows) {
168 EXPECT_GE(returnedTime, applicationTime + s2ns(5));
169 } else {
170 EXPECT_LE(returnedTime, applicationTime + s2ns(5));
171 }
Arthur Hung58144272021-01-16 03:43:53 +0000172 // Each transaction should have been placed on the transaction queue
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000173 auto transactionQueue = mFlinger.getTransactionQueue();
Arthur Hung58144272021-01-16 03:43:53 +0000174 EXPECT_EQ(1u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700175 }
176
177 void PlaceOnTransactionQueue(uint32_t flags, bool syncInputWindows) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000178 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -0700179 EXPECT_CALL(*mMessageQueue, scheduleCommit()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700180
181 // first check will see desired present time has not passed,
182 // but afterwards it will look like the desired present time has passed
183 nsecs_t time = systemTime();
Valerie Haud251afb2019-03-29 14:19:02 -0700184 TransactionInfo transaction;
185 setupSingle(transaction, flags, syncInputWindows,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000186 /*desiredPresentTime*/ time + s2ns(1), false, FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700187 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000188 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700189 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700190 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800191 transaction.desiredPresentTime, transaction.isAutoTimestamp,
192 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
193 transaction.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700194
195 nsecs_t returnedTime = systemTime();
Ady Abrahame46243a2021-02-23 19:33:49 -0800196 if ((flags & ISurfaceComposer::eSynchronous) || syncInputWindows) {
197 EXPECT_GE(systemTime(), applicationSentTime + s2ns(5));
198 } else {
199 EXPECT_LE(returnedTime, applicationSentTime + s2ns(5));
200 }
Valerie Haud251afb2019-03-29 14:19:02 -0700201 // This transaction should have been placed on the transaction queue
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000202 auto transactionQueue = mFlinger.getTransactionQueue();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000203 EXPECT_EQ(1u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700204 }
205
206 void BlockedByPriorTransaction(uint32_t flags, bool syncInputWindows) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000207 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Valerie Haud251afb2019-03-29 14:19:02 -0700208 nsecs_t time = systemTime();
Ady Abrahame46243a2021-02-23 19:33:49 -0800209 if (!syncInputWindows) {
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -0700210 EXPECT_CALL(*mMessageQueue, scheduleCommit()).Times(2);
Ady Abrahame46243a2021-02-23 19:33:49 -0800211 } else {
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -0700212 EXPECT_CALL(*mMessageQueue, scheduleCommit()).Times(1);
Ady Abrahame46243a2021-02-23 19:33:49 -0800213 }
Valerie Haud251afb2019-03-29 14:19:02 -0700214 // transaction that should go on the pending thread
215 TransactionInfo transactionA;
216 setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000217 /*desiredPresentTime*/ time + s2ns(1), false, FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700218
219 // transaction that would not have gone on the pending thread if not
220 // blocked
221 TransactionInfo transactionB;
222 setupSingle(transactionB, flags, syncInputWindows,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800223 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000224 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700225
226 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000227 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700228 transactionA.displays, transactionA.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700229 transactionA.applyToken, transactionA.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800230 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
231 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
232 transactionA.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700233
234 // This thread should not have been blocked by the above transaction
235 // (5s is the timeout period that applyTransactionState waits for SF to
236 // commit the transaction)
237 EXPECT_LE(systemTime(), applicationSentTime + s2ns(5));
Arthur Hung58144272021-01-16 03:43:53 +0000238 // transaction that would goes to pending transaciton queue.
239 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700240
241 applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000242 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700243 transactionB.displays, transactionB.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700244 transactionB.applyToken, transactionB.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800245 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
246 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
247 transactionB.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700248
249 // this thread should have been blocked by the above transaction
250 // if this is an animation, this thread should be blocked for 5s
251 // in setTransactionState waiting for transactionA to flush. Otherwise,
252 // the transaction should be placed on the pending queue
Ady Abrahame46243a2021-02-23 19:33:49 -0800253 if (flags & (ISurfaceComposer::eAnimation | ISurfaceComposer::eSynchronous) ||
254 syncInputWindows) {
Valerie Haud251afb2019-03-29 14:19:02 -0700255 EXPECT_GE(systemTime(), applicationSentTime + s2ns(5));
256 } else {
257 EXPECT_LE(systemTime(), applicationSentTime + s2ns(5));
258 }
259
Arthur Hung58144272021-01-16 03:43:53 +0000260 // transaction that would goes to pending transaciton queue.
261 mFlinger.flushTransactionQueues();
262
Ady Abrahame46243a2021-02-23 19:33:49 -0800263 // check that the transaction was applied.
Arthur Hung58144272021-01-16 03:43:53 +0000264 auto transactionQueue = mFlinger.getPendingTransactionQueue();
Ady Abrahame46243a2021-02-23 19:33:49 -0800265 EXPECT_EQ(0u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700266 }
267
ramindani4d48f902021-09-20 21:07:45 +0000268 void Flush_removesUnsignaledFromTheQueue(Vector<ComposerState> state1,
269 Vector<ComposerState> state2,
270 bool updateApplyToken = true) {
271 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
272
273 TransactionInfo transactionA;
274 setupSingleWithComposer(transactionA, ISurfaceComposer::eSynchronous,
275 /*syncInputWindows*/ false,
276 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
277 FrameTimelineInfo{}, &state1);
278
279 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
280 transactionA.displays, transactionA.flags,
281 transactionA.applyToken, transactionA.inputWindowCommands,
282 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
283 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
284 transactionA.id);
285
286 TransactionInfo transactionB;
287 if (updateApplyToken) {
288 transactionB.applyToken = sp<IBinder>();
289 }
290 setupSingleWithComposer(transactionB, ISurfaceComposer::eSynchronous,
291 /*syncInputWindows*/ false,
292 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
293 FrameTimelineInfo{}, &state2);
294 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
295 transactionB.displays, transactionB.flags,
296 transactionB.applyToken, transactionB.inputWindowCommands,
297 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
298 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
299 transactionB.id);
300
301 mFlinger.flushTransactionQueues();
302 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
303 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
304 EXPECT_EQ(2ul, mFlinger.getTransactionCommittedSignals().size());
305 }
306
307 void Flush_removesFromTheQueue(const Vector<ComposerState>& state) {
308 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
309 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
310
311 TransactionInfo transaction;
312 setupSingleWithComposer(transaction, ISurfaceComposer::eSynchronous,
313 /*syncInputWindows*/ false,
314 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
315 FrameTimelineInfo{}, &state);
316
317 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
318 transaction.displays, transaction.flags,
319 transaction.applyToken, transaction.inputWindowCommands,
320 transaction.desiredPresentTime, transaction.isAutoTimestamp,
321 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
322 transaction.id);
323
324 mFlinger.flushTransactionQueues();
325 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
326 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
327 EXPECT_EQ(1u, mFlinger.getTransactionCommittedSignals().size());
328 }
329
330 void Flush_keepsInTheQueue(const Vector<ComposerState>& state) {
331 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
332 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
333
334 TransactionInfo transaction;
335 setupSingleWithComposer(transaction, ISurfaceComposer::eSynchronous,
336 /*syncInputWindows*/ false,
337 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
338 FrameTimelineInfo{}, &state);
339
340 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
341 transaction.displays, transaction.flags,
342 transaction.applyToken, transaction.inputWindowCommands,
343 transaction.desiredPresentTime, transaction.isAutoTimestamp,
344 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
345 transaction.id);
346
347 mFlinger.flushTransactionQueues();
348 EXPECT_EQ(1u, mFlinger.getPendingTransactionQueue().size());
349 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
350 EXPECT_EQ(0ul, mFlinger.getTransactionCommittedSignals().size());
351 }
352
353 void Flush_KeepsUnsignaledInTheQueue(const Vector<ComposerState>& state1,
354 const Vector<ComposerState>& state2,
355 bool updateApplyToken = true,
356 uint32_t pendingTransactionQueueSize = 1u) {
357 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
358 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
359 auto time = systemTime();
360 TransactionInfo transactionA;
361 TransactionInfo transactionB;
362 setupSingleWithComposer(transactionA, ISurfaceComposer::eSynchronous,
363 /*syncInputWindows*/ false,
364 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
365 FrameTimelineInfo{}, &state1);
366 setupSingleWithComposer(transactionB, ISurfaceComposer::eSynchronous,
367 /*syncInputWindows*/ false,
368 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
369 FrameTimelineInfo{}, &state2);
370 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
371 transactionA.displays, transactionA.flags,
372 transactionA.applyToken, transactionA.inputWindowCommands,
373 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
374 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
375 transactionA.id);
376 if (updateApplyToken) {
377 transactionB.applyToken = sp<IBinder>();
378 }
379 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
380 transactionB.displays, transactionB.flags,
381 transactionB.applyToken, transactionB.inputWindowCommands,
382 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
383 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
384 transactionB.id);
385
386 mFlinger.flushTransactionQueues();
387 EXPECT_EQ(pendingTransactionQueueSize, mFlinger.getPendingTransactionQueue().size());
388 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
389 }
390
391 void Flush_removesSignaledFromTheQueue(const Vector<ComposerState>& state1,
392 const Vector<ComposerState>& state2) {
393 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
394 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
395
396 auto time = systemTime();
397 TransactionInfo transactionA;
398 TransactionInfo transactionB;
399 setupSingleWithComposer(transactionA, ISurfaceComposer::eSynchronous,
400 /*syncInputWindows*/ false,
401 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
402 FrameTimelineInfo{}, &state1);
403 setupSingleWithComposer(transactionB, ISurfaceComposer::eSynchronous,
404 /*syncInputWindows*/ false,
405 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
406 FrameTimelineInfo{}, &state2);
407 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
408 transactionA.displays, transactionA.flags,
409 transactionA.applyToken, transactionA.inputWindowCommands,
410 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
411 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
412 transactionA.id);
413 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
414 transactionB.displays, transactionB.flags,
415 transactionB.applyToken, transactionB.inputWindowCommands,
416 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
417 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
418 transactionB.id);
419
420 mFlinger.flushTransactionQueues();
421 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
422 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
423 EXPECT_EQ(2ul, mFlinger.getTransactionCommittedSignals().size());
424 }
425
426 static Vector<ComposerState> createComposerStateVector(const ComposerState& state1,
427 const ComposerState& state2) {
428 Vector<ComposerState> states;
429 states.push_back(state1);
430 states.push_back(state2);
431 return states;
432 }
433
434 static Vector<ComposerState> createComposerStateVector(const ComposerState& state) {
435 Vector<ComposerState> states;
436 states.push_back(state);
437 return states;
438 }
439
440 static ComposerState createComposerState(int layerId, sp<Fence> fence,
441 uint32_t stateFlags = layer_state_t::eBufferChanged) {
442 ComposerState composer_state;
443 composer_state.state.bufferData.acquireFence = std::move(fence);
444 composer_state.state.layerId = layerId;
445 composer_state.state.bufferData.flags = BufferData::BufferDataChange::fenceChanged;
446 composer_state.state.flags = stateFlags;
447 return composer_state;
448 }
449
Valerie Haud251afb2019-03-29 14:19:02 -0700450 bool mHasListenerCallbacks = false;
451 std::vector<ListenerCallbacks> mCallbacks;
452 int mTransactionNumber = 0;
453};
454
455TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000456 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Dominik Laskowskie0e0cde2021-07-30 10:42:05 -0700457 EXPECT_CALL(*mMessageQueue, scheduleCommit()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700458
Valerie Haud251afb2019-03-29 14:19:02 -0700459 TransactionInfo transactionA; // transaction to go on pending queue
460 setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000461 /*desiredPresentTime*/ s2ns(1), false, FrameTimelineInfo{});
462 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700463 transactionA.displays, transactionA.flags, transactionA.applyToken,
464 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800465 transactionA.isAutoTimestamp, transactionA.uncacheBuffer,
466 mHasListenerCallbacks, mCallbacks, transactionA.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700467
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000468 auto& transactionQueue = mFlinger.getTransactionQueue();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000469 ASSERT_EQ(1u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700470
Arthur Hung58144272021-01-16 03:43:53 +0000471 auto& transactionState = transactionQueue.front();
Valerie Haud251afb2019-03-29 14:19:02 -0700472 checkEqual(transactionA, transactionState);
473
474 // because flushing uses the cached expected present time, we send an empty
475 // transaction here (sending a null applyToken to fake it as from a
476 // different process) to re-query and reset the cached expected present time
477 TransactionInfo empty;
478 empty.applyToken = sp<IBinder>();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000479 mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
480 empty.applyToken, empty.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800481 empty.desiredPresentTime, empty.isAutoTimestamp,
482 empty.uncacheBuffer, mHasListenerCallbacks, mCallbacks, empty.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700483
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000484 // flush transaction queue should flush as desiredPresentTime has
Valerie Haud251afb2019-03-29 14:19:02 -0700485 // passed
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000486 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700487
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000488 EXPECT_EQ(0u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700489}
490
491TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_Synchronous) {
492 NotPlacedOnTransactionQueue(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
493}
494
495TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_Animation) {
496 NotPlacedOnTransactionQueue(ISurfaceComposer::eAnimation, /*syncInputWindows*/ false);
497}
498
499TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_SyncInputWindows) {
500 NotPlacedOnTransactionQueue(/*flags*/ 0, /*syncInputWindows*/ true);
501}
502
503TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_Synchronous) {
504 PlaceOnTransactionQueue(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
505}
506
507TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_Animation) {
508 PlaceOnTransactionQueue(ISurfaceComposer::eAnimation, /*syncInputWindows*/ false);
509}
510
511TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_SyncInputWindows) {
512 PlaceOnTransactionQueue(/*flags*/ 0, /*syncInputWindows*/ true);
513}
514
515TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_Synchronous) {
516 BlockedByPriorTransaction(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
517}
518
519TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_Animation) {
520 BlockedByPriorTransaction(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
521}
522
523TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_SyncInputWindows) {
524 BlockedByPriorTransaction(/*flags*/ 0, /*syncInputWindows*/ true);
525}
526
Valerie Hau09e60052019-12-15 14:51:15 -0800527TEST_F(TransactionApplicationTest, FromHandle) {
528 sp<IBinder> badHandle;
529 auto ret = mFlinger.fromHandle(badHandle);
Alec Mouri9a02eda2020-04-21 17:39:34 -0700530 EXPECT_EQ(nullptr, ret.promote().get());
Valerie Hau09e60052019-12-15 14:51:15 -0800531}
ramindani4d48f902021-09-20 21:07:45 +0000532
533TEST_F(TransactionApplicationTest, Flush_RemovesSingleSignaledFromTheQueue_LatchUnsignaled_Auto) {
534 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
535 Flush_removesFromTheQueue(
536 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
537}
538
539TEST_F(TransactionApplicationTest, Flush_RemovesSingleUnSignaledFromTheQueue_LatchUnsignaled_Auto) {
540 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
541 Flush_removesFromTheQueue(
542 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
543}
544
545TEST_F(TransactionApplicationTest,
546 Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange_LatchUnsignaled_Auto) {
547 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
548 Flush_keepsInTheQueue(createComposerStateVector(
549 createComposerState(/*layerId*/ 1, mFenceUnsignaled, layer_state_t::eCropChanged)));
550}
551
552TEST_F(TransactionApplicationTest,
553 Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed_LatchUnsignaled_Auto) {
554 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
555 Flush_keepsInTheQueue(createComposerStateVector(
556 createComposerState(/*layerId*/ 1, mFenceUnsignaled,
557 layer_state_t::eCropChanged | layer_state_t::eBufferChanged)));
558}
559
560TEST_F(TransactionApplicationTest,
561 Flush_KeepsInTheQueueSameApplyTokenMultiState_LatchUnsignaled_Auto) {
562 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
563 Flush_keepsInTheQueue(
564 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
565 createComposerState(/*layerId*/ 1, mFenceSignaled)));
566}
567
568TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueue_MultipleStateTransaction_Auto) {
569 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
570 Flush_keepsInTheQueue(
571 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
572 createComposerState(/*layerId*/ 2, mFenceSignaled)));
573}
574
575TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Auto) {
576 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
577 Flush_removesSignaledFromTheQueue(createComposerStateVector(
578 createComposerState(/*layerId*/ 1, mFenceSignaled)),
579 createComposerStateVector(
580 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
581}
582
583TEST_F(TransactionApplicationTest, Flush_RemoveSignaledWithUnsignaledIntact_LatchUnsignaled_Auto) {
584 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
585 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
586 createComposerState(/*layerId*/ 1, mFenceSignaled)),
587 createComposerStateVector(
588 createComposerState(/*layerId*/ 2, mFenceUnsignaled)));
589 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
590}
591
592TEST_F(TransactionApplicationTest,
593 Flush_KeepsTransactionInTheQueueSameApplyToken_LatchUnsignaled_Auto) {
594 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
595 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
596 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
597 createComposerStateVector(
598 createComposerState(/*layerId*/ 2, mFenceSignaled)),
599 /*updateApplyToken*/ false);
600 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
601}
602
603TEST_F(TransactionApplicationTest, Flush_KeepsTransactionInTheQueue_LatchUnsignaled_Auto) {
604 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
605 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
606 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
607 createComposerStateVector(
608 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
609 /*updateApplyToken*/ true,
610 /*pendingTransactionQueueSize*/ 2u);
611 EXPECT_EQ(0ul, mFlinger.getTransactionCommittedSignals().size());
612}
613
614TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Disabled) {
615 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
616 Flush_removesFromTheQueue(
617 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
618}
619
620TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueue_LatchUnsignaled_Disabled) {
621 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
622 Flush_keepsInTheQueue(
623 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
624}
625
626TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueueSameLayerId_LatchUnsignaled_Disabled) {
627 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
628 Flush_keepsInTheQueue(
629 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
630 createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
631}
632
633TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueueDifferentLayerId_LatchUnsignaled_Disabled) {
634 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
635 Flush_keepsInTheQueue(
636 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
637 createComposerState(/*layerId*/ 2, mFenceUnsignaled)));
638}
639
640TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnSignaled_Disabled) {
641 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
642 Flush_removesSignaledFromTheQueue(createComposerStateVector(
643 createComposerState(/*layerId*/ 1, mFenceSignaled)),
644 createComposerStateVector(
645 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
646}
647
648TEST_F(TransactionApplicationTest,
649 Flush_KeepInTheQueueDifferentApplyToken_LatchUnsignaled_Disabled) {
650 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
651 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
652 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
653 createComposerStateVector(
654 createComposerState(/*layerId*/ 2, mFenceSignaled)));
655 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
656}
657
658TEST_F(TransactionApplicationTest, Flush_KeepInTheQueueSameApplyToken_LatchUnsignaled_Disabled) {
659 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
660 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
661 createComposerState(/*layerId*/ 1, mFenceSignaled)),
662 createComposerStateVector(
663 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
664 /*updateApplyToken*/ false);
665 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
666}
667
668TEST_F(TransactionApplicationTest, Flush_KeepInTheUnsignaledTheQueue_LatchUnsignaled_Disabled) {
669 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
670 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
671 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
672 createComposerStateVector(
673 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
674 /*updateApplyToken*/ false);
675 EXPECT_EQ(0ul, mFlinger.getTransactionCommittedSignals().size());
676}
677
678TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Always) {
679 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
680 Flush_removesFromTheQueue(
681 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
682}
683
684TEST_F(TransactionApplicationTest, Flush_RemovesFromTheQueue_LatchUnsignaled_Always) {
685 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
686 Flush_removesFromTheQueue(
687 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
688}
689
690TEST_F(TransactionApplicationTest, Flush_RemovesFromTheQueueSameLayerId_LatchUnsignaled_Always) {
691 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
692 Flush_removesFromTheQueue(
693 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
694 createComposerState(/*layerId*/ 1, mFenceSignaled)));
695}
696
697TEST_F(TransactionApplicationTest,
698 Flush_RemovesFromTheQueueDifferentLayerId_LatchUnsignaled_Always) {
699 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
700 Flush_removesFromTheQueue(
701 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
702 createComposerState(/*layerId*/ 2, mFenceSignaled)));
703}
704
705TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnSignaled_Always) {
706 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
707 Flush_removesSignaledFromTheQueue(createComposerStateVector(
708 createComposerState(/*layerId*/ 1, mFenceSignaled)),
709 createComposerStateVector(
710 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
711}
712
713TEST_F(TransactionApplicationTest,
714 Flush_RemovesFromTheQueueDifferentApplyToken_LatchUnsignaled_Always) {
715 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
716 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
717 createComposerState(/*layerId*/ 1, mFenceSignaled)),
718 createComposerStateVector(
719 createComposerState(/*layerId*/ 2,
720 mFenceUnsignaled)));
721}
722
723TEST_F(TransactionApplicationTest,
724 Flush_RemovesUnsignaledFromTheQueueSameApplyToken_LatchUnsignaled_Always) {
725 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
726 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
727 createComposerState(/*layerId*/ 1,
728 mFenceUnsignaled)),
729 createComposerStateVector(
730 createComposerState(/*layerId*/ 2, mFenceSignaled)),
731 /*updateApplyToken*/ false);
732}
733
734TEST_F(TransactionApplicationTest, Flush_RemovesUnsignaledFromTheQueue_LatchUnsignaled_Always) {
735 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
736 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
737 createComposerState(/*layerId*/ 1,
738 mFenceUnsignaled)),
739 createComposerStateVector(
740 createComposerState(/*layerId*/ 2,
741 mFenceUnsignaled)));
742}
743
Valerie Haud251afb2019-03-29 14:19:02 -0700744} // namespace android