1 /*
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 
20 #include "DummyConsumer.h"
21 
22 #include <gui/BufferItem.h>
23 #include <gui/BufferQueue.h>
24 #include <gui/IProducerListener.h>
25 
26 #include <ui/GraphicBuffer.h>
27 
28 #include <binder/IPCThreadState.h>
29 #include <binder/IServiceManager.h>
30 #include <binder/ProcessState.h>
31 
32 #include <utils/String8.h>
33 #include <utils/threads.h>
34 
35 #include <system/window.h>
36 
37 #include <gtest/gtest.h>
38 
39 #include <thread>
40 
41 using namespace std::chrono_literals;
42 
43 namespace android {
44 
45 class BufferQueueTest : public ::testing::Test {
46 
47 public:
48 protected:
BufferQueueTest()49     BufferQueueTest() {
50         const ::testing::TestInfo* const testInfo =
51             ::testing::UnitTest::GetInstance()->current_test_info();
52         ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
53                 testInfo->name());
54     }
55 
~BufferQueueTest()56     ~BufferQueueTest() {
57         const ::testing::TestInfo* const testInfo =
58             ::testing::UnitTest::GetInstance()->current_test_info();
59         ALOGV("End test:   %s.%s", testInfo->test_case_name(),
60                 testInfo->name());
61     }
62 
GetMinUndequeuedBufferCount(int * bufferCount)63     void GetMinUndequeuedBufferCount(int* bufferCount) {
64         ASSERT_TRUE(bufferCount != nullptr);
65         ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
66                     bufferCount));
67         ASSERT_GE(*bufferCount, 0);
68     }
69 
createBufferQueue()70     void createBufferQueue() {
71         BufferQueue::createBufferQueue(&mProducer, &mConsumer);
72     }
73 
testBufferItem(const IGraphicBufferProducer::QueueBufferInput & input,const BufferItem & item)74     void testBufferItem(const IGraphicBufferProducer::QueueBufferInput& input,
75             const BufferItem& item) {
76         int64_t timestamp;
77         bool isAutoTimestamp;
78         android_dataspace dataSpace;
79         Rect crop;
80         int scalingMode;
81         uint32_t transform;
82         sp<Fence> fence;
83 
84         input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop,
85                 &scalingMode, &transform, &fence, nullptr);
86         ASSERT_EQ(timestamp, item.mTimestamp);
87         ASSERT_EQ(isAutoTimestamp, item.mIsAutoTimestamp);
88         ASSERT_EQ(dataSpace, item.mDataSpace);
89         ASSERT_EQ(crop, item.mCrop);
90         ASSERT_EQ(static_cast<uint32_t>(scalingMode), item.mScalingMode);
91         ASSERT_EQ(transform, item.mTransform);
92         ASSERT_EQ(fence, item.mFence);
93     }
94 
95     sp<IGraphicBufferProducer> mProducer;
96     sp<IGraphicBufferConsumer> mConsumer;
97 };
98 
99 static const uint32_t TEST_DATA = 0x12345678u;
100 
101 // XXX: Tests that fork a process to hold the BufferQueue must run before tests
102 // that use a local BufferQueue, or else Binder will get unhappy
103 //
104 // In one instance this was a crash in the createBufferQueue where the
105 // binder call to create a buffer allocator apparently got garbage back.
106 // See b/36592665.
TEST_F(BufferQueueTest,DISABLED_BufferQueueInAnotherProcess)107 TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) {
108     const String16 PRODUCER_NAME = String16("BQTestProducer");
109     const String16 CONSUMER_NAME = String16("BQTestConsumer");
110 
111     pid_t forkPid = fork();
112     ASSERT_NE(forkPid, -1);
113 
114     if (forkPid == 0) {
115         // Child process
116         sp<IGraphicBufferProducer> producer;
117         sp<IGraphicBufferConsumer> consumer;
118         BufferQueue::createBufferQueue(&producer, &consumer);
119         sp<IServiceManager> serviceManager = defaultServiceManager();
120         serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
121         serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
122         ProcessState::self()->startThreadPool();
123         IPCThreadState::self()->joinThreadPool();
124         LOG_ALWAYS_FATAL("Shouldn't be here");
125     }
126 
127     sp<IServiceManager> serviceManager = defaultServiceManager();
128     sp<IBinder> binderProducer =
129         serviceManager->getService(PRODUCER_NAME);
130     mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
131     EXPECT_TRUE(mProducer != nullptr);
132     sp<IBinder> binderConsumer =
133         serviceManager->getService(CONSUMER_NAME);
134     mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
135     EXPECT_TRUE(mConsumer != nullptr);
136 
137     sp<DummyConsumer> dc(new DummyConsumer);
138     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
139     IGraphicBufferProducer::QueueBufferOutput output;
140     ASSERT_EQ(OK,
141             mProducer->connect(nullptr, NATIVE_WINDOW_API_CPU, false, &output));
142 
143     int slot;
144     sp<Fence> fence;
145     sp<GraphicBuffer> buffer;
146     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
147               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
148                                        nullptr, nullptr));
149     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
150 
151     uint32_t* dataIn;
152     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
153             reinterpret_cast<void**>(&dataIn)));
154     *dataIn = TEST_DATA;
155     ASSERT_EQ(OK, buffer->unlock());
156 
157     IGraphicBufferProducer::QueueBufferInput input(0, false,
158             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
159             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
160     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
161 
162     BufferItem item;
163     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
164 
165     uint32_t* dataOut;
166     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
167             reinterpret_cast<void**>(&dataOut)));
168     ASSERT_EQ(*dataOut, TEST_DATA);
169     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
170 }
171 
TEST_F(BufferQueueTest,AcquireBuffer_ExceedsMaxAcquireCount_Fails)172 TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
173     createBufferQueue();
174     sp<DummyConsumer> dc(new DummyConsumer);
175     mConsumer->consumerConnect(dc, false);
176     IGraphicBufferProducer::QueueBufferOutput qbo;
177     mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
178             &qbo);
179     mProducer->setMaxDequeuedBufferCount(3);
180 
181     int slot;
182     sp<Fence> fence;
183     sp<GraphicBuffer> buf;
184     IGraphicBufferProducer::QueueBufferInput qbi(0, false,
185             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
186             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
187     BufferItem item;
188 
189     for (int i = 0; i < 2; i++) {
190         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
191                   mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
192                                            nullptr, nullptr));
193         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
194         ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
195         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
196     }
197 
198     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
199               mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
200                                        nullptr, nullptr));
201     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
202     ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
203 
204     // Acquire the third buffer, which should fail.
205     ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0));
206 }
207 
TEST_F(BufferQueueTest,SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError)208 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
209     createBufferQueue();
210     sp<DummyConsumer> dc(new DummyConsumer);
211     mConsumer->consumerConnect(dc, false);
212 
213     EXPECT_EQ(OK, mConsumer->setMaxBufferCount(10));
214     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(10));
215 
216     IGraphicBufferProducer::QueueBufferOutput qbo;
217     mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
218             &qbo);
219     mProducer->setMaxDequeuedBufferCount(3);
220 
221     int minBufferCount;
222     ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
223     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
224                 minBufferCount - 1));
225 
226     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0));
227     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3));
228     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
229             BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
230     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
231 
232     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,
242                   mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
243                                            nullptr, nullptr));
244         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));
250 }
251 
TEST_F(BufferQueueTest,SetMaxAcquiredBufferCountWithLegalValues_Succeeds)252 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
253     createBufferQueue();
254     sp<DummyConsumer> dc(new DummyConsumer);
255     mConsumer->consumerConnect(dc, false);
256 
257     IGraphicBufferProducer::QueueBufferOutput qbo;
258     mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
259             &qbo);
260     mProducer->setMaxDequeuedBufferCount(2);
261 
262     int minBufferCount;
263     ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
264 
265     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
266     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2));
267     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount));
268 
269     int slot;
270     sp<Fence> fence;
271     sp<GraphicBuffer> buf;
272     IGraphicBufferProducer::QueueBufferInput qbi(0, false,
273             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
274             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
275     BufferItem item;
276 
277     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
278               mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
279                                        nullptr, nullptr));
280     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
281     ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
282     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
283 
284     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
285 
286     for (int i = 0; i < 2; i++) {
287         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
288                   mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
289                                            nullptr, nullptr));
290         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
291         ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
292         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
293     }
294 
295     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(
296             BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
297 }
298 
TEST_F(BufferQueueTest,SetMaxBufferCountWithLegalValues_Succeeds)299 TEST_F(BufferQueueTest, SetMaxBufferCountWithLegalValues_Succeeds) {
300     createBufferQueue();
301     sp<DummyConsumer> dc(new DummyConsumer);
302     mConsumer->consumerConnect(dc, false);
303 
304     // Test shared buffer mode
305     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
306 }
307 
TEST_F(BufferQueueTest,SetMaxBufferCountWithIllegalValues_ReturnsError)308 TEST_F(BufferQueueTest, SetMaxBufferCountWithIllegalValues_ReturnsError) {
309     createBufferQueue();
310     sp<DummyConsumer> dc(new DummyConsumer);
311     mConsumer->consumerConnect(dc, false);
312 
313     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(0));
314     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(
315             BufferQueue::NUM_BUFFER_SLOTS + 1));
316 
317     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(5));
318     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(3));
319 }
320 
TEST_F(BufferQueueTest,DetachAndReattachOnProducerSide)321 TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
322     createBufferQueue();
323     sp<DummyConsumer> dc(new DummyConsumer);
324     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
325     IGraphicBufferProducer::QueueBufferOutput output;
326     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
327             NATIVE_WINDOW_API_CPU, false, &output));
328 
329     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low
330     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(
331                 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
332     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued
333 
334     int slot;
335     sp<Fence> fence;
336     sp<GraphicBuffer> buffer;
337     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
338               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
339                                        nullptr, nullptr));
340     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested
341     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
342     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
343     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued
344 
345     sp<GraphicBuffer> safeToClobberBuffer;
346     // Can no longer request buffer from this slot
347     ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer));
348 
349     uint32_t* dataIn;
350     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
351             reinterpret_cast<void**>(&dataIn)));
352     *dataIn = TEST_DATA;
353     ASSERT_EQ(OK, buffer->unlock());
354 
355     int newSlot;
356     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(nullptr, safeToClobberBuffer));
357     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, nullptr));
358 
359     ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
360     IGraphicBufferProducer::QueueBufferInput input(0, false,
361             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
362             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
363     ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
364 
365     BufferItem item;
366     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
367 
368     uint32_t* dataOut;
369     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
370             reinterpret_cast<void**>(&dataOut)));
371     ASSERT_EQ(*dataOut, TEST_DATA);
372     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
373 }
374 
TEST_F(BufferQueueTest,DetachAndReattachOnConsumerSide)375 TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
376     createBufferQueue();
377     sp<DummyConsumer> dc(new DummyConsumer);
378     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
379     IGraphicBufferProducer::QueueBufferOutput output;
380     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
381             NATIVE_WINDOW_API_CPU, false, &output));
382 
383     int slot;
384     sp<Fence> fence;
385     sp<GraphicBuffer> buffer;
386     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
387               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
388                                        nullptr, nullptr));
389     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
390     IGraphicBufferProducer::QueueBufferInput input(0, false,
391             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
392             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
393     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
394 
395     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low
396     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(
397             BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
398     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
399 
400     BufferItem item;
401     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
402 
403     ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
404     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mSlot)); // Not acquired
405 
406     uint32_t* dataIn;
407     ASSERT_EQ(OK, item.mGraphicBuffer->lock(
408             GraphicBuffer::USAGE_SW_WRITE_OFTEN,
409             reinterpret_cast<void**>(&dataIn)));
410     *dataIn = TEST_DATA;
411     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
412 
413     int newSlot;
414     sp<GraphicBuffer> safeToClobberBuffer;
415     ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(nullptr, safeToClobberBuffer));
416     ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, nullptr));
417     ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer));
418 
419     ASSERT_EQ(OK, mConsumer->releaseBuffer(newSlot, 0, EGL_NO_DISPLAY,
420             EGL_NO_SYNC_KHR, Fence::NO_FENCE));
421 
422     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
423               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
424                                        nullptr, nullptr));
425     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
426 
427     uint32_t* dataOut;
428     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
429             reinterpret_cast<void**>(&dataOut)));
430     ASSERT_EQ(*dataOut, TEST_DATA);
431     ASSERT_EQ(OK, buffer->unlock());
432 }
433 
TEST_F(BufferQueueTest,MoveFromConsumerToProducer)434 TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
435     createBufferQueue();
436     sp<DummyConsumer> dc(new DummyConsumer);
437     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
438     IGraphicBufferProducer::QueueBufferOutput output;
439     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
440             NATIVE_WINDOW_API_CPU, false, &output));
441 
442     int slot;
443     sp<Fence> fence;
444     sp<GraphicBuffer> buffer;
445     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
446               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
447                                        nullptr, nullptr));
448     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
449 
450     uint32_t* dataIn;
451     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
452             reinterpret_cast<void**>(&dataIn)));
453     *dataIn = TEST_DATA;
454     ASSERT_EQ(OK, buffer->unlock());
455 
456     IGraphicBufferProducer::QueueBufferInput input(0, false,
457             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
458             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
459     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
460 
461     BufferItem item;
462     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
463     ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
464 
465     int newSlot;
466     ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
467     ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
468     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
469 
470     uint32_t* dataOut;
471     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
472             reinterpret_cast<void**>(&dataOut)));
473     ASSERT_EQ(*dataOut, TEST_DATA);
474     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
475 }
476 
TEST_F(BufferQueueTest,TestDisallowingAllocation)477 TEST_F(BufferQueueTest, TestDisallowingAllocation) {
478     createBufferQueue();
479     sp<DummyConsumer> dc(new DummyConsumer);
480     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
481     IGraphicBufferProducer::QueueBufferOutput output;
482     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
483             NATIVE_WINDOW_API_CPU, true, &output));
484 
485     static const uint32_t WIDTH = 320;
486     static const uint32_t HEIGHT = 240;
487 
488     ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT));
489 
490     int slot;
491     sp<Fence> fence;
492     sp<GraphicBuffer> buffer;
493     // This should return an error since it would require an allocation
494     ASSERT_EQ(OK, mProducer->allowAllocation(false));
495     ASSERT_EQ(WOULD_BLOCK,
496               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
497                                        nullptr, nullptr));
498 
499     // This should succeed, now that we've lifted the prohibition
500     ASSERT_EQ(OK, mProducer->allowAllocation(true));
501     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
502               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
503                                        nullptr, nullptr));
504 
505     // Release the previous buffer back to the BufferQueue
506     mProducer->cancelBuffer(slot, fence);
507 
508     // This should fail since we're requesting a different size
509     ASSERT_EQ(OK, mProducer->allowAllocation(false));
510     ASSERT_EQ(WOULD_BLOCK,
511               mProducer->dequeueBuffer(&slot, &fence, WIDTH * 2, HEIGHT * 2, 0,
512                                        GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr));
513 }
514 
TEST_F(BufferQueueTest,TestGenerationNumbers)515 TEST_F(BufferQueueTest, TestGenerationNumbers) {
516     createBufferQueue();
517     sp<DummyConsumer> dc(new DummyConsumer);
518     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
519     IGraphicBufferProducer::QueueBufferOutput output;
520     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
521             NATIVE_WINDOW_API_CPU, true, &output));
522 
523     ASSERT_EQ(OK, mProducer->setGenerationNumber(1));
524 
525     // Get one buffer to play with
526     int slot;
527     sp<Fence> fence;
528     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
529               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
530 
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 
TEST_F(BufferQueueTest,TestSharedBufferModeWithoutAutoRefresh)557 TEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) {
558     createBufferQueue();
559     sp<DummyConsumer> dc(new DummyConsumer);
560     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
561     IGraphicBufferProducer::QueueBufferOutput output;
562     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
563             NATIVE_WINDOW_API_CPU, true, &output));
564 
565     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
566 
567     // Get a buffer
568     int sharedSlot;
569     sp<Fence> fence;
570     sp<GraphicBuffer> buffer;
571     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
572               mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr));
573     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
574 
575     // Queue the buffer
576     IGraphicBufferProducer::QueueBufferInput input(0, false,
577             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
578             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
579     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
580 
581     // Repeatedly queue and dequeue a buffer from the producer side, it should
582     // always return the same one. And we won't run out of buffers because it's
583     // always the same one and because async mode gets enabled.
584     int slot;
585     for (int i = 0; i < 5; i++) {
586         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
587         ASSERT_EQ(sharedSlot, slot);
588         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
589     }
590 
591     // acquire the buffer
592     BufferItem item;
593     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
594     ASSERT_EQ(sharedSlot, item.mSlot);
595     testBufferItem(input, item);
596     ASSERT_EQ(true, item.mQueuedBuffer);
597     ASSERT_EQ(false, item.mAutoRefresh);
598 
599     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
600             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
601 
602     // attempt to acquire a second time should return no buffer available
603     ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
604             mConsumer->acquireBuffer(&item, 0));
605 }
606 
TEST_F(BufferQueueTest,TestSharedBufferModeWithAutoRefresh)607 TEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) {
608     createBufferQueue();
609     sp<DummyConsumer> dc(new DummyConsumer);
610     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
611     IGraphicBufferProducer::QueueBufferOutput output;
612     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
613             NATIVE_WINDOW_API_CPU, true, &output));
614 
615     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
616     ASSERT_EQ(OK, mProducer->setAutoRefresh(true));
617 
618     // Get a buffer
619     int sharedSlot;
620     sp<Fence> fence;
621     sp<GraphicBuffer> buffer;
622     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
623               mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr));
624     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
625 
626     // Queue the buffer
627     IGraphicBufferProducer::QueueBufferInput input(0, false,
628             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
629             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
630     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
631 
632     // Repeatedly acquire and release a buffer from the consumer side, it should
633     // always return the same one.
634     BufferItem item;
635     for (int i = 0; i < 5; i++) {
636         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
637         ASSERT_EQ(sharedSlot, item.mSlot);
638         testBufferItem(input, item);
639         ASSERT_EQ(i == 0, item.mQueuedBuffer);
640         ASSERT_EQ(true, item.mAutoRefresh);
641 
642         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
643                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
644     }
645 
646     // Repeatedly queue and dequeue a buffer from the producer side, it should
647     // always return the same one.
648     int slot;
649     for (int i = 0; i < 5; i++) {
650         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
651         ASSERT_EQ(sharedSlot, slot);
652         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
653     }
654 
655     // Repeatedly acquire and release a buffer from the consumer side, it should
656     // always return the same one. First grabbing them from the queue and then
657     // when the queue is empty, returning the shared buffer.
658     for (int i = 0; i < 10; i++) {
659         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
660         ASSERT_EQ(sharedSlot, item.mSlot);
661         ASSERT_EQ(0, item.mTimestamp);
662         ASSERT_EQ(false, item.mIsAutoTimestamp);
663         ASSERT_EQ(HAL_DATASPACE_UNKNOWN, item.mDataSpace);
664         ASSERT_EQ(Rect(0, 0, 1, 1), item.mCrop);
665         ASSERT_EQ(NATIVE_WINDOW_SCALING_MODE_FREEZE, item.mScalingMode);
666         ASSERT_EQ(0u, item.mTransform);
667         ASSERT_EQ(Fence::NO_FENCE, item.mFence);
668         ASSERT_EQ(i == 0, item.mQueuedBuffer);
669         ASSERT_EQ(true, item.mAutoRefresh);
670 
671         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
672                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
673     }
674 }
675 
TEST_F(BufferQueueTest,TestSharedBufferModeUsingAlreadyDequeuedBuffer)676 TEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) {
677     createBufferQueue();
678     sp<DummyConsumer> dc(new DummyConsumer);
679     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
680     IGraphicBufferProducer::QueueBufferOutput output;
681     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
682             NATIVE_WINDOW_API_CPU, true, &output));
683 
684     // Dequeue a buffer
685     int sharedSlot;
686     sp<Fence> fence;
687     sp<GraphicBuffer> buffer;
688     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
689               mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr));
690     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
691 
692     // Enable shared buffer mode
693     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
694 
695     // Queue the buffer
696     IGraphicBufferProducer::QueueBufferInput input(0, false,
697             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
698             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
699     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
700 
701     // Repeatedly queue and dequeue a buffer from the producer side, it should
702     // always return the same one. And we won't run out of buffers because it's
703     // always the same one and because async mode gets enabled.
704     int slot;
705     for (int i = 0; i < 5; i++) {
706         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
707         ASSERT_EQ(sharedSlot, slot);
708         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
709     }
710 
711     // acquire the buffer
712     BufferItem item;
713     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
714     ASSERT_EQ(sharedSlot, item.mSlot);
715     testBufferItem(input, item);
716     ASSERT_EQ(true, item.mQueuedBuffer);
717     ASSERT_EQ(false, item.mAutoRefresh);
718 
719     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
720             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
721 
722     // attempt to acquire a second time should return no buffer available
723     ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
724             mConsumer->acquireBuffer(&item, 0));
725 }
726 
TEST_F(BufferQueueTest,TestTimeouts)727 TEST_F(BufferQueueTest, TestTimeouts) {
728     createBufferQueue();
729     sp<DummyConsumer> dc(new DummyConsumer);
730     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
731     IGraphicBufferProducer::QueueBufferOutput output;
732     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
733             NATIVE_WINDOW_API_CPU, true, &output));
734 
735     // Fill up the queue. Since the controlledByApp flags are set to true, this
736     // queue should be in non-blocking mode, and we should be recycling the same
737     // two buffers
738     for (int i = 0; i < 5; ++i) {
739         int slot = BufferQueue::INVALID_BUFFER_SLOT;
740         sp<Fence> fence = Fence::NO_FENCE;
741         auto result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr);
742         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;
768         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
769         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
770         IGraphicBufferProducer::QueueBufferInput input(0ull, true,
771                 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
772                 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
773         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
774     }
775 
776     int slot = BufferQueue::INVALID_BUFFER_SLOT;
777     sp<Fence> fence = Fence::NO_FENCE;
778     auto startTime = systemTime();
779     ASSERT_EQ(TIMED_OUT, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
780     ASSERT_GE(systemTime() - startTime, TIMEOUT);
781 
782     // We're technically attaching the same buffer multiple times (since we
783     // queued it previously), but that doesn't matter for this test
784     startTime = systemTime();
785     ASSERT_EQ(TIMED_OUT, mProducer->attachBuffer(&slot, buffer));
786     ASSERT_GE(systemTime() - startTime, TIMEOUT);
787 }
788 
TEST_F(BufferQueueTest,CanAttachWhileDisallowingAllocation)789 TEST_F(BufferQueueTest, CanAttachWhileDisallowingAllocation) {
790     createBufferQueue();
791     sp<DummyConsumer> dc(new DummyConsumer);
792     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
793     IGraphicBufferProducer::QueueBufferOutput output;
794     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
795             NATIVE_WINDOW_API_CPU, true, &output));
796 
797     int slot = BufferQueue::INVALID_BUFFER_SLOT;
798     sp<Fence> sourceFence;
799     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
800               mProducer->dequeueBuffer(&slot, &sourceFence, 0, 0, 0, 0, nullptr, nullptr));
801     sp<GraphicBuffer> buffer;
802     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
803     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
804 
805     ASSERT_EQ(OK, mProducer->allowAllocation(false));
806 
807     slot = BufferQueue::INVALID_BUFFER_SLOT;
808     ASSERT_EQ(OK, mProducer->attachBuffer(&slot, buffer));
809 }
810 
TEST_F(BufferQueueTest,CanRetrieveLastQueuedBuffer)811 TEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) {
812     createBufferQueue();
813     sp<DummyConsumer> dc(new DummyConsumer);
814     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
815     IGraphicBufferProducer::QueueBufferOutput output;
816     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
817             NATIVE_WINDOW_API_CPU, false, &output));
818 
819     // Dequeue and queue the first buffer, storing the handle
820     int slot = BufferQueue::INVALID_BUFFER_SLOT;
821     sp<Fence> fence;
822     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
823               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
824     sp<GraphicBuffer> firstBuffer;
825     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &firstBuffer));
826 
827     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
828         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
829         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
830     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
831 
832     // Dequeue a second buffer
833     slot = BufferQueue::INVALID_BUFFER_SLOT;
834     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
835               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
836     sp<GraphicBuffer> secondBuffer;
837     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &secondBuffer));
838 
839     // Ensure it's a new buffer
840     ASSERT_NE(firstBuffer->getNativeBuffer()->handle,
841             secondBuffer->getNativeBuffer()->handle);
842 
843     // Queue the second buffer
844     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
845 
846     // Acquire and release both buffers
847     for (size_t i = 0; i < 2; ++i) {
848         BufferItem item;
849         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
850         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
851                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
852     }
853 
854     // Make sure we got the second buffer back
855     sp<GraphicBuffer> returnedBuffer;
856     sp<Fence> returnedFence;
857     float transform[16];
858     ASSERT_EQ(OK,
859             mProducer->getLastQueuedBuffer(&returnedBuffer, &returnedFence,
860             transform));
861     ASSERT_EQ(secondBuffer->getNativeBuffer()->handle,
862             returnedBuffer->getNativeBuffer()->handle);
863 }
864 
TEST_F(BufferQueueTest,TestOccupancyHistory)865 TEST_F(BufferQueueTest, TestOccupancyHistory) {
866     createBufferQueue();
867     sp<DummyConsumer> dc(new DummyConsumer);
868     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
869     IGraphicBufferProducer::QueueBufferOutput output;
870     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
871             NATIVE_WINDOW_API_CPU, false, &output));
872 
873     int slot = BufferQueue::INVALID_BUFFER_SLOT;
874     sp<Fence> fence = Fence::NO_FENCE;
875     sp<GraphicBuffer> buffer = nullptr;
876     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
877         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
878         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
879     BufferItem item{};
880 
881     // Preallocate, dequeue, request, and cancel 3 buffers so we don't get
882     // BUFFER_NEEDS_REALLOCATION below
883     int slots[3] = {};
884     mProducer->setMaxDequeuedBufferCount(3);
885     for (size_t i = 0; i < 3; ++i) {
886         status_t result =
887                 mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr);
888         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
889         ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
890     }
891     for (size_t i = 0; i < 3; ++i) {
892         ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
893     }
894 
895     // Create 3 segments
896 
897     // The first segment is a two-buffer segment, so we only put one buffer into
898     // the queue at a time
899     for (size_t i = 0; i < 5; ++i) {
900         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
901         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
902         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
903         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
904                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
905         std::this_thread::sleep_for(16ms);
906     }
907 
908     // Sleep between segments
909     std::this_thread::sleep_for(500ms);
910 
911     // The second segment is a double-buffer segment. It starts the same as the
912     // two-buffer segment, but then at the end, we put two buffers in the queue
913     // at the same time before draining it.
914     for (size_t i = 0; i < 5; ++i) {
915         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
916         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
917         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
918         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
919                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
920         std::this_thread::sleep_for(16ms);
921     }
922     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
923     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
924     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
925     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
926     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
927     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
928             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
929     std::this_thread::sleep_for(16ms);
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 
934     // Sleep between segments
935     std::this_thread::sleep_for(500ms);
936 
937     // The third segment is a triple-buffer segment, so the queue is switching
938     // between one buffer and two buffers deep.
939     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
940     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
941     for (size_t i = 0; i < 5; ++i) {
942         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
943         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
944         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
945         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
946                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
947         std::this_thread::sleep_for(16ms);
948     }
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 
953     // Now we read the segments
954     std::vector<OccupancyTracker::Segment> history;
955     ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
956 
957     // Since we didn't force a flush, we should only get the first two segments
958     // (since the third segment hasn't been closed out by the appearance of a
959     // new segment yet)
960     ASSERT_EQ(2u, history.size());
961 
962     // The first segment (which will be history[1], since the newest segment
963     // should be at the front of the vector) should be a two-buffer segment,
964     // which implies that the occupancy average should be between 0 and 1, and
965     // usedThirdBuffer should be false
966     const auto& firstSegment = history[1];
967     ASSERT_EQ(5u, firstSegment.numFrames);
968     ASSERT_LT(0, firstSegment.occupancyAverage);
969     ASSERT_GT(1, firstSegment.occupancyAverage);
970     ASSERT_EQ(false, firstSegment.usedThirdBuffer);
971 
972     // The second segment should be a double-buffered segment, which implies that
973     // the occupancy average should be between 0 and 1, but usedThirdBuffer
974     // should be true
975     const auto& secondSegment = history[0];
976     ASSERT_EQ(7u, secondSegment.numFrames);
977     ASSERT_LT(0, secondSegment.occupancyAverage);
978     ASSERT_GT(1, secondSegment.occupancyAverage);
979     ASSERT_EQ(true, secondSegment.usedThirdBuffer);
980 
981     // If we read the segments again without flushing, we shouldn't get any new
982     // segments
983     ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
984     ASSERT_EQ(0u, history.size());
985 
986     // Read the segments again, this time forcing a flush so we get the third
987     // segment
988     ASSERT_EQ(OK, mConsumer->getOccupancyHistory(true, &history));
989     ASSERT_EQ(1u, history.size());
990 
991     // This segment should be a triple-buffered segment, which implies that the
992     // occupancy average should be between 1 and 2, and usedThirdBuffer should
993     // be true
994     const auto& thirdSegment = history[0];
995     ASSERT_EQ(6u, thirdSegment.numFrames);
996     ASSERT_LT(1, thirdSegment.occupancyAverage);
997     ASSERT_GT(2, thirdSegment.occupancyAverage);
998     ASSERT_EQ(true, thirdSegment.usedThirdBuffer);
999 }
1000 
TEST_F(BufferQueueTest,TestDiscardFreeBuffers)1001 TEST_F(BufferQueueTest, TestDiscardFreeBuffers) {
1002     createBufferQueue();
1003     sp<DummyConsumer> dc(new DummyConsumer);
1004     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
1005     IGraphicBufferProducer::QueueBufferOutput output;
1006     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
1007             NATIVE_WINDOW_API_CPU, false, &output));
1008 
1009     int slot = BufferQueue::INVALID_BUFFER_SLOT;
1010     sp<Fence> fence = Fence::NO_FENCE;
1011     sp<GraphicBuffer> buffer = nullptr;
1012     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1013         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1014         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1015     BufferItem item{};
1016 
1017     // Preallocate, dequeue, request, and cancel 4 buffers so we don't get
1018     // BUFFER_NEEDS_REALLOCATION below
1019     int slots[4] = {};
1020     mProducer->setMaxDequeuedBufferCount(4);
1021     for (size_t i = 0; i < 4; ++i) {
1022         status_t result =
1023                 mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr);
1024         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1025         ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
1026     }
1027     for (size_t i = 0; i < 4; ++i) {
1028         ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
1029     }
1030 
1031     // Get buffers in all states: dequeued, filled, acquired, free
1032 
1033     // Fill 3 buffers
1034     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1035     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1036     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1037     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1038     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1039     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1040     // Dequeue 1 buffer
1041     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1042 
1043     // Acquire and free 1 buffer
1044     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1045     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1046                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
1047     // Acquire 1 buffer, leaving 1 filled buffer in queue
1048     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1049 
1050     // Now discard the free buffers
1051     ASSERT_EQ(OK, mConsumer->discardFreeBuffers());
1052 
1053     // Check no free buffers in dump
1054     String8 dumpString;
1055     mConsumer->dumpState(String8{}, &dumpString);
1056 
1057     // Parse the dump to ensure that all buffer slots that are FREE also
1058     // have a null GraphicBuffer
1059     // Fragile - assumes the following format for the dump for a buffer entry:
1060     // ":%p\][^:]*state=FREE" where %p is the buffer pointer in hex.
1061     ssize_t idx = dumpString.find("state=FREE");
1062     while (idx != -1) {
1063         ssize_t bufferPtrIdx = idx - 1;
1064         while (bufferPtrIdx > 0) {
1065             if (dumpString[bufferPtrIdx] == ':') {
1066                 bufferPtrIdx++;
1067                 break;
1068             }
1069             bufferPtrIdx--;
1070         }
1071         ASSERT_GT(bufferPtrIdx, 0) << "Can't parse queue dump to validate";
1072         ssize_t nullPtrIdx = dumpString.find("0x0]", bufferPtrIdx);
1073         ASSERT_EQ(bufferPtrIdx, nullPtrIdx) << "Free buffer not discarded";
1074         idx = dumpString.find("FREE", idx + 1);
1075     }
1076 }
1077 
TEST_F(BufferQueueTest,TestBufferReplacedInQueueBuffer)1078 TEST_F(BufferQueueTest, TestBufferReplacedInQueueBuffer) {
1079     createBufferQueue();
1080     sp<DummyConsumer> dc(new DummyConsumer);
1081     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
1082     IGraphicBufferProducer::QueueBufferOutput output;
1083     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
1084             NATIVE_WINDOW_API_CPU, true, &output));
1085     ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
1086 
1087     int slot = BufferQueue::INVALID_BUFFER_SLOT;
1088     sp<Fence> fence = Fence::NO_FENCE;
1089     sp<GraphicBuffer> buffer = nullptr;
1090     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1091         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1092         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1093     BufferItem item{};
1094 
1095     // Preallocate, dequeue, request, and cancel 2 buffers so we don't get
1096     // BUFFER_NEEDS_REALLOCATION below
1097     int slots[2] = {};
1098     ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
1099     for (size_t i = 0; i < 2; ++i) {
1100         status_t result =
1101                 mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr);
1102         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1103         ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
1104     }
1105     for (size_t i = 0; i < 2; ++i) {
1106         ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
1107     }
1108 
1109     // Fill 2 buffers without consumer consuming them. Verify that all
1110     // queued buffer returns proper bufferReplaced flag
1111     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1112     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1113     ASSERT_EQ(false, output.bufferReplaced);
1114     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1115     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1116     ASSERT_EQ(true, output.bufferReplaced);
1117 }
1118 
TEST_F(BufferQueueTest,TestStaleBufferHandleSentAfterDisconnect)1119 TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) {
1120     createBufferQueue();
1121     sp<DummyConsumer> dc(new DummyConsumer);
1122     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
1123     IGraphicBufferProducer::QueueBufferOutput output;
1124     sp<IProducerListener> dummyListener(new DummyProducerListener);
1125     ASSERT_EQ(OK, mProducer->connect(dummyListener, NATIVE_WINDOW_API_CPU,
1126             true, &output));
1127 
1128     int slot = BufferQueue::INVALID_BUFFER_SLOT;
1129     sp<Fence> fence = Fence::NO_FENCE;
1130     sp<GraphicBuffer> buffer = nullptr;
1131     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
1132             HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
1133             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
1134 
1135     // Dequeue, request, and queue one buffer
1136     status_t result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr);
1137     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
1138     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
1139     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1140 
1141     // Acquire and release the buffer. Upon acquiring, the buffer handle should
1142     // be non-null since this is the first time we've acquired this slot.
1143     BufferItem item;
1144     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1145     ASSERT_EQ(slot, item.mSlot);
1146     ASSERT_NE(nullptr, item.mGraphicBuffer.get());
1147     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1148             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
1149 
1150     // Dequeue and queue the buffer again
1151     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1152     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1153 
1154     // Acquire and release the buffer again. Upon acquiring, the buffer handle
1155     // should be null since this is not the first time we've acquired this slot.
1156     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1157     ASSERT_EQ(slot, item.mSlot);
1158     ASSERT_EQ(nullptr, item.mGraphicBuffer.get());
1159     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
1160             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
1161 
1162     // Dequeue and queue the buffer again
1163     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
1164     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
1165 
1166     // Disconnect the producer end. This should clear all of the slots and mark
1167     // the buffer in the queue as stale.
1168     ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1169 
1170     // Acquire the buffer again. Upon acquiring, the buffer handle should not be
1171     // null since the queued buffer should have been marked as stale, which
1172     // should trigger the BufferQueue to resend the buffer handle.
1173     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1174     ASSERT_EQ(slot, item.mSlot);
1175     ASSERT_NE(nullptr, item.mGraphicBuffer.get());
1176 }
1177 
TEST_F(BufferQueueTest,TestProducerConnectDisconnect)1178 TEST_F(BufferQueueTest, TestProducerConnectDisconnect) {
1179     createBufferQueue();
1180     sp<DummyConsumer> dc(new DummyConsumer);
1181     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
1182     IGraphicBufferProducer::QueueBufferOutput output;
1183     sp<IProducerListener> dummyListener(new DummyProducerListener);
1184     ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1185     ASSERT_EQ(OK, mProducer->connect(
1186             dummyListener, NATIVE_WINDOW_API_CPU, true, &output));
1187     ASSERT_EQ(BAD_VALUE, mProducer->connect(
1188             dummyListener, NATIVE_WINDOW_API_MEDIA, true, &output));
1189 
1190     ASSERT_EQ(BAD_VALUE, mProducer->disconnect(NATIVE_WINDOW_API_MEDIA));
1191     ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1192     ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
1193 }
1194 
1195 } // namespace android
1196