1 /*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #undef LOG_TAG
18 #define LOG_TAG "CompositionTest"
19
20 #include <compositionengine/Display.h>
21 #include <compositionengine/mock/DisplaySurface.h>
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 #include <gui/LayerState.h>
25 #include <gui/SurfaceComposerClient.h>
26 #include <gui/fake/BufferData.h>
27 #include <log/log.h>
28 #include <ui/MockFence.h>
29 #include <utils/String8.h>
30 #include <vector>
31 #include <binder/Binder.h>
32
33 #include "FrontEnd/TransactionHandler.h"
34 #include "TestableSurfaceFlinger.h"
35 #include "TransactionState.h"
36
37 namespace android {
38
39 using testing::_;
40 using testing::Return;
41
42 using frontend::TransactionHandler;
43
44 constexpr nsecs_t TRANSACTION_TIMEOUT = s2ns(5);
45 class TransactionApplicationTest : public testing::Test {
46 public:
TransactionApplicationTest()47 TransactionApplicationTest() {
48 const ::testing::TestInfo* const test_info =
49 ::testing::UnitTest::GetInstance()->current_test_info();
50 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
51
52 mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
53 mFlinger.setupMockScheduler();
54 mFlinger.flinger()->addTransactionReadyFilters();
55 }
56
~TransactionApplicationTest()57 ~TransactionApplicationTest() {
58 const ::testing::TestInfo* const test_info =
59 ::testing::UnitTest::GetInstance()->current_test_info();
60 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
61 }
62
63 TestableSurfaceFlinger mFlinger;
64
65 struct TransactionInfo {
66 Vector<ComposerState> states;
67 Vector<DisplayState> displays;
68 uint32_t flags = 0;
69 sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
70 InputWindowCommands inputWindowCommands;
71 int64_t desiredPresentTime = 0;
72 bool isAutoTimestamp = true;
73 FrameTimelineInfo frameTimelineInfo;
74 std::vector<client_cache_t> uncacheBuffers;
75 uint64_t id = static_cast<uint64_t>(-1);
76 std::vector<uint64_t> mergedTransactionIds;
77 static_assert(0xffffffffffffffff == static_cast<uint64_t>(-1));
78 };
79
checkEqual(TransactionInfo info,TransactionState state)80 void checkEqual(TransactionInfo info, TransactionState state) {
81 EXPECT_EQ(0u, info.states.size());
82 EXPECT_EQ(0u, state.states.size());
83
84 EXPECT_EQ(0u, info.displays.size());
85 EXPECT_EQ(0u, state.displays.size());
86 EXPECT_EQ(info.flags, state.flags);
87 EXPECT_EQ(info.desiredPresentTime, state.desiredPresentTime);
88 }
89
setupSingle(TransactionInfo & transaction,uint32_t flags,int64_t desiredPresentTime,bool isAutoTimestamp,const FrameTimelineInfo & frameTimelineInfo)90 void setupSingle(TransactionInfo& transaction, uint32_t flags, int64_t desiredPresentTime,
91 bool isAutoTimestamp, const FrameTimelineInfo& frameTimelineInfo) {
92 mTransactionNumber++;
93 transaction.flags |= flags;
94 transaction.desiredPresentTime = desiredPresentTime;
95 transaction.isAutoTimestamp = isAutoTimestamp;
96 transaction.frameTimelineInfo = frameTimelineInfo;
97 }
98
NotPlacedOnTransactionQueue(uint32_t flags)99 void NotPlacedOnTransactionQueue(uint32_t flags) {
100 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
101 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
102 TransactionInfo transaction;
103 setupSingle(transaction, flags,
104 /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
105 FrameTimelineInfo{});
106 nsecs_t applicationTime = systemTime();
107 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
108 transaction.displays, transaction.flags,
109 transaction.applyToken, transaction.inputWindowCommands,
110 transaction.desiredPresentTime, transaction.isAutoTimestamp,
111 transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
112 transaction.id, transaction.mergedTransactionIds);
113
114 // If transaction is synchronous, SF applyTransactionState should time out (5s) wating for
115 // SF to commit the transaction. If this is animation, it should not time out waiting.
116 nsecs_t returnedTime = systemTime();
117 EXPECT_LE(returnedTime, applicationTime + TRANSACTION_TIMEOUT);
118 // Each transaction should have been placed on the transaction queue
119 auto& transactionQueue = mFlinger.getTransactionQueue();
120 EXPECT_FALSE(transactionQueue.isEmpty());
121 }
122
PlaceOnTransactionQueue(uint32_t flags)123 void PlaceOnTransactionQueue(uint32_t flags) {
124 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
125 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
126
127 // first check will see desired present time has not passed,
128 // but afterwards it will look like the desired present time has passed
129 nsecs_t time = systemTime();
130 TransactionInfo transaction;
131 setupSingle(transaction, flags, /*desiredPresentTime*/ time + s2ns(1), false,
132 FrameTimelineInfo{});
133 nsecs_t applicationSentTime = systemTime();
134 mFlinger.setTransactionState(transaction.frameTimelineInfo, transaction.states,
135 transaction.displays, transaction.flags,
136 transaction.applyToken, transaction.inputWindowCommands,
137 transaction.desiredPresentTime, transaction.isAutoTimestamp,
138 transaction.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
139 transaction.id, transaction.mergedTransactionIds);
140
141 nsecs_t returnedTime = systemTime();
142 EXPECT_LE(returnedTime, applicationSentTime + TRANSACTION_TIMEOUT);
143 // This transaction should have been placed on the transaction queue
144 auto& transactionQueue = mFlinger.getTransactionQueue();
145 EXPECT_FALSE(transactionQueue.isEmpty());
146 }
147
BlockedByPriorTransaction(uint32_t flags)148 void BlockedByPriorTransaction(uint32_t flags) {
149 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
150 nsecs_t time = systemTime();
151 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(2);
152
153 // transaction that should go on the pending thread
154 TransactionInfo transactionA;
155 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ time + s2ns(1), false,
156 FrameTimelineInfo{});
157
158 // transaction that would not have gone on the pending thread if not
159 // blocked
160 TransactionInfo transactionB;
161 setupSingle(transactionB, flags, /*desiredPresentTime*/ systemTime(),
162 /*isAutoTimestamp*/ true, FrameTimelineInfo{});
163
164 nsecs_t applicationSentTime = systemTime();
165 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
166 transactionA.displays, transactionA.flags,
167 transactionA.applyToken, transactionA.inputWindowCommands,
168 transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
169 transactionA.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
170 transactionA.id, transactionA.mergedTransactionIds);
171
172 // This thread should not have been blocked by the above transaction
173 // (5s is the timeout period that applyTransactionState waits for SF to
174 // commit the transaction)
175 EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
176 // transaction that would goes to pending transaciton queue.
177 mFlinger.flushTransactionQueues();
178
179 applicationSentTime = systemTime();
180 mFlinger.setTransactionState(transactionB.frameTimelineInfo, transactionB.states,
181 transactionB.displays, transactionB.flags,
182 transactionB.applyToken, transactionB.inputWindowCommands,
183 transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
184 transactionB.uncacheBuffers, mHasListenerCallbacks, mCallbacks,
185 transactionB.id, transactionB.mergedTransactionIds);
186
187 // this thread should have been blocked by the above transaction
188 // if this is an animation, this thread should be blocked for 5s
189 // in setTransactionState waiting for transactionA to flush. Otherwise,
190 // the transaction should be placed on the pending queue
191 EXPECT_LE(systemTime(), applicationSentTime + TRANSACTION_TIMEOUT);
192
193 // transaction that would goes to pending transaciton queue.
194 mFlinger.flushTransactionQueues();
195
196 // check that the transaction was applied.
197 auto transactionQueue = mFlinger.getPendingTransactionQueue();
198 EXPECT_EQ(0u, transactionQueue.size());
199 }
200
modulateVsync()201 void modulateVsync() {
202 static_cast<void>(
203 mFlinger.mutableScheduler().vsyncModulator().onRefreshRateChangeInitiated());
204 }
205
206 bool mHasListenerCallbacks = false;
207 std::vector<ListenerCallbacks> mCallbacks;
208 int mTransactionNumber = 0;
209 };
210
TEST_F(TransactionApplicationTest,AddToPendingQueue)211 TEST_F(TransactionApplicationTest, AddToPendingQueue) {
212 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
213 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
214
215 TransactionInfo transactionA; // transaction to go on pending queue
216 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
217 FrameTimelineInfo{});
218 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
219 transactionA.displays, transactionA.flags, transactionA.applyToken,
220 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
221 transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
222 mHasListenerCallbacks, mCallbacks, transactionA.id,
223 transactionA.mergedTransactionIds);
224
225 auto& transactionQueue = mFlinger.getTransactionQueue();
226 ASSERT_FALSE(transactionQueue.isEmpty());
227
228 auto transactionState = transactionQueue.pop().value();
229 checkEqual(transactionA, transactionState);
230 }
231
TEST_F(TransactionApplicationTest,Flush_RemovesFromQueue)232 TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
233 ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
234 EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
235
236 TransactionInfo transactionA; // transaction to go on pending queue
237 setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
238 FrameTimelineInfo{});
239 mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
240 transactionA.displays, transactionA.flags, transactionA.applyToken,
241 transactionA.inputWindowCommands, transactionA.desiredPresentTime,
242 transactionA.isAutoTimestamp, transactionA.uncacheBuffers,
243 mHasListenerCallbacks, mCallbacks, transactionA.id,
244 transactionA.mergedTransactionIds);
245
246 auto& transactionQueue = mFlinger.getTransactionQueue();
247 ASSERT_FALSE(transactionQueue.isEmpty());
248
249 // because flushing uses the cached expected present time, we send an empty
250 // transaction here (sending a null applyToken to fake it as from a
251 // different process) to re-query and reset the cached expected present time
252 TransactionInfo empty;
253 empty.applyToken = sp<IBinder>();
254 mFlinger.setTransactionState(empty.frameTimelineInfo, empty.states, empty.displays, empty.flags,
255 empty.applyToken, empty.inputWindowCommands,
256 empty.desiredPresentTime, empty.isAutoTimestamp,
257 empty.uncacheBuffers, mHasListenerCallbacks, mCallbacks, empty.id,
258 empty.mergedTransactionIds);
259
260 // flush transaction queue should flush as desiredPresentTime has
261 // passed
262 mFlinger.flushTransactionQueues();
263
264 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
265 }
266
TEST_F(TransactionApplicationTest,NotPlacedOnTransactionQueue_SyncInputWindows)267 TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_SyncInputWindows) {
268 NotPlacedOnTransactionQueue(/*flags*/ 0);
269 }
270
TEST_F(TransactionApplicationTest,PlaceOnTransactionQueue_SyncInputWindows)271 TEST_F(TransactionApplicationTest, PlaceOnTransactionQueue_SyncInputWindows) {
272 PlaceOnTransactionQueue(/*flags*/ 0);
273 }
274
TEST_F(TransactionApplicationTest,FromHandle)275 TEST_F(TransactionApplicationTest, FromHandle) {
276 sp<IBinder> badHandle;
277 auto ret = mFlinger.fromHandle(badHandle);
278 EXPECT_EQ(nullptr, ret.get());
279 }
280
281 class FakeExternalTexture : public renderengine::ExternalTexture {
282 const sp<GraphicBuffer> mEmptyBuffer = nullptr;
283 uint32_t mWidth;
284 uint32_t mHeight;
285 uint64_t mId;
286 PixelFormat mPixelFormat;
287 uint64_t mUsage;
288
289 public:
FakeExternalTexture(BufferData & bufferData)290 FakeExternalTexture(BufferData& bufferData)
291 : mWidth(bufferData.getWidth()),
292 mHeight(bufferData.getHeight()),
293 mId(bufferData.getId()),
294 mPixelFormat(bufferData.getPixelFormat()),
295 mUsage(bufferData.getUsage()) {}
getBuffer() const296 const sp<GraphicBuffer>& getBuffer() const { return mEmptyBuffer; }
hasSameBuffer(const renderengine::ExternalTexture & other) const297 bool hasSameBuffer(const renderengine::ExternalTexture& other) const override {
298 return getId() == other.getId();
299 }
getWidth() const300 uint32_t getWidth() const override { return mWidth; }
getHeight() const301 uint32_t getHeight() const override { return mHeight; }
getId() const302 uint64_t getId() const override { return mId; }
getPixelFormat() const303 PixelFormat getPixelFormat() const override { return mPixelFormat; }
getUsage() const304 uint64_t getUsage() const override { return mUsage; }
remapBuffer()305 void remapBuffer() override {}
306 ~FakeExternalTexture() = default;
307 };
308
309 class LatchUnsignaledTest : public TransactionApplicationTest {
310 public:
TearDown()311 void TearDown() override {
312 // Clear all transaction queues to release all transactions we sent
313 // in the tests. Otherwise, gmock complains about memory leaks.
314 while (!mFlinger.getTransactionQueue().isEmpty()) {
315 mFlinger.getTransactionQueue().pop();
316 }
317 mFlinger.getPendingTransactionQueue().clear();
318 mFlinger.commitTransactionsLocked(eTransactionMask);
319 mFlinger.mutableCurrentState().layersSortedByZ.clear();
320 mFlinger.mutableDrawingState().layersSortedByZ.clear();
321 }
322
fence(Fence::Status status)323 static sp<Fence> fence(Fence::Status status) {
324 const auto fence = sp<mock::MockFence>::make();
325 EXPECT_CALL(*fence, getStatus()).WillRepeatedly(Return(status));
326 return fence;
327 }
328
createComposerState(int layerId,sp<Fence> fence,uint64_t what,std::optional<sp<IBinder>> layerHandle=std::nullopt)329 ComposerState createComposerState(int layerId, sp<Fence> fence, uint64_t what,
330 std::optional<sp<IBinder>> layerHandle = std::nullopt) {
331 ComposerState state;
332 state.state.bufferData =
333 std::make_shared<fake::BufferData>(/* bufferId */ 123L, /* width */ 1,
334 /* height */ 2, /* pixelFormat */ 0,
335 /* outUsage */ 0);
336 state.state.bufferData->acquireFence = std::move(fence);
337 state.state.layerId = layerId;
338 state.state.surface = layerHandle.value_or(
339 sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
340 ->getHandle());
341 state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
342
343 state.state.what = what;
344 if (what & layer_state_t::eCropChanged) {
345 state.state.crop = Rect(1, 2, 3, 4);
346 }
347 if (what & layer_state_t::eFlagsChanged) {
348 state.state.flags = layer_state_t::eEnableBackpressure;
349 state.state.mask = layer_state_t::eEnableBackpressure;
350 }
351
352 return state;
353 }
354
createTransactionInfo(const sp<IBinder> & applyToken,const std::vector<ComposerState> & states)355 TransactionInfo createTransactionInfo(const sp<IBinder>& applyToken,
356 const std::vector<ComposerState>& states) {
357 TransactionInfo transaction;
358 const uint32_t kFlags = 0;
359 const nsecs_t kDesiredPresentTime = systemTime();
360 const bool kIsAutoTimestamp = true;
361 const auto kFrameTimelineInfo = FrameTimelineInfo{};
362
363 setupSingle(transaction, kFlags, kDesiredPresentTime, kIsAutoTimestamp, kFrameTimelineInfo);
364 transaction.applyToken = applyToken;
365 for (const auto& state : states) {
366 transaction.states.push_back(state);
367 }
368
369 return transaction;
370 }
371
setTransactionStates(const std::vector<TransactionInfo> & transactions,size_t expectedTransactionsPending)372 void setTransactionStates(const std::vector<TransactionInfo>& transactions,
373 size_t expectedTransactionsPending) {
374 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
375 EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
376
377 for (auto transaction : transactions) {
378 std::vector<ResolvedComposerState> resolvedStates;
379 resolvedStates.reserve(transaction.states.size());
380 for (auto& state : transaction.states) {
381 ResolvedComposerState resolvedState;
382 resolvedState.state = std::move(state.state);
383 resolvedState.externalTexture =
384 std::make_shared<FakeExternalTexture>(*resolvedState.state.bufferData);
385 resolvedStates.emplace_back(resolvedState);
386 }
387
388 TransactionState transactionState(transaction.frameTimelineInfo, resolvedStates,
389 transaction.displays, transaction.flags,
390 transaction.applyToken,
391 transaction.inputWindowCommands,
392 transaction.desiredPresentTime,
393 transaction.isAutoTimestamp, {}, systemTime(),
394 mHasListenerCallbacks, mCallbacks, getpid(),
395 static_cast<int>(getuid()), transaction.id,
396 transaction.mergedTransactionIds);
397 mFlinger.setTransactionStateInternal(transactionState);
398 }
399 mFlinger.flushTransactionQueues();
400 EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
401 EXPECT_EQ(expectedTransactionsPending, mFlinger.getPendingTransactionCount());
402 }
403 };
404
405 class LatchUnsignaledAutoSingleLayerTest : public LatchUnsignaledTest {
406 public:
SetUp()407 void SetUp() override {
408 LatchUnsignaledTest::SetUp();
409 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::AutoSingleLayer;
410 }
411 };
412
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_RemovesSingleSignaledFromTheQueue)413 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleSignaledFromTheQueue) {
414 const sp<IBinder> kApplyToken =
415 IInterface::asBinder(TransactionCompletedListener::getIInstance());
416 const auto kLayerId = 1;
417 const auto kExpectedTransactionsPending = 0u;
418
419 const auto signaledTransaction =
420 createTransactionInfo(kApplyToken,
421 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
422 layer_state_t::eBufferChanged)});
423 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
424 }
425
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_RemovesSingleUnSignaledFromTheQueue)426 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSingleUnSignaledFromTheQueue) {
427 const sp<IBinder> kApplyToken =
428 IInterface::asBinder(TransactionCompletedListener::getIInstance());
429 const auto kLayerId = 1;
430 const auto kExpectedTransactionsPending = 0u;
431
432 const auto unsignaledTransaction =
433 createTransactionInfo(kApplyToken,
434 {
435 createComposerState(kLayerId,
436 fence(Fence::Status::Unsignaled),
437 layer_state_t::eBufferChanged),
438 });
439 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
440 }
441
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange)442 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferCropChange) {
443 const sp<IBinder> kApplyToken =
444 IInterface::asBinder(TransactionCompletedListener::getIInstance());
445 const auto kLayerId = 1;
446 const auto kExpectedTransactionsPending = 1u;
447
448 const auto unsignaledTransaction =
449 createTransactionInfo(kApplyToken,
450 {
451 createComposerState(kLayerId,
452 fence(Fence::Status::Unsignaled),
453 layer_state_t::eCropChanged |
454 layer_state_t::
455 eBufferChanged),
456 });
457 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
458 }
459
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed)460 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsUnSignaledInTheQueue_NonBufferChangeClubed) {
461 const sp<IBinder> kApplyToken =
462 IInterface::asBinder(TransactionCompletedListener::getIInstance());
463 const auto kLayerId = 1;
464 const auto kExpectedTransactionsPending = 1u;
465
466 const auto unsignaledTransaction =
467 createTransactionInfo(kApplyToken,
468 {
469 createComposerState(kLayerId,
470 fence(Fence::Status::Unsignaled),
471 layer_state_t::eCropChanged |
472 layer_state_t::
473 eBufferChanged),
474 });
475 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
476 }
477
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsInTheQueueSameApplyTokenMultiState)478 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueueSameApplyTokenMultiState) {
479 const sp<IBinder> kApplyToken =
480 IInterface::asBinder(TransactionCompletedListener::getIInstance());
481 const auto kLayerId = 1;
482 const auto kExpectedTransactionsPending = 1u;
483
484 const auto mixedTransaction =
485 createTransactionInfo(kApplyToken,
486 {
487 createComposerState(kLayerId,
488 fence(Fence::Status::Unsignaled),
489 layer_state_t::eBufferChanged),
490 createComposerState(kLayerId,
491 fence(Fence::Status::Signaled),
492 layer_state_t::eBufferChanged),
493 });
494 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
495 }
496
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsInTheQueue_MultipleStateTransaction)497 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsInTheQueue_MultipleStateTransaction) {
498 const sp<IBinder> kApplyToken =
499 IInterface::asBinder(TransactionCompletedListener::getIInstance());
500 const auto kLayerId1 = 1;
501 const auto kLayerId2 = 2;
502 const auto kExpectedTransactionsPending = 1u;
503
504 const auto mixedTransaction =
505 createTransactionInfo(kApplyToken,
506 {
507 createComposerState(kLayerId1,
508 fence(Fence::Status::Unsignaled),
509 layer_state_t::eBufferChanged),
510 createComposerState(kLayerId2,
511 fence(Fence::Status::Signaled),
512 layer_state_t::eBufferChanged),
513 });
514 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
515 }
516
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_RemovesSignaledFromTheQueue)517 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_RemovesSignaledFromTheQueue) {
518 const sp<IBinder> kApplyToken =
519 IInterface::asBinder(TransactionCompletedListener::getIInstance());
520 const auto kLayerId1 = 1;
521 const auto kLayerId2 = 2;
522 const auto kExpectedTransactionsPending = 0u;
523
524 const auto signaledTransaction =
525 createTransactionInfo(kApplyToken,
526 {
527 createComposerState(kLayerId1,
528 fence(Fence::Status::Signaled),
529 layer_state_t::eBufferChanged),
530 });
531 const auto signaledTransaction2 =
532 createTransactionInfo(kApplyToken,
533 {
534 createComposerState(kLayerId2,
535 fence(Fence::Status::Signaled),
536 layer_state_t::eBufferChanged),
537 });
538 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
539 }
540
TEST_F(LatchUnsignaledAutoSingleLayerTest,UnsignaledNotAppliedWhenThereAreSignaled_UnsignaledFirst)541 TEST_F(LatchUnsignaledAutoSingleLayerTest,
542 UnsignaledNotAppliedWhenThereAreSignaled_UnsignaledFirst) {
543 const sp<IBinder> kApplyToken1 =
544 IInterface::asBinder(TransactionCompletedListener::getIInstance());
545 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
546 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
547 const auto kLayerId1 = 1;
548 const auto kLayerId2 = 2;
549 const auto kExpectedTransactionsPending = 1u;
550
551 const auto unsignaledTransaction =
552 createTransactionInfo(kApplyToken1,
553 {
554 createComposerState(kLayerId1,
555 fence(Fence::Status::Unsignaled),
556 layer_state_t::eBufferChanged),
557 });
558
559 const auto signaledTransaction =
560 createTransactionInfo(kApplyToken2,
561 {
562 createComposerState(kLayerId2,
563 fence(Fence::Status::Signaled),
564 layer_state_t::eBufferChanged),
565 });
566 const auto signaledTransaction2 =
567 createTransactionInfo(kApplyToken3,
568 {
569 createComposerState(kLayerId2,
570 fence(Fence::Status::Signaled),
571 layer_state_t::eBufferChanged),
572 });
573
574 setTransactionStates({unsignaledTransaction, signaledTransaction, signaledTransaction2},
575 kExpectedTransactionsPending);
576 }
577
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsTransactionInTheQueueSameApplyToken)578 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueueSameApplyToken) {
579 const sp<IBinder> kApplyToken =
580 IInterface::asBinder(TransactionCompletedListener::getIInstance());
581 const auto kLayerId1 = 1;
582 const auto kLayerId2 = 2;
583 const auto kExpectedTransactionsPending = 1u;
584
585 const auto unsignaledTransaction =
586 createTransactionInfo(kApplyToken,
587 {
588 createComposerState(kLayerId1,
589 fence(Fence::Status::Unsignaled),
590 layer_state_t::eBufferChanged),
591 });
592 const auto signaledTransaction =
593 createTransactionInfo(kApplyToken,
594 {
595 createComposerState(kLayerId2,
596 fence(Fence::Status::Signaled),
597 layer_state_t::eBufferChanged),
598 });
599 setTransactionStates({unsignaledTransaction, signaledTransaction},
600 kExpectedTransactionsPending);
601 }
602
TEST_F(LatchUnsignaledAutoSingleLayerTest,Flush_KeepsTransactionInTheQueue)603 TEST_F(LatchUnsignaledAutoSingleLayerTest, Flush_KeepsTransactionInTheQueue) {
604 const sp<IBinder> kApplyToken1 =
605 IInterface::asBinder(TransactionCompletedListener::getIInstance());
606 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
607 const auto kLayerId1 = 1;
608 const auto kLayerId2 = 2;
609 const auto kExpectedTransactionsPending = 1u;
610
611 const auto unsignaledTransaction =
612 createTransactionInfo(kApplyToken1,
613 {
614 createComposerState(kLayerId1,
615 fence(Fence::Status::Unsignaled),
616 layer_state_t::eBufferChanged),
617 });
618 const auto unsignaledTransaction2 =
619 createTransactionInfo(kApplyToken2,
620 {
621 createComposerState(kLayerId2,
622 fence(Fence::Status::Unsignaled),
623 layer_state_t::eBufferChanged),
624 });
625 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
626 kExpectedTransactionsPending);
627 }
628
TEST_F(LatchUnsignaledAutoSingleLayerTest,DontLatchUnsignaledWhenEarlyOffset)629 TEST_F(LatchUnsignaledAutoSingleLayerTest, DontLatchUnsignaledWhenEarlyOffset) {
630 const sp<IBinder> kApplyToken =
631 IInterface::asBinder(TransactionCompletedListener::getIInstance());
632 const auto kLayerId = 1;
633 const auto kExpectedTransactionsPending = 1u;
634
635 const auto unsignaledTransaction =
636 createTransactionInfo(kApplyToken,
637 {
638 createComposerState(kLayerId,
639 fence(Fence::Status::Unsignaled),
640 layer_state_t::eBufferChanged),
641 });
642
643 modulateVsync();
644 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
645 }
646
TEST_F(LatchUnsignaledAutoSingleLayerTest,UnsignaledNotAppliedWhenThereAreSignaled_SignaledFirst)647 TEST_F(LatchUnsignaledAutoSingleLayerTest, UnsignaledNotAppliedWhenThereAreSignaled_SignaledFirst) {
648 const sp<IBinder> kApplyToken1 =
649 IInterface::asBinder(TransactionCompletedListener::getIInstance());
650 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
651 const sp<IBinder> kApplyToken3 = sp<BBinder>::make();
652 const auto kLayerId1 = 1;
653 const auto kLayerId2 = 2;
654 const auto kExpectedTransactionsPending = 1u;
655
656 const auto signaledTransaction =
657 createTransactionInfo(kApplyToken1,
658 {
659 createComposerState(kLayerId1,
660 fence(Fence::Status::Signaled),
661 layer_state_t::eBufferChanged),
662 });
663 const auto signaledTransaction2 =
664 createTransactionInfo(kApplyToken2,
665 {
666 createComposerState(kLayerId1,
667 fence(Fence::Status::Signaled),
668 layer_state_t::eBufferChanged),
669 });
670 const auto unsignaledTransaction =
671 createTransactionInfo(kApplyToken3,
672 {
673 createComposerState(kLayerId2,
674 fence(Fence::Status::Unsignaled),
675 layer_state_t::eBufferChanged),
676 });
677
678 setTransactionStates({signaledTransaction, signaledTransaction2, unsignaledTransaction},
679 kExpectedTransactionsPending);
680 }
681
682 class LatchUnsignaledDisabledTest : public LatchUnsignaledTest {
683 public:
SetUp()684 void SetUp() override {
685 LatchUnsignaledTest::SetUp();
686 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Disabled;
687 }
688 };
689
TEST_F(LatchUnsignaledDisabledTest,Flush_RemovesSignaledFromTheQueue)690 TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue) {
691 const sp<IBinder> kApplyToken =
692 IInterface::asBinder(TransactionCompletedListener::getIInstance());
693 const auto kLayerId = 1;
694 const auto kExpectedTransactionsPending = 0u;
695
696 const auto signaledTransaction =
697 createTransactionInfo(kApplyToken,
698 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
699 layer_state_t::eBufferChanged)});
700 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
701 }
702
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepsInTheQueue)703 TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueue) {
704 const sp<IBinder> kApplyToken =
705 IInterface::asBinder(TransactionCompletedListener::getIInstance());
706 const auto kLayerId = 1;
707 const auto kExpectedTransactionsPending = 1u;
708
709 const auto unsignaledTransaction =
710 createTransactionInfo(kApplyToken,
711 {
712 createComposerState(kLayerId,
713 fence(Fence::Status::Unsignaled),
714 layer_state_t::eBufferChanged),
715 });
716 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
717 }
718
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepsInTheQueueSameLayerId)719 TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueSameLayerId) {
720 const sp<IBinder> kApplyToken =
721 IInterface::asBinder(TransactionCompletedListener::getIInstance());
722 const auto kLayerId = 1;
723 const auto kExpectedTransactionsPending = 1u;
724
725 const auto unsignaledTransaction =
726 createTransactionInfo(kApplyToken,
727 {
728 createComposerState(kLayerId,
729 fence(Fence::Status::Unsignaled),
730 layer_state_t::eBufferChanged),
731 createComposerState(kLayerId,
732 fence(Fence::Status::Unsignaled),
733 layer_state_t::eBufferChanged),
734 });
735 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
736 }
737
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepsInTheQueueDifferentLayerId)738 TEST_F(LatchUnsignaledDisabledTest, Flush_KeepsInTheQueueDifferentLayerId) {
739 const sp<IBinder> kApplyToken =
740 IInterface::asBinder(TransactionCompletedListener::getIInstance());
741 const auto kLayerId1 = 1;
742 const auto kLayerId2 = 2;
743 const auto kExpectedTransactionsPending = 1u;
744
745 const auto unsignaledTransaction =
746 createTransactionInfo(kApplyToken,
747 {
748 createComposerState(kLayerId1,
749 fence(Fence::Status::Unsignaled),
750 layer_state_t::eBufferChanged),
751 createComposerState(kLayerId2,
752 fence(Fence::Status::Unsignaled),
753 layer_state_t::eBufferChanged),
754 });
755 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
756 }
757
TEST_F(LatchUnsignaledDisabledTest,Flush_RemovesSignaledFromTheQueue_MultipleLayers)758 TEST_F(LatchUnsignaledDisabledTest, Flush_RemovesSignaledFromTheQueue_MultipleLayers) {
759 const sp<IBinder> kApplyToken =
760 IInterface::asBinder(TransactionCompletedListener::getIInstance());
761 const auto kLayerId1 = 1;
762 const auto kLayerId2 = 2;
763 const auto kExpectedTransactionsPending = 0u;
764
765 const auto signaledTransaction =
766 createTransactionInfo(kApplyToken,
767 {
768 createComposerState(kLayerId1,
769 fence(Fence::Status::Signaled),
770 layer_state_t::eBufferChanged),
771 });
772 const auto signaledTransaction2 =
773 createTransactionInfo(kApplyToken,
774 {
775 createComposerState(kLayerId2,
776 fence(Fence::Status::Signaled),
777 layer_state_t::eBufferChanged),
778 });
779 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
780 }
781
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepInTheQueueDifferentApplyToken)782 TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueDifferentApplyToken) {
783 const sp<IBinder> kApplyToken1 =
784 IInterface::asBinder(TransactionCompletedListener::getIInstance());
785 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
786 const auto kLayerId1 = 1;
787 const auto kLayerId2 = 2;
788 const auto kExpectedTransactionsPending = 1u;
789
790 const auto unsignaledTransaction =
791 createTransactionInfo(kApplyToken1,
792 {
793 createComposerState(kLayerId1,
794 fence(Fence::Status::Unsignaled),
795 layer_state_t::eBufferChanged),
796 });
797 const auto signaledTransaction =
798 createTransactionInfo(kApplyToken2,
799 {
800 createComposerState(kLayerId2,
801 fence(Fence::Status::Signaled),
802 layer_state_t::eBufferChanged),
803 });
804 setTransactionStates({unsignaledTransaction, signaledTransaction},
805 kExpectedTransactionsPending);
806 }
807
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepInTheQueueSameApplyToken)808 TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheQueueSameApplyToken) {
809 const sp<IBinder> kApplyToken =
810 IInterface::asBinder(TransactionCompletedListener::getIInstance());
811 const auto kLayerId1 = 1;
812 const auto kLayerId2 = 2;
813 const auto kExpectedTransactionsPending = 1u;
814
815 const auto signaledTransaction =
816 createTransactionInfo(kApplyToken,
817 {
818 createComposerState(kLayerId1,
819 fence(Fence::Status::Signaled),
820 layer_state_t::eBufferChanged),
821 });
822 const auto unsignaledTransaction =
823 createTransactionInfo(kApplyToken,
824 {
825 createComposerState(kLayerId2,
826 fence(Fence::Status::Unsignaled),
827 layer_state_t::eBufferChanged),
828 });
829 setTransactionStates({signaledTransaction, unsignaledTransaction},
830 kExpectedTransactionsPending);
831 }
832
TEST_F(LatchUnsignaledDisabledTest,Flush_KeepInTheUnsignaledTheQueue)833 TEST_F(LatchUnsignaledDisabledTest, Flush_KeepInTheUnsignaledTheQueue) {
834 const sp<IBinder> kApplyToken =
835 IInterface::asBinder(TransactionCompletedListener::getIInstance());
836 const auto kLayerId1 = 1;
837 const auto kLayerId2 = 2;
838 const auto kExpectedTransactionsPending = 2u;
839
840 const auto unsignaledTransaction =
841 createTransactionInfo(kApplyToken,
842 {
843 createComposerState(kLayerId1,
844 fence(Fence::Status::Unsignaled),
845 layer_state_t::eBufferChanged),
846 });
847 const auto unsignaledTransaction2 =
848 createTransactionInfo(kApplyToken,
849 {
850 createComposerState(kLayerId2,
851 fence(Fence::Status::Unsignaled),
852 layer_state_t::eBufferChanged),
853 });
854 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
855 kExpectedTransactionsPending);
856 }
857
858 class LatchUnsignaledAlwaysTest : public LatchUnsignaledTest {
859 public:
SetUp()860 void SetUp() override {
861 LatchUnsignaledTest::SetUp();
862 SurfaceFlinger::enableLatchUnsignaledConfig = LatchUnsignaledConfig::Always;
863 }
864 };
865
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesSignaledFromTheQueue)866 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesSignaledFromTheQueue) {
867 const sp<IBinder> kApplyToken =
868 IInterface::asBinder(TransactionCompletedListener::getIInstance());
869 const auto kLayerId = 1;
870 const auto kExpectedTransactionsPending = 0u;
871
872 const auto signaledTransaction =
873 createTransactionInfo(kApplyToken,
874 {createComposerState(kLayerId, fence(Fence::Status::Signaled),
875 layer_state_t::eBufferChanged)});
876 setTransactionStates({signaledTransaction}, kExpectedTransactionsPending);
877 }
878
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesFromTheQueue)879 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueue) {
880 const sp<IBinder> kApplyToken =
881 IInterface::asBinder(TransactionCompletedListener::getIInstance());
882 const auto kLayerId = 1;
883 const auto kExpectedTransactionsPending = 0u;
884
885 const auto unsignaledTransaction =
886 createTransactionInfo(kApplyToken,
887 {createComposerState(kLayerId, fence(Fence::Status::Unsignaled),
888 layer_state_t::eBufferChanged)});
889 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
890 }
891
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesFromTheQueueSameLayerId)892 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueueSameLayerId) {
893 const sp<IBinder> kApplyToken =
894 IInterface::asBinder(TransactionCompletedListener::getIInstance());
895 const auto kLayerId = 1;
896 const auto kExpectedTransactionsPending = 0u;
897
898 const auto mixedTransaction =
899 createTransactionInfo(kApplyToken,
900 {createComposerState(kLayerId, fence(Fence::Status::Unsignaled),
901 layer_state_t::eBufferChanged),
902 createComposerState(kLayerId, fence(Fence::Status::Signaled),
903 layer_state_t::eBufferChanged)});
904 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
905 }
906
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesFromTheQueueDifferentLayerId)907 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueueDifferentLayerId) {
908 const sp<IBinder> kApplyToken =
909 IInterface::asBinder(TransactionCompletedListener::getIInstance());
910 const auto kLayerId1 = 1;
911 const auto kLayerId2 = 2;
912 const auto kExpectedTransactionsPending = 0u;
913
914 const auto mixedTransaction =
915 createTransactionInfo(kApplyToken,
916 {createComposerState(kLayerId1, fence(Fence::Status::Unsignaled),
917 layer_state_t::eBufferChanged),
918 createComposerState(kLayerId2, fence(Fence::Status::Signaled),
919 layer_state_t::eBufferChanged)});
920 setTransactionStates({mixedTransaction}, kExpectedTransactionsPending);
921 }
922
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesSignaledFromTheQueue_MultipleLayers)923 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesSignaledFromTheQueue_MultipleLayers) {
924 const sp<IBinder> kApplyToken =
925 IInterface::asBinder(TransactionCompletedListener::getIInstance());
926 const auto kLayerId1 = 1;
927 const auto kLayerId2 = 2;
928 const auto kExpectedTransactionsPending = 0u;
929
930 const auto signaledTransaction =
931 createTransactionInfo(kApplyToken,
932 {
933 createComposerState(kLayerId1,
934 fence(Fence::Status::Signaled),
935 layer_state_t::eBufferChanged),
936 });
937 const auto signaledTransaction2 =
938 createTransactionInfo(kApplyToken,
939 {
940 createComposerState(kLayerId2,
941 fence(Fence::Status::Signaled),
942 layer_state_t::eBufferChanged),
943 });
944 setTransactionStates({signaledTransaction, signaledTransaction2}, kExpectedTransactionsPending);
945 }
946
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesFromTheQueueDifferentApplyToken)947 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesFromTheQueueDifferentApplyToken) {
948 const sp<IBinder> kApplyToken1 =
949 IInterface::asBinder(TransactionCompletedListener::getIInstance());
950 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
951 const auto kLayerId1 = 1;
952 const auto kLayerId2 = 2;
953 const auto kExpectedTransactionsPending = 0u;
954
955 const auto signaledTransaction =
956 createTransactionInfo(kApplyToken1,
957 {
958 createComposerState(kLayerId1,
959 fence(Fence::Status::Signaled),
960 layer_state_t::eBufferChanged),
961 });
962 const auto unsignaledTransaction =
963 createTransactionInfo(kApplyToken2,
964 {
965 createComposerState(kLayerId2,
966 fence(Fence::Status::Unsignaled),
967 layer_state_t::eBufferChanged),
968 });
969 setTransactionStates({signaledTransaction, unsignaledTransaction},
970 kExpectedTransactionsPending);
971 }
972
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesUnsignaledFromTheQueueSameApplyToken)973 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesUnsignaledFromTheQueueSameApplyToken) {
974 const sp<IBinder> kApplyToken =
975 IInterface::asBinder(TransactionCompletedListener::getIInstance());
976 const auto kLayerId1 = 1;
977 const auto kLayerId2 = 2;
978 const auto kExpectedTransactionsPending = 0u;
979
980 const auto unsignaledTransaction =
981 createTransactionInfo(kApplyToken,
982 {
983 createComposerState(kLayerId1,
984 fence(Fence::Status::Unsignaled),
985 layer_state_t::eBufferChanged),
986 });
987 const auto signaledTransaction =
988 createTransactionInfo(kApplyToken,
989 {
990 createComposerState(kLayerId2,
991 fence(Fence::Status::Signaled),
992 layer_state_t::eBufferChanged),
993 });
994 setTransactionStates({unsignaledTransaction, signaledTransaction},
995 kExpectedTransactionsPending);
996 }
997
TEST_F(LatchUnsignaledAlwaysTest,Flush_RemovesUnsignaledFromTheQueue)998 TEST_F(LatchUnsignaledAlwaysTest, Flush_RemovesUnsignaledFromTheQueue) {
999 const sp<IBinder> kApplyToken1 =
1000 IInterface::asBinder(TransactionCompletedListener::getIInstance());
1001 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
1002 const auto kLayerId1 = 1;
1003 const auto kLayerId2 = 2;
1004 const auto kExpectedTransactionsPending = 0u;
1005
1006 const auto unsignaledTransaction =
1007 createTransactionInfo(kApplyToken1,
1008 {
1009 createComposerState(kLayerId1,
1010 fence(Fence::Status::Unsignaled),
1011 layer_state_t::eBufferChanged),
1012 });
1013 const auto unsignaledTransaction2 =
1014 createTransactionInfo(kApplyToken2,
1015 {
1016 createComposerState(kLayerId2,
1017 fence(Fence::Status::Unsignaled),
1018 layer_state_t::eBufferChanged),
1019 });
1020 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
1021 kExpectedTransactionsPending);
1022 }
1023
TEST_F(LatchUnsignaledAlwaysTest,RespectsBackPressureFlag)1024 TEST_F(LatchUnsignaledAlwaysTest, RespectsBackPressureFlag) {
1025 const sp<IBinder> kApplyToken1 =
1026 IInterface::asBinder(TransactionCompletedListener::getIInstance());
1027 const sp<IBinder> kApplyToken2 = sp<BBinder>::make();
1028 const auto kLayerId1 = 1;
1029 const auto kExpectedTransactionsPending = 1u;
1030 auto layer =
1031 sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}));
1032 auto layerHandle = layer->getHandle();
1033 const auto setBackPressureFlagTransaction =
1034 createTransactionInfo(kApplyToken1,
1035 {createComposerState(kLayerId1, fence(Fence::Status::Unsignaled),
1036 layer_state_t::eBufferChanged |
1037 layer_state_t::eFlagsChanged,
1038 {layerHandle})});
1039 setTransactionStates({setBackPressureFlagTransaction}, 0u);
1040
1041 const auto unsignaledTransaction =
1042 createTransactionInfo(kApplyToken1,
1043 {
1044 createComposerState(kLayerId1,
1045 fence(Fence::Status::Unsignaled),
1046 layer_state_t::eBufferChanged,
1047 {layerHandle}),
1048 });
1049 const auto unsignaledTransaction2 =
1050 createTransactionInfo(kApplyToken1,
1051 {
1052 createComposerState(kLayerId1,
1053 fence(Fence::Status::Unsignaled),
1054 layer_state_t::eBufferChanged,
1055 {layerHandle}),
1056 });
1057 setTransactionStates({unsignaledTransaction, unsignaledTransaction2},
1058 kExpectedTransactionsPending);
1059 }
1060
TEST_F(LatchUnsignaledAlwaysTest,LatchUnsignaledWhenEarlyOffset)1061 TEST_F(LatchUnsignaledAlwaysTest, LatchUnsignaledWhenEarlyOffset) {
1062 const sp<IBinder> kApplyToken =
1063 IInterface::asBinder(TransactionCompletedListener::getIInstance());
1064 const auto kLayerId = 1;
1065 const auto kExpectedTransactionsPending = 0u;
1066
1067 const auto unsignaledTransaction =
1068 createTransactionInfo(kApplyToken,
1069 {
1070 createComposerState(kLayerId,
1071 fence(Fence::Status::Unsignaled),
1072 layer_state_t::eBufferChanged),
1073 });
1074
1075 modulateVsync();
1076 setTransactionStates({unsignaledTransaction}, kExpectedTransactionsPending);
1077 }
1078
TEST(TransactionHandlerTest,QueueTransaction)1079 TEST(TransactionHandlerTest, QueueTransaction) {
1080 TransactionHandler handler;
1081 TransactionState transaction;
1082 transaction.applyToken = sp<BBinder>::make();
1083 transaction.id = 42;
1084 handler.queueTransaction(std::move(transaction));
1085 std::vector<TransactionState> transactionsReadyToBeApplied = handler.flushTransactions();
1086
1087 EXPECT_EQ(transactionsReadyToBeApplied.size(), 1u);
1088 EXPECT_EQ(transactionsReadyToBeApplied.front().id, 42u);
1089 }
1090
TEST(TransactionHandlerTest,TransactionsKeepTrackOfDirectMerges)1091 TEST(TransactionHandlerTest, TransactionsKeepTrackOfDirectMerges) {
1092 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
1093
1094 uint64_t transaction2Id = transaction2.getId();
1095 uint64_t transaction3Id = transaction3.getId();
1096 EXPECT_NE(transaction2Id, transaction3Id);
1097
1098 transaction1.merge(std::move(transaction2));
1099 transaction1.merge(std::move(transaction3));
1100
1101 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
1102 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
1103 EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction2Id);
1104 }
1105
TEST(TransactionHandlerTest,TransactionsKeepTrackOfIndirectMerges)1106 TEST(TransactionHandlerTest, TransactionsKeepTrackOfIndirectMerges) {
1107 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3, transaction4;
1108
1109 uint64_t transaction2Id = transaction2.getId();
1110 uint64_t transaction3Id = transaction3.getId();
1111 uint64_t transaction4Id = transaction4.getId();
1112 EXPECT_NE(transaction2Id, transaction3Id);
1113 EXPECT_NE(transaction2Id, transaction4Id);
1114 EXPECT_NE(transaction3Id, transaction4Id);
1115
1116 transaction4.merge(std::move(transaction2));
1117 transaction4.merge(std::move(transaction3));
1118
1119 EXPECT_EQ(transaction4.getMergedTransactionIds().size(), 2u);
1120 EXPECT_EQ(transaction4.getMergedTransactionIds()[0], transaction3Id);
1121 EXPECT_EQ(transaction4.getMergedTransactionIds()[1], transaction2Id);
1122
1123 transaction1.merge(std::move(transaction4));
1124
1125 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 3u);
1126 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction4Id);
1127 EXPECT_EQ(transaction1.getMergedTransactionIds()[1], transaction3Id);
1128 EXPECT_EQ(transaction1.getMergedTransactionIds()[2], transaction2Id);
1129 }
1130
TEST(TransactionHandlerTest,TransactionMergesAreCleared)1131 TEST(TransactionHandlerTest, TransactionMergesAreCleared) {
1132 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
1133
1134 transaction1.merge(std::move(transaction2));
1135 transaction1.merge(std::move(transaction3));
1136
1137 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 2u);
1138
1139 transaction1.clear();
1140
1141 EXPECT_EQ(transaction1.getMergedTransactionIds().empty(), true);
1142 }
1143
TEST(TransactionHandlerTest,TransactionMergesAreCapped)1144 TEST(TransactionHandlerTest, TransactionMergesAreCapped) {
1145 SurfaceComposerClient::Transaction transaction;
1146 std::vector<uint64_t> mergedTransactionIds;
1147
1148 for (uint i = 0; i < 20u; i++) {
1149 SurfaceComposerClient::Transaction transactionToMerge;
1150 mergedTransactionIds.push_back(transactionToMerge.getId());
1151 transaction.merge(std::move(transactionToMerge));
1152 }
1153
1154 // Keeps latest 10 merges in order of merge recency
1155 EXPECT_EQ(transaction.getMergedTransactionIds().size(), 10u);
1156 for (uint i = 0; i < 10u; i++) {
1157 EXPECT_EQ(transaction.getMergedTransactionIds()[i],
1158 mergedTransactionIds[mergedTransactionIds.size() - 1 - i]);
1159 }
1160 }
1161
TEST(TransactionHandlerTest,KeepsMergesFromMoreRecentMerge)1162 TEST(TransactionHandlerTest, KeepsMergesFromMoreRecentMerge) {
1163 SurfaceComposerClient::Transaction transaction1, transaction2, transaction3;
1164 std::vector<uint64_t> mergedTransactionIds1, mergedTransactionIds2, mergedTransactionIds3;
1165 uint64_t transaction2Id = transaction2.getId();
1166 uint64_t transaction3Id = transaction3.getId();
1167
1168 for (uint i = 0; i < 20u; i++) {
1169 SurfaceComposerClient::Transaction transactionToMerge;
1170 mergedTransactionIds1.push_back(transactionToMerge.getId());
1171 transaction1.merge(std::move(transactionToMerge));
1172 }
1173
1174 for (uint i = 0; i < 5u; i++) {
1175 SurfaceComposerClient::Transaction transactionToMerge;
1176 mergedTransactionIds2.push_back(transactionToMerge.getId());
1177 transaction2.merge(std::move(transactionToMerge));
1178 }
1179
1180 transaction1.merge(std::move(transaction2));
1181 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1182 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction2Id);
1183 for (uint i = 0; i < 5u; i++) {
1184 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1u],
1185 mergedTransactionIds2[mergedTransactionIds2.size() - 1 - i]);
1186 }
1187 for (uint i = 0; i < 4u; i++) {
1188 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 6u],
1189 mergedTransactionIds1[mergedTransactionIds1.size() - 1 - i]);
1190 }
1191
1192 for (uint i = 0; i < 20u; i++) {
1193 SurfaceComposerClient::Transaction transactionToMerge;
1194 mergedTransactionIds3.push_back(transactionToMerge.getId());
1195 transaction3.merge(std::move(transactionToMerge));
1196 }
1197
1198 transaction1.merge(std::move(transaction3));
1199 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1200 EXPECT_EQ(transaction1.getMergedTransactionIds()[0], transaction3Id);
1201 for (uint i = 0; i < 9u; i++) {
1202 EXPECT_EQ(transaction1.getMergedTransactionIds()[i + 1],
1203 mergedTransactionIds3[mergedTransactionIds3.size() - 1 - i]);
1204 }
1205 }
1206
TEST(TransactionHandlerTest,CanAddTransactionWithFullMergedIds)1207 TEST(TransactionHandlerTest, CanAddTransactionWithFullMergedIds) {
1208 SurfaceComposerClient::Transaction transaction1, transaction2;
1209 for (uint i = 0; i < 20u; i++) {
1210 SurfaceComposerClient::Transaction transactionToMerge;
1211 transaction1.merge(std::move(transactionToMerge));
1212 }
1213
1214 EXPECT_EQ(transaction1.getMergedTransactionIds().size(), 10u);
1215
1216 auto transaction1Id = transaction1.getId();
1217 transaction2.merge(std::move(transaction1));
1218 EXPECT_EQ(transaction2.getMergedTransactionIds().size(), 10u);
1219 auto mergedTransactionIds = transaction2.getMergedTransactionIds();
1220 EXPECT_TRUE(std::count(mergedTransactionIds.begin(), mergedTransactionIds.end(),
1221 transaction1Id) > 0);
1222 }
1223
1224 } // namespace android
1225