blob: 0168877478f9eeb81eb0eab1ade7722f7a5e58bc [file] [log] [blame]
Jamie Gennis9e75ddd2012-08-31 15:32:45 -07001/*
2 * Copyright (C) 2012 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#define LOG_TAG "BufferQueue_test"
18//#define LOG_NDEBUG 0
19
Nolan Scobie9c427942023-05-01 16:41:28 -040020#include "Constants.h"
Peiyong Lind8460c82020-07-28 16:04:22 -070021#include "MockConsumer.h"
Dan Stozac6f30bd2015-06-08 09:32:50 -070022
Dan Stozacf3834d2015-03-11 14:04:22 -070023#include <gui/BufferItem.h>
John Reck12daff92023-07-28 16:36:27 -040024#include <gui/BufferItemConsumer.h>
Dan Stozaf0eaf252014-03-21 13:05:51 -070025#include <gui/BufferQueue.h>
26#include <gui/IProducerListener.h>
John Reck12daff92023-07-28 16:36:27 -040027#include <gui/Surface.h>
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070028
29#include <ui/GraphicBuffer.h>
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070030
Dan Stoza1a0b8612014-03-20 15:36:31 -070031#include <binder/IPCThreadState.h>
Dan Stoza9f3053d2014-03-06 15:14:33 -080032#include <binder/IServiceManager.h>
Dan Stoza1a0b8612014-03-20 15:36:31 -070033#include <binder/ProcessState.h>
Dan Stozaf0eaf252014-03-21 13:05:51 -070034
35#include <utils/String8.h>
36#include <utils/threads.h>
37
Mathias Agopian6a3c05b2017-04-27 20:06:55 -070038#include <system/window.h>
39
Dan Stozaf0eaf252014-03-21 13:05:51 -070040#include <gtest/gtest.h>
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070041
John Reck12daff92023-07-28 16:36:27 -040042#include <future>
Dan Stozae77c7662016-05-13 11:37:28 -070043#include <thread>
44
45using namespace std::chrono_literals;
46
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070047namespace android {
48
49class BufferQueueTest : public ::testing::Test {
Dan Stoza9f3053d2014-03-06 15:14:33 -080050
51public:
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070052protected:
Igor Murashkin7ea777f2013-11-18 16:58:36 -080053 void GetMinUndequeuedBufferCount(int* bufferCount) {
Yi Konga03e0442018-07-17 11:16:57 -070054 ASSERT_TRUE(bufferCount != nullptr);
Dan Stoza9f3053d2014-03-06 15:14:33 -080055 ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
56 bufferCount));
57 ASSERT_GE(*bufferCount, 0);
Igor Murashkin7ea777f2013-11-18 16:58:36 -080058 }
59
Dan Stoza1a0b8612014-03-20 15:36:31 -070060 void createBufferQueue() {
61 BufferQueue::createBufferQueue(&mProducer, &mConsumer);
62 }
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070063
Pablo Ceballosff95aab2016-01-13 17:09:58 -080064 void testBufferItem(const IGraphicBufferProducer::QueueBufferInput& input,
65 const BufferItem& item) {
66 int64_t timestamp;
67 bool isAutoTimestamp;
68 android_dataspace dataSpace;
69 Rect crop;
70 int scalingMode;
71 uint32_t transform;
72 sp<Fence> fence;
73
74 input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop,
Yi Konga03e0442018-07-17 11:16:57 -070075 &scalingMode, &transform, &fence, nullptr);
Pablo Ceballosff95aab2016-01-13 17:09:58 -080076 ASSERT_EQ(timestamp, item.mTimestamp);
77 ASSERT_EQ(isAutoTimestamp, item.mIsAutoTimestamp);
78 ASSERT_EQ(dataSpace, item.mDataSpace);
79 ASSERT_EQ(crop, item.mCrop);
80 ASSERT_EQ(static_cast<uint32_t>(scalingMode), item.mScalingMode);
81 ASSERT_EQ(transform, item.mTransform);
82 ASSERT_EQ(fence, item.mFence);
83 }
84
Dan Stoza1a0b8612014-03-20 15:36:31 -070085 sp<IGraphicBufferProducer> mProducer;
86 sp<IGraphicBufferConsumer> mConsumer;
87};
Dan Stoza9f3053d2014-03-06 15:14:33 -080088
Dan Stozaf8cebe52015-04-20 12:09:38 -070089static const uint32_t TEST_DATA = 0x12345678u;
90
Dan Stoza1a0b8612014-03-20 15:36:31 -070091// XXX: Tests that fork a process to hold the BufferQueue must run before tests
92// that use a local BufferQueue, or else Binder will get unhappy
Kalle Raita88752d72017-03-27 14:11:54 -070093//
94// In one instance this was a crash in the createBufferQueue where the
95// binder call to create a buffer allocator apparently got garbage back.
96// See b/36592665.
97TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) {
Dan Stoza1a0b8612014-03-20 15:36:31 -070098 const String16 PRODUCER_NAME = String16("BQTestProducer");
99 const String16 CONSUMER_NAME = String16("BQTestConsumer");
100
101 pid_t forkPid = fork();
102 ASSERT_NE(forkPid, -1);
103
104 if (forkPid == 0) {
105 // Child process
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700106 sp<IGraphicBufferProducer> producer;
107 sp<IGraphicBufferConsumer> consumer;
Dan Stoza1a0b8612014-03-20 15:36:31 -0700108 BufferQueue::createBufferQueue(&producer, &consumer);
109 sp<IServiceManager> serviceManager = defaultServiceManager();
Marco Nelissen097ca272014-11-14 08:01:01 -0800110 serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
111 serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
Dan Stoza1a0b8612014-03-20 15:36:31 -0700112 ProcessState::self()->startThreadPool();
113 IPCThreadState::self()->joinThreadPool();
114 LOG_ALWAYS_FATAL("Shouldn't be here");
115 }
116
117 sp<IServiceManager> serviceManager = defaultServiceManager();
118 sp<IBinder> binderProducer =
119 serviceManager->getService(PRODUCER_NAME);
120 mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
Yi Konga03e0442018-07-17 11:16:57 -0700121 EXPECT_TRUE(mProducer != nullptr);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700122 sp<IBinder> binderConsumer =
123 serviceManager->getService(CONSUMER_NAME);
124 mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
Yi Konga03e0442018-07-17 11:16:57 -0700125 EXPECT_TRUE(mConsumer != nullptr);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700126
Peiyong Lind8460c82020-07-28 16:04:22 -0700127 sp<MockConsumer> mc(new MockConsumer);
128 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
Dan Stoza1a0b8612014-03-20 15:36:31 -0700129 IGraphicBufferProducer::QueueBufferOutput output;
130 ASSERT_EQ(OK,
Yi Konga03e0442018-07-17 11:16:57 -0700131 mProducer->connect(nullptr, NATIVE_WINDOW_API_CPU, false, &output));
Dan Stoza1a0b8612014-03-20 15:36:31 -0700132
133 int slot;
134 sp<Fence> fence;
135 sp<GraphicBuffer> buffer;
136 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Ian Elliottd11b0442017-07-18 11:05:49 -0600137 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
138 nullptr, nullptr));
Dan Stoza1a0b8612014-03-20 15:36:31 -0700139 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
140
141 uint32_t* dataIn;
142 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
143 reinterpret_cast<void**>(&dataIn)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700144 *dataIn = TEST_DATA;
Dan Stoza1a0b8612014-03-20 15:36:31 -0700145 ASSERT_EQ(OK, buffer->unlock());
146
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800147 IGraphicBufferProducer::QueueBufferInput input(0, false,
148 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700149 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700150 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
151
Dan Stozacf3834d2015-03-11 14:04:22 -0700152 BufferItem item;
Dan Stoza1a0b8612014-03-20 15:36:31 -0700153 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
154
155 uint32_t* dataOut;
156 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
157 reinterpret_cast<void**>(&dataOut)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700158 ASSERT_EQ(*dataOut, TEST_DATA);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700159 ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
160}
161
silence_dogoode9d092a2019-06-19 16:14:53 -0700162TEST_F(BufferQueueTest, GetMaxBufferCountInQueueBufferOutput_Succeeds) {
163 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700164 sp<MockConsumer> mc(new MockConsumer);
165 mConsumer->consumerConnect(mc, false);
silence_dogoode9d092a2019-06-19 16:14:53 -0700166 int bufferCount = 50;
167 mConsumer->setMaxBufferCount(bufferCount);
168
169 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700170 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output);
silence_dogoode9d092a2019-06-19 16:14:53 -0700171 ASSERT_EQ(output.maxBufferCount, bufferCount);
172}
173
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700174TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700175 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700176 sp<MockConsumer> mc(new MockConsumer);
177 mConsumer->consumerConnect(mc, false);
Andy McFadden2adaf042012-12-18 09:49:45 -0800178 IGraphicBufferProducer::QueueBufferOutput qbo;
Peiyong Lind8460c82020-07-28 16:04:22 -0700179 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbo);
Pablo Ceballosfa455352015-08-12 17:47:47 -0700180 mProducer->setMaxDequeuedBufferCount(3);
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700181
182 int slot;
183 sp<Fence> fence;
184 sp<GraphicBuffer> buf;
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800185 IGraphicBufferProducer::QueueBufferInput qbi(0, false,
186 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700187 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Dan Stozacf3834d2015-03-11 14:04:22 -0700188 BufferItem item;
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700189
190 for (int i = 0; i < 2; i++) {
Andy McFadden2adaf042012-12-18 09:49:45 -0800191 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Ian Elliottd11b0442017-07-18 11:05:49 -0600192 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
193 nullptr, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800194 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
195 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
196 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700197 }
198
Andy McFadden2adaf042012-12-18 09:49:45 -0800199 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Ian Elliottd11b0442017-07-18 11:05:49 -0600200 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
201 nullptr, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800202 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
203 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700204
205 // Acquire the third buffer, which should fail.
Dan Stoza9f3053d2014-03-06 15:14:33 -0800206 ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0));
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700207}
208
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700209TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700210 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700211 sp<MockConsumer> mc(new MockConsumer);
212 mConsumer->consumerConnect(mc, false);
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700213
Pablo Ceballos72daab62015-12-07 16:38:43 -0800214 EXPECT_EQ(OK, mConsumer->setMaxBufferCount(10));
215 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(10));
216
217 IGraphicBufferProducer::QueueBufferOutput qbo;
Peiyong Lind8460c82020-07-28 16:04:22 -0700218 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbo);
Pablo Ceballos72daab62015-12-07 16:38:43 -0800219 mProducer->setMaxDequeuedBufferCount(3);
220
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800221 int minBufferCount;
222 ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800223 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
224 minBufferCount - 1));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800225
Dan Stoza9f3053d2014-03-06 15:14:33 -0800226 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0));
227 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3));
228 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700229 BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800230 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700231
Pablo Ceballos72daab62015-12-07 16:38:43 -0800232 int slot;
233 sp<Fence> fence;
234 sp<GraphicBuffer> buf;
235 IGraphicBufferProducer::QueueBufferInput qbi(0, false,
236 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
237 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
238 BufferItem item;
239 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
240 for (int i = 0; i < 3; i++) {
241 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Ian Elliottd11b0442017-07-18 11:05:49 -0600242 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
243 nullptr, nullptr));
Pablo Ceballos72daab62015-12-07 16:38:43 -0800244 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
245 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
246 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
247 }
248
249 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(2));
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700250}
251
252TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700253 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700254 sp<MockConsumer> mc(new MockConsumer);
255 mConsumer->consumerConnect(mc, false);
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700256
Pablo Ceballos72daab62015-12-07 16:38:43 -0800257 IGraphicBufferProducer::QueueBufferOutput qbo;
Peiyong Lind8460c82020-07-28 16:04:22 -0700258 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbo);
Pablo Ceballos72daab62015-12-07 16:38:43 -0800259 mProducer->setMaxDequeuedBufferCount(2);
260
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800261 int minBufferCount;
262 ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
263
Dan Stoza9f3053d2014-03-06 15:14:33 -0800264 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
265 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2));
266 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount));
Pablo Ceballos72daab62015-12-07 16:38:43 -0800267
268 int slot;
269 sp<Fence> fence;
270 sp<GraphicBuffer> buf;
271 IGraphicBufferProducer::QueueBufferInput qbi(0, false,
272 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
273 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
274 BufferItem item;
275
276 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Ian Elliottd11b0442017-07-18 11:05:49 -0600277 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
278 nullptr, nullptr));
Pablo Ceballos72daab62015-12-07 16:38:43 -0800279 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
280 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
281 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
282
283 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
284
285 for (int i = 0; i < 2; i++) {
286 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Ian Elliottd11b0442017-07-18 11:05:49 -0600287 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
288 nullptr, nullptr));
Pablo Ceballos72daab62015-12-07 16:38:43 -0800289 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
290 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
291 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
292 }
293
Dan Stoza9f3053d2014-03-06 15:14:33 -0800294 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700295 BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
296}
297
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700298TEST_F(BufferQueueTest, SetMaxBufferCountWithLegalValues_Succeeds) {
299 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700300 sp<MockConsumer> mc(new MockConsumer);
301 mConsumer->consumerConnect(mc, false);
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700302
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700303 // Test shared buffer mode
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700304 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
305}
306
307TEST_F(BufferQueueTest, SetMaxBufferCountWithIllegalValues_ReturnsError) {
308 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700309 sp<MockConsumer> mc(new MockConsumer);
310 mConsumer->consumerConnect(mc, false);
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700311
312 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(0));
313 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(
314 BufferQueue::NUM_BUFFER_SLOTS + 1));
315
316 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(5));
317 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(3));
318}
319
Dan Stoza9f3053d2014-03-06 15:14:33 -0800320TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700321 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700322 sp<MockConsumer> mc(new MockConsumer);
323 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800324 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700325 ASSERT_EQ(OK,
326 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800327
328 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low
329 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(
330 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
331 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued
332
333 int slot;
334 sp<Fence> fence;
335 sp<GraphicBuffer> buffer;
336 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Ian Elliottd11b0442017-07-18 11:05:49 -0600337 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
338 nullptr, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800339 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested
340 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
341 ASSERT_EQ(OK, mProducer->detachBuffer(slot));
342 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued
343
344 sp<GraphicBuffer> safeToClobberBuffer;
345 // Can no longer request buffer from this slot
346 ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer));
347
348 uint32_t* dataIn;
349 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
350 reinterpret_cast<void**>(&dataIn)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700351 *dataIn = TEST_DATA;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800352 ASSERT_EQ(OK, buffer->unlock());
353
354 int newSlot;
Yi Konga03e0442018-07-17 11:16:57 -0700355 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(nullptr, safeToClobberBuffer));
356 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800357
358 ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800359 IGraphicBufferProducer::QueueBufferInput input(0, false,
360 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700361 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800362 ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
363
Dan Stozacf3834d2015-03-11 14:04:22 -0700364 BufferItem item;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800365 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
366
367 uint32_t* dataOut;
368 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
369 reinterpret_cast<void**>(&dataOut)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700370 ASSERT_EQ(*dataOut, TEST_DATA);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700371 ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
Dan Stoza9f3053d2014-03-06 15:14:33 -0800372}
373
374TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700375 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700376 sp<MockConsumer> mc(new MockConsumer);
377 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800378 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700379 ASSERT_EQ(OK,
380 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800381
382 int slot;
383 sp<Fence> fence;
384 sp<GraphicBuffer> buffer;
385 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Ian Elliottd11b0442017-07-18 11:05:49 -0600386 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
387 nullptr, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800388 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800389 IGraphicBufferProducer::QueueBufferInput input(0, false,
390 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700391 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800392 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
393
394 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low
395 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(
396 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
397 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
398
Dan Stozacf3834d2015-03-11 14:04:22 -0700399 BufferItem item;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800400 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
401
Pablo Ceballos47650f42015-08-04 16:38:17 -0700402 ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
403 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mSlot)); // Not acquired
Dan Stoza9f3053d2014-03-06 15:14:33 -0800404
405 uint32_t* dataIn;
406 ASSERT_EQ(OK, item.mGraphicBuffer->lock(
407 GraphicBuffer::USAGE_SW_WRITE_OFTEN,
408 reinterpret_cast<void**>(&dataIn)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700409 *dataIn = TEST_DATA;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800410 ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
411
412 int newSlot;
413 sp<GraphicBuffer> safeToClobberBuffer;
Yi Konga03e0442018-07-17 11:16:57 -0700414 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(nullptr, safeToClobberBuffer));
415 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800416 ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer));
417
Dan Stoza99b18b42014-03-28 15:34:33 -0700418 ASSERT_EQ(OK, mConsumer->releaseBuffer(newSlot, 0, EGL_NO_DISPLAY,
Dan Stoza9f3053d2014-03-06 15:14:33 -0800419 EGL_NO_SYNC_KHR, Fence::NO_FENCE));
420
421 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Ian Elliottd11b0442017-07-18 11:05:49 -0600422 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
423 nullptr, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800424 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
425
426 uint32_t* dataOut;
427 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
428 reinterpret_cast<void**>(&dataOut)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700429 ASSERT_EQ(*dataOut, TEST_DATA);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700430 ASSERT_EQ(OK, buffer->unlock());
Dan Stoza9f3053d2014-03-06 15:14:33 -0800431}
432
433TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700434 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700435 sp<MockConsumer> mc(new MockConsumer);
436 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800437 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700438 ASSERT_EQ(OK,
439 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800440
441 int slot;
442 sp<Fence> fence;
443 sp<GraphicBuffer> buffer;
444 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Ian Elliottd11b0442017-07-18 11:05:49 -0600445 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
446 nullptr, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800447 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
448
449 uint32_t* dataIn;
450 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
451 reinterpret_cast<void**>(&dataIn)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700452 *dataIn = TEST_DATA;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800453 ASSERT_EQ(OK, buffer->unlock());
454
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800455 IGraphicBufferProducer::QueueBufferInput input(0, false,
456 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700457 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800458 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
459
Dan Stozacf3834d2015-03-11 14:04:22 -0700460 BufferItem item;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800461 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
Pablo Ceballos47650f42015-08-04 16:38:17 -0700462 ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800463
464 int newSlot;
465 ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
466 ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
467 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
468
469 uint32_t* dataOut;
470 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
471 reinterpret_cast<void**>(&dataOut)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700472 ASSERT_EQ(*dataOut, TEST_DATA);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700473 ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
Dan Stoza9f3053d2014-03-06 15:14:33 -0800474}
475
Dan Stoza9de72932015-04-16 17:28:43 -0700476TEST_F(BufferQueueTest, TestDisallowingAllocation) {
477 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700478 sp<MockConsumer> mc(new MockConsumer);
479 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
Dan Stoza9de72932015-04-16 17:28:43 -0700480 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700481 ASSERT_EQ(OK,
482 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
Dan Stoza9de72932015-04-16 17:28:43 -0700483
484 static const uint32_t WIDTH = 320;
485 static const uint32_t HEIGHT = 240;
486
487 ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT));
488
489 int slot;
490 sp<Fence> fence;
491 sp<GraphicBuffer> buffer;
492 // This should return an error since it would require an allocation
493 ASSERT_EQ(OK, mProducer->allowAllocation(false));
Ian Elliottd11b0442017-07-18 11:05:49 -0600494 ASSERT_EQ(WOULD_BLOCK,
495 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
496 nullptr, nullptr));
Dan Stoza9de72932015-04-16 17:28:43 -0700497
498 // This should succeed, now that we've lifted the prohibition
499 ASSERT_EQ(OK, mProducer->allowAllocation(true));
500 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Ian Elliottd11b0442017-07-18 11:05:49 -0600501 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
502 nullptr, nullptr));
Dan Stoza9de72932015-04-16 17:28:43 -0700503
504 // Release the previous buffer back to the BufferQueue
505 mProducer->cancelBuffer(slot, fence);
506
507 // This should fail since we're requesting a different size
508 ASSERT_EQ(OK, mProducer->allowAllocation(false));
Ian Elliottd11b0442017-07-18 11:05:49 -0600509 ASSERT_EQ(WOULD_BLOCK,
510 mProducer->dequeueBuffer(&slot, &fence, WIDTH * 2, HEIGHT * 2, 0,
511 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr));
Dan Stoza9de72932015-04-16 17:28:43 -0700512}
513
Dan Stoza812ed062015-06-02 15:45:22 -0700514TEST_F(BufferQueueTest, TestGenerationNumbers) {
515 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700516 sp<MockConsumer> mc(new MockConsumer);
517 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
Dan Stoza812ed062015-06-02 15:45:22 -0700518 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700519 ASSERT_EQ(OK,
520 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
Dan Stoza812ed062015-06-02 15:45:22 -0700521
522 ASSERT_EQ(OK, mProducer->setGenerationNumber(1));
523
524 // Get one buffer to play with
525 int slot;
526 sp<Fence> fence;
527 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Nolan Scobie9c427942023-05-01 16:41:28 -0400528 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
529 nullptr));
Dan Stoza812ed062015-06-02 15:45:22 -0700530
531 sp<GraphicBuffer> buffer;
532 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
533
534 // Ensure that the generation number we set propagates to allocated buffers
535 ASSERT_EQ(1U, buffer->getGenerationNumber());
536
537 ASSERT_EQ(OK, mProducer->detachBuffer(slot));
538
539 ASSERT_EQ(OK, mProducer->setGenerationNumber(2));
540
541 // These should fail, since we've changed the generation number on the queue
542 int outSlot;
543 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&outSlot, buffer));
544 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&outSlot, buffer));
545
546 buffer->setGenerationNumber(2);
547
548 // This should succeed now that we've changed the buffer's generation number
549 ASSERT_EQ(OK, mProducer->attachBuffer(&outSlot, buffer));
550
551 ASSERT_EQ(OK, mProducer->detachBuffer(outSlot));
552
553 // This should also succeed with the new generation number
554 ASSERT_EQ(OK, mConsumer->attachBuffer(&outSlot, buffer));
555}
556
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700557TEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700558 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700559 sp<MockConsumer> mc(new MockConsumer);
560 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700561 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700562 ASSERT_EQ(OK,
563 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700564
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700565 ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700566
567 // Get a buffer
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700568 int sharedSlot;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700569 sp<Fence> fence;
570 sp<GraphicBuffer> buffer;
571 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Nolan Scobie9c427942023-05-01 16:41:28 -0400572 mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
573 nullptr, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700574 ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700575
576 // Queue the buffer
577 IGraphicBufferProducer::QueueBufferInput input(0, false,
578 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
579 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700580 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700581
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800582 // Repeatedly queue and dequeue a buffer from the producer side, it should
583 // always return the same one. And we won't run out of buffers because it's
584 // always the same one and because async mode gets enabled.
585 int slot;
586 for (int i = 0; i < 5; i++) {
Nolan Scobie9c427942023-05-01 16:41:28 -0400587 ASSERT_EQ(OK,
588 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
589 nullptr, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700590 ASSERT_EQ(sharedSlot, slot);
591 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800592 }
593
594 // acquire the buffer
595 BufferItem item;
596 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700597 ASSERT_EQ(sharedSlot, item.mSlot);
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800598 testBufferItem(input, item);
599 ASSERT_EQ(true, item.mQueuedBuffer);
600 ASSERT_EQ(false, item.mAutoRefresh);
601
602 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
603 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
604
605 // attempt to acquire a second time should return no buffer available
606 ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
607 mConsumer->acquireBuffer(&item, 0));
608}
609
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700610TEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) {
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800611 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700612 sp<MockConsumer> mc(new MockConsumer);
613 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800614 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700615 ASSERT_EQ(OK,
616 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800617
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700618 ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800619 ASSERT_EQ(OK, mProducer->setAutoRefresh(true));
620
621 // Get a buffer
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700622 int sharedSlot;
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800623 sp<Fence> fence;
624 sp<GraphicBuffer> buffer;
625 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Nolan Scobie9c427942023-05-01 16:41:28 -0400626 mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
627 nullptr, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700628 ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800629
630 // Queue the buffer
631 IGraphicBufferProducer::QueueBufferInput input(0, false,
632 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
633 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700634 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800635
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700636 // Repeatedly acquire and release a buffer from the consumer side, it should
637 // always return the same one.
638 BufferItem item;
639 for (int i = 0; i < 5; i++) {
640 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700641 ASSERT_EQ(sharedSlot, item.mSlot);
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800642 testBufferItem(input, item);
643 ASSERT_EQ(i == 0, item.mQueuedBuffer);
644 ASSERT_EQ(true, item.mAutoRefresh);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700645
646 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
647 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
648 }
649
650 // Repeatedly queue and dequeue a buffer from the producer side, it should
651 // always return the same one.
652 int slot;
653 for (int i = 0; i < 5; i++) {
Nolan Scobie9c427942023-05-01 16:41:28 -0400654 ASSERT_EQ(OK,
655 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
656 nullptr, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700657 ASSERT_EQ(sharedSlot, slot);
658 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700659 }
660
661 // Repeatedly acquire and release a buffer from the consumer side, it should
662 // always return the same one. First grabbing them from the queue and then
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700663 // when the queue is empty, returning the shared buffer.
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700664 for (int i = 0; i < 10; i++) {
665 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700666 ASSERT_EQ(sharedSlot, item.mSlot);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700667 ASSERT_EQ(0, item.mTimestamp);
668 ASSERT_EQ(false, item.mIsAutoTimestamp);
669 ASSERT_EQ(HAL_DATASPACE_UNKNOWN, item.mDataSpace);
670 ASSERT_EQ(Rect(0, 0, 1, 1), item.mCrop);
671 ASSERT_EQ(NATIVE_WINDOW_SCALING_MODE_FREEZE, item.mScalingMode);
Dan Stoza5ecfb682016-01-04 17:01:02 -0800672 ASSERT_EQ(0u, item.mTransform);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700673 ASSERT_EQ(Fence::NO_FENCE, item.mFence);
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800674 ASSERT_EQ(i == 0, item.mQueuedBuffer);
675 ASSERT_EQ(true, item.mAutoRefresh);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700676
677 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
678 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
679 }
680}
681
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700682TEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) {
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700683 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700684 sp<MockConsumer> mc(new MockConsumer);
685 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700686 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700687 ASSERT_EQ(OK,
688 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700689
690 // Dequeue a buffer
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700691 int sharedSlot;
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700692 sp<Fence> fence;
693 sp<GraphicBuffer> buffer;
694 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Nolan Scobie9c427942023-05-01 16:41:28 -0400695 mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
696 nullptr, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700697 ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700698
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700699 // Enable shared buffer mode
700 ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700701
702 // Queue the buffer
703 IGraphicBufferProducer::QueueBufferInput input(0, false,
704 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
705 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700706 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700707
708 // Repeatedly queue and dequeue a buffer from the producer side, it should
709 // always return the same one. And we won't run out of buffers because it's
710 // always the same one and because async mode gets enabled.
711 int slot;
712 for (int i = 0; i < 5; i++) {
Nolan Scobie9c427942023-05-01 16:41:28 -0400713 ASSERT_EQ(OK,
714 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
715 nullptr, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700716 ASSERT_EQ(sharedSlot, slot);
717 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700718 }
719
720 // acquire the buffer
721 BufferItem item;
722 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700723 ASSERT_EQ(sharedSlot, item.mSlot);
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700724 testBufferItem(input, item);
725 ASSERT_EQ(true, item.mQueuedBuffer);
726 ASSERT_EQ(false, item.mAutoRefresh);
727
728 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
729 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
730
731 // attempt to acquire a second time should return no buffer available
732 ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
733 mConsumer->acquireBuffer(&item, 0));
734}
735
Dan Stoza127fc632015-06-30 13:43:32 -0700736TEST_F(BufferQueueTest, TestTimeouts) {
737 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700738 sp<MockConsumer> mc(new MockConsumer);
739 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
Dan Stoza127fc632015-06-30 13:43:32 -0700740 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700741 ASSERT_EQ(OK,
742 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
Dan Stoza127fc632015-06-30 13:43:32 -0700743
744 // Fill up the queue. Since the controlledByApp flags are set to true, this
745 // queue should be in non-blocking mode, and we should be recycling the same
746 // two buffers
747 for (int i = 0; i < 5; ++i) {
748 int slot = BufferQueue::INVALID_BUFFER_SLOT;
749 sp<Fence> fence = Fence::NO_FENCE;
Nolan Scobie9c427942023-05-01 16:41:28 -0400750 auto result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
751 nullptr, nullptr);
Dan Stoza127fc632015-06-30 13:43:32 -0700752 if (i < 2) {
753 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
754 result);
755 } else {
756 ASSERT_EQ(OK, result);
757 }
758 sp<GraphicBuffer> buffer;
759 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
760 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
761 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
762 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
763 IGraphicBufferProducer::QueueBufferOutput output{};
764 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
765 }
766
767 const auto TIMEOUT = ms2ns(250);
768 mProducer->setDequeueTimeout(TIMEOUT);
769
770 // Setting a timeout will change the BufferQueue into blocking mode (with
771 // one droppable buffer in the queue and one free from the previous
772 // dequeue/queues), so dequeue and queue two more buffers: one to replace
773 // the current droppable buffer, and a second to max out the buffer count
774 sp<GraphicBuffer> buffer; // Save a buffer to attach later
775 for (int i = 0; i < 2; ++i) {
776 int slot = BufferQueue::INVALID_BUFFER_SLOT;
777 sp<Fence> fence = Fence::NO_FENCE;
Nolan Scobie9c427942023-05-01 16:41:28 -0400778 ASSERT_EQ(OK,
779 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
780 nullptr, nullptr));
Dan Stoza127fc632015-06-30 13:43:32 -0700781 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
782 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
783 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
784 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
785 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
786 }
787
788 int slot = BufferQueue::INVALID_BUFFER_SLOT;
789 sp<Fence> fence = Fence::NO_FENCE;
790 auto startTime = systemTime();
Nolan Scobie9c427942023-05-01 16:41:28 -0400791 ASSERT_EQ(TIMED_OUT,
792 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
793 nullptr));
Dan Stoza127fc632015-06-30 13:43:32 -0700794 ASSERT_GE(systemTime() - startTime, TIMEOUT);
795
796 // We're technically attaching the same buffer multiple times (since we
797 // queued it previously), but that doesn't matter for this test
798 startTime = systemTime();
799 ASSERT_EQ(TIMED_OUT, mProducer->attachBuffer(&slot, buffer));
800 ASSERT_GE(systemTime() - startTime, TIMEOUT);
801}
802
Dan Stoza5ecfb682016-01-04 17:01:02 -0800803TEST_F(BufferQueueTest, CanAttachWhileDisallowingAllocation) {
804 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700805 sp<MockConsumer> mc(new MockConsumer);
806 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
Dan Stoza5ecfb682016-01-04 17:01:02 -0800807 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700808 ASSERT_EQ(OK,
809 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
Dan Stoza5ecfb682016-01-04 17:01:02 -0800810
811 int slot = BufferQueue::INVALID_BUFFER_SLOT;
812 sp<Fence> sourceFence;
813 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Nolan Scobie9c427942023-05-01 16:41:28 -0400814 mProducer->dequeueBuffer(&slot, &sourceFence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
815 nullptr, nullptr));
Dan Stoza5ecfb682016-01-04 17:01:02 -0800816 sp<GraphicBuffer> buffer;
817 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
818 ASSERT_EQ(OK, mProducer->detachBuffer(slot));
819
820 ASSERT_EQ(OK, mProducer->allowAllocation(false));
821
822 slot = BufferQueue::INVALID_BUFFER_SLOT;
823 ASSERT_EQ(OK, mProducer->attachBuffer(&slot, buffer));
824}
825
Dan Stoza50101d02016-04-07 16:53:23 -0700826TEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) {
827 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700828 sp<MockConsumer> mc(new MockConsumer);
829 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
Dan Stoza50101d02016-04-07 16:53:23 -0700830 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700831 ASSERT_EQ(OK,
832 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output));
Dan Stoza50101d02016-04-07 16:53:23 -0700833
834 // Dequeue and queue the first buffer, storing the handle
835 int slot = BufferQueue::INVALID_BUFFER_SLOT;
836 sp<Fence> fence;
837 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Nolan Scobie9c427942023-05-01 16:41:28 -0400838 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
839 nullptr));
Dan Stoza50101d02016-04-07 16:53:23 -0700840 sp<GraphicBuffer> firstBuffer;
841 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &firstBuffer));
842
843 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
844 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
845 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
846 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
847
848 // Dequeue a second buffer
849 slot = BufferQueue::INVALID_BUFFER_SLOT;
850 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Nolan Scobie9c427942023-05-01 16:41:28 -0400851 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
852 nullptr));
Dan Stoza50101d02016-04-07 16:53:23 -0700853 sp<GraphicBuffer> secondBuffer;
854 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &secondBuffer));
855
856 // Ensure it's a new buffer
857 ASSERT_NE(firstBuffer->getNativeBuffer()->handle,
858 secondBuffer->getNativeBuffer()->handle);
859
860 // Queue the second buffer
861 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
862
863 // Acquire and release both buffers
864 for (size_t i = 0; i < 2; ++i) {
865 BufferItem item;
866 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
867 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
868 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
869 }
870
871 // Make sure we got the second buffer back
872 sp<GraphicBuffer> returnedBuffer;
873 sp<Fence> returnedFence;
John Reck1a61da52016-04-28 13:18:15 -0700874 float transform[16];
Dan Stoza50101d02016-04-07 16:53:23 -0700875 ASSERT_EQ(OK,
John Reck1a61da52016-04-28 13:18:15 -0700876 mProducer->getLastQueuedBuffer(&returnedBuffer, &returnedFence,
877 transform));
Dan Stoza50101d02016-04-07 16:53:23 -0700878 ASSERT_EQ(secondBuffer->getNativeBuffer()->handle,
879 returnedBuffer->getNativeBuffer()->handle);
880}
881
Dan Stozae77c7662016-05-13 11:37:28 -0700882TEST_F(BufferQueueTest, TestOccupancyHistory) {
883 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -0700884 sp<MockConsumer> mc(new MockConsumer);
885 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
Dan Stozae77c7662016-05-13 11:37:28 -0700886 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -0700887 ASSERT_EQ(OK,
888 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &output));
Dan Stozae77c7662016-05-13 11:37:28 -0700889
890 int slot = BufferQueue::INVALID_BUFFER_SLOT;
891 sp<Fence> fence = Fence::NO_FENCE;
892 sp<GraphicBuffer> buffer = nullptr;
893 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
894 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
895 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
896 BufferItem item{};
897
898 // Preallocate, dequeue, request, and cancel 3 buffers so we don't get
899 // BUFFER_NEEDS_REALLOCATION below
900 int slots[3] = {};
901 mProducer->setMaxDequeuedBufferCount(3);
902 for (size_t i = 0; i < 3; ++i) {
Nolan Scobie9c427942023-05-01 16:41:28 -0400903 status_t result = mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0,
904 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr);
Dan Stozae77c7662016-05-13 11:37:28 -0700905 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
906 ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
907 }
908 for (size_t i = 0; i < 3; ++i) {
909 ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
910 }
911
912 // Create 3 segments
913
914 // The first segment is a two-buffer segment, so we only put one buffer into
915 // the queue at a time
916 for (size_t i = 0; i < 5; ++i) {
Nolan Scobie9c427942023-05-01 16:41:28 -0400917 ASSERT_EQ(OK,
918 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
919 nullptr, nullptr));
Dan Stozae77c7662016-05-13 11:37:28 -0700920 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
921 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
922 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
923 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
924 std::this_thread::sleep_for(16ms);
925 }
926
927 // Sleep between segments
928 std::this_thread::sleep_for(500ms);
929
930 // The second segment is a double-buffer segment. It starts the same as the
931 // two-buffer segment, but then at the end, we put two buffers in the queue
932 // at the same time before draining it.
933 for (size_t i = 0; i < 5; ++i) {
Nolan Scobie9c427942023-05-01 16:41:28 -0400934 ASSERT_EQ(OK,
935 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
936 nullptr, nullptr));
Dan Stozae77c7662016-05-13 11:37:28 -0700937 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
938 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
939 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
940 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
941 std::this_thread::sleep_for(16ms);
942 }
Nolan Scobie9c427942023-05-01 16:41:28 -0400943 ASSERT_EQ(OK,
944 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
945 nullptr));
Dan Stozae77c7662016-05-13 11:37:28 -0700946 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
Nolan Scobie9c427942023-05-01 16:41:28 -0400947 ASSERT_EQ(OK,
948 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
949 nullptr));
Dan Stozae77c7662016-05-13 11:37:28 -0700950 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
951 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
952 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
953 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
954 std::this_thread::sleep_for(16ms);
955 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
956 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
957 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
958
959 // Sleep between segments
960 std::this_thread::sleep_for(500ms);
961
962 // The third segment is a triple-buffer segment, so the queue is switching
963 // between one buffer and two buffers deep.
Nolan Scobie9c427942023-05-01 16:41:28 -0400964 ASSERT_EQ(OK,
965 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
966 nullptr));
Dan Stozae77c7662016-05-13 11:37:28 -0700967 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
968 for (size_t i = 0; i < 5; ++i) {
Nolan Scobie9c427942023-05-01 16:41:28 -0400969 ASSERT_EQ(OK,
970 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
971 nullptr, nullptr));
Dan Stozae77c7662016-05-13 11:37:28 -0700972 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
973 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
974 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
975 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
976 std::this_thread::sleep_for(16ms);
977 }
978 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
979 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
980 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
981
982 // Now we read the segments
983 std::vector<OccupancyTracker::Segment> history;
984 ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
985
986 // Since we didn't force a flush, we should only get the first two segments
987 // (since the third segment hasn't been closed out by the appearance of a
988 // new segment yet)
989 ASSERT_EQ(2u, history.size());
990
991 // The first segment (which will be history[1], since the newest segment
992 // should be at the front of the vector) should be a two-buffer segment,
993 // which implies that the occupancy average should be between 0 and 1, and
994 // usedThirdBuffer should be false
995 const auto& firstSegment = history[1];
996 ASSERT_EQ(5u, firstSegment.numFrames);
997 ASSERT_LT(0, firstSegment.occupancyAverage);
998 ASSERT_GT(1, firstSegment.occupancyAverage);
999 ASSERT_EQ(false, firstSegment.usedThirdBuffer);
1000
1001 // The second segment should be a double-buffered segment, which implies that
1002 // the occupancy average should be between 0 and 1, but usedThirdBuffer
1003 // should be true
1004 const auto& secondSegment = history[0];
1005 ASSERT_EQ(7u, secondSegment.numFrames);
1006 ASSERT_LT(0, secondSegment.occupancyAverage);
1007 ASSERT_GT(1, secondSegment.occupancyAverage);
1008 ASSERT_EQ(true, secondSegment.usedThirdBuffer);
1009
1010 // If we read the segments again without flushing, we shouldn't get any new
1011 // segments
1012 ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
1013 ASSERT_EQ(0u, history.size());
1014
1015 // Read the segments again, this time forcing a flush so we get the third
1016 // segment
1017 ASSERT_EQ(OK, mConsumer->getOccupancyHistory(true, &history));
1018 ASSERT_EQ(1u, history.size());
1019
1020 // This segment should be a triple-buffered segment, which implies that the
1021 // occupancy average should be between 1 and 2, and usedThirdBuffer should
1022 // be true
1023 const auto& thirdSegment = history[0];
1024 ASSERT_EQ(6u, thirdSegment.numFrames);
1025 ASSERT_LT(1, thirdSegment.occupancyAverage);
1026 ASSERT_GT(2, thirdSegment.occupancyAverage);
1027 ASSERT_EQ(true, thirdSegment.usedThirdBuffer);
1028}
1029
Shuzhen Wang067fcd32019-08-14 10:41:12 -07001030struct BufferDiscardedListener : public BnProducerListener {
1031public:
1032 BufferDiscardedListener() = default;
1033 virtual ~BufferDiscardedListener() = default;
1034
1035 virtual void onBufferReleased() {}
1036 virtual bool needsReleaseNotify() { return false; }
1037 virtual void onBuffersDiscarded(const std::vector<int32_t>& slots) {
1038 mDiscardedSlots.insert(mDiscardedSlots.end(), slots.begin(), slots.end());
1039 }
1040
1041 const std::vector<int32_t>& getDiscardedSlots() const { return mDiscardedSlots; }
1042private:
1043 // No need to use lock given the test triggers the listener in the same
1044 // thread context.
1045 std::vector<int32_t> mDiscardedSlots;
1046};
1047
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001048TEST_F(BufferQueueTest, TestDiscardFreeBuffers) {
1049 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -07001050 sp<MockConsumer> mc(new MockConsumer);
1051 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, false));
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001052 IGraphicBufferProducer::QueueBufferOutput output;
Shuzhen Wang067fcd32019-08-14 10:41:12 -07001053 sp<BufferDiscardedListener> pl(new BufferDiscardedListener);
1054 ASSERT_EQ(OK, mProducer->connect(pl,
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001055 NATIVE_WINDOW_API_CPU, false, &output));
1056
1057 int slot = BufferQueue::INVALID_BUFFER_SLOT;
1058 sp<Fence> fence = Fence::NO_FENCE;
1059 sp<GraphicBuffer> buffer = nullptr;
1060 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1061 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1062 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1063 BufferItem item{};
1064
1065 // Preallocate, dequeue, request, and cancel 4 buffers so we don't get
1066 // BUFFER_NEEDS_REALLOCATION below
1067 int slots[4] = {};
1068 mProducer->setMaxDequeuedBufferCount(4);
1069 for (size_t i = 0; i < 4; ++i) {
Nolan Scobie9c427942023-05-01 16:41:28 -04001070 status_t result = mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0,
1071 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr);
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001072 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1073 ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
1074 }
1075 for (size_t i = 0; i < 4; ++i) {
1076 ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
1077 }
1078
1079 // Get buffers in all states: dequeued, filled, acquired, free
1080
1081 // Fill 3 buffers
Nolan Scobie9c427942023-05-01 16:41:28 -04001082 ASSERT_EQ(OK,
1083 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1084 nullptr));
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001085 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
Nolan Scobie9c427942023-05-01 16:41:28 -04001086 ASSERT_EQ(OK,
1087 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1088 nullptr));
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001089 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
Nolan Scobie9c427942023-05-01 16:41:28 -04001090 ASSERT_EQ(OK,
1091 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1092 nullptr));
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001093 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1094 // Dequeue 1 buffer
Nolan Scobie9c427942023-05-01 16:41:28 -04001095 ASSERT_EQ(OK,
1096 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1097 nullptr));
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001098
1099 // Acquire and free 1 buffer
1100 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1101 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1102 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
Shuzhen Wang067fcd32019-08-14 10:41:12 -07001103 int releasedSlot = item.mSlot;
1104
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001105 // Acquire 1 buffer, leaving 1 filled buffer in queue
1106 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1107
1108 // Now discard the free buffers
1109 ASSERT_EQ(OK, mConsumer->discardFreeBuffers());
1110
Shuzhen Wang067fcd32019-08-14 10:41:12 -07001111 // Check onBuffersDiscarded is called with correct slots
1112 auto buffersDiscarded = pl->getDiscardedSlots();
1113 ASSERT_EQ(buffersDiscarded.size(), 1);
1114 ASSERT_EQ(buffersDiscarded[0], releasedSlot);
1115
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001116 // Check no free buffers in dump
1117 String8 dumpString;
Dan Stoza0c9a1ed2017-04-06 15:10:21 -07001118 mConsumer->dumpState(String8{}, &dumpString);
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001119
1120 // Parse the dump to ensure that all buffer slots that are FREE also
1121 // have a null GraphicBuffer
1122 // Fragile - assumes the following format for the dump for a buffer entry:
1123 // ":%p\][^:]*state=FREE" where %p is the buffer pointer in hex.
1124 ssize_t idx = dumpString.find("state=FREE");
1125 while (idx != -1) {
1126 ssize_t bufferPtrIdx = idx - 1;
1127 while (bufferPtrIdx > 0) {
1128 if (dumpString[bufferPtrIdx] == ':') {
1129 bufferPtrIdx++;
1130 break;
1131 }
1132 bufferPtrIdx--;
1133 }
1134 ASSERT_GT(bufferPtrIdx, 0) << "Can't parse queue dump to validate";
1135 ssize_t nullPtrIdx = dumpString.find("0x0]", bufferPtrIdx);
1136 ASSERT_EQ(bufferPtrIdx, nullPtrIdx) << "Free buffer not discarded";
1137 idx = dumpString.find("FREE", idx + 1);
1138 }
1139}
1140
Shuzhen Wang22f842b2017-01-18 23:02:36 -08001141TEST_F(BufferQueueTest, TestBufferReplacedInQueueBuffer) {
1142 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -07001143 sp<MockConsumer> mc(new MockConsumer);
1144 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
Shuzhen Wang22f842b2017-01-18 23:02:36 -08001145 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -07001146 ASSERT_EQ(OK,
1147 mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, true, &output));
Shuzhen Wang22f842b2017-01-18 23:02:36 -08001148 ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
1149
1150 int slot = BufferQueue::INVALID_BUFFER_SLOT;
1151 sp<Fence> fence = Fence::NO_FENCE;
1152 sp<GraphicBuffer> buffer = nullptr;
1153 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1154 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1155 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1156 BufferItem item{};
1157
1158 // Preallocate, dequeue, request, and cancel 2 buffers so we don't get
1159 // BUFFER_NEEDS_REALLOCATION below
1160 int slots[2] = {};
1161 ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
1162 for (size_t i = 0; i < 2; ++i) {
Nolan Scobie9c427942023-05-01 16:41:28 -04001163 status_t result = mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0,
1164 TEST_PRODUCER_USAGE_BITS, nullptr, nullptr);
Shuzhen Wang22f842b2017-01-18 23:02:36 -08001165 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1166 ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
1167 }
1168 for (size_t i = 0; i < 2; ++i) {
1169 ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
1170 }
1171
1172 // Fill 2 buffers without consumer consuming them. Verify that all
1173 // queued buffer returns proper bufferReplaced flag
Nolan Scobie9c427942023-05-01 16:41:28 -04001174 ASSERT_EQ(OK,
1175 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1176 nullptr));
Shuzhen Wang22f842b2017-01-18 23:02:36 -08001177 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1178 ASSERT_EQ(false, output.bufferReplaced);
Nolan Scobie9c427942023-05-01 16:41:28 -04001179 ASSERT_EQ(OK,
1180 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1181 nullptr));
Shuzhen Wang22f842b2017-01-18 23:02:36 -08001182 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1183 ASSERT_EQ(true, output.bufferReplaced);
1184}
1185
Dan Stozad4c6f992017-03-21 13:43:22 -07001186TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) {
1187 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -07001188 sp<MockConsumer> mc(new MockConsumer);
1189 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
Dan Stozad4c6f992017-03-21 13:43:22 -07001190 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -07001191 sp<IProducerListener> fakeListener(new StubProducerListener);
1192 ASSERT_EQ(OK, mProducer->connect(fakeListener, NATIVE_WINDOW_API_CPU, true, &output));
Dan Stozad4c6f992017-03-21 13:43:22 -07001193
1194 int slot = BufferQueue::INVALID_BUFFER_SLOT;
1195 sp<Fence> fence = Fence::NO_FENCE;
1196 sp<GraphicBuffer> buffer = nullptr;
1197 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1198 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1199 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1200
1201 // Dequeue, request, and queue one buffer
Nolan Scobie9c427942023-05-01 16:41:28 -04001202 status_t result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS,
1203 nullptr, nullptr);
Dan Stozad4c6f992017-03-21 13:43:22 -07001204 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1205 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
1206 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1207
1208 // Acquire and release the buffer. Upon acquiring, the buffer handle should
1209 // be non-null since this is the first time we've acquired this slot.
1210 BufferItem item;
1211 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1212 ASSERT_EQ(slot, item.mSlot);
1213 ASSERT_NE(nullptr, item.mGraphicBuffer.get());
1214 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1215 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
1216
1217 // Dequeue and queue the buffer again
Nolan Scobie9c427942023-05-01 16:41:28 -04001218 ASSERT_EQ(OK,
1219 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1220 nullptr));
Dan Stozad4c6f992017-03-21 13:43:22 -07001221 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1222
1223 // Acquire and release the buffer again. Upon acquiring, the buffer handle
1224 // should be null since this is not the first time we've acquired this slot.
1225 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1226 ASSERT_EQ(slot, item.mSlot);
1227 ASSERT_EQ(nullptr, item.mGraphicBuffer.get());
1228 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1229 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
1230
1231 // Dequeue and queue the buffer again
Nolan Scobie9c427942023-05-01 16:41:28 -04001232 ASSERT_EQ(OK,
1233 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, TEST_PRODUCER_USAGE_BITS, nullptr,
1234 nullptr));
Dan Stozad4c6f992017-03-21 13:43:22 -07001235 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1236
1237 // Disconnect the producer end. This should clear all of the slots and mark
1238 // the buffer in the queue as stale.
1239 ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1240
1241 // Acquire the buffer again. Upon acquiring, the buffer handle should not be
1242 // null since the queued buffer should have been marked as stale, which
1243 // should trigger the BufferQueue to resend the buffer handle.
1244 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1245 ASSERT_EQ(slot, item.mSlot);
1246 ASSERT_NE(nullptr, item.mGraphicBuffer.get());
1247}
1248
Wonsik Kim3e198b22017-04-07 15:43:16 -07001249TEST_F(BufferQueueTest, TestProducerConnectDisconnect) {
1250 createBufferQueue();
Peiyong Lind8460c82020-07-28 16:04:22 -07001251 sp<MockConsumer> mc(new MockConsumer);
1252 ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
Wonsik Kim3e198b22017-04-07 15:43:16 -07001253 IGraphicBufferProducer::QueueBufferOutput output;
Peiyong Lind8460c82020-07-28 16:04:22 -07001254 sp<IProducerListener> fakeListener(new StubProducerListener);
Wonsik Kim3e198b22017-04-07 15:43:16 -07001255 ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
Peiyong Lind8460c82020-07-28 16:04:22 -07001256 ASSERT_EQ(OK, mProducer->connect(fakeListener, NATIVE_WINDOW_API_CPU, true, &output));
1257 ASSERT_EQ(BAD_VALUE, mProducer->connect(fakeListener, NATIVE_WINDOW_API_MEDIA, true, &output));
Wonsik Kim3e198b22017-04-07 15:43:16 -07001258
1259 ASSERT_EQ(BAD_VALUE, mProducer->disconnect(NATIVE_WINDOW_API_MEDIA));
1260 ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1261 ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1262}
1263
John Reck12daff92023-07-28 16:36:27 -04001264class Latch {
1265public:
1266 explicit Latch(int expected) : mExpected(expected) {}
1267 Latch(const Latch&) = delete;
1268 Latch& operator=(const Latch&) = delete;
1269
1270 void CountDown() {
1271 std::unique_lock<std::mutex> lock(mLock);
1272 mExpected--;
1273 if (mExpected <= 0) {
1274 mCV.notify_all();
1275 }
1276 }
1277
1278 void Wait() {
1279 std::unique_lock<std::mutex> lock(mLock);
1280 mCV.wait(lock, [&] { return mExpected == 0; });
1281 }
1282
1283private:
1284 int mExpected;
1285 std::mutex mLock;
1286 std::condition_variable mCV;
1287};
1288
1289struct OneshotOnDequeuedListener final : public BufferItemConsumer::FrameAvailableListener {
1290 OneshotOnDequeuedListener(std::function<void()>&& oneshot)
1291 : mOneshotRunnable(std::move(oneshot)) {}
1292
1293 std::function<void()> mOneshotRunnable;
1294
1295 void run() {
1296 if (mOneshotRunnable) {
1297 mOneshotRunnable();
1298 mOneshotRunnable = nullptr;
1299 }
1300 }
1301
1302 void onFrameDequeued(const uint64_t) override { run(); }
1303
1304 void onFrameAvailable(const BufferItem&) override {}
1305};
1306
1307// See b/270004534
1308TEST(BufferQueueThreading, TestProducerDequeueConsumerDestroy) {
1309 sp<IGraphicBufferProducer> producer;
1310 sp<IGraphicBufferConsumer> consumer;
1311 BufferQueue::createBufferQueue(&producer, &consumer);
1312
1313 sp<BufferItemConsumer> bufferConsumer =
1314 sp<BufferItemConsumer>::make(consumer, GRALLOC_USAGE_SW_READ_OFTEN, 2);
1315 ASSERT_NE(nullptr, bufferConsumer.get());
1316 sp<Surface> surface = sp<Surface>::make(producer);
1317 native_window_set_buffers_format(surface.get(), PIXEL_FORMAT_RGBA_8888);
1318 native_window_set_buffers_dimensions(surface.get(), 100, 100);
1319
1320 Latch triggerDisconnect(1);
1321 Latch resumeCallback(1);
1322 auto luckyListener = sp<OneshotOnDequeuedListener>::make([&]() {
1323 triggerDisconnect.CountDown();
1324 resumeCallback.Wait();
1325 });
1326 bufferConsumer->setFrameAvailableListener(luckyListener);
1327
1328 std::future<void> disconnecter = std::async(std::launch::async, [&]() {
1329 triggerDisconnect.Wait();
1330 luckyListener = nullptr;
1331 bufferConsumer = nullptr;
1332 resumeCallback.CountDown();
1333 });
1334
1335 std::future<void> render = std::async(std::launch::async, [=]() {
1336 ANativeWindow_Buffer buffer;
1337 surface->lock(&buffer, nullptr);
1338 surface->unlockAndPost();
1339 });
1340
1341 ASSERT_EQ(std::future_status::ready, render.wait_for(1s));
1342 EXPECT_EQ(nullptr, luckyListener.get());
1343 EXPECT_EQ(nullptr, bufferConsumer.get());
1344}
1345
Jamie Gennis9e75ddd2012-08-31 15:32:45 -07001346} // namespace android