Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2017 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 "BufferItemConsumer_test"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include <gtest/gtest.h>
     21 #include <gui/BufferItemConsumer.h>
     22 #include <gui/IProducerListener.h>
     23 #include <gui/Surface.h>
     24 
     25 namespace android {
     26 
     27 static constexpr int kWidth = 100;
     28 static constexpr int kHeight = 100;
     29 static constexpr int kMaxLockedBuffers = 3;
     30 static constexpr int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
     31 static constexpr int kFrameSleepUs = 30 * 1000;
     32 
     33 class BufferItemConsumerTest : public ::testing::Test {
     34    protected:
     35     struct BufferFreedListener
     36         : public BufferItemConsumer::BufferFreedListener {
     37         explicit BufferFreedListener(BufferItemConsumerTest* test)
     38             : mTest(test) {}
     39         void onBufferFreed(const wp<GraphicBuffer>& /* gBuffer */) override {
     40             mTest->HandleBufferFreed();
     41         }
     42         BufferItemConsumerTest* mTest;
     43     };
     44 
     45     void SetUp() override {
     46         BufferQueue::createBufferQueue(&mProducer, &mConsumer);
     47         mBIC =
     48             new BufferItemConsumer(mConsumer, kFormat, kMaxLockedBuffers, true);
     49         String8 name("BufferItemConsumer_Under_Test");
     50         mBIC->setName(name);
     51         mBFL = new BufferFreedListener(this);
     52         mBIC->setBufferFreedListener(mBFL);
     53 
     54         sp<IProducerListener> producerListener = new DummyProducerListener();
     55         IGraphicBufferProducer::QueueBufferOutput bufferOutput;
     56         ASSERT_EQ(NO_ERROR,
     57                   mProducer->connect(producerListener, NATIVE_WINDOW_API_CPU,
     58                                      true, &bufferOutput));
     59         ASSERT_EQ(NO_ERROR,
     60                   mProducer->setMaxDequeuedBufferCount(kMaxLockedBuffers));
     61     }
     62 
     63     int GetFreedBufferCount() {
     64         std::lock_guard<std::mutex> lock(mMutex);
     65         return mFreedBufferCount;
     66     }
     67 
     68     void HandleBufferFreed() {
     69         std::lock_guard<std::mutex> lock(mMutex);
     70         mFreedBufferCount++;
     71         ALOGV("HandleBufferFreed, mFreedBufferCount=%d", mFreedBufferCount);
     72     }
     73 
     74     void DequeueBuffer(int* outSlot) {
     75         ASSERT_NE(outSlot, nullptr);
     76 
     77         int slot;
     78         sp<Fence> outFence;
     79         status_t ret = mProducer->dequeueBuffer(&slot, &outFence, kWidth, kHeight, 0, 0,
     80                                                 nullptr, nullptr);
     81         ASSERT_GE(ret, 0);
     82 
     83         ALOGV("dequeueBuffer: slot=%d", slot);
     84         if (ret & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
     85             ret = mProducer->requestBuffer(slot, &mBuffers[slot]);
     86             ASSERT_EQ(NO_ERROR, ret);
     87         }
     88         *outSlot = slot;
     89     }
     90 
     91     void QueueBuffer(int slot) {
     92         ALOGV("enqueueBuffer: slot=%d", slot);
     93         IGraphicBufferProducer::QueueBufferInput bufferInput(
     94             0ULL, true, HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
     95             NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
     96         IGraphicBufferProducer::QueueBufferOutput bufferOutput;
     97         status_t ret = mProducer->queueBuffer(slot, bufferInput, &bufferOutput);
     98         ASSERT_EQ(NO_ERROR, ret);
     99     }
    100 
    101     void AcquireBuffer(int* outSlot) {
    102         ASSERT_NE(outSlot, nullptr);
    103         BufferItem buffer;
    104         status_t ret = mBIC->acquireBuffer(&buffer, 0, false);
    105         ASSERT_EQ(NO_ERROR, ret);
    106 
    107         ALOGV("acquireBuffer: slot=%d", buffer.mSlot);
    108         *outSlot = buffer.mSlot;
    109     }
    110 
    111     void ReleaseBuffer(int slot) {
    112         ALOGV("releaseBuffer: slot=%d", slot);
    113         BufferItem buffer;
    114         buffer.mSlot = slot;
    115         buffer.mGraphicBuffer = mBuffers[slot];
    116         status_t ret = mBIC->releaseBuffer(buffer, Fence::NO_FENCE);
    117         ASSERT_EQ(NO_ERROR, ret);
    118     }
    119 
    120 
    121     std::mutex mMutex;
    122     int mFreedBufferCount{0};
    123 
    124     sp<BufferItemConsumer> mBIC;
    125     sp<BufferFreedListener> mBFL;
    126     sp<IGraphicBufferProducer> mProducer;
    127     sp<IGraphicBufferConsumer> mConsumer;
    128     sp<GraphicBuffer> mBuffers[BufferQueueDefs::NUM_BUFFER_SLOTS];
    129 };
    130 
    131 // Test that detaching buffer from consumer side triggers onBufferFreed.
    132 TEST_F(BufferItemConsumerTest, TriggerBufferFreed_DetachBufferFromConsumer) {
    133     int slot;
    134     // Producer: generate a dummy buffer.
    135     DequeueBuffer(&slot);
    136     QueueBuffer(slot);
    137 
    138     ASSERT_EQ(0, GetFreedBufferCount());
    139     // Consumer: acquire the buffer and then detach it.
    140     AcquireBuffer(&slot);
    141     status_t ret = mBIC->detachBuffer(slot);
    142     ASSERT_EQ(NO_ERROR, ret);
    143 
    144     // Sleep to give some time for callbacks to happen.
    145     usleep(kFrameSleepUs);
    146     ASSERT_EQ(1, GetFreedBufferCount());
    147 }
    148 
    149 // Test that detaching buffer from producer side triggers onBufferFreed.
    150 TEST_F(BufferItemConsumerTest, TriggerBufferFreed_DetachBufferFromProducer) {
    151     int slot;
    152     // Let buffer go through the cycle at least once.
    153     DequeueBuffer(&slot);
    154     QueueBuffer(slot);
    155     AcquireBuffer(&slot);
    156     ReleaseBuffer(slot);
    157 
    158     ASSERT_EQ(0, GetFreedBufferCount());
    159 
    160     // Producer: generate the buffer again.
    161     DequeueBuffer(&slot);
    162 
    163     // Producer: detach the buffer.
    164     status_t ret = mProducer->detachBuffer(slot);
    165     ASSERT_EQ(NO_ERROR, ret);
    166 
    167     // Sleep to give some time for callbacks to happen.
    168     usleep(kFrameSleepUs);
    169     ASSERT_EQ(1, GetFreedBufferCount());
    170 }
    171 
    172 // Test that abandoning BufferItemConsumer triggers onBufferFreed.
    173 TEST_F(BufferItemConsumerTest, TriggerBufferFreed_AbandonBufferItemConsumer) {
    174     int slot;
    175     // Let buffer go through the cycle at least once.
    176     DequeueBuffer(&slot);
    177     QueueBuffer(slot);
    178     AcquireBuffer(&slot);
    179     ReleaseBuffer(slot);
    180 
    181     // Abandon the BufferItemConsumer.
    182     mBIC->abandon();
    183 
    184     // Sleep to give some time for callbacks to happen.
    185     usleep(kFrameSleepUs);
    186     ASSERT_EQ(1, GetFreedBufferCount());
    187 }
    188 
    189 // Test that delete BufferItemConsumer triggers onBufferFreed.
    190 TEST_F(BufferItemConsumerTest, TriggerBufferFreed_DeleteBufferItemConsumer) {
    191     int slot;
    192     // Let buffer go through the cycle at least once.
    193     DequeueBuffer(&slot);
    194     QueueBuffer(slot);
    195     AcquireBuffer(&slot);
    196     ReleaseBuffer(slot);
    197 
    198     // Delete the BufferItemConsumer.
    199     mBIC.clear();
    200 
    201     // Sleep to give some time for callbacks to happen.
    202     usleep(kFrameSleepUs);
    203     ASSERT_EQ(1, GetFreedBufferCount());
    204 }
    205 
    206 }  // namespace android
    207