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