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 "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 } // namespace android
    854