OSDN Git Service

Rename dump methods to dumpState (again)
[android-x86/frameworks-native.git] / libs / gui / tests / BufferQueue_test.cpp
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 <gtest/gtest.h>
36
37 namespace android {
38
39 class BufferQueueTest : public ::testing::Test {
40
41 public:
42 protected:
43     BufferQueueTest() {
44         const ::testing::TestInfo* const testInfo =
45             ::testing::UnitTest::GetInstance()->current_test_info();
46         ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
47                 testInfo->name());
48     }
49
50     ~BufferQueueTest() {
51         const ::testing::TestInfo* const testInfo =
52             ::testing::UnitTest::GetInstance()->current_test_info();
53         ALOGV("End test:   %s.%s", testInfo->test_case_name(),
54                 testInfo->name());
55     }
56
57     void GetMinUndequeuedBufferCount(int* bufferCount) {
58         ASSERT_TRUE(bufferCount != NULL);
59         ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
60                     bufferCount));
61         ASSERT_GE(*bufferCount, 0);
62     }
63
64     void createBufferQueue() {
65         BufferQueue::createBufferQueue(&mProducer, &mConsumer);
66     }
67
68     void testBufferItem(const IGraphicBufferProducer::QueueBufferInput& input,
69             const BufferItem& item) {
70         int64_t timestamp;
71         bool isAutoTimestamp;
72         android_dataspace dataSpace;
73         Rect crop;
74         int scalingMode;
75         uint32_t transform;
76         sp<Fence> fence;
77
78         input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop,
79                 &scalingMode, &transform, &fence, NULL);
80         ASSERT_EQ(timestamp, item.mTimestamp);
81         ASSERT_EQ(isAutoTimestamp, item.mIsAutoTimestamp);
82         ASSERT_EQ(dataSpace, item.mDataSpace);
83         ASSERT_EQ(crop, item.mCrop);
84         ASSERT_EQ(static_cast<uint32_t>(scalingMode), item.mScalingMode);
85         ASSERT_EQ(transform, item.mTransform);
86         ASSERT_EQ(fence, item.mFence);
87     }
88
89     sp<IGraphicBufferProducer> mProducer;
90     sp<IGraphicBufferConsumer> mConsumer;
91 };
92
93 static const uint32_t TEST_DATA = 0x12345678u;
94
95 // XXX: Tests that fork a process to hold the BufferQueue must run before tests
96 // that use a local BufferQueue, or else Binder will get unhappy
97 TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) {
98     const String16 PRODUCER_NAME = String16("BQTestProducer");
99     const String16 CONSUMER_NAME = String16("BQTestConsumer");
100
101     pid_t forkPid = fork();
102     ASSERT_NE(forkPid, -1);
103
104     if (forkPid == 0) {
105         // Child process
106         sp<IGraphicBufferProducer> producer;
107         sp<IGraphicBufferConsumer> consumer;
108         BufferQueue::createBufferQueue(&producer, &consumer);
109         sp<IServiceManager> serviceManager = defaultServiceManager();
110         serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
111         serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
112         ProcessState::self()->startThreadPool();
113         IPCThreadState::self()->joinThreadPool();
114         LOG_ALWAYS_FATAL("Shouldn't be here");
115     }
116
117     sp<IServiceManager> serviceManager = defaultServiceManager();
118     sp<IBinder> binderProducer =
119         serviceManager->getService(PRODUCER_NAME);
120     mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
121     EXPECT_TRUE(mProducer != NULL);
122     sp<IBinder> binderConsumer =
123         serviceManager->getService(CONSUMER_NAME);
124     mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
125     EXPECT_TRUE(mConsumer != NULL);
126
127     sp<DummyConsumer> dc(new DummyConsumer);
128     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
129     IGraphicBufferProducer::QueueBufferOutput output;
130     ASSERT_EQ(OK,
131             mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
132
133     int slot;
134     sp<Fence> fence;
135     sp<GraphicBuffer> buffer;
136     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
137             mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
138                     GRALLOC_USAGE_SW_WRITE_OFTEN));
139     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
140
141     uint32_t* dataIn;
142     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
143             reinterpret_cast<void**>(&dataIn)));
144     *dataIn = TEST_DATA;
145     ASSERT_EQ(OK, buffer->unlock());
146
147     IGraphicBufferProducer::QueueBufferInput input(0, false,
148             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
149             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
150     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
151
152     BufferItem item;
153     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
154
155     uint32_t* dataOut;
156     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
157             reinterpret_cast<void**>(&dataOut)));
158     ASSERT_EQ(*dataOut, TEST_DATA);
159     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
160 }
161
162 TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
163     createBufferQueue();
164     sp<DummyConsumer> dc(new DummyConsumer);
165     mConsumer->consumerConnect(dc, false);
166     IGraphicBufferProducer::QueueBufferOutput qbo;
167     mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
168             &qbo);
169     mProducer->setMaxDequeuedBufferCount(3);
170
171     int slot;
172     sp<Fence> fence;
173     sp<GraphicBuffer> buf;
174     IGraphicBufferProducer::QueueBufferInput qbi(0, false,
175             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
176             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
177     BufferItem item;
178
179     for (int i = 0; i < 2; i++) {
180         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
181                 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0,
182                     GRALLOC_USAGE_SW_READ_OFTEN));
183         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
184         ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
185         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
186     }
187
188     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
189             mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0,
190                 GRALLOC_USAGE_SW_READ_OFTEN));
191     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
192     ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
193
194     // Acquire the third buffer, which should fail.
195     ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0));
196 }
197
198 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
199     createBufferQueue();
200     sp<DummyConsumer> dc(new DummyConsumer);
201     mConsumer->consumerConnect(dc, false);
202
203     EXPECT_EQ(OK, mConsumer->setMaxBufferCount(10));
204     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(10));
205
206     IGraphicBufferProducer::QueueBufferOutput qbo;
207     mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
208             &qbo);
209     mProducer->setMaxDequeuedBufferCount(3);
210
211     int minBufferCount;
212     ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
213     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
214                 minBufferCount - 1));
215
216     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0));
217     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3));
218     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
219             BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
220     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
221
222     int slot;
223     sp<Fence> fence;
224     sp<GraphicBuffer> buf;
225     IGraphicBufferProducer::QueueBufferInput qbi(0, false,
226             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
227             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
228     BufferItem item;
229     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
230     for (int i = 0; i < 3; i++) {
231         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
232                 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0,
233                     GRALLOC_USAGE_SW_READ_OFTEN));
234         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
235         ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
236         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
237     }
238
239     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(2));
240 }
241
242 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
243     createBufferQueue();
244     sp<DummyConsumer> dc(new DummyConsumer);
245     mConsumer->consumerConnect(dc, false);
246
247     IGraphicBufferProducer::QueueBufferOutput qbo;
248     mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
249             &qbo);
250     mProducer->setMaxDequeuedBufferCount(2);
251
252     int minBufferCount;
253     ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
254
255     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
256     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2));
257     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount));
258
259     int slot;
260     sp<Fence> fence;
261     sp<GraphicBuffer> buf;
262     IGraphicBufferProducer::QueueBufferInput qbi(0, false,
263             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
264             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
265     BufferItem item;
266
267     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
268             mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0,
269             GRALLOC_USAGE_SW_READ_OFTEN));
270     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
271     ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
272     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
273
274     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
275
276     for (int i = 0; i < 2; i++) {
277         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
278                 mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0,
279                 GRALLOC_USAGE_SW_READ_OFTEN));
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
285     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(
286             BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
287 }
288
289 TEST_F(BufferQueueTest, SetMaxBufferCountWithLegalValues_Succeeds) {
290     createBufferQueue();
291     sp<DummyConsumer> dc(new DummyConsumer);
292     mConsumer->consumerConnect(dc, false);
293
294     // Test shared buffer mode
295     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
296 }
297
298 TEST_F(BufferQueueTest, SetMaxBufferCountWithIllegalValues_ReturnsError) {
299     createBufferQueue();
300     sp<DummyConsumer> dc(new DummyConsumer);
301     mConsumer->consumerConnect(dc, false);
302
303     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(0));
304     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(
305             BufferQueue::NUM_BUFFER_SLOTS + 1));
306
307     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(5));
308     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(3));
309 }
310
311 TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
312     createBufferQueue();
313     sp<DummyConsumer> dc(new DummyConsumer);
314     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
315     IGraphicBufferProducer::QueueBufferOutput output;
316     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
317             NATIVE_WINDOW_API_CPU, false, &output));
318
319     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low
320     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(
321                 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
322     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued
323
324     int slot;
325     sp<Fence> fence;
326     sp<GraphicBuffer> buffer;
327     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
328             mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
329                     GRALLOC_USAGE_SW_WRITE_OFTEN));
330     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested
331     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
332     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
333     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued
334
335     sp<GraphicBuffer> safeToClobberBuffer;
336     // Can no longer request buffer from this slot
337     ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer));
338
339     uint32_t* dataIn;
340     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
341             reinterpret_cast<void**>(&dataIn)));
342     *dataIn = TEST_DATA;
343     ASSERT_EQ(OK, buffer->unlock());
344
345     int newSlot;
346     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(NULL, safeToClobberBuffer));
347     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL));
348
349     ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
350     IGraphicBufferProducer::QueueBufferInput input(0, false,
351             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
352             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
353     ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
354
355     BufferItem item;
356     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
357
358     uint32_t* dataOut;
359     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
360             reinterpret_cast<void**>(&dataOut)));
361     ASSERT_EQ(*dataOut, TEST_DATA);
362     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
363 }
364
365 TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
366     createBufferQueue();
367     sp<DummyConsumer> dc(new DummyConsumer);
368     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
369     IGraphicBufferProducer::QueueBufferOutput output;
370     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
371             NATIVE_WINDOW_API_CPU, false, &output));
372
373     int slot;
374     sp<Fence> fence;
375     sp<GraphicBuffer> buffer;
376     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
377             mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
378                     GRALLOC_USAGE_SW_WRITE_OFTEN));
379     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
380     IGraphicBufferProducer::QueueBufferInput input(0, false,
381             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
382             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
383     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
384
385     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low
386     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(
387             BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
388     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
389
390     BufferItem item;
391     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
392
393     ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
394     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mSlot)); // Not acquired
395
396     uint32_t* dataIn;
397     ASSERT_EQ(OK, item.mGraphicBuffer->lock(
398             GraphicBuffer::USAGE_SW_WRITE_OFTEN,
399             reinterpret_cast<void**>(&dataIn)));
400     *dataIn = TEST_DATA;
401     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
402
403     int newSlot;
404     sp<GraphicBuffer> safeToClobberBuffer;
405     ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(NULL, safeToClobberBuffer));
406     ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, NULL));
407     ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer));
408
409     ASSERT_EQ(OK, mConsumer->releaseBuffer(newSlot, 0, EGL_NO_DISPLAY,
410             EGL_NO_SYNC_KHR, Fence::NO_FENCE));
411
412     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
413             mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
414                     GRALLOC_USAGE_SW_WRITE_OFTEN));
415     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
416
417     uint32_t* dataOut;
418     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
419             reinterpret_cast<void**>(&dataOut)));
420     ASSERT_EQ(*dataOut, TEST_DATA);
421     ASSERT_EQ(OK, buffer->unlock());
422 }
423
424 TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
425     createBufferQueue();
426     sp<DummyConsumer> dc(new DummyConsumer);
427     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
428     IGraphicBufferProducer::QueueBufferOutput output;
429     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
430             NATIVE_WINDOW_API_CPU, false, &output));
431
432     int slot;
433     sp<Fence> fence;
434     sp<GraphicBuffer> buffer;
435     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
436             mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
437                     GRALLOC_USAGE_SW_WRITE_OFTEN));
438     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
439
440     uint32_t* dataIn;
441     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
442             reinterpret_cast<void**>(&dataIn)));
443     *dataIn = TEST_DATA;
444     ASSERT_EQ(OK, buffer->unlock());
445
446     IGraphicBufferProducer::QueueBufferInput input(0, false,
447             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
448             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
449     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
450
451     BufferItem item;
452     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
453     ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
454
455     int newSlot;
456     ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
457     ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
458     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
459
460     uint32_t* dataOut;
461     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
462             reinterpret_cast<void**>(&dataOut)));
463     ASSERT_EQ(*dataOut, TEST_DATA);
464     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
465 }
466
467 TEST_F(BufferQueueTest, TestDisallowingAllocation) {
468     createBufferQueue();
469     sp<DummyConsumer> dc(new DummyConsumer);
470     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
471     IGraphicBufferProducer::QueueBufferOutput output;
472     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
473             NATIVE_WINDOW_API_CPU, true, &output));
474
475     static const uint32_t WIDTH = 320;
476     static const uint32_t HEIGHT = 240;
477
478     ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT));
479
480     int slot;
481     sp<Fence> fence;
482     sp<GraphicBuffer> buffer;
483     // This should return an error since it would require an allocation
484     ASSERT_EQ(OK, mProducer->allowAllocation(false));
485     ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, 0, 0,
486             0, GRALLOC_USAGE_SW_WRITE_OFTEN));
487
488     // This should succeed, now that we've lifted the prohibition
489     ASSERT_EQ(OK, mProducer->allowAllocation(true));
490     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
491             mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
492             GRALLOC_USAGE_SW_WRITE_OFTEN));
493
494     // Release the previous buffer back to the BufferQueue
495     mProducer->cancelBuffer(slot, fence);
496
497     // This should fail since we're requesting a different size
498     ASSERT_EQ(OK, mProducer->allowAllocation(false));
499     ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence,
500             WIDTH * 2, HEIGHT * 2, 0, GRALLOC_USAGE_SW_WRITE_OFTEN));
501 }
502
503 TEST_F(BufferQueueTest, TestGenerationNumbers) {
504     createBufferQueue();
505     sp<DummyConsumer> dc(new DummyConsumer);
506     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
507     IGraphicBufferProducer::QueueBufferOutput output;
508     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
509             NATIVE_WINDOW_API_CPU, true, &output));
510
511     ASSERT_EQ(OK, mProducer->setGenerationNumber(1));
512
513     // Get one buffer to play with
514     int slot;
515     sp<Fence> fence;
516     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
517             mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
518
519     sp<GraphicBuffer> buffer;
520     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
521
522     // Ensure that the generation number we set propagates to allocated buffers
523     ASSERT_EQ(1U, buffer->getGenerationNumber());
524
525     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
526
527     ASSERT_EQ(OK, mProducer->setGenerationNumber(2));
528
529     // These should fail, since we've changed the generation number on the queue
530     int outSlot;
531     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&outSlot, buffer));
532     ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&outSlot, buffer));
533
534     buffer->setGenerationNumber(2);
535
536     // This should succeed now that we've changed the buffer's generation number
537     ASSERT_EQ(OK, mProducer->attachBuffer(&outSlot, buffer));
538
539     ASSERT_EQ(OK, mProducer->detachBuffer(outSlot));
540
541     // This should also succeed with the new generation number
542     ASSERT_EQ(OK, mConsumer->attachBuffer(&outSlot, buffer));
543 }
544
545 TEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) {
546     createBufferQueue();
547     sp<DummyConsumer> dc(new DummyConsumer);
548     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
549     IGraphicBufferProducer::QueueBufferOutput output;
550     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
551             NATIVE_WINDOW_API_CPU, true, &output));
552
553     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
554
555     // Get a buffer
556     int sharedSlot;
557     sp<Fence> fence;
558     sp<GraphicBuffer> buffer;
559     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
560             mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0));
561     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
562
563     // Queue the buffer
564     IGraphicBufferProducer::QueueBufferInput input(0, false,
565             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
566             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
567     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
568
569     // Repeatedly queue and dequeue a buffer from the producer side, it should
570     // always return the same one. And we won't run out of buffers because it's
571     // always the same one and because async mode gets enabled.
572     int slot;
573     for (int i = 0; i < 5; i++) {
574         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
575         ASSERT_EQ(sharedSlot, slot);
576         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
577     }
578
579     // acquire the buffer
580     BufferItem item;
581     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
582     ASSERT_EQ(sharedSlot, item.mSlot);
583     testBufferItem(input, item);
584     ASSERT_EQ(true, item.mQueuedBuffer);
585     ASSERT_EQ(false, item.mAutoRefresh);
586
587     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
588             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
589
590     // attempt to acquire a second time should return no buffer available
591     ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
592             mConsumer->acquireBuffer(&item, 0));
593 }
594
595 TEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) {
596     createBufferQueue();
597     sp<DummyConsumer> dc(new DummyConsumer);
598     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
599     IGraphicBufferProducer::QueueBufferOutput output;
600     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
601             NATIVE_WINDOW_API_CPU, true, &output));
602
603     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
604     ASSERT_EQ(OK, mProducer->setAutoRefresh(true));
605
606     // Get a buffer
607     int sharedSlot;
608     sp<Fence> fence;
609     sp<GraphicBuffer> buffer;
610     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
611             mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0));
612     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
613
614     // Queue the buffer
615     IGraphicBufferProducer::QueueBufferInput input(0, false,
616             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
617             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
618     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
619
620     // Repeatedly acquire and release a buffer from the consumer side, it should
621     // always return the same one.
622     BufferItem item;
623     for (int i = 0; i < 5; i++) {
624         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
625         ASSERT_EQ(sharedSlot, item.mSlot);
626         testBufferItem(input, item);
627         ASSERT_EQ(i == 0, item.mQueuedBuffer);
628         ASSERT_EQ(true, item.mAutoRefresh);
629
630         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
631                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
632     }
633
634     // Repeatedly queue and dequeue a buffer from the producer side, it should
635     // always return the same one.
636     int slot;
637     for (int i = 0; i < 5; i++) {
638         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
639         ASSERT_EQ(sharedSlot, slot);
640         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
641     }
642
643     // Repeatedly acquire and release a buffer from the consumer side, it should
644     // always return the same one. First grabbing them from the queue and then
645     // when the queue is empty, returning the shared buffer.
646     for (int i = 0; i < 10; i++) {
647         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
648         ASSERT_EQ(sharedSlot, item.mSlot);
649         ASSERT_EQ(0, item.mTimestamp);
650         ASSERT_EQ(false, item.mIsAutoTimestamp);
651         ASSERT_EQ(HAL_DATASPACE_UNKNOWN, item.mDataSpace);
652         ASSERT_EQ(Rect(0, 0, 1, 1), item.mCrop);
653         ASSERT_EQ(NATIVE_WINDOW_SCALING_MODE_FREEZE, item.mScalingMode);
654         ASSERT_EQ(0u, item.mTransform);
655         ASSERT_EQ(Fence::NO_FENCE, item.mFence);
656         ASSERT_EQ(i == 0, item.mQueuedBuffer);
657         ASSERT_EQ(true, item.mAutoRefresh);
658
659         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
660                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
661     }
662 }
663
664 TEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) {
665     createBufferQueue();
666     sp<DummyConsumer> dc(new DummyConsumer);
667     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
668     IGraphicBufferProducer::QueueBufferOutput output;
669     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
670             NATIVE_WINDOW_API_CPU, true, &output));
671
672     // Dequeue a buffer
673     int sharedSlot;
674     sp<Fence> fence;
675     sp<GraphicBuffer> buffer;
676     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
677             mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0));
678     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
679
680     // Enable shared buffer mode
681     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
682
683     // Queue the buffer
684     IGraphicBufferProducer::QueueBufferInput input(0, false,
685             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
686             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
687     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
688
689     // Repeatedly queue and dequeue a buffer from the producer side, it should
690     // always return the same one. And we won't run out of buffers because it's
691     // always the same one and because async mode gets enabled.
692     int slot;
693     for (int i = 0; i < 5; i++) {
694         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
695         ASSERT_EQ(sharedSlot, slot);
696         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
697     }
698
699     // acquire the buffer
700     BufferItem item;
701     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
702     ASSERT_EQ(sharedSlot, item.mSlot);
703     testBufferItem(input, item);
704     ASSERT_EQ(true, item.mQueuedBuffer);
705     ASSERT_EQ(false, item.mAutoRefresh);
706
707     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
708             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
709
710     // attempt to acquire a second time should return no buffer available
711     ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
712             mConsumer->acquireBuffer(&item, 0));
713 }
714
715 TEST_F(BufferQueueTest, TestTimeouts) {
716     createBufferQueue();
717     sp<DummyConsumer> dc(new DummyConsumer);
718     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
719     IGraphicBufferProducer::QueueBufferOutput output;
720     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
721             NATIVE_WINDOW_API_CPU, true, &output));
722
723     // Fill up the queue. Since the controlledByApp flags are set to true, this
724     // queue should be in non-blocking mode, and we should be recycling the same
725     // two buffers
726     for (int i = 0; i < 5; ++i) {
727         int slot = BufferQueue::INVALID_BUFFER_SLOT;
728         sp<Fence> fence = Fence::NO_FENCE;
729         auto result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0);
730         if (i < 2) {
731             ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
732                     result);
733         } else {
734             ASSERT_EQ(OK, result);
735         }
736         sp<GraphicBuffer> buffer;
737         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
738         IGraphicBufferProducer::QueueBufferInput input(0ull, true,
739                 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
740                 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
741         IGraphicBufferProducer::QueueBufferOutput output{};
742         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
743     }
744
745     const auto TIMEOUT = ms2ns(250);
746     mProducer->setDequeueTimeout(TIMEOUT);
747
748     // Setting a timeout will change the BufferQueue into blocking mode (with
749     // one droppable buffer in the queue and one free from the previous
750     // dequeue/queues), so dequeue and queue two more buffers: one to replace
751     // the current droppable buffer, and a second to max out the buffer count
752     sp<GraphicBuffer> buffer; // Save a buffer to attach later
753     for (int i = 0; i < 2; ++i) {
754         int slot = BufferQueue::INVALID_BUFFER_SLOT;
755         sp<Fence> fence = Fence::NO_FENCE;
756         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
757         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
758         IGraphicBufferProducer::QueueBufferInput input(0ull, true,
759                 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
760                 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
761         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
762     }
763
764     int slot = BufferQueue::INVALID_BUFFER_SLOT;
765     sp<Fence> fence = Fence::NO_FENCE;
766     auto startTime = systemTime();
767     ASSERT_EQ(TIMED_OUT, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
768     ASSERT_GE(systemTime() - startTime, TIMEOUT);
769
770     // We're technically attaching the same buffer multiple times (since we
771     // queued it previously), but that doesn't matter for this test
772     startTime = systemTime();
773     ASSERT_EQ(TIMED_OUT, mProducer->attachBuffer(&slot, buffer));
774     ASSERT_GE(systemTime() - startTime, TIMEOUT);
775 }
776
777 TEST_F(BufferQueueTest, CanAttachWhileDisallowingAllocation) {
778     createBufferQueue();
779     sp<DummyConsumer> dc(new DummyConsumer);
780     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
781     IGraphicBufferProducer::QueueBufferOutput output;
782     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
783             NATIVE_WINDOW_API_CPU, true, &output));
784
785     int slot = BufferQueue::INVALID_BUFFER_SLOT;
786     sp<Fence> sourceFence;
787     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
788             mProducer->dequeueBuffer(&slot, &sourceFence, 0, 0, 0, 0));
789     sp<GraphicBuffer> buffer;
790     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
791     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
792
793     ASSERT_EQ(OK, mProducer->allowAllocation(false));
794
795     slot = BufferQueue::INVALID_BUFFER_SLOT;
796     ASSERT_EQ(OK, mProducer->attachBuffer(&slot, buffer));
797 }
798
799 TEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) {
800     createBufferQueue();
801     sp<DummyConsumer> dc(new DummyConsumer);
802     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
803     IGraphicBufferProducer::QueueBufferOutput output;
804     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
805             NATIVE_WINDOW_API_CPU, false, &output));
806
807     // Dequeue and queue the first buffer, storing the handle
808     int slot = BufferQueue::INVALID_BUFFER_SLOT;
809     sp<Fence> fence;
810     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
811             mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
812     sp<GraphicBuffer> firstBuffer;
813     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &firstBuffer));
814
815     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
816         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
817         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
818     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
819
820     // Dequeue a second buffer
821     slot = BufferQueue::INVALID_BUFFER_SLOT;
822     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
823             mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
824     sp<GraphicBuffer> secondBuffer;
825     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &secondBuffer));
826
827     // Ensure it's a new buffer
828     ASSERT_NE(firstBuffer->getNativeBuffer()->handle,
829             secondBuffer->getNativeBuffer()->handle);
830
831     // Queue the second buffer
832     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
833
834     // Acquire and release both buffers
835     for (size_t i = 0; i < 2; ++i) {
836         BufferItem item;
837         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
838         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
839                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
840     }
841
842     // Make sure we got the second buffer back
843     sp<GraphicBuffer> returnedBuffer;
844     sp<Fence> returnedFence;
845     float transform[16];
846     ASSERT_EQ(OK,
847             mProducer->getLastQueuedBuffer(&returnedBuffer, &returnedFence,
848             transform));
849     ASSERT_EQ(secondBuffer->getNativeBuffer()->handle,
850             returnedBuffer->getNativeBuffer()->handle);
851 }
852
853 TEST_F(BufferQueueTest, TestDiscardFreeBuffers) {
854     createBufferQueue();
855     sp<DummyConsumer> dc(new DummyConsumer);
856     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
857     IGraphicBufferProducer::QueueBufferOutput output;
858     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
859             NATIVE_WINDOW_API_CPU, false, &output));
860
861     int slot = BufferQueue::INVALID_BUFFER_SLOT;
862     sp<Fence> fence = Fence::NO_FENCE;
863     sp<GraphicBuffer> buffer = nullptr;
864     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
865         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
866         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
867     BufferItem item{};
868
869     // Preallocate, dequeue, request, and cancel 4 buffers so we don't get
870     // BUFFER_NEEDS_REALLOCATION below
871     int slots[4] = {};
872     mProducer->setMaxDequeuedBufferCount(4);
873     for (size_t i = 0; i < 4; ++i) {
874         status_t result = mProducer->dequeueBuffer(&slots[i], &fence,
875                 0, 0, 0, 0);
876         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
877         ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
878     }
879     for (size_t i = 0; i < 4; ++i) {
880         ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
881     }
882
883     // Get buffers in all states: dequeued, filled, acquired, free
884
885     // Fill 3 buffers
886     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
887     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
888     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
889     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
890     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
891     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
892     // Dequeue 1 buffer
893     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0));
894
895     // Acquire and free 1 buffer
896     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
897     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
898                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
899     // Acquire 1 buffer, leaving 1 filled buffer in queue
900     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
901
902     // Now discard the free buffers
903     ASSERT_EQ(OK, mConsumer->discardFreeBuffers());
904
905     // Check no free buffers in dump
906     String8 dumpString;
907     mConsumer->dumpState(dumpString, nullptr);
908
909     // Parse the dump to ensure that all buffer slots that are FREE also
910     // have a null GraphicBuffer
911     // Fragile - assumes the following format for the dump for a buffer entry:
912     // ":%p\][^:]*state=FREE" where %p is the buffer pointer in hex.
913     ssize_t idx = dumpString.find("state=FREE");
914     while (idx != -1) {
915         ssize_t bufferPtrIdx = idx - 1;
916         while (bufferPtrIdx > 0) {
917             if (dumpString[bufferPtrIdx] == ':') {
918                 bufferPtrIdx++;
919                 break;
920             }
921             bufferPtrIdx--;
922         }
923         ASSERT_GT(bufferPtrIdx, 0) << "Can't parse queue dump to validate";
924         ssize_t nullPtrIdx = dumpString.find("0x0]", bufferPtrIdx);
925         ASSERT_EQ(bufferPtrIdx, nullPtrIdx) << "Free buffer not discarded";
926         idx = dumpString.find("FREE", idx + 1);
927     }
928 }
929
930 } // namespace android