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