Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7264a0eb authored by Tom Murphy's avatar Tom Murphy Committed by Android (Google) Code Review
Browse files

Merge "Add unittesting for the bufferQueueConsumer::acquireBuffer" into main

parents aa53a746 bfdd1132
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -51,11 +51,17 @@ namespace android {

class IConsumerListener;
class IProducerListener;
#ifdef ENABLE_BQC_TESTING
class MockBufferQueueCore;
#endif

class BufferQueueCore : public virtual RefBase {

    friend class BufferQueueProducer;
    friend class BufferQueueConsumer;
#ifdef ENABLE_BQC_TESTING
    friend class TestableBufferQueueCore;
#endif

public:
    // Used as a placeholder slot number when the value isn't pointing to an
+3 −0
Original line number Diff line number Diff line
@@ -51,12 +51,15 @@ cc_test {
        "-Werror",
        "-Wextra",
        "-Wthread-safety",
        // Allow access to buffer queue core private members
        "-DENABLE_BQC_TESTING",
    ],

    srcs: [
        "BLASTBufferQueue_test.cpp",
        "BufferItemConsumer_test.cpp",
        "BufferQueue_test.cpp",
        "BufferQueueConsumer_test.cpp",
        "BufferReleaseChannel_test.cpp",
        "Choreographer_test.cpp",
        "CompositorTiming_test.cpp",
+161 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ENABLE_BQC_TESTING
#define ENABLE_BQC_TESTING
#endif

#define LOG_TAG "BufferQueueConsumer_test"

#include <gui/BufferItem.h>
#include <gui/BufferQueueConsumer.h>
#include <gui/BufferQueueCore.h>
#include <gui/BufferQueueProducer.h>
#include <gui/IConsumerListener.h>
#include <ui/GraphicTypes.h>
#include <ui/Rect.h>
#include <utils/Timers.h>

#include <mutex>
#include <vector>

#include <gtest/gtest.h>

namespace android {

class TestableBufferQueueCore : public BufferQueueCore {
public:
    TestableBufferQueueCore() = default;
    ~TestableBufferQueueCore() override = default;

    void ConfigureQueueStateViaFriend(const std::vector<android::BufferItem>& initialQueue) {
        this->mQueue.clear();
        for (const auto& item : initialQueue) {
            this->mQueue.push_back(item);
        }
    }

    size_t getQueueSizeForTest() { return this->mQueue.size(); }

    android::BufferItem getQueueFrontForTest() {
        return this->mQueue.empty() ? android::BufferItem() : this->mQueue.itemAt(0);
    }
};

class BufferQueueConsumerVkTimingTest : public ::testing::Test {
protected:
    sp<TestableBufferQueueCore> mTestableCore;
    sp<BufferQueueConsumer> mConsumer;

    virtual void SetUp() override {
        mTestableCore = sp<TestableBufferQueueCore>::make();
        mConsumer = sp<BufferQueueConsumer>::make(mTestableCore);
    }

    virtual void TearDown() override {
        mConsumer.clear();
        mTestableCore.clear();
    }

    android::BufferItem CreateBufferItem(int slot, uint64_t frameNum, nsecs_t timestamp,
                                         bool isReady = true, bool isAutoTimestamp = true,
                                         bool isStale = false, bool isDroppable = true) {
        android::BufferItem item;
        item.mSlot = slot;
        item.mFrameNumber = frameNum;
        item.mTimestamp = timestamp;
        item.mGraphicBuffer = nullptr;
        item.mFence = isReady ? Fence::NO_FENCE : new Fence();
        item.mIsStale = isStale;
        item.mIsDroppable = isDroppable;
        item.mAcquireCalled = false;
        item.mIsAutoTimestamp = isAutoTimestamp;
        item.mCrop = Rect::INVALID_RECT;
        item.mTransform = 0;
        //            item.mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
        item.mDataSpace = HAL_DATASPACE_UNKNOWN;
        item.mSurfaceDamage = Region::INVALID_REGION;
        item.mQueuedBuffer = true;
        item.mAutoRefresh = false;
        item.mApi = 0;
        item.mTransformToDisplayInverse = false;
        return item;
    }

    void runBufferTest(nsecs_t expectedPresentTime, int expectedAcquiredSlotNum,
                       size_t expectedAcquiredFrameNum, size_t expectedNumberOfDroppedBuffers,
                       uint64_t maxFrameNumber = 99) {
        std::vector<BufferItem> queue = {CreateBufferItem(0, 0, 10000, true /*isReady*/,
                                                          false /*isAutoGeneratedTimestamp*/),
                                         CreateBufferItem(1, 1, 20000, true, false),
                                         CreateBufferItem(2, 2, 30000, true, true),
                                         CreateBufferItem(3, 3, 40000, true, true),
                                         CreateBufferItem(4, 4, 50000, true, false),
                                         CreateBufferItem(5, 5, 60000, true, false),
                                         CreateBufferItem(6, 6, 70000, true, true),
                                         CreateBufferItem(7, 7, 80000, false, true),
                                         CreateBufferItem(8, 8, 90000, false, true)};
        mTestableCore->ConfigureQueueStateViaFriend(queue);

        BufferItem acquiredBuffer;
        status_t result =
                mConsumer->acquireBuffer(&acquiredBuffer, expectedPresentTime, maxFrameNumber);

        EXPECT_EQ(result, android::OK);
        EXPECT_EQ(acquiredBuffer.mSlot, expectedAcquiredSlotNum);
        EXPECT_EQ(acquiredBuffer.mFrameNumber, expectedAcquiredFrameNum);

        EXPECT_EQ(mTestableCore->getQueueSizeForTest(), (size_t)9 - expectedNumberOfDroppedBuffers);
        if (mTestableCore->getQueueSizeForTest() > 0) {
            android::BufferItem frontItem = mTestableCore->getQueueFrontForTest();
            EXPECT_EQ(frontItem.mSlot, expectedAcquiredSlotNum + 1);
        }
    }
};

TEST_F(BufferQueueConsumerVkTimingTest, FifoLatestReadyTestZeroExpectPresent) {
    // Verify that we dequeue and acquire only the first frame when expected present is 0
    nsecs_t expectedPresentTime = 0;
    int expectedAcquiredSlotNum = 0;
    size_t expectedAcquiredFrameNum = 0;
    size_t expectedNumberOfDroppedBuffers = 1;
    runBufferTest(expectedPresentTime, expectedAcquiredSlotNum, expectedAcquiredFrameNum,
                  expectedNumberOfDroppedBuffers);
}

TEST_F(BufferQueueConsumerVkTimingTest, FifoLatestReadyTestBasicTimestamp) {
    // Verify that we dequeue the first frame (with timestamp 1000) and acquire the second frame
    // based on  it's timestamp of 2000
    nsecs_t expectedPresentTime = 21000;
    int expectedAcquiredSlotNum = 1;
    size_t expectedAcquiredFrameNum = 1;
    size_t expectedNumberOfDroppedBuffers = 2;
    runBufferTest(expectedPresentTime, expectedAcquiredSlotNum, expectedAcquiredFrameNum,
                  expectedNumberOfDroppedBuffers);
}

TEST_F(BufferQueueConsumerVkTimingTest, FifoLatestReadyTestBasicLaterTimestamp) {
    // Verify that we dequeue up until the 3rd frame with timestamp of 3000. We don't dequeue the
    // next frame even though it's timestamp is in the past because
    nsecs_t expectedPresentTime = 41000;
    int expectedAcquiredSlotNum = 2;
    size_t expectedAcquiredFrameNum = 2;
    size_t expectedNumberOfDroppedBuffers = 3;
    runBufferTest(expectedPresentTime, expectedAcquiredSlotNum, expectedAcquiredFrameNum,
                  expectedNumberOfDroppedBuffers);
}

} // namespace android