blob: b3a6a1b26421ef7de4d8baaec18085a61aa51bf2 [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"
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
88 TestableScheduler* mScheduler;
89 TestableSurfaceFlinger mFlinger;
90
91 std::unique_ptr<mock::EventThread> mEventThread = std::make_unique<mock::EventThread>();
Valerie Haud251afb2019-03-29 14:19:02 -070092
Ady Abraham8cb21882020-08-26 18:22:05 -070093 mock::VsyncController* mVsyncController = new mock::VsyncController();
94 mock::VSyncTracker* mVSyncTracker = new mock::VSyncTracker();
ramindani4d48f902021-09-20 21:07:45 +000095 mock::MockFence* mFenceUnsignaled = new mock::MockFence();
96 mock::MockFence* mFenceSignaled = new mock::MockFence();
97 mock::MockFence* mFenceUnsignaled2 = new mock::MockFence();
98 mock::MockFence* mFenceSignaled2 = new mock::MockFence();
Valerie Haud251afb2019-03-29 14:19:02 -070099
100 struct TransactionInfo {
101 Vector<ComposerState> states;
102 Vector<DisplayState> displays;
103 uint32_t flags = 0;
104 sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
105 InputWindowCommands inputWindowCommands;
Ady Abrahamf0c56492020-12-17 18:04:15 -0800106 int64_t desiredPresentTime = 0;
107 bool isAutoTimestamp = true;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000108 FrameTimelineInfo frameTimelineInfo;
Valerie Haud251afb2019-03-29 14:19:02 -0700109 client_cache_t uncacheBuffer;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000110 uint64_t id = static_cast<uint64_t>(-1);
111 static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1));
Valerie Haud251afb2019-03-29 14:19:02 -0700112 };
113
Vishnu Nair6b591152021-10-08 11:45:14 -0700114 void checkEqual(TransactionInfo info, TransactionState state) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000115 EXPECT_EQ(0u, info.states.size());
116 EXPECT_EQ(0u, state.states.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700117
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000118 EXPECT_EQ(0u, info.displays.size());
119 EXPECT_EQ(0u, state.displays.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700120 EXPECT_EQ(info.flags, state.flags);
121 EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime);
122 }
123
124 void setupSingle(TransactionInfo& transaction, uint32_t flags, bool syncInputWindows,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800125 int64_t desiredPresentTime, bool isAutoTimestamp,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000126 const FrameTimelineInfo& frameTimelineInfo) {
Valerie Haud251afb2019-03-29 14:19:02 -0700127 mTransactionNumber++;
128 transaction.flags |= flags; // ISurfaceComposer::eSynchronous;
129 transaction.inputWindowCommands.syncInputWindows = syncInputWindows;
130 transaction.desiredPresentTime = desiredPresentTime;
Ady Abrahamf0c56492020-12-17 18:04:15 -0800131 transaction.isAutoTimestamp = isAutoTimestamp;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000132 transaction.frameTimelineInfo = frameTimelineInfo;
Valerie Haud251afb2019-03-29 14:19:02 -0700133 }
134
ramindani4d48f902021-09-20 21:07:45 +0000135 void setupSingleWithComposer(TransactionInfo& transaction, uint32_t flags,
136 bool syncInputWindows, int64_t desiredPresentTime,
137 bool isAutoTimestamp, const FrameTimelineInfo& frameTimelineInfo,
138 const Vector<ComposerState>* states) {
139 setupSingle(transaction, flags, syncInputWindows, desiredPresentTime, isAutoTimestamp,
140 frameTimelineInfo);
141 transaction.states = *states;
142 }
143
Valerie Haud251afb2019-03-29 14:19:02 -0700144 void NotPlacedOnTransactionQueue(uint32_t flags, bool syncInputWindows) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000145 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Dominik Laskowski756b7892021-08-04 12:53:59 -0700146 EXPECT_CALL(*mFlinger.scheduler(), scheduleCommit()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700147 TransactionInfo transaction;
148 setupSingle(transaction, flags, syncInputWindows,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800149 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000150 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700151 nsecs_t applicationTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000152 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700153 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700154 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800155 transaction.desiredPresentTime, transaction.isAutoTimestamp,
156 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
157 transaction.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700158
Valerie Haud251afb2019-03-29 14:19:02 -0700159 // If transaction is synchronous or syncs input windows, SF
160 // applyTransactionState should time out (5s) wating for SF to commit
161 // the transaction or to receive a signal that syncInputWindows has
162 // completed. If this is animation, it should not time out waiting.
163 nsecs_t returnedTime = systemTime();
164 if (flags & ISurfaceComposer::eSynchronous || syncInputWindows) {
165 EXPECT_GE(returnedTime, applicationTime + s2ns(5));
166 } else {
167 EXPECT_LE(returnedTime, applicationTime + s2ns(5));
168 }
Arthur Hung58144272021-01-16 03:43:53 +0000169 // Each transaction should have been placed on the transaction queue
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000170 auto transactionQueue = mFlinger.getTransactionQueue();
Arthur Hung58144272021-01-16 03:43:53 +0000171 EXPECT_EQ(1u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700172 }
173
174 void PlaceOnTransactionQueue(uint32_t flags, bool syncInputWindows) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000175 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Dominik Laskowski756b7892021-08-04 12:53:59 -0700176 EXPECT_CALL(*mFlinger.scheduler(), scheduleCommit()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700177
178 // first check will see desired present time has not passed,
179 // but afterwards it will look like the desired present time has passed
180 nsecs_t time = systemTime();
Valerie Haud251afb2019-03-29 14:19:02 -0700181 TransactionInfo transaction;
182 setupSingle(transaction, flags, syncInputWindows,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000183 /*desiredPresentTime*/ time + s2ns(1), false, FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700184 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000185 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700186 transaction.displays, transaction.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700187 transaction.applyToken, transaction.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800188 transaction.desiredPresentTime, transaction.isAutoTimestamp,
189 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
190 transaction.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700191
192 nsecs_t returnedTime = systemTime();
Ady Abrahame46243a2021-02-23 19:33:49 -0800193 if ((flags & ISurfaceComposer::eSynchronous) || syncInputWindows) {
194 EXPECT_GE(systemTime(), applicationSentTime + s2ns(5));
195 } else {
196 EXPECT_LE(returnedTime, applicationSentTime + s2ns(5));
197 }
Valerie Haud251afb2019-03-29 14:19:02 -0700198 // This transaction should have been placed on the transaction queue
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000199 auto transactionQueue = mFlinger.getTransactionQueue();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000200 EXPECT_EQ(1u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700201 }
202
203 void BlockedByPriorTransaction(uint32_t flags, bool syncInputWindows) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000204 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Valerie Haud251afb2019-03-29 14:19:02 -0700205 nsecs_t time = systemTime();
Ady Abrahame46243a2021-02-23 19:33:49 -0800206 if (!syncInputWindows) {
Dominik Laskowski756b7892021-08-04 12:53:59 -0700207 EXPECT_CALL(*mFlinger.scheduler(), scheduleCommit()).Times(2);
Ady Abrahame46243a2021-02-23 19:33:49 -0800208 } else {
Dominik Laskowski756b7892021-08-04 12:53:59 -0700209 EXPECT_CALL(*mFlinger.scheduler(), scheduleCommit()).Times(1);
Ady Abrahame46243a2021-02-23 19:33:49 -0800210 }
Valerie Haud251afb2019-03-29 14:19:02 -0700211 // transaction that should go on the pending thread
212 TransactionInfo transactionA;
213 setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000214 /*desiredPresentTime*/ time + s2ns(1), false, FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700215
216 // transaction that would not have gone on the pending thread if not
217 // blocked
218 TransactionInfo transactionB;
219 setupSingle(transactionB, flags, syncInputWindows,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800220 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000221 FrameTimelineInfo{});
Valerie Haud251afb2019-03-29 14:19:02 -0700222
223 nsecs_t applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000224 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700225 transactionA.displays, transactionA.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700226 transactionA.applyToken, transactionA.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800227 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
228 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
229 transactionA.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700230
231 // This thread should not have been blocked by the above transaction
232 // (5s is the timeout period that applyTransactionState waits for SF to
233 // commit the transaction)
234 EXPECT_LE(systemTime(), applicationSentTime + s2ns(5));
Arthur Hung58144272021-01-16 03:43:53 +0000235 // transaction that would goes to pending transaciton queue.
236 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700237
238 applicationSentTime = systemTime();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000239 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700240 transactionB.displays, transactionB.flags,
Valerie Haud251afb2019-03-29 14:19:02 -0700241 transactionB.applyToken, transactionB.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800242 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
243 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
244 transactionB.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700245
246 // this thread should have been blocked by the above transaction
247 // if this is an animation, this thread should be blocked for 5s
248 // in setTransactionState waiting for transactionA to flush. Otherwise,
249 // the transaction should be placed on the pending queue
Ady Abrahame46243a2021-02-23 19:33:49 -0800250 if (flags & (ISurfaceComposer::eAnimation | ISurfaceComposer::eSynchronous) ||
251 syncInputWindows) {
Valerie Haud251afb2019-03-29 14:19:02 -0700252 EXPECT_GE(systemTime(), applicationSentTime + s2ns(5));
253 } else {
254 EXPECT_LE(systemTime(), applicationSentTime + s2ns(5));
255 }
256
Arthur Hung58144272021-01-16 03:43:53 +0000257 // transaction that would goes to pending transaciton queue.
258 mFlinger.flushTransactionQueues();
259
Ady Abrahame46243a2021-02-23 19:33:49 -0800260 // check that the transaction was applied.
Arthur Hung58144272021-01-16 03:43:53 +0000261 auto transactionQueue = mFlinger.getPendingTransactionQueue();
Ady Abrahame46243a2021-02-23 19:33:49 -0800262 EXPECT_EQ(0u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700263 }
264
ramindani4d48f902021-09-20 21:07:45 +0000265 void Flush_removesUnsignaledFromTheQueue(Vector<ComposerState> state1,
266 Vector<ComposerState> state2,
267 bool updateApplyToken = true) {
268 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
269
270 TransactionInfo transactionA;
271 setupSingleWithComposer(transactionA, ISurfaceComposer::eSynchronous,
272 /*syncInputWindows*/ false,
273 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
274 FrameTimelineInfo{}, &state1);
275
276 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
277 transactionA.displays, transactionA.flags,
278 transactionA.applyToken, transactionA.inputWindowCommands,
279 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
280 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
281 transactionA.id);
282
283 TransactionInfo transactionB;
284 if (updateApplyToken) {
285 transactionB.applyToken = sp<IBinder>();
286 }
287 setupSingleWithComposer(transactionB, ISurfaceComposer::eSynchronous,
288 /*syncInputWindows*/ false,
289 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
290 FrameTimelineInfo{}, &state2);
291 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
292 transactionB.displays, transactionB.flags,
293 transactionB.applyToken, transactionB.inputWindowCommands,
294 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
295 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
296 transactionB.id);
297
298 mFlinger.flushTransactionQueues();
299 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
300 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
301 EXPECT_EQ(2ul, mFlinger.getTransactionCommittedSignals().size());
302 }
303
304 void Flush_removesFromTheQueue(const Vector<ComposerState>& state) {
305 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
306 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
307
308 TransactionInfo transaction;
309 setupSingleWithComposer(transaction, ISurfaceComposer::eSynchronous,
310 /*syncInputWindows*/ false,
311 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
312 FrameTimelineInfo{}, &state);
313
314 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
315 transaction.displays, transaction.flags,
316 transaction.applyToken, transaction.inputWindowCommands,
317 transaction.desiredPresentTime, transaction.isAutoTimestamp,
318 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
319 transaction.id);
320
321 mFlinger.flushTransactionQueues();
322 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
323 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
324 EXPECT_EQ(1u, mFlinger.getTransactionCommittedSignals().size());
325 }
326
327 void Flush_keepsInTheQueue(const Vector<ComposerState>& state) {
328 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
329 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
330
331 TransactionInfo transaction;
332 setupSingleWithComposer(transaction, ISurfaceComposer::eSynchronous,
333 /*syncInputWindows*/ false,
334 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
335 FrameTimelineInfo{}, &state);
336
337 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
338 transaction.displays, transaction.flags,
339 transaction.applyToken, transaction.inputWindowCommands,
340 transaction.desiredPresentTime, transaction.isAutoTimestamp,
341 transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
342 transaction.id);
343
344 mFlinger.flushTransactionQueues();
345 EXPECT_EQ(1u, mFlinger.getPendingTransactionQueue().size());
346 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
347 EXPECT_EQ(0ul, mFlinger.getTransactionCommittedSignals().size());
348 }
349
350 void Flush_KeepsUnsignaledInTheQueue(const Vector<ComposerState>& state1,
351 const Vector<ComposerState>& state2,
352 bool updateApplyToken = true,
353 uint32_t pendingTransactionQueueSize = 1u) {
354 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
355 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
356 auto time = systemTime();
357 TransactionInfo transactionA;
358 TransactionInfo transactionB;
359 setupSingleWithComposer(transactionA, ISurfaceComposer::eSynchronous,
360 /*syncInputWindows*/ false,
361 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
362 FrameTimelineInfo{}, &state1);
363 setupSingleWithComposer(transactionB, ISurfaceComposer::eSynchronous,
364 /*syncInputWindows*/ false,
365 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
366 FrameTimelineInfo{}, &state2);
367 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
368 transactionA.displays, transactionA.flags,
369 transactionA.applyToken, transactionA.inputWindowCommands,
370 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
371 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
372 transactionA.id);
373 if (updateApplyToken) {
374 transactionB.applyToken = sp<IBinder>();
375 }
376 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
377 transactionB.displays, transactionB.flags,
378 transactionB.applyToken, transactionB.inputWindowCommands,
379 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
380 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
381 transactionB.id);
382
383 mFlinger.flushTransactionQueues();
384 EXPECT_EQ(pendingTransactionQueueSize, mFlinger.getPendingTransactionQueue().size());
385 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
386 }
387
388 void Flush_removesSignaledFromTheQueue(const Vector<ComposerState>& state1,
389 const Vector<ComposerState>& state2) {
390 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
391 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
392
393 auto time = systemTime();
394 TransactionInfo transactionA;
395 TransactionInfo transactionB;
396 setupSingleWithComposer(transactionA, ISurfaceComposer::eSynchronous,
397 /*syncInputWindows*/ false,
398 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
399 FrameTimelineInfo{}, &state1);
400 setupSingleWithComposer(transactionB, ISurfaceComposer::eSynchronous,
401 /*syncInputWindows*/ false,
402 /*desiredPresentTime*/ time, /*isAutoTimestamp*/ true,
403 FrameTimelineInfo{}, &state2);
404 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
405 transactionA.displays, transactionA.flags,
406 transactionA.applyToken, transactionA.inputWindowCommands,
407 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
408 transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
409 transactionA.id);
410 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
411 transactionB.displays, transactionB.flags,
412 transactionB.applyToken, transactionB.inputWindowCommands,
413 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
414 transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
415 transactionB.id);
416
417 mFlinger.flushTransactionQueues();
418 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
419 EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
420 EXPECT_EQ(2ul, mFlinger.getTransactionCommittedSignals().size());
421 }
422
423 static Vector<ComposerState> createComposerStateVector(const ComposerState& state1,
424 const ComposerState& state2) {
425 Vector<ComposerState> states;
426 states.push_back(state1);
427 states.push_back(state2);
428 return states;
429 }
430
431 static Vector<ComposerState> createComposerStateVector(const ComposerState& state) {
432 Vector<ComposerState> states;
433 states.push_back(state);
434 return states;
435 }
436
437 static ComposerState createComposerState(int layerId, sp<Fence> fence,
438 uint32_t stateFlags = layer_state_t::eBufferChanged) {
439 ComposerState composer_state;
440 composer_state.state.bufferData.acquireFence = std::move(fence);
441 composer_state.state.layerId = layerId;
442 composer_state.state.bufferData.flags = BufferData::BufferDataChange::fenceChanged;
443 composer_state.state.flags = stateFlags;
444 return composer_state;
445 }
446
Valerie Haud251afb2019-03-29 14:19:02 -0700447 bool mHasListenerCallbacks = false;
448 std::vector<ListenerCallbacks> mCallbacks;
449 int mTransactionNumber = 0;
450};
451
452TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000453 ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
Dominik Laskowski756b7892021-08-04 12:53:59 -0700454 EXPECT_CALL(*mFlinger.scheduler(), scheduleCommit()).Times(1);
Valerie Haud251afb2019-03-29 14:19:02 -0700455
Valerie Haud251afb2019-03-29 14:19:02 -0700456 TransactionInfo transactionA; // transaction to go on pending queue
457 setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000458 /*desiredPresentTime*/ s2ns(1), false, FrameTimelineInfo{});
459 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
Ady Abraham22c7b5c2020-09-22 19:33:40 -0700460 transactionA.displays, transactionA.flags, transactionA.applyToken,
461 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800462 transactionA.isAutoTimestamp, transactionA.uncacheBuffer,
463 mHasListenerCallbacks, mCallbacks, transactionA.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700464
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000465 auto& transactionQueue = mFlinger.getTransactionQueue();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000466 ASSERT_EQ(1u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700467
Arthur Hung58144272021-01-16 03:43:53 +0000468 auto& transactionState = transactionQueue.front();
Valerie Haud251afb2019-03-29 14:19:02 -0700469 checkEqual(transactionA, transactionState);
470
471 // because flushing uses the cached expected present time, we send an empty
472 // transaction here (sending a null applyToken to fake it as from a
473 // different process) to re-query and reset the cached expected present time
474 TransactionInfo empty;
475 empty.applyToken = sp<IBinder>();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000476 mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
477 empty.applyToken, empty.inputWindowCommands,
Ady Abrahamf0c56492020-12-17 18:04:15 -0800478 empty.desiredPresentTime, empty.isAutoTimestamp,
479 empty.uncacheBuffer, mHasListenerCallbacks, mCallbacks, empty.id);
Valerie Haud251afb2019-03-29 14:19:02 -0700480
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000481 // flush transaction queue should flush as desiredPresentTime has
Valerie Haud251afb2019-03-29 14:19:02 -0700482 // passed
Zhuoyao Zhang3d3540d2021-01-14 05:14:54 +0000483 mFlinger.flushTransactionQueues();
Valerie Haud251afb2019-03-29 14:19:02 -0700484
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000485 EXPECT_EQ(0u, transactionQueue.size());
Valerie Haud251afb2019-03-29 14:19:02 -0700486}
487
488TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_Synchronous) {
489 NotPlacedOnTransactionQueue(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
490}
491
492TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_Animation) {
493 NotPlacedOnTransactionQueue(ISurfaceComposer::eAnimation, /*syncInputWindows*/ false);
494}
495
496TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_SyncInputWindows) {
497 NotPlacedOnTransactionQueue(/*flags*/ 0, /*syncInputWindows*/ true);
498}
499
500TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_Synchronous) {
501 PlaceOnTransactionQueue(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
502}
503
504TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_Animation) {
505 PlaceOnTransactionQueue(ISurfaceComposer::eAnimation, /*syncInputWindows*/ false);
506}
507
508TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_SyncInputWindows) {
509 PlaceOnTransactionQueue(/*flags*/ 0, /*syncInputWindows*/ true);
510}
511
512TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_Synchronous) {
513 BlockedByPriorTransaction(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
514}
515
516TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_Animation) {
517 BlockedByPriorTransaction(ISurfaceComposer::eSynchronous, /*syncInputWindows*/ false);
518}
519
520TEST_F(TransactionApplicationTest, BlockWithPriorTransaction_SyncInputWindows) {
521 BlockedByPriorTransaction(/*flags*/ 0, /*syncInputWindows*/ true);
522}
523
Valerie Hau09e60052019-12-15 14:51:15 -0800524TEST_F(TransactionApplicationTest, FromHandle) {
525 sp<IBinder> badHandle;
526 auto ret = mFlinger.fromHandle(badHandle);
Alec Mouri9a02eda2020-04-21 17:39:34 -0700527 EXPECT_EQ(nullptr, ret.promote().get());
Valerie Hau09e60052019-12-15 14:51:15 -0800528}
ramindani4d48f902021-09-20 21:07:45 +0000529
530TEST_F(TransactionApplicationTest, Flush_RemovesSingleSignaledFromTheQueue_LatchUnsignaled_Auto) {
531 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
532 Flush_removesFromTheQueue(
533 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
534}
535
536TEST_F(TransactionApplicationTest, Flush_RemovesSingleUnSignaledFromTheQueue_LatchUnsignaled_Auto) {
537 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
538 Flush_removesFromTheQueue(
539 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
540}
541
542TEST_F(TransactionApplicationTest,
543 Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange_LatchUnsignaled_Auto) {
544 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
545 Flush_keepsInTheQueue(createComposerStateVector(
546 createComposerState(/*layerId*/ 1, mFenceUnsignaled, layer_state_t::eCropChanged)));
547}
548
549TEST_F(TransactionApplicationTest,
550 Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed_LatchUnsignaled_Auto) {
551 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
552 Flush_keepsInTheQueue(createComposerStateVector(
553 createComposerState(/*layerId*/ 1, mFenceUnsignaled,
554 layer_state_t::eCropChanged | layer_state_t::eBufferChanged)));
555}
556
557TEST_F(TransactionApplicationTest,
558 Flush_KeepsInTheQueueSameApplyTokenMultiState_LatchUnsignaled_Auto) {
559 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
560 Flush_keepsInTheQueue(
561 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
562 createComposerState(/*layerId*/ 1, mFenceSignaled)));
563}
564
565TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueue_MultipleStateTransaction_Auto) {
566 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
567 Flush_keepsInTheQueue(
568 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
569 createComposerState(/*layerId*/ 2, mFenceSignaled)));
570}
571
572TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Auto) {
573 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
574 Flush_removesSignaledFromTheQueue(createComposerStateVector(
575 createComposerState(/*layerId*/ 1, mFenceSignaled)),
576 createComposerStateVector(
577 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
578}
579
580TEST_F(TransactionApplicationTest, Flush_RemoveSignaledWithUnsignaledIntact_LatchUnsignaled_Auto) {
581 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
582 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
583 createComposerState(/*layerId*/ 1, mFenceSignaled)),
584 createComposerStateVector(
585 createComposerState(/*layerId*/ 2, mFenceUnsignaled)));
586 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
587}
588
589TEST_F(TransactionApplicationTest,
590 Flush_KeepsTransactionInTheQueueSameApplyToken_LatchUnsignaled_Auto) {
591 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
592 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
593 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
594 createComposerStateVector(
595 createComposerState(/*layerId*/ 2, mFenceSignaled)),
596 /*updateApplyToken*/ false);
597 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
598}
599
600TEST_F(TransactionApplicationTest, Flush_KeepsTransactionInTheQueue_LatchUnsignaled_Auto) {
601 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Auto;
602 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
603 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
604 createComposerStateVector(
605 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
606 /*updateApplyToken*/ true,
607 /*pendingTransactionQueueSize*/ 2u);
608 EXPECT_EQ(0ul, mFlinger.getTransactionCommittedSignals().size());
609}
610
611TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Disabled) {
612 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
613 Flush_removesFromTheQueue(
614 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
615}
616
617TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueue_LatchUnsignaled_Disabled) {
618 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
619 Flush_keepsInTheQueue(
620 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
621}
622
623TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueueSameLayerId_LatchUnsignaled_Disabled) {
624 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
625 Flush_keepsInTheQueue(
626 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
627 createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
628}
629
630TEST_F(TransactionApplicationTest, Flush_KeepsInTheQueueDifferentLayerId_LatchUnsignaled_Disabled) {
631 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
632 Flush_keepsInTheQueue(
633 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
634 createComposerState(/*layerId*/ 2, mFenceUnsignaled)));
635}
636
637TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnSignaled_Disabled) {
638 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
639 Flush_removesSignaledFromTheQueue(createComposerStateVector(
640 createComposerState(/*layerId*/ 1, mFenceSignaled)),
641 createComposerStateVector(
642 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
643}
644
645TEST_F(TransactionApplicationTest,
646 Flush_KeepInTheQueueDifferentApplyToken_LatchUnsignaled_Disabled) {
647 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
648 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
649 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
650 createComposerStateVector(
651 createComposerState(/*layerId*/ 2, mFenceSignaled)));
652 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
653}
654
655TEST_F(TransactionApplicationTest, Flush_KeepInTheQueueSameApplyToken_LatchUnsignaled_Disabled) {
656 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
657 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
658 createComposerState(/*layerId*/ 1, mFenceSignaled)),
659 createComposerStateVector(
660 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
661 /*updateApplyToken*/ false);
662 EXPECT_EQ(1ul, mFlinger.getTransactionCommittedSignals().size());
663}
664
665TEST_F(TransactionApplicationTest, Flush_KeepInTheUnsignaledTheQueue_LatchUnsignaled_Disabled) {
666 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
667 Flush_KeepsUnsignaledInTheQueue(createComposerStateVector(
668 createComposerState(/*layerId*/ 1, mFenceUnsignaled)),
669 createComposerStateVector(
670 createComposerState(/*layerId*/ 2, mFenceUnsignaled)),
671 /*updateApplyToken*/ false);
672 EXPECT_EQ(0ul, mFlinger.getTransactionCommittedSignals().size());
673}
674
675TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnsignaled_Always) {
676 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
677 Flush_removesFromTheQueue(
678 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceSignaled)));
679}
680
681TEST_F(TransactionApplicationTest, Flush_RemovesFromTheQueue_LatchUnsignaled_Always) {
682 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
683 Flush_removesFromTheQueue(
684 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled)));
685}
686
687TEST_F(TransactionApplicationTest, Flush_RemovesFromTheQueueSameLayerId_LatchUnsignaled_Always) {
688 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
689 Flush_removesFromTheQueue(
690 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
691 createComposerState(/*layerId*/ 1, mFenceSignaled)));
692}
693
694TEST_F(TransactionApplicationTest,
695 Flush_RemovesFromTheQueueDifferentLayerId_LatchUnsignaled_Always) {
696 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
697 Flush_removesFromTheQueue(
698 createComposerStateVector(createComposerState(/*layerId*/ 1, mFenceUnsignaled),
699 createComposerState(/*layerId*/ 2, mFenceSignaled)));
700}
701
702TEST_F(TransactionApplicationTest, Flush_RemovesSignaledFromTheQueue_LatchUnSignaled_Always) {
703 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
704 Flush_removesSignaledFromTheQueue(createComposerStateVector(
705 createComposerState(/*layerId*/ 1, mFenceSignaled)),
706 createComposerStateVector(
707 createComposerState(/*layerId*/ 2, mFenceSignaled2)));
708}
709
710TEST_F(TransactionApplicationTest,
711 Flush_RemovesFromTheQueueDifferentApplyToken_LatchUnsignaled_Always) {
712 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
713 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
714 createComposerState(/*layerId*/ 1, mFenceSignaled)),
715 createComposerStateVector(
716 createComposerState(/*layerId*/ 2,
717 mFenceUnsignaled)));
718}
719
720TEST_F(TransactionApplicationTest,
721 Flush_RemovesUnsignaledFromTheQueueSameApplyToken_LatchUnsignaled_Always) {
722 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
723 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
724 createComposerState(/*layerId*/ 1,
725 mFenceUnsignaled)),
726 createComposerStateVector(
727 createComposerState(/*layerId*/ 2, mFenceSignaled)),
728 /*updateApplyToken*/ false);
729}
730
731TEST_F(TransactionApplicationTest, Flush_RemovesUnsignaledFromTheQueue_LatchUnsignaled_Always) {
732 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
733 Flush_removesUnsignaledFromTheQueue(createComposerStateVector(
734 createComposerState(/*layerId*/ 1,
735 mFenceUnsignaled)),
736 createComposerStateVector(
737 createComposerState(/*layerId*/ 2,
738 mFenceUnsignaled)));
739}
740
Valerie Haud251afb2019-03-29 14:19:02 -0700741} // namespace android