BufferQueue_test.cpp revision b3d0bdf0dbc19f0a0d7d924693025371e24828fd
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 <gtest/gtest.h>
21
22#include <utils/String8.h>
23#include <utils/threads.h>
24
25#include <ui/GraphicBuffer.h>
26
27#include <binder/IPCThreadState.h>
28#include <binder/IServiceManager.h>
29#include <binder/ProcessState.h>
30#include <gui/BufferQueue.h>
31
32namespace android {
33
34class BufferQueueTest : public ::testing::Test {
35
36public:
37protected:
38    BufferQueueTest() {
39        const ::testing::TestInfo* const testInfo =
40            ::testing::UnitTest::GetInstance()->current_test_info();
41        ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
42                testInfo->name());
43    }
44
45    ~BufferQueueTest() {
46        const ::testing::TestInfo* const testInfo =
47            ::testing::UnitTest::GetInstance()->current_test_info();
48        ALOGV("End test:   %s.%s", testInfo->test_case_name(),
49                testInfo->name());
50    }
51
52    void GetMinUndequeuedBufferCount(int* bufferCount) {
53        ASSERT_TRUE(bufferCount != NULL);
54        ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
55                    bufferCount));
56        ASSERT_GE(*bufferCount, 0);
57    }
58
59    void createBufferQueue() {
60        BufferQueue::createBufferQueue(&mProducer, &mConsumer);
61    }
62
63    sp<IGraphicBufferProducer> mProducer;
64    sp<IGraphicBufferConsumer> mConsumer;
65};
66
67struct DummyConsumer : public BnConsumerListener {
68    virtual void onFrameAvailable() {}
69    virtual void onBuffersReleased() {}
70    virtual void onSidebandStreamChanged() {}
71};
72
73// XXX: Tests that fork a process to hold the BufferQueue must run before tests
74// that use a local BufferQueue, or else Binder will get unhappy
75TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) {
76    const String16 PRODUCER_NAME = String16("BQTestProducer");
77    const String16 CONSUMER_NAME = String16("BQTestConsumer");
78
79    pid_t forkPid = fork();
80    ASSERT_NE(forkPid, -1);
81
82    if (forkPid == 0) {
83        // Child process
84        sp<IGraphicBufferProducer> producer;
85        sp<IGraphicBufferConsumer> consumer;
86        BufferQueue::createBufferQueue(&producer, &consumer);
87        sp<IServiceManager> serviceManager = defaultServiceManager();
88        serviceManager->addService(PRODUCER_NAME, producer->asBinder());
89        serviceManager->addService(CONSUMER_NAME, consumer->asBinder());
90        ProcessState::self()->startThreadPool();
91        IPCThreadState::self()->joinThreadPool();
92        LOG_ALWAYS_FATAL("Shouldn't be here");
93    }
94
95    sp<IServiceManager> serviceManager = defaultServiceManager();
96    sp<IBinder> binderProducer =
97        serviceManager->getService(PRODUCER_NAME);
98    mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
99    EXPECT_TRUE(mProducer != NULL);
100    sp<IBinder> binderConsumer =
101        serviceManager->getService(CONSUMER_NAME);
102    mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
103    EXPECT_TRUE(mConsumer != NULL);
104
105    sp<DummyConsumer> dc(new DummyConsumer);
106    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
107    IGraphicBufferProducer::QueueBufferOutput output;
108    ASSERT_EQ(OK,
109            mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
110
111    int slot;
112    sp<Fence> fence;
113    sp<GraphicBuffer> buffer;
114    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
115            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
116                    GRALLOC_USAGE_SW_WRITE_OFTEN));
117    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
118
119    uint32_t* dataIn;
120    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
121            reinterpret_cast<void**>(&dataIn)));
122    *dataIn = 0x12345678;
123    ASSERT_EQ(OK, buffer->unlock());
124
125    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
126            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
127    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
128
129    IGraphicBufferConsumer::BufferItem item;
130    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
131
132    uint32_t* dataOut;
133    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
134            reinterpret_cast<void**>(&dataOut)));
135    ASSERT_EQ(*dataOut, 0x12345678);
136    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
137}
138
139TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
140    createBufferQueue();
141    sp<DummyConsumer> dc(new DummyConsumer);
142    mConsumer->consumerConnect(dc, false);
143    IGraphicBufferProducer::QueueBufferOutput qbo;
144    mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &qbo);
145    mProducer->setBufferCount(4);
146
147    int slot;
148    sp<Fence> fence;
149    sp<GraphicBuffer> buf;
150    IGraphicBufferProducer::QueueBufferInput qbi(0, false, Rect(0, 0, 1, 1),
151            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
152    BufferQueue::BufferItem item;
153
154    for (int i = 0; i < 2; i++) {
155        ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
156                mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0,
157                    GRALLOC_USAGE_SW_READ_OFTEN));
158        ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
159        ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
160        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
161    }
162
163    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
164            mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0,
165                GRALLOC_USAGE_SW_READ_OFTEN));
166    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
167    ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
168
169    // Acquire the third buffer, which should fail.
170    ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0));
171}
172
173TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
174    createBufferQueue();
175    sp<DummyConsumer> dc(new DummyConsumer);
176    mConsumer->consumerConnect(dc, false);
177
178    int minBufferCount;
179    ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
180    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
181                minBufferCount - 1));
182
183    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0));
184    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3));
185    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
186            BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
187    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
188}
189
190TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
191    createBufferQueue();
192    sp<DummyConsumer> dc(new DummyConsumer);
193    mConsumer->consumerConnect(dc, false);
194
195    int minBufferCount;
196    ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
197
198    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
199    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2));
200    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount));
201    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(
202            BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
203}
204
205TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
206    createBufferQueue();
207    sp<DummyConsumer> dc(new DummyConsumer);
208    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
209    IGraphicBufferProducer::QueueBufferOutput output;
210    ASSERT_EQ(OK,
211            mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
212
213    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low
214    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(
215                BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
216    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued
217
218    int slot;
219    sp<Fence> fence;
220    sp<GraphicBuffer> buffer;
221    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
222            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
223                    GRALLOC_USAGE_SW_WRITE_OFTEN));
224    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested
225    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
226    ASSERT_EQ(OK, mProducer->detachBuffer(slot));
227    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued
228
229    sp<GraphicBuffer> safeToClobberBuffer;
230    // Can no longer request buffer from this slot
231    ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer));
232
233    uint32_t* dataIn;
234    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
235            reinterpret_cast<void**>(&dataIn)));
236    *dataIn = 0x12345678;
237    ASSERT_EQ(OK, buffer->unlock());
238
239    int newSlot;
240    ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(NULL, safeToClobberBuffer));
241    ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL));
242
243    ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
244    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
245            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
246    ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
247
248    IGraphicBufferConsumer::BufferItem item;
249    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
250
251    uint32_t* dataOut;
252    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
253            reinterpret_cast<void**>(&dataOut)));
254    ASSERT_EQ(*dataOut, 0x12345678);
255    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
256}
257
258TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
259    createBufferQueue();
260    sp<DummyConsumer> dc(new DummyConsumer);
261    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
262    IGraphicBufferProducer::QueueBufferOutput output;
263    ASSERT_EQ(OK,
264            mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
265
266    int slot;
267    sp<Fence> fence;
268    sp<GraphicBuffer> buffer;
269    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
270            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
271                    GRALLOC_USAGE_SW_WRITE_OFTEN));
272    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
273    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
274            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
275    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
276
277    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low
278    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(
279            BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
280    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
281
282    IGraphicBufferConsumer::BufferItem item;
283    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
284
285    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
286    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mBuf)); // Not acquired
287
288    uint32_t* dataIn;
289    ASSERT_EQ(OK, item.mGraphicBuffer->lock(
290            GraphicBuffer::USAGE_SW_WRITE_OFTEN,
291            reinterpret_cast<void**>(&dataIn)));
292    *dataIn = 0x12345678;
293    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
294
295    int newSlot;
296    sp<GraphicBuffer> safeToClobberBuffer;
297    ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(NULL, safeToClobberBuffer));
298    ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, NULL));
299    ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer));
300
301    ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mBuf, 0, EGL_NO_DISPLAY,
302            EGL_NO_SYNC_KHR, Fence::NO_FENCE));
303
304    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
305            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
306                    GRALLOC_USAGE_SW_WRITE_OFTEN));
307    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
308
309    uint32_t* dataOut;
310    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
311            reinterpret_cast<void**>(&dataOut)));
312    ASSERT_EQ(*dataOut, 0x12345678);
313    ASSERT_EQ(OK, buffer->unlock());
314}
315
316TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
317    createBufferQueue();
318    sp<DummyConsumer> dc(new DummyConsumer);
319    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
320    IGraphicBufferProducer::QueueBufferOutput output;
321    ASSERT_EQ(OK,
322            mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
323
324    int slot;
325    sp<Fence> fence;
326    sp<GraphicBuffer> buffer;
327    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
328            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
329                    GRALLOC_USAGE_SW_WRITE_OFTEN));
330    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
331
332    uint32_t* dataIn;
333    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
334            reinterpret_cast<void**>(&dataIn)));
335    *dataIn = 0x12345678;
336    ASSERT_EQ(OK, buffer->unlock());
337
338    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
339            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
340    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
341
342    IGraphicBufferConsumer::BufferItem item;
343    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
344    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
345
346    int newSlot;
347    ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
348    ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
349    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
350
351    uint32_t* dataOut;
352    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
353            reinterpret_cast<void**>(&dataOut)));
354    ASSERT_EQ(*dataOut, 0x12345678);
355    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
356}
357
358} // namespace android
359