1 /*
2 * Copyright (C) 2021 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 #include <gui/test/CallbackUtils.h>
18 #include "LayerTransactionTest.h"
19
20 using namespace std::chrono_literals;
21
22 namespace android {
23
24 using android::hardware::graphics::common::V1_1::BufferUsage;
25
26 ::testing::Environment* const binderEnv =
27 ::testing::AddGlobalTestEnvironment(new BinderEnvironment());
28
29 // b/181132765 - disabled until cuttlefish failures are investigated
30 class ReleaseBufferCallbackHelper {
31 public:
function(void * callbackContext,ReleaseCallbackId callbackId,const sp<Fence> & releaseFence,std::optional<uint32_t>)32 static void function(void* callbackContext, ReleaseCallbackId callbackId,
33 const sp<Fence>& releaseFence,
34 std::optional<uint32_t> /*currentMaxAcquiredBufferCount*/) {
35 if (!callbackContext) {
36 FAIL() << "failed to get callback context";
37 }
38 ReleaseBufferCallbackHelper* helper =
39 static_cast<ReleaseBufferCallbackHelper*>(callbackContext);
40 std::lock_guard lock(helper->mMutex);
41 helper->mCallbackDataQueue.emplace(callbackId, releaseFence);
42 helper->mConditionVariable.notify_all();
43 }
44
getCallbackData(ReleaseCallbackId * callbackId)45 void getCallbackData(ReleaseCallbackId* callbackId) {
46 std::unique_lock lock(mMutex);
47 if (mCallbackDataQueue.empty()) {
48 if (!mConditionVariable.wait_for(lock, std::chrono::seconds(3),
49 [&] { return !mCallbackDataQueue.empty(); })) {
50 FAIL() << "failed to get releaseBuffer callback";
51 }
52 }
53
54 auto callbackData = mCallbackDataQueue.front();
55 mCallbackDataQueue.pop();
56 *callbackId = callbackData.first;
57 }
58
verifyNoCallbacks()59 void verifyNoCallbacks() {
60 // Wait to see if there are extra callbacks
61 std::this_thread::sleep_for(300ms);
62
63 std::lock_guard lock(mMutex);
64 EXPECT_EQ(mCallbackDataQueue.size(), 0U) << "extra callbacks received";
65 mCallbackDataQueue = {};
66 }
67
getCallback()68 android::ReleaseBufferCallback getCallback() {
69 return std::bind(function, static_cast<void*>(this) /* callbackContext */,
70 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
71 }
72
73 std::mutex mMutex;
74 std::condition_variable mConditionVariable;
75 std::queue<std::pair<ReleaseCallbackId, sp<Fence>>> mCallbackDataQueue;
76 };
77
78 class ReleaseBufferCallbackTest : public LayerTransactionTest {
79 public:
createBufferStateLayer()80 virtual sp<SurfaceControl> createBufferStateLayer() {
81 return createLayer(mClient, "test", 0, 0, ISurfaceComposerClient::eFXSurfaceBufferState);
82 }
83
submitBuffer(const sp<SurfaceControl> & layer,sp<GraphicBuffer> buffer,sp<Fence> fence,CallbackHelper & callback,const ReleaseCallbackId & id,ReleaseBufferCallbackHelper & releaseCallback)84 static void submitBuffer(const sp<SurfaceControl>& layer, sp<GraphicBuffer> buffer,
85 sp<Fence> fence, CallbackHelper& callback, const ReleaseCallbackId& id,
86 ReleaseBufferCallbackHelper& releaseCallback) {
87 Transaction t;
88 t.setBuffer(layer, buffer, fence, id.framenumber, releaseCallback.getCallback());
89 t.addTransactionCompletedCallback(callback.function, callback.getContext());
90 t.apply();
91 }
92
waitForCallback(CallbackHelper & helper,const ExpectedResult & expectedResult)93 static void waitForCallback(CallbackHelper& helper, const ExpectedResult& expectedResult) {
94 CallbackData callbackData;
95 helper.getCallbackData(&callbackData);
96 expectedResult.verifyCallbackData(callbackData);
97 }
98
waitForReleaseBufferCallback(ReleaseBufferCallbackHelper & releaseCallback,const ReleaseCallbackId & expectedReleaseBufferId)99 static void waitForReleaseBufferCallback(ReleaseBufferCallbackHelper& releaseCallback,
100 const ReleaseCallbackId& expectedReleaseBufferId) {
101 ReleaseCallbackId actualReleaseBufferId;
102 releaseCallback.getCallbackData(&actualReleaseBufferId);
103 EXPECT_EQ(expectedReleaseBufferId, actualReleaseBufferId);
104 releaseCallback.verifyNoCallbacks();
105 }
getReleaseBufferCallbackHelper()106 static ReleaseBufferCallbackHelper* getReleaseBufferCallbackHelper() {
107 static std::vector<ReleaseBufferCallbackHelper*> sCallbacks;
108 sCallbacks.emplace_back(new ReleaseBufferCallbackHelper());
109 return sCallbacks.back();
110 }
111
getBuffer()112 static sp<GraphicBuffer> getBuffer() {
113 return new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1,
114 BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
115 BufferUsage::COMPOSER_OVERLAY,
116 "test");
117 }
generateFrameNumber()118 static uint64_t generateFrameNumber() {
119 static uint64_t sFrameNumber = 0;
120 return ++sFrameNumber;
121 }
122 };
123
TEST_F(ReleaseBufferCallbackTest,DISABLED_PresentBuffer)124 TEST_F(ReleaseBufferCallbackTest, DISABLED_PresentBuffer) {
125 sp<SurfaceControl> layer = createBufferStateLayer();
126 CallbackHelper transactionCallback;
127 ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
128
129 // If a buffer is being presented, we should not emit a release callback.
130 sp<GraphicBuffer> firstBuffer = getBuffer();
131 ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
132 submitBuffer(layer, firstBuffer, Fence::NO_FENCE, transactionCallback, firstBufferCallbackId,
133 *releaseCallback);
134 ExpectedResult expected;
135 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
136 ExpectedResult::Buffer::NOT_ACQUIRED);
137 ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
138 EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
139
140 // if state doesn't change, no release callbacks are expected
141 Transaction t;
142 t.addTransactionCompletedCallback(transactionCallback.function,
143 transactionCallback.getContext());
144 t.apply();
145 ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, ExpectedResult()));
146 EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
147
148 // If a presented buffer is replaced, we should emit a release callback for the
149 // previously presented buffer.
150 sp<GraphicBuffer> secondBuffer = getBuffer();
151 ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
152 submitBuffer(layer, secondBuffer, Fence::NO_FENCE, transactionCallback, secondBufferCallbackId,
153 *releaseCallback);
154 expected = ExpectedResult();
155 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
156 ExpectedResult::Buffer::NOT_ACQUIRED,
157 ExpectedResult::PreviousBuffer::RELEASED);
158 ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
159 ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
160 }
161
TEST_F(ReleaseBufferCallbackTest,DISABLED_OffScreenLayer)162 TEST_F(ReleaseBufferCallbackTest, DISABLED_OffScreenLayer) {
163 sp<SurfaceControl> layer = createBufferStateLayer();
164
165 CallbackHelper transactionCallback;
166 ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
167
168 // If a buffer is being presented, we should not emit a release callback.
169 sp<GraphicBuffer> firstBuffer = getBuffer();
170 ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
171 submitBuffer(layer, firstBuffer, Fence::NO_FENCE, transactionCallback, firstBufferCallbackId,
172 *releaseCallback);
173 ExpectedResult expected;
174 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
175 ExpectedResult::Buffer::NOT_ACQUIRED);
176 ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
177 releaseCallback->verifyNoCallbacks();
178
179 // If a layer is parented offscreen then it should not emit a callback since sf still owns
180 // the buffer and can render it again.
181 Transaction t;
182 t.reparent(layer, nullptr);
183 t.addTransactionCompletedCallback(transactionCallback.function,
184 transactionCallback.getContext());
185 t.apply();
186 expected = ExpectedResult();
187 expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer,
188 ExpectedResult::Buffer::NOT_ACQUIRED,
189 ExpectedResult::PreviousBuffer::NOT_RELEASED);
190 ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
191 ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
192
193 // If a presented buffer is replaced, we should emit a release callback for the
194 // previously presented buffer.
195 sp<GraphicBuffer> secondBuffer = getBuffer();
196 ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
197 submitBuffer(layer, secondBuffer, Fence::NO_FENCE, transactionCallback, secondBufferCallbackId,
198 *releaseCallback);
199 expected = ExpectedResult();
200 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
201 ExpectedResult::Buffer::NOT_ACQUIRED,
202 ExpectedResult::PreviousBuffer::NOT_RELEASED);
203 ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
204 ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
205
206 // If continue to submit buffer we continue to get release callbacks
207 sp<GraphicBuffer> thirdBuffer = getBuffer();
208 ReleaseCallbackId thirdBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
209 submitBuffer(layer, thirdBuffer, Fence::NO_FENCE, transactionCallback, thirdBufferCallbackId,
210 *releaseCallback);
211 expected = ExpectedResult();
212 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
213 ExpectedResult::Buffer::NOT_ACQUIRED,
214 ExpectedResult::PreviousBuffer::NOT_RELEASED);
215 ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
216 ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, secondBufferCallbackId));
217 }
218
TEST_F(ReleaseBufferCallbackTest,DISABLED_LayerLifecycle_layerdestroy)219 TEST_F(ReleaseBufferCallbackTest, DISABLED_LayerLifecycle_layerdestroy) {
220 sp<SurfaceControl> layer = createBufferStateLayer();
221 CallbackHelper* transactionCallback = new CallbackHelper();
222 ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
223
224 // If a buffer is being presented, we should not emit a release callback.
225 sp<GraphicBuffer> firstBuffer = getBuffer();
226 ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
227 submitBuffer(layer, firstBuffer, Fence::NO_FENCE, *transactionCallback, firstBufferCallbackId,
228 *releaseCallback);
229 {
230 ExpectedResult expected;
231 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
232 ExpectedResult::Buffer::NOT_ACQUIRED);
233 ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected));
234 ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
235 }
236
237 // Destroying a currently presenting layer emits a callback.
238 Transaction t;
239 t.reparent(layer, nullptr);
240 t.apply();
241 layer = nullptr;
242
243 ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
244 }
245
246 // Destroying a never presented layer emits a callback.
TEST_F(ReleaseBufferCallbackTest,DISABLED_LayerLifecycle_OffScreenLayerDestroy)247 TEST_F(ReleaseBufferCallbackTest, DISABLED_LayerLifecycle_OffScreenLayerDestroy) {
248 sp<SurfaceControl> layer = createBufferStateLayer();
249
250 // make layer offscreen
251 Transaction t;
252 t.reparent(layer, nullptr);
253 t.apply();
254
255 CallbackHelper* transactionCallback = new CallbackHelper();
256 ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
257
258 // Submitting a buffer does not emit a callback.
259 sp<GraphicBuffer> firstBuffer = getBuffer();
260 ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
261 submitBuffer(layer, firstBuffer, Fence::NO_FENCE, *transactionCallback, firstBufferCallbackId,
262 *releaseCallback);
263 {
264 ExpectedResult expected;
265 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
266 ExpectedResult::Buffer::NOT_ACQUIRED);
267 ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected));
268 ASSERT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
269 }
270
271 // Submitting a second buffer will replace the drawing state buffer and emit a callback.
272 sp<GraphicBuffer> secondBuffer = getBuffer();
273 ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
274 submitBuffer(layer, secondBuffer, Fence::NO_FENCE, *transactionCallback, secondBufferCallbackId,
275 *releaseCallback);
276 {
277 ExpectedResult expected;
278 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
279 ExpectedResult::Buffer::NOT_ACQUIRED);
280 ASSERT_NO_FATAL_FAILURE(waitForCallback(*transactionCallback, expected));
281 ASSERT_NO_FATAL_FAILURE(
282 waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
283 }
284
285 // Destroying the offscreen layer emits a callback.
286 layer = nullptr;
287 ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, secondBufferCallbackId));
288 }
289
TEST_F(ReleaseBufferCallbackTest,DISABLED_FrameDropping)290 TEST_F(ReleaseBufferCallbackTest, DISABLED_FrameDropping) {
291 sp<SurfaceControl> layer = createBufferStateLayer();
292 CallbackHelper transactionCallback;
293 ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
294
295 // If a buffer is being presented, we should not emit a release callback.
296 sp<GraphicBuffer> firstBuffer = getBuffer();
297 ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
298
299 // Try to present 100ms in the future
300 nsecs_t time = systemTime() + std::chrono::nanoseconds(100ms).count();
301
302 Transaction t;
303 t.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
304 releaseCallback->getCallback());
305 t.addTransactionCompletedCallback(transactionCallback.function,
306 transactionCallback.getContext());
307 t.setDesiredPresentTime(time);
308 t.apply();
309
310 ExpectedResult expected;
311 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
312 ExpectedResult::Buffer::NOT_ACQUIRED);
313 ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
314 EXPECT_NO_FATAL_FAILURE(releaseCallback->verifyNoCallbacks());
315
316 // Dropping frames in transaction queue emits a callback
317 sp<GraphicBuffer> secondBuffer = getBuffer();
318 ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
319 t.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
320 releaseCallback->getCallback());
321 t.addTransactionCompletedCallback(transactionCallback.function,
322 transactionCallback.getContext());
323 t.setDesiredPresentTime(time);
324 t.apply();
325
326 expected = ExpectedResult();
327 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
328 ExpectedResult::Buffer::NOT_ACQUIRED,
329 ExpectedResult::PreviousBuffer::RELEASED);
330 ASSERT_NO_FATAL_FAILURE(waitForCallback(transactionCallback, expected));
331 ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
332 }
333
TEST_F(ReleaseBufferCallbackTest,DISABLED_Merge_Different_Processes)334 TEST_F(ReleaseBufferCallbackTest, DISABLED_Merge_Different_Processes) {
335 sp<TransactionCompletedListener> firstCompletedListener = new TransactionCompletedListener();
336 sp<TransactionCompletedListener> secondCompletedListener = new TransactionCompletedListener();
337
338 CallbackHelper callback1, callback2;
339
340 TransactionCompletedListener::setInstance(firstCompletedListener);
341
342 sp<SurfaceControl> layer = createBufferStateLayer();
343 ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
344
345 sp<GraphicBuffer> firstBuffer = getBuffer();
346 ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
347
348 // Send initial buffer for the layer
349 submitBuffer(layer, firstBuffer, Fence::NO_FENCE, callback1, firstBufferCallbackId,
350 *releaseCallback);
351
352 ExpectedResult expected;
353 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
354 ExpectedResult::Buffer::NOT_ACQUIRED);
355 ASSERT_NO_FATAL_FAILURE(waitForCallback(callback1, expected));
356
357 // Sent a second buffer to allow the first buffer to get released.
358 sp<GraphicBuffer> secondBuffer = getBuffer();
359 ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
360
361 Transaction transaction1;
362 transaction1.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
363 releaseCallback->getCallback());
364 transaction1.addTransactionCompletedCallback(callback1.function, callback1.getContext());
365
366 // Set a different TransactionCompletedListener to mimic a second process
367 TransactionCompletedListener::setInstance(secondCompletedListener);
368
369 // Make sure the second "process" has a callback set up.
370 Transaction transaction2;
371 transaction2.addTransactionCompletedCallback(callback2.function, callback2.getContext());
372
373 // This merging order, merge transaction1 first then transaction2, seems to ensure the listener
374 // for transaction2 is ordered first. This makes sure the wrong process is added first to the
375 // layer's vector of listeners. With the bug, only the secondCompletedListener will get the
376 // release callback id, since it's ordered first. Then firstCompletedListener would fail to get
377 // the release callback id and not invoke the release callback.
378 Transaction().merge(std::move(transaction1)).merge(std::move(transaction2)).apply();
379
380 expected = ExpectedResult();
381 expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
382 ExpectedResult::Buffer::NOT_ACQUIRED,
383 ExpectedResult::PreviousBuffer::RELEASED);
384 ASSERT_NO_FATAL_FAILURE(waitForCallback(callback1, expected));
385 ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
386 }
387
TEST_F(ReleaseBufferCallbackTest,DISABLED_SetBuffer_OverwriteBuffers)388 TEST_F(ReleaseBufferCallbackTest, DISABLED_SetBuffer_OverwriteBuffers) {
389 sp<SurfaceControl> layer = createBufferStateLayer();
390 ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
391
392 sp<GraphicBuffer> firstBuffer = getBuffer();
393 ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
394
395 // Create transaction with a buffer.
396 Transaction transaction;
397 transaction.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
398 releaseCallback->getCallback());
399
400 sp<GraphicBuffer> secondBuffer = getBuffer();
401 ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
402
403 // Call setBuffer on the same transaction with a different buffer.
404 transaction.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
405 releaseCallback->getCallback());
406
407 ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
408 }
409
TEST_F(ReleaseBufferCallbackTest,DISABLED_Merge_Transactions_OverwriteBuffers)410 TEST_F(ReleaseBufferCallbackTest, DISABLED_Merge_Transactions_OverwriteBuffers) {
411 sp<SurfaceControl> layer = createBufferStateLayer();
412 ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
413
414 sp<GraphicBuffer> firstBuffer = getBuffer();
415 ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
416
417 // Create transaction with a buffer.
418 Transaction transaction1;
419 transaction1.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
420 releaseCallback->getCallback());
421
422 sp<GraphicBuffer> secondBuffer = getBuffer();
423 ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
424
425 // Create a second transaction with a new buffer for the same layer.
426 Transaction transaction2;
427 transaction2.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
428 releaseCallback->getCallback());
429
430 // merge transaction1 into transaction2 so ensure we get a proper buffer release callback.
431 transaction1.merge(std::move(transaction2));
432 ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
433 }
434
TEST_F(ReleaseBufferCallbackTest,DISABLED_MergeBuffers_Different_Processes)435 TEST_F(ReleaseBufferCallbackTest, DISABLED_MergeBuffers_Different_Processes) {
436 sp<TransactionCompletedListener> firstCompletedListener = new TransactionCompletedListener();
437 sp<TransactionCompletedListener> secondCompletedListener = new TransactionCompletedListener();
438
439 TransactionCompletedListener::setInstance(firstCompletedListener);
440
441 sp<SurfaceControl> layer = createBufferStateLayer();
442 ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
443
444 sp<GraphicBuffer> firstBuffer = getBuffer();
445 ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
446
447 Transaction transaction1;
448 transaction1.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
449 releaseCallback->getCallback());
450
451 // Sent a second buffer to allow the first buffer to get released.
452 sp<GraphicBuffer> secondBuffer = getBuffer();
453 ReleaseCallbackId secondBufferCallbackId(secondBuffer->getId(), generateFrameNumber());
454
455 Transaction transaction2;
456 transaction2.setBuffer(layer, secondBuffer, std::nullopt, secondBufferCallbackId.framenumber,
457 releaseCallback->getCallback());
458
459 // Set a different TransactionCompletedListener to mimic a second process
460 TransactionCompletedListener::setInstance(secondCompletedListener);
461 Transaction().merge(std::move(transaction1)).merge(std::move(transaction2)).apply();
462
463 // Make sure we can still get the release callback even though the merge happened in a different
464 // process.
465 ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
466 }
467
TEST_F(ReleaseBufferCallbackTest,SetBuffer_OverwriteBuffersWithNull)468 TEST_F(ReleaseBufferCallbackTest, SetBuffer_OverwriteBuffersWithNull) {
469 sp<SurfaceControl> layer = createBufferStateLayer();
470 ReleaseBufferCallbackHelper* releaseCallback = getReleaseBufferCallbackHelper();
471
472 sp<GraphicBuffer> firstBuffer = getBuffer();
473 ReleaseCallbackId firstBufferCallbackId(firstBuffer->getId(), generateFrameNumber());
474
475 // Create transaction with a buffer.
476 Transaction transaction;
477 transaction.setBuffer(layer, firstBuffer, std::nullopt, firstBufferCallbackId.framenumber,
478 releaseCallback->getCallback());
479
480 // Call setBuffer on the same transaction with a null buffer.
481 transaction.setBuffer(layer, nullptr, std::nullopt, 0, releaseCallback->getCallback());
482
483 ASSERT_NO_FATAL_FAILURE(waitForReleaseBufferCallback(*releaseCallback, firstBufferCallbackId));
484 }
485
486 } // namespace android
487