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 <system/window.h>
     36 
     37 #include <gtest/gtest.h>
     38 
     39 #include <thread>
     40 
     41 using namespace std::chrono_literals;
     42 
     43 namespace android {
     44 
     45 class BufferQueueTest : public ::testing::Test {
     46 
     47 public:
     48 protected:
     49     BufferQueueTest() {
     50         const ::testing::TestInfo* const testInfo =
     51             ::testing::UnitTest::GetInstance()->current_test_info();
     52         ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
     53                 testInfo->name());
     54     }
     55 
     56     ~BufferQueueTest() {
     57         const ::testing::TestInfo* const testInfo =
     58             ::testing::UnitTest::GetInstance()->current_test_info();
     59         ALOGV("End test:   %s.%s", testInfo->test_case_name(),
     60                 testInfo->name());
     61     }
     62 
     63     void GetMinUndequeuedBufferCount(int* bufferCount) {
     64         ASSERT_TRUE(bufferCount != NULL);
     65         ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
     66                     bufferCount));
     67         ASSERT_GE(*bufferCount, 0);
     68     }
     69 
     70     void createBufferQueue() {
     71         BufferQueue::createBufferQueue(&mProducer, &mConsumer);
     72     }
     73 
     74     void testBufferItem(const IGraphicBufferProducer::QueueBufferInput& input,
     75             const BufferItem& item) {
     76         int64_t timestamp;
     77         bool isAutoTimestamp;
     78         android_dataspace dataSpace;
     79         Rect crop;
     80         int scalingMode;
     81         uint32_t transform;
     82         sp<Fence> fence;
     83 
     84         input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop,
     85                 &scalingMode, &transform, &fence, NULL);
     86         ASSERT_EQ(timestamp, item.mTimestamp);
     87         ASSERT_EQ(isAutoTimestamp, item.mIsAutoTimestamp);
     88         ASSERT_EQ(dataSpace, item.mDataSpace);
     89         ASSERT_EQ(crop, item.mCrop);
     90         ASSERT_EQ(static_cast<uint32_t>(scalingMode), item.mScalingMode);
     91         ASSERT_EQ(transform, item.mTransform);
     92         ASSERT_EQ(fence, item.mFence);
     93     }
     94 
     95     sp<IGraphicBufferProducer> mProducer;
     96     sp<IGraphicBufferConsumer> mConsumer;
     97 };
     98 
     99 static const uint32_t TEST_DATA = 0x12345678u;
    100 
    101 // XXX: Tests that fork a process to hold the BufferQueue must run before tests
    102 // that use a local BufferQueue, or else Binder will get unhappy
    103 //
    104 // In one instance this was a crash in the createBufferQueue where the
    105 // binder call to create a buffer allocator apparently got garbage back.
    106 // See b/36592665.
    107 TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) {
    108     const String16 PRODUCER_NAME = String16("BQTestProducer");
    109     const String16 CONSUMER_NAME = String16("BQTestConsumer");
    110 
    111     pid_t forkPid = fork();
    112     ASSERT_NE(forkPid, -1);
    113 
    114     if (forkPid == 0) {
    115         // Child process
    116         sp<IGraphicBufferProducer> producer;
    117         sp<IGraphicBufferConsumer> consumer;
    118         BufferQueue::createBufferQueue(&producer, &consumer);
    119         sp<IServiceManager> serviceManager = defaultServiceManager();
    120         serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
    121         serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
    122         ProcessState::self()->startThreadPool();
    123         IPCThreadState::self()->joinThreadPool();
    124         LOG_ALWAYS_FATAL("Shouldn't be here");
    125     }
    126 
    127     sp<IServiceManager> serviceManager = defaultServiceManager();
    128     sp<IBinder> binderProducer =
    129         serviceManager->getService(PRODUCER_NAME);
    130     mProducer = interface_cast<IGraphicBufferProducer>(binderProducer);
    131     EXPECT_TRUE(mProducer != NULL);
    132     sp<IBinder> binderConsumer =
    133         serviceManager->getService(CONSUMER_NAME);
    134     mConsumer = interface_cast<IGraphicBufferConsumer>(binderConsumer);
    135     EXPECT_TRUE(mConsumer != NULL);
    136 
    137     sp<DummyConsumer> dc(new DummyConsumer);
    138     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    139     IGraphicBufferProducer::QueueBufferOutput output;
    140     ASSERT_EQ(OK,
    141             mProducer->connect(NULL, NATIVE_WINDOW_API_CPU, false, &output));
    142 
    143     int slot;
    144     sp<Fence> fence;
    145     sp<GraphicBuffer> buffer;
    146     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    147               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
    148                                        nullptr, nullptr));
    149     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
    150 
    151     uint32_t* dataIn;
    152     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
    153             reinterpret_cast<void**>(&dataIn)));
    154     *dataIn = TEST_DATA;
    155     ASSERT_EQ(OK, buffer->unlock());
    156 
    157     IGraphicBufferProducer::QueueBufferInput input(0, false,
    158             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
    159             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    160     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    161 
    162     BufferItem item;
    163     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    164 
    165     uint32_t* dataOut;
    166     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
    167             reinterpret_cast<void**>(&dataOut)));
    168     ASSERT_EQ(*dataOut, TEST_DATA);
    169     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
    170 }
    171 
    172 TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
    173     createBufferQueue();
    174     sp<DummyConsumer> dc(new DummyConsumer);
    175     mConsumer->consumerConnect(dc, false);
    176     IGraphicBufferProducer::QueueBufferOutput qbo;
    177     mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
    178             &qbo);
    179     mProducer->setMaxDequeuedBufferCount(3);
    180 
    181     int slot;
    182     sp<Fence> fence;
    183     sp<GraphicBuffer> buf;
    184     IGraphicBufferProducer::QueueBufferInput qbi(0, false,
    185             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
    186             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    187     BufferItem item;
    188 
    189     for (int i = 0; i < 2; i++) {
    190         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    191                   mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
    192                                            nullptr, nullptr));
    193         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
    194         ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
    195         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    196     }
    197 
    198     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    199               mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
    200                                        nullptr, nullptr));
    201     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
    202     ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
    203 
    204     // Acquire the third buffer, which should fail.
    205     ASSERT_EQ(INVALID_OPERATION, mConsumer->acquireBuffer(&item, 0));
    206 }
    207 
    208 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
    209     createBufferQueue();
    210     sp<DummyConsumer> dc(new DummyConsumer);
    211     mConsumer->consumerConnect(dc, false);
    212 
    213     EXPECT_EQ(OK, mConsumer->setMaxBufferCount(10));
    214     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(10));
    215 
    216     IGraphicBufferProducer::QueueBufferOutput qbo;
    217     mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
    218             &qbo);
    219     mProducer->setMaxDequeuedBufferCount(3);
    220 
    221     int minBufferCount;
    222     ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
    223     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
    224                 minBufferCount - 1));
    225 
    226     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(0));
    227     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(-3));
    228     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(
    229             BufferQueue::MAX_MAX_ACQUIRED_BUFFERS+1));
    230     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(100));
    231 
    232     int slot;
    233     sp<Fence> fence;
    234     sp<GraphicBuffer> buf;
    235     IGraphicBufferProducer::QueueBufferInput qbi(0, false,
    236             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
    237             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    238     BufferItem item;
    239     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
    240     for (int i = 0; i < 3; i++) {
    241         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    242                   mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
    243                                            nullptr, nullptr));
    244         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
    245         ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
    246         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    247     }
    248 
    249     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxAcquiredBufferCount(2));
    250 }
    251 
    252 TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
    253     createBufferQueue();
    254     sp<DummyConsumer> dc(new DummyConsumer);
    255     mConsumer->consumerConnect(dc, false);
    256 
    257     IGraphicBufferProducer::QueueBufferOutput qbo;
    258     mProducer->connect(new DummyProducerListener, NATIVE_WINDOW_API_CPU, false,
    259             &qbo);
    260     mProducer->setMaxDequeuedBufferCount(2);
    261 
    262     int minBufferCount;
    263     ASSERT_NO_FATAL_FAILURE(GetMinUndequeuedBufferCount(&minBufferCount));
    264 
    265     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
    266     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(2));
    267     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(minBufferCount));
    268 
    269     int slot;
    270     sp<Fence> fence;
    271     sp<GraphicBuffer> buf;
    272     IGraphicBufferProducer::QueueBufferInput qbi(0, false,
    273             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
    274             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    275     BufferItem item;
    276 
    277     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    278               mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
    279                                        nullptr, nullptr));
    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     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(3));
    285 
    286     for (int i = 0; i < 2; i++) {
    287         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    288                   mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
    289                                            nullptr, nullptr));
    290         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buf));
    291         ASSERT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
    292         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    293     }
    294 
    295     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(
    296             BufferQueue::MAX_MAX_ACQUIRED_BUFFERS));
    297 }
    298 
    299 TEST_F(BufferQueueTest, SetMaxBufferCountWithLegalValues_Succeeds) {
    300     createBufferQueue();
    301     sp<DummyConsumer> dc(new DummyConsumer);
    302     mConsumer->consumerConnect(dc, false);
    303 
    304     // Test shared buffer mode
    305     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
    306 }
    307 
    308 TEST_F(BufferQueueTest, SetMaxBufferCountWithIllegalValues_ReturnsError) {
    309     createBufferQueue();
    310     sp<DummyConsumer> dc(new DummyConsumer);
    311     mConsumer->consumerConnect(dc, false);
    312 
    313     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(0));
    314     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(
    315             BufferQueue::NUM_BUFFER_SLOTS + 1));
    316 
    317     EXPECT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(5));
    318     EXPECT_EQ(BAD_VALUE, mConsumer->setMaxBufferCount(3));
    319 }
    320 
    321 TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
    322     createBufferQueue();
    323     sp<DummyConsumer> dc(new DummyConsumer);
    324     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    325     IGraphicBufferProducer::QueueBufferOutput output;
    326     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    327             NATIVE_WINDOW_API_CPU, false, &output));
    328 
    329     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(-1)); // Index too low
    330     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(
    331                 BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
    332     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(0)); // Not dequeued
    333 
    334     int slot;
    335     sp<Fence> fence;
    336     sp<GraphicBuffer> buffer;
    337     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    338               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
    339                                        nullptr, nullptr));
    340     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not requested
    341     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
    342     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
    343     ASSERT_EQ(BAD_VALUE, mProducer->detachBuffer(slot)); // Not dequeued
    344 
    345     sp<GraphicBuffer> safeToClobberBuffer;
    346     // Can no longer request buffer from this slot
    347     ASSERT_EQ(BAD_VALUE, mProducer->requestBuffer(slot, &safeToClobberBuffer));
    348 
    349     uint32_t* dataIn;
    350     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
    351             reinterpret_cast<void**>(&dataIn)));
    352     *dataIn = TEST_DATA;
    353     ASSERT_EQ(OK, buffer->unlock());
    354 
    355     int newSlot;
    356     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(NULL, safeToClobberBuffer));
    357     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL));
    358 
    359     ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
    360     IGraphicBufferProducer::QueueBufferInput input(0, false,
    361             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
    362             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    363     ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
    364 
    365     BufferItem item;
    366     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
    367 
    368     uint32_t* dataOut;
    369     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
    370             reinterpret_cast<void**>(&dataOut)));
    371     ASSERT_EQ(*dataOut, TEST_DATA);
    372     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
    373 }
    374 
    375 TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
    376     createBufferQueue();
    377     sp<DummyConsumer> dc(new DummyConsumer);
    378     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    379     IGraphicBufferProducer::QueueBufferOutput output;
    380     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    381             NATIVE_WINDOW_API_CPU, false, &output));
    382 
    383     int slot;
    384     sp<Fence> fence;
    385     sp<GraphicBuffer> buffer;
    386     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    387               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
    388                                        nullptr, nullptr));
    389     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
    390     IGraphicBufferProducer::QueueBufferInput input(0, false,
    391             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
    392             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    393     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    394 
    395     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(-1)); // Index too low
    396     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(
    397             BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
    398     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
    399 
    400     BufferItem item;
    401     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
    402 
    403     ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
    404     ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(item.mSlot)); // Not acquired
    405 
    406     uint32_t* dataIn;
    407     ASSERT_EQ(OK, item.mGraphicBuffer->lock(
    408             GraphicBuffer::USAGE_SW_WRITE_OFTEN,
    409             reinterpret_cast<void**>(&dataIn)));
    410     *dataIn = TEST_DATA;
    411     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
    412 
    413     int newSlot;
    414     sp<GraphicBuffer> safeToClobberBuffer;
    415     ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(NULL, safeToClobberBuffer));
    416     ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&newSlot, NULL));
    417     ASSERT_EQ(OK, mConsumer->attachBuffer(&newSlot, item.mGraphicBuffer));
    418 
    419     ASSERT_EQ(OK, mConsumer->releaseBuffer(newSlot, 0, EGL_NO_DISPLAY,
    420             EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    421 
    422     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    423               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
    424                                        nullptr, nullptr));
    425     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
    426 
    427     uint32_t* dataOut;
    428     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
    429             reinterpret_cast<void**>(&dataOut)));
    430     ASSERT_EQ(*dataOut, TEST_DATA);
    431     ASSERT_EQ(OK, buffer->unlock());
    432 }
    433 
    434 TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
    435     createBufferQueue();
    436     sp<DummyConsumer> dc(new DummyConsumer);
    437     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    438     IGraphicBufferProducer::QueueBufferOutput output;
    439     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    440             NATIVE_WINDOW_API_CPU, false, &output));
    441 
    442     int slot;
    443     sp<Fence> fence;
    444     sp<GraphicBuffer> buffer;
    445     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    446               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
    447                                        nullptr, nullptr));
    448     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
    449 
    450     uint32_t* dataIn;
    451     ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
    452             reinterpret_cast<void**>(&dataIn)));
    453     *dataIn = TEST_DATA;
    454     ASSERT_EQ(OK, buffer->unlock());
    455 
    456     IGraphicBufferProducer::QueueBufferInput input(0, false,
    457             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
    458             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    459     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    460 
    461     BufferItem item;
    462     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
    463     ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
    464 
    465     int newSlot;
    466     ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, item.mGraphicBuffer));
    467     ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
    468     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
    469 
    470     uint32_t* dataOut;
    471     ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
    472             reinterpret_cast<void**>(&dataOut)));
    473     ASSERT_EQ(*dataOut, TEST_DATA);
    474     ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
    475 }
    476 
    477 TEST_F(BufferQueueTest, TestDisallowingAllocation) {
    478     createBufferQueue();
    479     sp<DummyConsumer> dc(new DummyConsumer);
    480     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
    481     IGraphicBufferProducer::QueueBufferOutput output;
    482     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    483             NATIVE_WINDOW_API_CPU, true, &output));
    484 
    485     static const uint32_t WIDTH = 320;
    486     static const uint32_t HEIGHT = 240;
    487 
    488     ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT));
    489 
    490     int slot;
    491     sp<Fence> fence;
    492     sp<GraphicBuffer> buffer;
    493     // This should return an error since it would require an allocation
    494     ASSERT_EQ(OK, mProducer->allowAllocation(false));
    495     ASSERT_EQ(WOULD_BLOCK,
    496               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
    497                                        nullptr, nullptr));
    498 
    499     // This should succeed, now that we've lifted the prohibition
    500     ASSERT_EQ(OK, mProducer->allowAllocation(true));
    501     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    502               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, GRALLOC_USAGE_SW_WRITE_OFTEN,
    503                                        nullptr, nullptr));
    504 
    505     // Release the previous buffer back to the BufferQueue
    506     mProducer->cancelBuffer(slot, fence);
    507 
    508     // This should fail since we're requesting a different size
    509     ASSERT_EQ(OK, mProducer->allowAllocation(false));
    510     ASSERT_EQ(WOULD_BLOCK,
    511               mProducer->dequeueBuffer(&slot, &fence, WIDTH * 2, HEIGHT * 2, 0,
    512                                        GRALLOC_USAGE_SW_WRITE_OFTEN, nullptr, nullptr));
    513 }
    514 
    515 TEST_F(BufferQueueTest, TestGenerationNumbers) {
    516     createBufferQueue();
    517     sp<DummyConsumer> dc(new DummyConsumer);
    518     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
    519     IGraphicBufferProducer::QueueBufferOutput output;
    520     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    521             NATIVE_WINDOW_API_CPU, true, &output));
    522 
    523     ASSERT_EQ(OK, mProducer->setGenerationNumber(1));
    524 
    525     // Get one buffer to play with
    526     int slot;
    527     sp<Fence> fence;
    528     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    529               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    530 
    531     sp<GraphicBuffer> buffer;
    532     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
    533 
    534     // Ensure that the generation number we set propagates to allocated buffers
    535     ASSERT_EQ(1U, buffer->getGenerationNumber());
    536 
    537     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
    538 
    539     ASSERT_EQ(OK, mProducer->setGenerationNumber(2));
    540 
    541     // These should fail, since we've changed the generation number on the queue
    542     int outSlot;
    543     ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&outSlot, buffer));
    544     ASSERT_EQ(BAD_VALUE, mConsumer->attachBuffer(&outSlot, buffer));
    545 
    546     buffer->setGenerationNumber(2);
    547 
    548     // This should succeed now that we've changed the buffer's generation number
    549     ASSERT_EQ(OK, mProducer->attachBuffer(&outSlot, buffer));
    550 
    551     ASSERT_EQ(OK, mProducer->detachBuffer(outSlot));
    552 
    553     // This should also succeed with the new generation number
    554     ASSERT_EQ(OK, mConsumer->attachBuffer(&outSlot, buffer));
    555 }
    556 
    557 TEST_F(BufferQueueTest, TestSharedBufferModeWithoutAutoRefresh) {
    558     createBufferQueue();
    559     sp<DummyConsumer> dc(new DummyConsumer);
    560     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
    561     IGraphicBufferProducer::QueueBufferOutput output;
    562     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    563             NATIVE_WINDOW_API_CPU, true, &output));
    564 
    565     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
    566 
    567     // Get a buffer
    568     int sharedSlot;
    569     sp<Fence> fence;
    570     sp<GraphicBuffer> buffer;
    571     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    572               mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    573     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
    574 
    575     // Queue the buffer
    576     IGraphicBufferProducer::QueueBufferInput input(0, false,
    577             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
    578             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    579     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
    580 
    581     // Repeatedly queue and dequeue a buffer from the producer side, it should
    582     // always return the same one. And we won't run out of buffers because it's
    583     // always the same one and because async mode gets enabled.
    584     int slot;
    585     for (int i = 0; i < 5; i++) {
    586         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    587         ASSERT_EQ(sharedSlot, slot);
    588         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
    589     }
    590 
    591     // acquire the buffer
    592     BufferItem item;
    593     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    594     ASSERT_EQ(sharedSlot, item.mSlot);
    595     testBufferItem(input, item);
    596     ASSERT_EQ(true, item.mQueuedBuffer);
    597     ASSERT_EQ(false, item.mAutoRefresh);
    598 
    599     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
    600             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    601 
    602     // attempt to acquire a second time should return no buffer available
    603     ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
    604             mConsumer->acquireBuffer(&item, 0));
    605 }
    606 
    607 TEST_F(BufferQueueTest, TestSharedBufferModeWithAutoRefresh) {
    608     createBufferQueue();
    609     sp<DummyConsumer> dc(new DummyConsumer);
    610     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
    611     IGraphicBufferProducer::QueueBufferOutput output;
    612     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    613             NATIVE_WINDOW_API_CPU, true, &output));
    614 
    615     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
    616     ASSERT_EQ(OK, mProducer->setAutoRefresh(true));
    617 
    618     // Get a buffer
    619     int sharedSlot;
    620     sp<Fence> fence;
    621     sp<GraphicBuffer> buffer;
    622     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    623               mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    624     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
    625 
    626     // Queue the buffer
    627     IGraphicBufferProducer::QueueBufferInput input(0, false,
    628             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
    629             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    630     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
    631 
    632     // Repeatedly acquire and release a buffer from the consumer side, it should
    633     // always return the same one.
    634     BufferItem item;
    635     for (int i = 0; i < 5; i++) {
    636         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    637         ASSERT_EQ(sharedSlot, item.mSlot);
    638         testBufferItem(input, item);
    639         ASSERT_EQ(i == 0, item.mQueuedBuffer);
    640         ASSERT_EQ(true, item.mAutoRefresh);
    641 
    642         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
    643                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    644     }
    645 
    646     // Repeatedly queue and dequeue a buffer from the producer side, it should
    647     // always return the same one.
    648     int slot;
    649     for (int i = 0; i < 5; i++) {
    650         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    651         ASSERT_EQ(sharedSlot, slot);
    652         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
    653     }
    654 
    655     // Repeatedly acquire and release a buffer from the consumer side, it should
    656     // always return the same one. First grabbing them from the queue and then
    657     // when the queue is empty, returning the shared buffer.
    658     for (int i = 0; i < 10; i++) {
    659         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    660         ASSERT_EQ(sharedSlot, item.mSlot);
    661         ASSERT_EQ(0, item.mTimestamp);
    662         ASSERT_EQ(false, item.mIsAutoTimestamp);
    663         ASSERT_EQ(HAL_DATASPACE_UNKNOWN, item.mDataSpace);
    664         ASSERT_EQ(Rect(0, 0, 1, 1), item.mCrop);
    665         ASSERT_EQ(NATIVE_WINDOW_SCALING_MODE_FREEZE, item.mScalingMode);
    666         ASSERT_EQ(0u, item.mTransform);
    667         ASSERT_EQ(Fence::NO_FENCE, item.mFence);
    668         ASSERT_EQ(i == 0, item.mQueuedBuffer);
    669         ASSERT_EQ(true, item.mAutoRefresh);
    670 
    671         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
    672                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    673     }
    674 }
    675 
    676 TEST_F(BufferQueueTest, TestSharedBufferModeUsingAlreadyDequeuedBuffer) {
    677     createBufferQueue();
    678     sp<DummyConsumer> dc(new DummyConsumer);
    679     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
    680     IGraphicBufferProducer::QueueBufferOutput output;
    681     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    682             NATIVE_WINDOW_API_CPU, true, &output));
    683 
    684     // Dequeue a buffer
    685     int sharedSlot;
    686     sp<Fence> fence;
    687     sp<GraphicBuffer> buffer;
    688     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    689               mProducer->dequeueBuffer(&sharedSlot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    690     ASSERT_EQ(OK, mProducer->requestBuffer(sharedSlot, &buffer));
    691 
    692     // Enable shared buffer mode
    693     ASSERT_EQ(OK, mProducer->setSharedBufferMode(true));
    694 
    695     // Queue the buffer
    696     IGraphicBufferProducer::QueueBufferInput input(0, false,
    697             HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
    698             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    699     ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
    700 
    701     // Repeatedly queue and dequeue a buffer from the producer side, it should
    702     // always return the same one. And we won't run out of buffers because it's
    703     // always the same one and because async mode gets enabled.
    704     int slot;
    705     for (int i = 0; i < 5; i++) {
    706         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    707         ASSERT_EQ(sharedSlot, slot);
    708         ASSERT_EQ(OK, mProducer->queueBuffer(sharedSlot, input, &output));
    709     }
    710 
    711     // acquire the buffer
    712     BufferItem item;
    713     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    714     ASSERT_EQ(sharedSlot, item.mSlot);
    715     testBufferItem(input, item);
    716     ASSERT_EQ(true, item.mQueuedBuffer);
    717     ASSERT_EQ(false, item.mAutoRefresh);
    718 
    719     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
    720             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    721 
    722     // attempt to acquire a second time should return no buffer available
    723     ASSERT_EQ(IGraphicBufferConsumer::NO_BUFFER_AVAILABLE,
    724             mConsumer->acquireBuffer(&item, 0));
    725 }
    726 
    727 TEST_F(BufferQueueTest, TestTimeouts) {
    728     createBufferQueue();
    729     sp<DummyConsumer> dc(new DummyConsumer);
    730     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
    731     IGraphicBufferProducer::QueueBufferOutput output;
    732     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    733             NATIVE_WINDOW_API_CPU, true, &output));
    734 
    735     // Fill up the queue. Since the controlledByApp flags are set to true, this
    736     // queue should be in non-blocking mode, and we should be recycling the same
    737     // two buffers
    738     for (int i = 0; i < 5; ++i) {
    739         int slot = BufferQueue::INVALID_BUFFER_SLOT;
    740         sp<Fence> fence = Fence::NO_FENCE;
    741         auto result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr);
    742         if (i < 2) {
    743             ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    744                     result);
    745         } else {
    746             ASSERT_EQ(OK, result);
    747         }
    748         sp<GraphicBuffer> buffer;
    749         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
    750         IGraphicBufferProducer::QueueBufferInput input(0ull, true,
    751                 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
    752                 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    753         IGraphicBufferProducer::QueueBufferOutput output{};
    754         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    755     }
    756 
    757     const auto TIMEOUT = ms2ns(250);
    758     mProducer->setDequeueTimeout(TIMEOUT);
    759 
    760     // Setting a timeout will change the BufferQueue into blocking mode (with
    761     // one droppable buffer in the queue and one free from the previous
    762     // dequeue/queues), so dequeue and queue two more buffers: one to replace
    763     // the current droppable buffer, and a second to max out the buffer count
    764     sp<GraphicBuffer> buffer; // Save a buffer to attach later
    765     for (int i = 0; i < 2; ++i) {
    766         int slot = BufferQueue::INVALID_BUFFER_SLOT;
    767         sp<Fence> fence = Fence::NO_FENCE;
    768         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    769         ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
    770         IGraphicBufferProducer::QueueBufferInput input(0ull, true,
    771                 HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
    772                 NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    773         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    774     }
    775 
    776     int slot = BufferQueue::INVALID_BUFFER_SLOT;
    777     sp<Fence> fence = Fence::NO_FENCE;
    778     auto startTime = systemTime();
    779     ASSERT_EQ(TIMED_OUT, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    780     ASSERT_GE(systemTime() - startTime, TIMEOUT);
    781 
    782     // We're technically attaching the same buffer multiple times (since we
    783     // queued it previously), but that doesn't matter for this test
    784     startTime = systemTime();
    785     ASSERT_EQ(TIMED_OUT, mProducer->attachBuffer(&slot, buffer));
    786     ASSERT_GE(systemTime() - startTime, TIMEOUT);
    787 }
    788 
    789 TEST_F(BufferQueueTest, CanAttachWhileDisallowingAllocation) {
    790     createBufferQueue();
    791     sp<DummyConsumer> dc(new DummyConsumer);
    792     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
    793     IGraphicBufferProducer::QueueBufferOutput output;
    794     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    795             NATIVE_WINDOW_API_CPU, true, &output));
    796 
    797     int slot = BufferQueue::INVALID_BUFFER_SLOT;
    798     sp<Fence> sourceFence;
    799     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    800               mProducer->dequeueBuffer(&slot, &sourceFence, 0, 0, 0, 0, nullptr, nullptr));
    801     sp<GraphicBuffer> buffer;
    802     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
    803     ASSERT_EQ(OK, mProducer->detachBuffer(slot));
    804 
    805     ASSERT_EQ(OK, mProducer->allowAllocation(false));
    806 
    807     slot = BufferQueue::INVALID_BUFFER_SLOT;
    808     ASSERT_EQ(OK, mProducer->attachBuffer(&slot, buffer));
    809 }
    810 
    811 TEST_F(BufferQueueTest, CanRetrieveLastQueuedBuffer) {
    812     createBufferQueue();
    813     sp<DummyConsumer> dc(new DummyConsumer);
    814     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    815     IGraphicBufferProducer::QueueBufferOutput output;
    816     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    817             NATIVE_WINDOW_API_CPU, false, &output));
    818 
    819     // Dequeue and queue the first buffer, storing the handle
    820     int slot = BufferQueue::INVALID_BUFFER_SLOT;
    821     sp<Fence> fence;
    822     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    823               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    824     sp<GraphicBuffer> firstBuffer;
    825     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &firstBuffer));
    826 
    827     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
    828         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
    829         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    830     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    831 
    832     // Dequeue a second buffer
    833     slot = BufferQueue::INVALID_BUFFER_SLOT;
    834     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
    835               mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    836     sp<GraphicBuffer> secondBuffer;
    837     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &secondBuffer));
    838 
    839     // Ensure it's a new buffer
    840     ASSERT_NE(firstBuffer->getNativeBuffer()->handle,
    841             secondBuffer->getNativeBuffer()->handle);
    842 
    843     // Queue the second buffer
    844     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    845 
    846     // Acquire and release both buffers
    847     for (size_t i = 0; i < 2; ++i) {
    848         BufferItem item;
    849         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    850         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
    851                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    852     }
    853 
    854     // Make sure we got the second buffer back
    855     sp<GraphicBuffer> returnedBuffer;
    856     sp<Fence> returnedFence;
    857     float transform[16];
    858     ASSERT_EQ(OK,
    859             mProducer->getLastQueuedBuffer(&returnedBuffer, &returnedFence,
    860             transform));
    861     ASSERT_EQ(secondBuffer->getNativeBuffer()->handle,
    862             returnedBuffer->getNativeBuffer()->handle);
    863 }
    864 
    865 TEST_F(BufferQueueTest, TestOccupancyHistory) {
    866     createBufferQueue();
    867     sp<DummyConsumer> dc(new DummyConsumer);
    868     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
    869     IGraphicBufferProducer::QueueBufferOutput output;
    870     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
    871             NATIVE_WINDOW_API_CPU, false, &output));
    872 
    873     int slot = BufferQueue::INVALID_BUFFER_SLOT;
    874     sp<Fence> fence = Fence::NO_FENCE;
    875     sp<GraphicBuffer> buffer = nullptr;
    876     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
    877         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
    878         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
    879     BufferItem item{};
    880 
    881     // Preallocate, dequeue, request, and cancel 3 buffers so we don't get
    882     // BUFFER_NEEDS_REALLOCATION below
    883     int slots[3] = {};
    884     mProducer->setMaxDequeuedBufferCount(3);
    885     for (size_t i = 0; i < 3; ++i) {
    886         status_t result =
    887                 mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr);
    888         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
    889         ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
    890     }
    891     for (size_t i = 0; i < 3; ++i) {
    892         ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
    893     }
    894 
    895     // Create 3 segments
    896 
    897     // The first segment is a two-buffer segment, so we only put one buffer into
    898     // the queue at a time
    899     for (size_t i = 0; i < 5; ++i) {
    900         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    901         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    902         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    903         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
    904                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    905         std::this_thread::sleep_for(16ms);
    906     }
    907 
    908     // Sleep between segments
    909     std::this_thread::sleep_for(500ms);
    910 
    911     // The second segment is a double-buffer segment. It starts the same as the
    912     // two-buffer segment, but then at the end, we put two buffers in the queue
    913     // at the same time before draining it.
    914     for (size_t i = 0; i < 5; ++i) {
    915         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    916         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    917         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    918         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
    919                 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    920         std::this_thread::sleep_for(16ms);
    921     }
    922     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    923     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    924     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    925     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    926     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    927     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
    928             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    929     std::this_thread::sleep_for(16ms);
    930     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    931     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
    932             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    933 
    934     // Sleep between segments
    935     std::this_thread::sleep_for(500ms);
    936 
    937     // The third segment is a triple-buffer segment, so the queue is switching
    938     // between one buffer and two buffers deep.
    939     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    940     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    941     for (size_t i = 0; i < 5; ++i) {
    942         ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
    943         ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
    944         ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    945         ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
    946                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    947         std::this_thread::sleep_for(16ms);
    948     }
    949     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
    950     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
    951             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
    952 
    953     // Now we read the segments
    954     std::vector<OccupancyTracker::Segment> history;
    955     ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
    956 
    957     // Since we didn't force a flush, we should only get the first two segments
    958     // (since the third segment hasn't been closed out by the appearance of a
    959     // new segment yet)
    960     ASSERT_EQ(2u, history.size());
    961 
    962     // The first segment (which will be history[1], since the newest segment
    963     // should be at the front of the vector) should be a two-buffer segment,
    964     // which implies that the occupancy average should be between 0 and 1, and
    965     // usedThirdBuffer should be false
    966     const auto& firstSegment = history[1];
    967     ASSERT_EQ(5u, firstSegment.numFrames);
    968     ASSERT_LT(0, firstSegment.occupancyAverage);
    969     ASSERT_GT(1, firstSegment.occupancyAverage);
    970     ASSERT_EQ(false, firstSegment.usedThirdBuffer);
    971 
    972     // The second segment should be a double-buffered segment, which implies that
    973     // the occupancy average should be between 0 and 1, but usedThirdBuffer
    974     // should be true
    975     const auto& secondSegment = history[0];
    976     ASSERT_EQ(7u, secondSegment.numFrames);
    977     ASSERT_LT(0, secondSegment.occupancyAverage);
    978     ASSERT_GT(1, secondSegment.occupancyAverage);
    979     ASSERT_EQ(true, secondSegment.usedThirdBuffer);
    980 
    981     // If we read the segments again without flushing, we shouldn't get any new
    982     // segments
    983     ASSERT_EQ(OK, mConsumer->getOccupancyHistory(false, &history));
    984     ASSERT_EQ(0u, history.size());
    985 
    986     // Read the segments again, this time forcing a flush so we get the third
    987     // segment
    988     ASSERT_EQ(OK, mConsumer->getOccupancyHistory(true, &history));
    989     ASSERT_EQ(1u, history.size());
    990 
    991     // This segment should be a triple-buffered segment, which implies that the
    992     // occupancy average should be between 1 and 2, and usedThirdBuffer should
    993     // be true
    994     const auto& thirdSegment = history[0];
    995     ASSERT_EQ(6u, thirdSegment.numFrames);
    996     ASSERT_LT(1, thirdSegment.occupancyAverage);
    997     ASSERT_GT(2, thirdSegment.occupancyAverage);
    998     ASSERT_EQ(true, thirdSegment.usedThirdBuffer);
    999 }
   1000 
   1001 TEST_F(BufferQueueTest, TestDiscardFreeBuffers) {
   1002     createBufferQueue();
   1003     sp<DummyConsumer> dc(new DummyConsumer);
   1004     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, false));
   1005     IGraphicBufferProducer::QueueBufferOutput output;
   1006     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
   1007             NATIVE_WINDOW_API_CPU, false, &output));
   1008 
   1009     int slot = BufferQueue::INVALID_BUFFER_SLOT;
   1010     sp<Fence> fence = Fence::NO_FENCE;
   1011     sp<GraphicBuffer> buffer = nullptr;
   1012     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
   1013         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
   1014         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
   1015     BufferItem item{};
   1016 
   1017     // Preallocate, dequeue, request, and cancel 4 buffers so we don't get
   1018     // BUFFER_NEEDS_REALLOCATION below
   1019     int slots[4] = {};
   1020     mProducer->setMaxDequeuedBufferCount(4);
   1021     for (size_t i = 0; i < 4; ++i) {
   1022         status_t result =
   1023                 mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr);
   1024         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
   1025         ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
   1026     }
   1027     for (size_t i = 0; i < 4; ++i) {
   1028         ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
   1029     }
   1030 
   1031     // Get buffers in all states: dequeued, filled, acquired, free
   1032 
   1033     // Fill 3 buffers
   1034     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
   1035     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
   1036     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
   1037     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
   1038     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
   1039     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
   1040     // Dequeue 1 buffer
   1041     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
   1042 
   1043     // Acquire and free 1 buffer
   1044     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
   1045     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
   1046                     EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
   1047     // Acquire 1 buffer, leaving 1 filled buffer in queue
   1048     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
   1049 
   1050     // Now discard the free buffers
   1051     ASSERT_EQ(OK, mConsumer->discardFreeBuffers());
   1052 
   1053     // Check no free buffers in dump
   1054     String8 dumpString;
   1055     mConsumer->dumpState(String8{}, &dumpString);
   1056 
   1057     // Parse the dump to ensure that all buffer slots that are FREE also
   1058     // have a null GraphicBuffer
   1059     // Fragile - assumes the following format for the dump for a buffer entry:
   1060     // ":%p\][^:]*state=FREE" where %p is the buffer pointer in hex.
   1061     ssize_t idx = dumpString.find("state=FREE");
   1062     while (idx != -1) {
   1063         ssize_t bufferPtrIdx = idx - 1;
   1064         while (bufferPtrIdx > 0) {
   1065             if (dumpString[bufferPtrIdx] == ':') {
   1066                 bufferPtrIdx++;
   1067                 break;
   1068             }
   1069             bufferPtrIdx--;
   1070         }
   1071         ASSERT_GT(bufferPtrIdx, 0) << "Can't parse queue dump to validate";
   1072         ssize_t nullPtrIdx = dumpString.find("0x0]", bufferPtrIdx);
   1073         ASSERT_EQ(bufferPtrIdx, nullPtrIdx) << "Free buffer not discarded";
   1074         idx = dumpString.find("FREE", idx + 1);
   1075     }
   1076 }
   1077 
   1078 TEST_F(BufferQueueTest, TestBufferReplacedInQueueBuffer) {
   1079     createBufferQueue();
   1080     sp<DummyConsumer> dc(new DummyConsumer);
   1081     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
   1082     IGraphicBufferProducer::QueueBufferOutput output;
   1083     ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
   1084             NATIVE_WINDOW_API_CPU, true, &output));
   1085     ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
   1086 
   1087     int slot = BufferQueue::INVALID_BUFFER_SLOT;
   1088     sp<Fence> fence = Fence::NO_FENCE;
   1089     sp<GraphicBuffer> buffer = nullptr;
   1090     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
   1091         HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
   1092         NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
   1093     BufferItem item{};
   1094 
   1095     // Preallocate, dequeue, request, and cancel 2 buffers so we don't get
   1096     // BUFFER_NEEDS_REALLOCATION below
   1097     int slots[2] = {};
   1098     ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
   1099     for (size_t i = 0; i < 2; ++i) {
   1100         status_t result =
   1101                 mProducer->dequeueBuffer(&slots[i], &fence, 0, 0, 0, 0, nullptr, nullptr);
   1102         ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
   1103         ASSERT_EQ(OK, mProducer->requestBuffer(slots[i], &buffer));
   1104     }
   1105     for (size_t i = 0; i < 2; ++i) {
   1106         ASSERT_EQ(OK, mProducer->cancelBuffer(slots[i], Fence::NO_FENCE));
   1107     }
   1108 
   1109     // Fill 2 buffers without consumer consuming them. Verify that all
   1110     // queued buffer returns proper bufferReplaced flag
   1111     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
   1112     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
   1113     ASSERT_EQ(false, output.bufferReplaced);
   1114     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
   1115     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
   1116     ASSERT_EQ(true, output.bufferReplaced);
   1117 }
   1118 
   1119 TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) {
   1120     createBufferQueue();
   1121     sp<DummyConsumer> dc(new DummyConsumer);
   1122     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
   1123     IGraphicBufferProducer::QueueBufferOutput output;
   1124     sp<IProducerListener> dummyListener(new DummyProducerListener);
   1125     ASSERT_EQ(OK, mProducer->connect(dummyListener, NATIVE_WINDOW_API_CPU,
   1126             true, &output));
   1127 
   1128     int slot = BufferQueue::INVALID_BUFFER_SLOT;
   1129     sp<Fence> fence = Fence::NO_FENCE;
   1130     sp<GraphicBuffer> buffer = nullptr;
   1131     IGraphicBufferProducer::QueueBufferInput input(0ull, true,
   1132             HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
   1133             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
   1134 
   1135     // Dequeue, request, and queue one buffer
   1136     status_t result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr);
   1137     ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
   1138     ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
   1139     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
   1140 
   1141     // Acquire and release the buffer. Upon acquiring, the buffer handle should
   1142     // be non-null since this is the first time we've acquired this slot.
   1143     BufferItem item;
   1144     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
   1145     ASSERT_EQ(slot, item.mSlot);
   1146     ASSERT_NE(nullptr, item.mGraphicBuffer.get());
   1147     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
   1148             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
   1149 
   1150     // Dequeue and queue the buffer again
   1151     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
   1152     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
   1153 
   1154     // Acquire and release the buffer again. Upon acquiring, the buffer handle
   1155     // should be null since this is not the first time we've acquired this slot.
   1156     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
   1157     ASSERT_EQ(slot, item.mSlot);
   1158     ASSERT_EQ(nullptr, item.mGraphicBuffer.get());
   1159     ASSERT_EQ(OK, mConsumer->releaseBuffer(item.mSlot, item.mFrameNumber,
   1160             EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE));
   1161 
   1162     // Dequeue and queue the buffer again
   1163     ASSERT_EQ(OK, mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0, 0, nullptr, nullptr));
   1164     ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
   1165 
   1166     // Disconnect the producer end. This should clear all of the slots and mark
   1167     // the buffer in the queue as stale.
   1168     ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
   1169 
   1170     // Acquire the buffer again. Upon acquiring, the buffer handle should not be
   1171     // null since the queued buffer should have been marked as stale, which
   1172     // should trigger the BufferQueue to resend the buffer handle.
   1173     ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
   1174     ASSERT_EQ(slot, item.mSlot);
   1175     ASSERT_NE(nullptr, item.mGraphicBuffer.get());
   1176 }
   1177 
   1178 TEST_F(BufferQueueTest, TestProducerConnectDisconnect) {
   1179     createBufferQueue();
   1180     sp<DummyConsumer> dc(new DummyConsumer);
   1181     ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
   1182     IGraphicBufferProducer::QueueBufferOutput output;
   1183     sp<IProducerListener> dummyListener(new DummyProducerListener);
   1184     ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
   1185     ASSERT_EQ(OK, mProducer->connect(
   1186             dummyListener, NATIVE_WINDOW_API_CPU, true, &output));
   1187     ASSERT_EQ(BAD_VALUE, mProducer->connect(
   1188             dummyListener, NATIVE_WINDOW_API_MEDIA, true, &output));
   1189 
   1190     ASSERT_EQ(BAD_VALUE, mProducer->disconnect(NATIVE_WINDOW_API_MEDIA));
   1191     ASSERT_EQ(OK, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
   1192     ASSERT_EQ(NO_INIT, mProducer->disconnect(NATIVE_WINDOW_API_CPU));
   1193 }
   1194 
   1195 } // namespace android
   1196