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