BufferQueue_test.cpp revision 9f3053de78630815d60cf48a2cf2348cc5867c45
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/IServiceManager.h>
28#include <gui/BufferQueue.h>
29
30namespace android {
31
32class BufferQueueTest : public ::testing::Test {
33
34public:
35    static const String16 PRODUCER_NAME;
36    static const String16 CONSUMER_NAME;
37
38protected:
39    BufferQueueTest() {
40        const ::testing::TestInfo* const testInfo =
41            ::testing::UnitTest::GetInstance()->current_test_info();
42        ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
43                testInfo->name());
44
45        BufferQueue::createBufferQueue(&mProducer, &mConsumer);
46        sp<IServiceManager> serviceManager = defaultServiceManager();
47        serviceManager->addService(PRODUCER_NAME, mProducer.get());
48        serviceManager->addService(CONSUMER_NAME, mConsumer.get());
49    }
50
51    ~BufferQueueTest() {
52        const ::testing::TestInfo* const testInfo =
53            ::testing::UnitTest::GetInstance()->current_test_info();
54        ALOGV("End test:   %s.%s", testInfo->test_case_name(),
55                testInfo->name());
56    }
57
58    void GetMinUndequeuedBufferCount(int* bufferCount) {
59        ASSERT_TRUE(bufferCount != NULL);
60        ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
61                    bufferCount));
62        ASSERT_GE(*bufferCount, 0);
63    }
64
65    sp<BnGraphicBufferProducer> mProducer;
66    sp<BnGraphicBufferConsumer> mConsumer;
67};
68
69const String16 BufferQueueTest::PRODUCER_NAME = String16("BQTestProducer");
70const String16 BufferQueueTest::CONSUMER_NAME = String16("BQTestConsumer");
71
72struct DummyConsumer : public BnConsumerListener {
73    virtual void onFrameAvailable() {}
74    virtual void onBuffersReleased() {}
75};
76
77TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
78    sp<DummyConsumer> dc(new DummyConsumer);
79    mConsumer->consumerConnect(dc, false);
80    IGraphicBufferProducer::QueueBufferOutput qbo;
81    mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &qbo);
82    mProducer->setBufferCount(4);
83
84    int slot;
85    sp<Fence> fence;
86    sp<GraphicBuffer> buf;
87    IGraphicBufferProducer::QueueBufferInput qbi(0, false, Rect(0, 0, 1, 1),
88            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
89    BufferQueue::BufferItem item;
90
91    for (int i = 0; i < 2; i++) {
92        ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
93                mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0,
94                    GRALLOC_USAGE_SW_READ_OFTEN));
95        ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
96        ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
97        ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
98    }
99
100    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
101            mProducer->dequeueBuffer(&slot, &fence, false, 1, 1, 0,
102                GRALLOC_USAGE_SW_READ_OFTEN));
103    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
104    ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
105
106    // Acquire the third buffer, which should fail.
107    ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0));
108}
109
110TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
111    sp<DummyConsumer> dc(new DummyConsumer);
112    mConsumer->consumerConnect(dc, false);
113
114    int minBufferCount;
115    ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
116    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
117                minBufferCount - 1));
118
119    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0));
120    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3));
121    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
122            BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
123    EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
124}
125
126TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
127    sp<DummyConsumer> dc(new DummyConsumer);
128    mConsumer->consumerConnect(dc, false);
129
130    int minBufferCount;
131    ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
132
133    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
134    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2));
135    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount));
136    EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(
137            BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
138}
139
140TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
141    sp<DummyConsumer> dc(new DummyConsumer);
142    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
143    IGraphicBufferProducer::QueueBufferOutput output;
144    ASSERT_EQ(OK,
145            mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
146
147    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low
148    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(
149                BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
150    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued
151
152    int slot;
153    sp<Fence> fence;
154    sp<GraphicBuffer> buffer;
155    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
156            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
157                    GRALLOC_USAGE_SW_WRITE_OFTEN));
158    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested
159    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
160    ASSERT_EQ(OK, mProducer->detachBuffer(slot));
161    ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued
162
163    sp<GraphicBuffer> safeToClobberBuffer;
164    // Can no longer request buffer from this slot
165    ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer));
166
167    uint32_t* dataIn;
168    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
169            reinterpret_cast<void**>(&dataIn)));
170    *dataIn = 0x12345678;
171    ASSERT_EQ(OK, buffer->unlock());
172
173    int newSlot;
174    ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(NULL, safeToClobberBuffer));
175    ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL));
176
177    ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
178    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
179            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
180    ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
181
182    IGraphicBufferConsumer::BufferItem item;
183    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
184
185    uint32_t* dataOut;
186    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
187            reinterpret_cast<void**>(&dataOut)));
188    ASSERT_EQ(*dataOut, 0x12345678);
189}
190
191TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
192    sp<DummyConsumer> dc(new DummyConsumer);
193    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
194    IGraphicBufferProducer::QueueBufferOutput output;
195    ASSERT_EQ(OK,
196            mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
197
198    int slot;
199    sp<Fence> fence;
200    sp<GraphicBuffer> buffer;
201    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
202            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
203                    GRALLOC_USAGE_SW_WRITE_OFTEN));
204    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
205    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
206            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
207    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
208
209    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low
210    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(
211            BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
212    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
213
214    IGraphicBufferConsumer::BufferItem item;
215    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
216
217    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
218    ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mBuf)); // Not acquired
219
220    uint32_t* dataIn;
221    ASSERT_EQ(OK, item.mGraphicBuffer->lock(
222            GraphicBuffer::USAGE_SW_WRITE_OFTEN,
223            reinterpret_cast<void**>(&dataIn)));
224    *dataIn = 0x12345678;
225    ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
226
227    int newSlot;
228    sp<GraphicBuffer> safeToClobberBuffer;
229    ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(NULL, safeToClobberBuffer));
230    ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, NULL));
231    ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer));
232
233    ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mBuf, 0, EGL_NO_DISPLAY,
234            EGL_NO_SYNC_KHR, Fence::NO_FENCE));
235
236    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
237            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
238                    GRALLOC_USAGE_SW_WRITE_OFTEN));
239    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
240
241    uint32_t* dataOut;
242    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
243            reinterpret_cast<void**>(&dataOut)));
244    ASSERT_EQ(*dataOut, 0x12345678);
245}
246
247TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
248    sp<DummyConsumer> dc(new DummyConsumer);
249    ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
250    IGraphicBufferProducer::QueueBufferOutput output;
251    ASSERT_EQ(OK,
252            mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
253
254    int slot;
255    sp<Fence> fence;
256    sp<GraphicBuffer> buffer;
257    ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
258            mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
259                    GRALLOC_USAGE_SW_WRITE_OFTEN));
260    ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
261
262    uint32_t* dataIn;
263    ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
264            reinterpret_cast<void**>(&dataIn)));
265    *dataIn = 0x12345678;
266    ASSERT_EQ(OK, buffer->unlock());
267
268    IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
269            NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
270    ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
271
272    IGraphicBufferConsumer::BufferItem item;
273    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
274    ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
275
276    int newSlot;
277    ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
278    ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
279    ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
280
281    uint32_t* dataOut;
282    ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
283            reinterpret_cast<void**>(&dataOut)));
284    ASSERT_EQ(*dataOut, 0x12345678);
285}
286
287} // namespace android
288