blob: 55e6fbf8515b8656853a801c9aa7b5923fa13cf3 [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
Dan Stozac6f30bd2015-06-08 09:32:50 -070020#include "DummyConsumer.h"
21
Dan Stozacf3834d2015-03-11 14:04:22 -070022#include <gui/BufferItem.h>
Dan Stozaf0eaf252014-03-21 13:05:51 -070023#include <gui/BufferQueue.h>
24#include <gui/IProducerListener.h>
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070025
26#include <ui/GraphicBuffer.h>
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070027
Dan Stoza1a0b8612014-03-20 15:36:31 -070028#include <binder/IPCThreadState.h>
Dan Stoza9f3053d2014-03-06 15:14:33 -080029#include <binder/IServiceManager.h>
Dan Stoza1a0b8612014-03-20 15:36:31 -070030#include <binder/ProcessState.h>
Dan Stozaf0eaf252014-03-21 13:05:51 -070031
32#include <utils/String8.h>
33#include <utils/threads.h>
34
35#include <gtest/gtest.h>
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070036
Dan Stozae77c7662016-05-13 11:37:28 -070037#include <thread>
38
39using namespace std::chrono_literals;
40
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070041namespace android {
42
43class BufferQueueTest : public ::testing::Test {
Dan Stoza9f3053d2014-03-06 15:14:33 -080044
45public:
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070046protected:
Dan Stoza9f3053d2014-03-06 15:14:33 -080047 BufferQueueTest() {
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070048 const ::testing::TestInfo* const testInfo =
49 ::testing::UnitTest::GetInstance()->current_test_info();
50 ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
51 testInfo->name());
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070052 }
53
Dan Stoza9f3053d2014-03-06 15:14:33 -080054 ~BufferQueueTest() {
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070055 const ::testing::TestInfo* const testInfo =
56 ::testing::UnitTest::GetInstance()->current_test_info();
57 ALOGV("End test: %s.%s", testInfo->test_case_name(),
58 testInfo->name());
59 }
60
Igor Murashkin7ea777f2013-11-18 16:58:36 -080061 void GetMinUndequeuedBufferCount(int* bufferCount) {
Dan Stoza9f3053d2014-03-06 15:14:33 -080062 ASSERT_TRUE(bufferCount != NULL);
63 ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
64 bufferCount));
65 ASSERT_GE(*bufferCount, 0);
Igor Murashkin7ea777f2013-11-18 16:58:36 -080066 }
67
Dan Stoza1a0b8612014-03-20 15:36:31 -070068 void createBufferQueue() {
69 BufferQueue::createBufferQueue(&mProducer, &mConsumer);
70 }
Jamie Gennis9e75ddd2012-08-31 15:32:45 -070071
Pablo Ceballosff95aab2016-01-13 17:09:58 -080072 void testBufferItem(const IGraphicBufferProducer::QueueBufferInput& input,
73 const BufferItem& item) {
74 int64_t timestamp;
75 bool isAutoTimestamp;
76 android_dataspace dataSpace;
77 Rect crop;
78 int scalingMode;
79 uint32_t transform;
80 sp<Fence> fence;
81
82 input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop,
83 &scalingMode, &transform, &fence, NULL);
84 ASSERT_EQ(timestamp, item.mTimestamp);
85 ASSERT_EQ(isAutoTimestamp, item.mIsAutoTimestamp);
86 ASSERT_EQ(dataSpace, item.mDataSpace);
87 ASSERT_EQ(crop, item.mCrop);
88 ASSERT_EQ(static_cast<uint32_t>(scalingMode), item.mScalingMode);
89 ASSERT_EQ(transform, item.mTransform);
90 ASSERT_EQ(fence, item.mFence);
91 }
92
Dan Stoza1a0b8612014-03-20 15:36:31 -070093 sp<IGraphicBufferProducer> mProducer;
94 sp<IGraphicBufferConsumer> mConsumer;
95};
Dan Stoza9f3053d2014-03-06 15:14:33 -080096
Dan Stozaf8cebe52015-04-20 12:09:38 -070097static const uint32_t TEST_DATA = 0x12345678u;
98
Dan Stoza1a0b8612014-03-20 15:36:31 -070099// XXX: Tests that fork a process to hold the BufferQueue must run before tests
100// that use a local BufferQueue, or else Binder will get unhappy
Kalle Raita88752d72017-03-27 14:11:54 -0700101//
102// In one instance this was a crash in the createBufferQueue where the
103// binder call to create a buffer allocator apparently got garbage back.
104// See b/36592665.
105TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700106 const String16 PRODUCER_NAME = String16("BQTestProducer");
107 const String16 CONSUMER_NAME = String16("BQTestConsumer");
108
109 pid_t forkPid = fork();
110 ASSERT_NE(forkPid, -1);
111
112 if (forkPid == 0) {
113 // Child process
Dan Stozab3d0bdf2014-04-07 16:33:59 -0700114 sp<IGraphicBufferProducer> producer;
115 sp<IGraphicBufferConsumer> consumer;
Dan Stoza1a0b8612014-03-20 15:36:31 -0700116 BufferQueue::createBufferQueue(&producer, &consumer);
117 sp<IServiceManager> serviceManager = defaultServiceManager();
Marco Nelissen097ca272014-11-14 08:01:01 -0800118 serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
119 serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
Dan Stoza1a0b8612014-03-20 15:36:31 -0700120 ProcessState::self()->startThreadPool();
121 IPCThreadState::self()->joinThreadPool();
122 LOG_ALWAYS_FATAL("Shouldn't be here");
123 }
124
125 sp<IServiceManager> serviceManager = defaultServiceManager();
126 sp<IBinder> binderProducer =
127 serviceManager->getService(PRODUCER_NAME);
128 mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
129 EXPECT_TRUE(mProducer != NULL);
130 sp<IBinder> binderConsumer =
131 serviceManager->getService(CONSUMER_NAME);
132 mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
133 EXPECT_TRUE(mConsumer != NULL);
134
135 sp<DummyConsumer> dc(new DummyConsumer);
136 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
137 IGraphicBufferProducer::QueueBufferOutput output;
138 ASSERT_EQ(OK,
139 mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
140
141 int slot;
142 sp<Fence> fence;
143 sp<GraphicBuffer> buffer;
144 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700145 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700146 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr));
Dan Stoza1a0b8612014-03-20 15:36:31 -0700147 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
148
149 uint32_t* dataIn;
150 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
151 reinterpret_cast<void**>(&dataIn)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700152 *dataIn = TEST_DATA;
Dan Stoza1a0b8612014-03-20 15:36:31 -0700153 ASSERT_EQ(OK, buffer->unlock());
154
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800155 IGraphicBufferProducer::QueueBufferInput input(0, false,
156 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700157 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700158 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
159
Dan Stozacf3834d2015-03-11 14:04:22 -0700160 BufferItem item;
Dan Stoza1a0b8612014-03-20 15:36:31 -0700161 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
162
163 uint32_t* dataOut;
164 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
165 reinterpret_cast<void**>(&dataOut)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700166 ASSERT_EQ(*dataOut, TEST_DATA);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700167 ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
168}
169
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700170TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700171 createBufferQueue();
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700172 sp<DummyConsumer> dc(new DummyConsumer);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800173 mConsumer->consumerConnect(dc, false);
Andy McFadden2adaf042012-12-18 09:49:45 -0800174 IGraphicBufferProducer::QueueBufferOutput qbo;
Dan Stozaf0eaf252014-03-21 13:05:51 -0700175 mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
176 &qbo);
Pablo Ceballosfa455352015-08-12 17:47:47 -0700177 mProducer->setMaxDequeuedBufferCount(3);
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700178
179 int slot;
180 sp<Fence> fence;
181 sp<GraphicBuffer> buf;
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800182 IGraphicBufferProducer::QueueBufferInput qbi(0, false,
183 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700184 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Dan Stozacf3834d2015-03-11 14:04:22 -0700185 BufferItem item;
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700186
187 for (int i = 0; i < 2; i++) {
Andy McFadden2adaf042012-12-18 09:49:45 -0800188 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700189 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700190 GRALLOC_USAGE_SW_READ_OFTEN, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800191 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
192 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
193 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700194 }
195
Andy McFadden2adaf042012-12-18 09:49:45 -0800196 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700197 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700198 GRALLOC_USAGE_SW_READ_OFTEN, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800199 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
200 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700201
202 // Acquire the third buffer, which should fail.
Dan Stoza9f3053d2014-03-06 15:14:33 -0800203 ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0));
Jamie Gennis9e75ddd2012-08-31 15:32:45 -0700204}
205
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700206TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700207 createBufferQueue();
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700208 sp<DummyConsumer> dc(new DummyConsumer);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800209 mConsumer->consumerConnect(dc, false);
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700210
Pablo Ceballos72daab62015-12-07 16:38:43 -0800211 EXPECT_EQ(OK, mConsumer->setMaxBufferCount(10));
212 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(10));
213
214 IGraphicBufferProducer::QueueBufferOutput qbo;
215 mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
216 &qbo);
217 mProducer->setMaxDequeuedBufferCount(3);
218
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800219 int minBufferCount;
220 ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800221 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
222 minBufferCount - 1));
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800223
Dan Stoza9f3053d2014-03-06 15:14:33 -0800224 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0));
225 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3));
226 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700227 BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800228 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700229
Pablo Ceballos72daab62015-12-07 16:38:43 -0800230 int slot;
231 sp<Fence> fence;
232 sp<GraphicBuffer> buf;
233 IGraphicBufferProducer::QueueBufferInput qbi(0, false,
234 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
235 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
236 BufferItem item;
237 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
238 for (int i = 0; i < 3; i++) {
239 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
240 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700241 GRALLOC_USAGE_SW_READ_OFTEN, nullptr));
Pablo Ceballos72daab62015-12-07 16:38:43 -0800242 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
243 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
244 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
245 }
246
247 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(2));
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700248}
249
250TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700251 createBufferQueue();
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700252 sp<DummyConsumer> dc(new DummyConsumer);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800253 mConsumer->consumerConnect(dc, false);
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700254
Pablo Ceballos72daab62015-12-07 16:38:43 -0800255 IGraphicBufferProducer::QueueBufferOutput qbo;
256 mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
257 &qbo);
258 mProducer->setMaxDequeuedBufferCount(2);
259
Igor Murashkin7ea777f2013-11-18 16:58:36 -0800260 int minBufferCount;
261 ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
262
Dan Stoza9f3053d2014-03-06 15:14:33 -0800263 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
264 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2));
265 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount));
Pablo Ceballos72daab62015-12-07 16:38:43 -0800266
267 int slot;
268 sp<Fence> fence;
269 sp<GraphicBuffer> buf;
270 IGraphicBufferProducer::QueueBufferInput qbi(0, false,
271 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
272 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
273 BufferItem item;
274
275 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
276 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700277 GRALLOC_USAGE_SW_READ_OFTEN, nullptr));
Pablo Ceballos72daab62015-12-07 16:38:43 -0800278 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
279 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
280 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
281
282 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
283
284 for (int i = 0; i < 2; i++) {
285 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
286 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700287 GRALLOC_USAGE_SW_READ_OFTEN, nullptr));
Pablo Ceballos72daab62015-12-07 16:38:43 -0800288 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
289 ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
290 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
291 }
292
Dan Stoza9f3053d2014-03-06 15:14:33 -0800293 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(
Jamie Gennisc68f2ec2012-08-30 18:36:22 -0700294 BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
295}
296
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700297TEST_F(BufferQueueTest, SetMaxBufferCountWithLegalValues_Succeeds) {
298 createBufferQueue();
299 sp<DummyConsumer> dc(new DummyConsumer);
300 mConsumer->consumerConnect(dc, false);
301
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700302 // Test shared buffer mode
Pablo Ceballos19e3e062015-08-19 16:16:06 -0700303 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
304}
305
306TEST_F(BufferQueueTest, SetMaxBufferCountWithIllegalValues_ReturnsError) {
307 createBufferQueue();
308 sp<DummyConsumer> dc(new DummyConsumer);
309 mConsumer->consumerConnect(dc, false);
310
311 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(0));
312 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(
313 BufferQueue::NUM_BUFFER_SLOTS + 1));
314
315 EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(5));
316 EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(3));
317}
318
Dan Stoza9f3053d2014-03-06 15:14:33 -0800319TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700320 createBufferQueue();
Dan Stoza9f3053d2014-03-06 15:14:33 -0800321 sp<DummyConsumer> dc(new DummyConsumer);
322 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
323 IGraphicBufferProducer::QueueBufferOutput output;
Dan Stozaf0eaf252014-03-21 13:05:51 -0700324 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
325 NATIVE_WINDOW_API_CPU, false, &output));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800326
327 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low
328 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(
329 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
330 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued
331
332 int slot;
333 sp<Fence> fence;
334 sp<GraphicBuffer> buffer;
335 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700336 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700337 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800338 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested
339 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
340 ASSERT_EQ(OK, mProducer->detachBuffer(slot));
341 ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued
342
343 sp<GraphicBuffer> safeToClobberBuffer;
344 // Can no longer request buffer from this slot
345 ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer));
346
347 uint32_t* dataIn;
348 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
349 reinterpret_cast<void**>(&dataIn)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700350 *dataIn = TEST_DATA;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800351 ASSERT_EQ(OK, buffer->unlock());
352
353 int newSlot;
354 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(NULL, safeToClobberBuffer));
355 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL));
356
357 ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800358 IGraphicBufferProducer::QueueBufferInput input(0, false,
359 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700360 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800361 ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
362
Dan Stozacf3834d2015-03-11 14:04:22 -0700363 BufferItem item;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800364 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
365
366 uint32_t* dataOut;
367 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
368 reinterpret_cast<void**>(&dataOut)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700369 ASSERT_EQ(*dataOut, TEST_DATA);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700370 ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
Dan Stoza9f3053d2014-03-06 15:14:33 -0800371}
372
373TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700374 createBufferQueue();
Dan Stoza9f3053d2014-03-06 15:14:33 -0800375 sp<DummyConsumer> dc(new DummyConsumer);
376 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
377 IGraphicBufferProducer::QueueBufferOutput output;
Dan Stozaf0eaf252014-03-21 13:05:51 -0700378 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
379 NATIVE_WINDOW_API_CPU, false, &output));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800380
381 int slot;
382 sp<Fence> fence;
383 sp<GraphicBuffer> buffer;
384 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700385 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700386 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800387 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800388 IGraphicBufferProducer::QueueBufferInput input(0, false,
389 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700390 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800391 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
392
393 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low
394 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(
395 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
396 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
397
Dan Stozacf3834d2015-03-11 14:04:22 -0700398 BufferItem item;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800399 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
400
Pablo Ceballos47650f42015-08-04 16:38:17 -0700401 ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
402 ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mSlot)); // Not acquired
Dan Stoza9f3053d2014-03-06 15:14:33 -0800403
404 uint32_t* dataIn;
405 ASSERT_EQ(OK, item.mGraphicBuffer->lock(
406 GraphicBuffer::USAGE_SW_WRITE_OFTEN,
407 reinterpret_cast<void**>(&dataIn)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700408 *dataIn = TEST_DATA;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800409 ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
410
411 int newSlot;
412 sp<GraphicBuffer> safeToClobberBuffer;
413 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(NULL, safeToClobberBuffer));
414 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, NULL));
415 ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer));
416
Dan Stoza99b18b42014-03-28 15:34:33 -0700417 ASSERT_EQ(OK, mConsumer->releaseBuffer(newSlot, 0, EGL_NO_DISPLAY,
Dan Stoza9f3053d2014-03-06 15:14:33 -0800418 EGL_NO_SYNC_KHR, Fence::NO_FENCE));
419
420 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700421 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700422 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800423 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
424
425 uint32_t* dataOut;
426 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
427 reinterpret_cast<void**>(&dataOut)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700428 ASSERT_EQ(*dataOut, TEST_DATA);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700429 ASSERT_EQ(OK, buffer->unlock());
Dan Stoza9f3053d2014-03-06 15:14:33 -0800430}
431
432TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
Dan Stoza1a0b8612014-03-20 15:36:31 -0700433 createBufferQueue();
Dan Stoza9f3053d2014-03-06 15:14:33 -0800434 sp<DummyConsumer> dc(new DummyConsumer);
435 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
436 IGraphicBufferProducer::QueueBufferOutput output;
Dan Stozaf0eaf252014-03-21 13:05:51 -0700437 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
438 NATIVE_WINDOW_API_CPU, false, &output));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800439
440 int slot;
441 sp<Fence> fence;
442 sp<GraphicBuffer> buffer;
443 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700444 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700445 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800446 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
447
448 uint32_t* dataIn;
449 ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
450 reinterpret_cast<void**>(&dataIn)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700451 *dataIn = TEST_DATA;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800452 ASSERT_EQ(OK, buffer->unlock());
453
Eino-Ville Talvala82c6bcc2015-02-19 16:10:43 -0800454 IGraphicBufferProducer::QueueBufferInput input(0, false,
455 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700456 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Dan Stoza9f3053d2014-03-06 15:14:33 -0800457 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
458
Dan Stozacf3834d2015-03-11 14:04:22 -0700459 BufferItem item;
Dan Stoza9f3053d2014-03-06 15:14:33 -0800460 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
Pablo Ceballos47650f42015-08-04 16:38:17 -0700461 ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
Dan Stoza9f3053d2014-03-06 15:14:33 -0800462
463 int newSlot;
464 ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
465 ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
466 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
467
468 uint32_t* dataOut;
469 ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
470 reinterpret_cast<void**>(&dataOut)));
Dan Stozaf8cebe52015-04-20 12:09:38 -0700471 ASSERT_EQ(*dataOut, TEST_DATA);
Dan Stoza1a0b8612014-03-20 15:36:31 -0700472 ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
Dan Stoza9f3053d2014-03-06 15:14:33 -0800473}
474
Dan Stoza9de72932015-04-16 17:28:43 -0700475TEST_F(BufferQueueTest, TestDisallowingAllocation) {
476 createBufferQueue();
477 sp<DummyConsumer> dc(new DummyConsumer);
478 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
479 IGraphicBufferProducer::QueueBufferOutput output;
480 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
481 NATIVE_WINDOW_API_CPU, true, &output));
482
483 static const uint32_t WIDTH = 320;
484 static const uint32_t HEIGHT = 240;
485
486 ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT));
487
488 int slot;
489 sp<Fence> fence;
490 sp<GraphicBuffer> buffer;
491 // This should return an error since it would require an allocation
492 ASSERT_EQ(OK, mProducer->allowAllocation(false));
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700493 ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, 0, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700494 0, GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr));
Dan Stoza9de72932015-04-16 17:28:43 -0700495
496 // This should succeed, now that we've lifted the prohibition
497 ASSERT_EQ(OK, mProducer->allowAllocation(true));
498 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700499 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700500 GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr));
Dan Stoza9de72932015-04-16 17:28:43 -0700501
502 // Release the previous buffer back to the BufferQueue
503 mProducer->cancelBuffer(slot, fence);
504
505 // This should fail since we're requesting a different size
506 ASSERT_EQ(OK, mProducer->allowAllocation(false));
Pablo Ceballos567dbbb2015-08-26 18:59:08 -0700507 ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700508 WIDTH * 2, HEIGHT * 2, 0, GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr));
Dan Stoza9de72932015-04-16 17:28:43 -0700509}
510
Dan Stoza812ed062015-06-02 15:45:22 -0700511TEST_F(BufferQueueTest, TestGenerationNumbers) {
512 createBufferQueue();
513 sp<DummyConsumer> dc(new DummyConsumer);
514 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
515 IGraphicBufferProducer::QueueBufferOutput output;
516 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
517 NATIVE_WINDOW_API_CPU, true, &output));
518
519 ASSERT_EQ(OK, mProducer->setGenerationNumber(1));
520
521 // Get one buffer to play with
522 int slot;
523 sp<Fence> fence;
524 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700525 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
Dan Stoza812ed062015-06-02 15:45:22 -0700526
527 sp<GraphicBuffer> buffer;
528 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
529
530 // Ensure that the generation number we set propagates to allocated buffers
531 ASSERT_EQ(1U, buffer->getGenerationNumber());
532
533 ASSERT_EQ(OK, mProducer->detachBuffer(slot));
534
535 ASSERT_EQ(OK, mProducer->setGenerationNumber(2));
536
537 // These should fail, since we've changed the generation number on the queue
538 int outSlot;
539 ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&outSlot, buffer));
540 ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&outSlot, buffer));
541
542 buffer->setGenerationNumber(2);
543
544 // This should succeed now that we've changed the buffer's generation number
545 ASSERT_EQ(OK, mProducer->attachBuffer(&outSlot, buffer));
546
547 ASSERT_EQ(OK, mProducer->detachBuffer(outSlot));
548
549 // This should also succeed with the new generation number
550 ASSERT_EQ(OK, mConsumer->attachBuffer(&outSlot, buffer));
551}
552
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700553TEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) {
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700554 createBufferQueue();
555 sp<DummyConsumer> dc(new DummyConsumer);
556 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
557 IGraphicBufferProducer::QueueBufferOutput output;
558 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
559 NATIVE_WINDOW_API_CPU, true, &output));
560
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700561 ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700562
563 // Get a buffer
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700564 int sharedSlot;
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700565 sp<Fence> fence;
566 sp<GraphicBuffer> buffer;
567 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700568 mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700569 ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700570
571 // Queue the buffer
572 IGraphicBufferProducer::QueueBufferInput input(0, false,
573 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
574 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700575 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700576
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800577 // Repeatedly queue and dequeue a buffer from the producer side, it should
578 // always return the same one. And we won't run out of buffers because it's
579 // always the same one and because async mode gets enabled.
580 int slot;
581 for (int i = 0; i < 5; i++) {
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700582 ASSERT_EQ(OK, mProducer->dequeueBuffer(
583 &slot, &fence, 0, 0, 0, 0, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700584 ASSERT_EQ(sharedSlot, slot);
585 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800586 }
587
588 // acquire the buffer
589 BufferItem item;
590 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700591 ASSERT_EQ(sharedSlot, item.mSlot);
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800592 testBufferItem(input, item);
593 ASSERT_EQ(true, item.mQueuedBuffer);
594 ASSERT_EQ(false, item.mAutoRefresh);
595
596 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
597 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
598
599 // attempt to acquire a second time should return no buffer available
600 ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
601 mConsumer->acquireBuffer(&item, 0));
602}
603
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700604TEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) {
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800605 createBufferQueue();
606 sp<DummyConsumer> dc(new DummyConsumer);
607 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
608 IGraphicBufferProducer::QueueBufferOutput output;
609 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
610 NATIVE_WINDOW_API_CPU, true, &output));
611
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700612 ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800613 ASSERT_EQ(OK, mProducer->setAutoRefresh(true));
614
615 // Get a buffer
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700616 int sharedSlot;
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800617 sp<Fence> fence;
618 sp<GraphicBuffer> buffer;
619 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700620 mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700621 ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800622
623 // Queue the buffer
624 IGraphicBufferProducer::QueueBufferInput input(0, false,
625 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
626 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700627 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800628
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700629 // Repeatedly acquire and release a buffer from the consumer side, it should
630 // always return the same one.
631 BufferItem item;
632 for (int i = 0; i < 5; i++) {
633 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700634 ASSERT_EQ(sharedSlot, item.mSlot);
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800635 testBufferItem(input, item);
636 ASSERT_EQ(i == 0, item.mQueuedBuffer);
637 ASSERT_EQ(true, item.mAutoRefresh);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700638
639 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
640 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
641 }
642
643 // Repeatedly queue and dequeue a buffer from the producer side, it should
644 // always return the same one.
645 int slot;
646 for (int i = 0; i < 5; i++) {
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700647 ASSERT_EQ(OK, mProducer->dequeueBuffer(
648 &slot, &fence, 0, 0, 0, 0, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700649 ASSERT_EQ(sharedSlot, slot);
650 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700651 }
652
653 // Repeatedly acquire and release a buffer from the consumer side, it should
654 // always return the same one. First grabbing them from the queue and then
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700655 // when the queue is empty, returning the shared buffer.
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700656 for (int i = 0; i < 10; i++) {
657 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700658 ASSERT_EQ(sharedSlot, item.mSlot);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700659 ASSERT_EQ(0, item.mTimestamp);
660 ASSERT_EQ(false, item.mIsAutoTimestamp);
661 ASSERT_EQ(HAL_DATASPACE_UNKNOWN, item.mDataSpace);
662 ASSERT_EQ(Rect(0, 0, 1, 1), item.mCrop);
663 ASSERT_EQ(NATIVE_WINDOW_SCALING_MODE_FREEZE, item.mScalingMode);
Dan Stoza5ecfb682016-01-04 17:01:02 -0800664 ASSERT_EQ(0u, item.mTransform);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700665 ASSERT_EQ(Fence::NO_FENCE, item.mFence);
Pablo Ceballosff95aab2016-01-13 17:09:58 -0800666 ASSERT_EQ(i == 0, item.mQueuedBuffer);
667 ASSERT_EQ(true, item.mAutoRefresh);
Pablo Ceballosccdfd602015-10-07 15:05:45 -0700668
669 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
670 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
671 }
672}
673
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700674TEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) {
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700675 createBufferQueue();
676 sp<DummyConsumer> dc(new DummyConsumer);
677 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
678 IGraphicBufferProducer::QueueBufferOutput output;
679 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
680 NATIVE_WINDOW_API_CPU, true, &output));
681
682 // Dequeue a buffer
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700683 int sharedSlot;
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700684 sp<Fence> fence;
685 sp<GraphicBuffer> buffer;
686 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700687 mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700688 ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700689
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700690 // Enable shared buffer mode
691 ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700692
693 // Queue the buffer
694 IGraphicBufferProducer::QueueBufferInput input(0, false,
695 HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
696 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700697 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700698
699 // Repeatedly queue and dequeue a buffer from the producer side, it should
700 // always return the same one. And we won't run out of buffers because it's
701 // always the same one and because async mode gets enabled.
702 int slot;
703 for (int i = 0; i < 5; i++) {
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700704 ASSERT_EQ(OK, mProducer->dequeueBuffer(
705 &slot, &fence, 0, 0, 0, 0, nullptr));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700706 ASSERT_EQ(sharedSlot, slot);
707 ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700708 }
709
710 // acquire the buffer
711 BufferItem item;
712 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
Pablo Ceballos3559fbf2016-03-17 15:50:23 -0700713 ASSERT_EQ(sharedSlot, item.mSlot);
Pablo Ceballos295a9fc2016-03-14 16:02:19 -0700714 testBufferItem(input, item);
715 ASSERT_EQ(true, item.mQueuedBuffer);
716 ASSERT_EQ(false, item.mAutoRefresh);
717
718 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
719 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
720
721 // attempt to acquire a second time should return no buffer available
722 ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
723 mConsumer->acquireBuffer(&item, 0));
724}
725
Dan Stoza127fc632015-06-30 13:43:32 -0700726TEST_F(BufferQueueTest, TestTimeouts) {
727 createBufferQueue();
728 sp<DummyConsumer> dc(new DummyConsumer);
729 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
730 IGraphicBufferProducer::QueueBufferOutput output;
731 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
732 NATIVE_WINDOW_API_CPU, true, &output));
733
734 // Fill up the queue. Since the controlledByApp flags are set to true, this
735 // queue should be in non-blocking mode, and we should be recycling the same
736 // two buffers
737 for (int i = 0; i < 5; ++i) {
738 int slot = BufferQueue::INVALID_BUFFER_SLOT;
739 sp<Fence> fence = Fence::NO_FENCE;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700740 auto result = mProducer->dequeueBuffer(
741 &slot, &fence, 0, 0, 0, 0, nullptr);
Dan Stoza127fc632015-06-30 13:43:32 -0700742 if (i < 2) {
743 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
744 result);
745 } else {
746 ASSERT_EQ(OK, result);
747 }
748 sp<GraphicBuffer> buffer;
749 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
750 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
751 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
752 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
753 IGraphicBufferProducer::QueueBufferOutput output{};
754 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
755 }
756
757 const auto TIMEOUT = ms2ns(250);
758 mProducer->setDequeueTimeout(TIMEOUT);
759
760 // Setting a timeout will change the BufferQueue into blocking mode (with
761 // one droppable buffer in the queue and one free from the previous
762 // dequeue/queues), so dequeue and queue two more buffers: one to replace
763 // the current droppable buffer, and a second to max out the buffer count
764 sp<GraphicBuffer> buffer; // Save a buffer to attach later
765 for (int i = 0; i < 2; ++i) {
766 int slot = BufferQueue::INVALID_BUFFER_SLOT;
767 sp<Fence> fence = Fence::NO_FENCE;
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700768 ASSERT_EQ(OK, mProducer->dequeueBuffer(
769 &slot, &fence, 0, 0, 0, 0, nullptr));
Dan Stoza127fc632015-06-30 13:43:32 -0700770 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
771 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
772 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
773 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
774 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
775 }
776
777 int slot = BufferQueue::INVALID_BUFFER_SLOT;
778 sp<Fence> fence = Fence::NO_FENCE;
779 auto startTime = systemTime();
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700780 ASSERT_EQ(TIMED_OUT, mProducer->dequeueBuffer(
781 &slot, &fence, 0, 0, 0, 0, nullptr));
Dan Stoza127fc632015-06-30 13:43:32 -0700782 ASSERT_GE(systemTime() - startTime, TIMEOUT);
783
784 // We're technically attaching the same buffer multiple times (since we
785 // queued it previously), but that doesn't matter for this test
786 startTime = systemTime();
787 ASSERT_EQ(TIMED_OUT, mProducer->attachBuffer(&slot, buffer));
788 ASSERT_GE(systemTime() - startTime, TIMEOUT);
789}
790
Dan Stoza5ecfb682016-01-04 17:01:02 -0800791TEST_F(BufferQueueTest, CanAttachWhileDisallowingAllocation) {
792 createBufferQueue();
793 sp<DummyConsumer> dc(new DummyConsumer);
794 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
795 IGraphicBufferProducer::QueueBufferOutput output;
796 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
797 NATIVE_WINDOW_API_CPU, true, &output));
798
799 int slot = BufferQueue::INVALID_BUFFER_SLOT;
800 sp<Fence> sourceFence;
801 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700802 mProducer->dequeueBuffer(&slot, &sourceFence, 0, 0, 0, 0, nullptr));
Dan Stoza5ecfb682016-01-04 17:01:02 -0800803 sp<GraphicBuffer> buffer;
804 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
805 ASSERT_EQ(OK, mProducer->detachBuffer(slot));
806
807 ASSERT_EQ(OK, mProducer->allowAllocation(false));
808
809 slot = BufferQueue::INVALID_BUFFER_SLOT;
810 ASSERT_EQ(OK, mProducer->attachBuffer(&slot, buffer));
811}
812
Dan Stoza50101d02016-04-07 16:53:23 -0700813TEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) {
814 createBufferQueue();
815 sp<DummyConsumer> dc(new DummyConsumer);
816 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
817 IGraphicBufferProducer::QueueBufferOutput output;
818 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
819 NATIVE_WINDOW_API_CPU, false, &output));
820
821 // Dequeue and queue the first buffer, storing the handle
822 int slot = BufferQueue::INVALID_BUFFER_SLOT;
823 sp<Fence> fence;
824 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700825 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
Dan Stoza50101d02016-04-07 16:53:23 -0700826 sp<GraphicBuffer> firstBuffer;
827 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &firstBuffer));
828
829 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
830 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
831 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
832 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
833
834 // Dequeue a second buffer
835 slot = BufferQueue::INVALID_BUFFER_SLOT;
836 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700837 mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
Dan Stoza50101d02016-04-07 16:53:23 -0700838 sp<GraphicBuffer> secondBuffer;
839 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &secondBuffer));
840
841 // Ensure it's a new buffer
842 ASSERT_NE(firstBuffer->getNativeBuffer()->handle,
843 secondBuffer->getNativeBuffer()->handle);
844
845 // Queue the second buffer
846 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
847
848 // Acquire and release both buffers
849 for (size_t i = 0; i < 2; ++i) {
850 BufferItem item;
851 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
852 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
853 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
854 }
855
856 // Make sure we got the second buffer back
857 sp<GraphicBuffer> returnedBuffer;
858 sp<Fence> returnedFence;
John Reck1a61da52016-04-28 13:18:15 -0700859 float transform[16];
Dan Stoza50101d02016-04-07 16:53:23 -0700860 ASSERT_EQ(OK,
John Reck1a61da52016-04-28 13:18:15 -0700861 mProducer->getLastQueuedBuffer(&returnedBuffer, &returnedFence,
862 transform));
Dan Stoza50101d02016-04-07 16:53:23 -0700863 ASSERT_EQ(secondBuffer->getNativeBuffer()->handle,
864 returnedBuffer->getNativeBuffer()->handle);
865}
866
Dan Stozae77c7662016-05-13 11:37:28 -0700867TEST_F(BufferQueueTest, TestOccupancyHistory) {
868 createBufferQueue();
869 sp<DummyConsumer> dc(new DummyConsumer);
870 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
871 IGraphicBufferProducer::QueueBufferOutput output;
872 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
873 NATIVE_WINDOW_API_CPU, false, &output));
874
875 int slot = BufferQueue::INVALID_BUFFER_SLOT;
876 sp<Fence> fence = Fence::NO_FENCE;
877 sp<GraphicBuffer> buffer = nullptr;
878 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
879 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
880 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
881 BufferItem item{};
882
883 // Preallocate, dequeue, request, and cancel 3 buffers so we don't get
884 // BUFFER_NEEDS_REALLOCATION below
885 int slots[3] = {};
886 mProducer->setMaxDequeuedBufferCount(3);
887 for (size_t i = 0; i < 3; ++i) {
888 status_t result = mProducer->dequeueBuffer(&slots[i], &fence,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700889 0, 0, 0, 0, nullptr);
Dan Stozae77c7662016-05-13 11:37:28 -0700890 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
891 ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
892 }
893 for (size_t i = 0; i < 3; ++i) {
894 ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
895 }
896
897 // Create 3 segments
898
899 // The first segment is a two-buffer segment, so we only put one buffer into
900 // the queue at a time
901 for (size_t i = 0; i < 5; ++i) {
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700902 ASSERT_EQ(OK, mProducer->dequeueBuffer(
903 &slot, &fence, 0, 0, 0, 0, nullptr));
Dan Stozae77c7662016-05-13 11:37:28 -0700904 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
905 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
906 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
907 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
908 std::this_thread::sleep_for(16ms);
909 }
910
911 // Sleep between segments
912 std::this_thread::sleep_for(500ms);
913
914 // The second segment is a double-buffer segment. It starts the same as the
915 // two-buffer segment, but then at the end, we put two buffers in the queue
916 // at the same time before draining it.
917 for (size_t i = 0; i < 5; ++i) {
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700918 ASSERT_EQ(OK, mProducer->dequeueBuffer(
919 &slot, &fence, 0, 0, 0, 0, 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 }
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700926 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
Dan Stozae77c7662016-05-13 11:37:28 -0700927 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700928 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
Dan Stozae77c7662016-05-13 11:37:28 -0700929 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
930 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
931 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
932 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
933 std::this_thread::sleep_for(16ms);
934 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
935 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
936 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
937
938 // Sleep between segments
939 std::this_thread::sleep_for(500ms);
940
941 // The third segment is a triple-buffer segment, so the queue is switching
942 // between one buffer and two buffers deep.
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700943 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
Dan Stozae77c7662016-05-13 11:37:28 -0700944 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
945 for (size_t i = 0; i < 5; ++i) {
Brian Anderson7c3ba8a2016-07-25 12:48:08 -0700946 ASSERT_EQ(OK, mProducer->dequeueBuffer(
947 &slot, &fence, 0, 0, 0, 0, nullptr));
Dan Stozae77c7662016-05-13 11:37:28 -0700948 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
949 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
950 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
951 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
952 std::this_thread::sleep_for(16ms);
953 }
954 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
955 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
956 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
957
958 // Now we read the segments
959 std::vector<OccupancyTracker::Segment> history;
960 ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
961
962 // Since we didn't force a flush, we should only get the first two segments
963 // (since the third segment hasn't been closed out by the appearance of a
964 // new segment yet)
965 ASSERT_EQ(2u, history.size());
966
967 // The first segment (which will be history[1], since the newest segment
968 // should be at the front of the vector) should be a two-buffer segment,
969 // which implies that the occupancy average should be between 0 and 1, and
970 // usedThirdBuffer should be false
971 const auto& firstSegment = history[1];
972 ASSERT_EQ(5u, firstSegment.numFrames);
973 ASSERT_LT(0, firstSegment.occupancyAverage);
974 ASSERT_GT(1, firstSegment.occupancyAverage);
975 ASSERT_EQ(false, firstSegment.usedThirdBuffer);
976
977 // The second segment should be a double-buffered segment, which implies that
978 // the occupancy average should be between 0 and 1, but usedThirdBuffer
979 // should be true
980 const auto& secondSegment = history[0];
981 ASSERT_EQ(7u, secondSegment.numFrames);
982 ASSERT_LT(0, secondSegment.occupancyAverage);
983 ASSERT_GT(1, secondSegment.occupancyAverage);
984 ASSERT_EQ(true, secondSegment.usedThirdBuffer);
985
986 // If we read the segments again without flushing, we shouldn't get any new
987 // segments
988 ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
989 ASSERT_EQ(0u, history.size());
990
991 // Read the segments again, this time forcing a flush so we get the third
992 // segment
993 ASSERT_EQ(OK, mConsumer->getOccupancyHistory(true, &history));
994 ASSERT_EQ(1u, history.size());
995
996 // This segment should be a triple-buffered segment, which implies that the
997 // occupancy average should be between 1 and 2, and usedThirdBuffer should
998 // be true
999 const auto& thirdSegment = history[0];
1000 ASSERT_EQ(6u, thirdSegment.numFrames);
1001 ASSERT_LT(1, thirdSegment.occupancyAverage);
1002 ASSERT_GT(2, thirdSegment.occupancyAverage);
1003 ASSERT_EQ(true, thirdSegment.usedThirdBuffer);
1004}
1005
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001006TEST_F(BufferQueueTest, TestDiscardFreeBuffers) {
1007 createBufferQueue();
1008 sp<DummyConsumer> dc(new DummyConsumer);
1009 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
1010 IGraphicBufferProducer::QueueBufferOutput output;
1011 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
1012 NATIVE_WINDOW_API_CPU, false, &output));
1013
1014 int slot = BufferQueue::INVALID_BUFFER_SLOT;
1015 sp<Fence> fence = Fence::NO_FENCE;
1016 sp<GraphicBuffer> buffer = nullptr;
1017 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1018 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1019 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1020 BufferItem item{};
1021
1022 // Preallocate, dequeue, request, and cancel 4 buffers so we don't get
1023 // BUFFER_NEEDS_REALLOCATION below
1024 int slots[4] = {};
1025 mProducer->setMaxDequeuedBufferCount(4);
1026 for (size_t i = 0; i < 4; ++i) {
1027 status_t result = mProducer->dequeueBuffer(&slots[i], &fence,
Brian Anderson7c3ba8a2016-07-25 12:48:08 -07001028 0, 0, 0, 0, nullptr);
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001029 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1030 ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
1031 }
1032 for (size_t i = 0; i < 4; ++i) {
1033 ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
1034 }
1035
1036 // Get buffers in all states: dequeued, filled, acquired, free
1037
1038 // Fill 3 buffers
Brian Anderson7c3ba8a2016-07-25 12:48:08 -07001039 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001040 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
Brian Anderson7c3ba8a2016-07-25 12:48:08 -07001041 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001042 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
Brian Anderson7c3ba8a2016-07-25 12:48:08 -07001043 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001044 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1045 // Dequeue 1 buffer
Brian Anderson7c3ba8a2016-07-25 12:48:08 -07001046 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001047
1048 // Acquire and free 1 buffer
1049 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1050 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1051 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
1052 // Acquire 1 buffer, leaving 1 filled buffer in queue
1053 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1054
1055 // Now discard the free buffers
1056 ASSERT_EQ(OK, mConsumer->discardFreeBuffers());
1057
1058 // Check no free buffers in dump
1059 String8 dumpString;
Colin Cross3d1d2802016-09-26 18:10:16 -07001060 mConsumer->dumpState(dumpString, nullptr);
Eino-Ville Talvalabc2df652016-07-21 17:06:58 -07001061
1062 // Parse the dump to ensure that all buffer slots that are FREE also
1063 // have a null GraphicBuffer
1064 // Fragile - assumes the following format for the dump for a buffer entry:
1065 // ":%p\][^:]*state=FREE" where %p is the buffer pointer in hex.
1066 ssize_t idx = dumpString.find("state=FREE");
1067 while (idx != -1) {
1068 ssize_t bufferPtrIdx = idx - 1;
1069 while (bufferPtrIdx > 0) {
1070 if (dumpString[bufferPtrIdx] == ':') {
1071 bufferPtrIdx++;
1072 break;
1073 }
1074 bufferPtrIdx--;
1075 }
1076 ASSERT_GT(bufferPtrIdx, 0) << "Can't parse queue dump to validate";
1077 ssize_t nullPtrIdx = dumpString.find("0x0]", bufferPtrIdx);
1078 ASSERT_EQ(bufferPtrIdx, nullPtrIdx) << "Free buffer not discarded";
1079 idx = dumpString.find("FREE", idx + 1);
1080 }
1081}
1082
Shuzhen Wang22f842b2017-01-18 23:02:36 -08001083TEST_F(BufferQueueTest, TestBufferReplacedInQueueBuffer) {
1084 createBufferQueue();
1085 sp<DummyConsumer> dc(new DummyConsumer);
1086 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
1087 IGraphicBufferProducer::QueueBufferOutput output;
1088 ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
1089 NATIVE_WINDOW_API_CPU, true, &output));
1090 ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
1091
1092 int slot = BufferQueue::INVALID_BUFFER_SLOT;
1093 sp<Fence> fence = Fence::NO_FENCE;
1094 sp<GraphicBuffer> buffer = nullptr;
1095 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1096 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1097 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1098 BufferItem item{};
1099
1100 // Preallocate, dequeue, request, and cancel 2 buffers so we don't get
1101 // BUFFER_NEEDS_REALLOCATION below
1102 int slots[2] = {};
1103 ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
1104 for (size_t i = 0; i < 2; ++i) {
1105 status_t result = mProducer->dequeueBuffer(&slots[i], &fence,
1106 0, 0, 0, 0, nullptr);
1107 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1108 ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
1109 }
1110 for (size_t i = 0; i < 2; ++i) {
1111 ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
1112 }
1113
1114 // Fill 2 buffers without consumer consuming them. Verify that all
1115 // queued buffer returns proper bufferReplaced flag
1116 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
1117 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1118 ASSERT_EQ(false, output.bufferReplaced);
1119 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
1120 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1121 ASSERT_EQ(true, output.bufferReplaced);
1122}
1123
Dan Stozad4c6f992017-03-21 13:43:22 -07001124TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) {
1125 createBufferQueue();
1126 sp<DummyConsumer> dc(new DummyConsumer);
1127 ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
1128 IGraphicBufferProducer::QueueBufferOutput output;
1129 sp<IProducerListener> dummyListener(new DummyProducerListener);
1130 ASSERT_EQ(OK, mProducer->connect(dummyListener, NATIVE_WINDOW_API_CPU,
1131 true, &output));
1132
1133 int slot = BufferQueue::INVALID_BUFFER_SLOT;
1134 sp<Fence> fence = Fence::NO_FENCE;
1135 sp<GraphicBuffer> buffer = nullptr;
1136 IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1137 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1138 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1139
1140 // Dequeue, request, and queue one buffer
1141 status_t result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0,
1142 nullptr);
1143 ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1144 ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
1145 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1146
1147 // Acquire and release the buffer. Upon acquiring, the buffer handle should
1148 // be non-null since this is the first time we've acquired this slot.
1149 BufferItem item;
1150 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1151 ASSERT_EQ(slot, item.mSlot);
1152 ASSERT_NE(nullptr, item.mGraphicBuffer.get());
1153 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1154 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
1155
1156 // Dequeue and queue the buffer again
1157 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
1158 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1159
1160 // Acquire and release the buffer again. Upon acquiring, the buffer handle
1161 // should be null since this is not the first time we've acquired this slot.
1162 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1163 ASSERT_EQ(slot, item.mSlot);
1164 ASSERT_EQ(nullptr, item.mGraphicBuffer.get());
1165 ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1166 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
1167
1168 // Dequeue and queue the buffer again
1169 ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr));
1170 ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1171
1172 // Disconnect the producer end. This should clear all of the slots and mark
1173 // the buffer in the queue as stale.
1174 ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1175
1176 // Acquire the buffer again. Upon acquiring, the buffer handle should not be
1177 // null since the queued buffer should have been marked as stale, which
1178 // should trigger the BufferQueue to resend the buffer handle.
1179 ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1180 ASSERT_EQ(slot, item.mSlot);
1181 ASSERT_NE(nullptr, item.mGraphicBuffer.get());
1182}
1183
Jamie Gennis9e75ddd2012-08-31 15:32:45 -07001184} // namespace android