Add dvr_buffer_queue C API
Bug: 36401767
Bug: 32213274
Bug: 36266201
Test: build and ran dvr_buffer_queue-test
Change-Id: Icd8d063bd8b7adb15bf67f7e543b87dad1c32a68
diff --git a/libs/vr/libdvr/tests/Android.mk b/libs/vr/libdvr/tests/Android.mk
new file mode 100644
index 0000000..158d58f
--- /dev/null
+++ b/libs/vr/libdvr/tests/Android.mk
@@ -0,0 +1,29 @@
+LOCAL_PATH := $(call my-dir)
+
+shared_libraries := \
+ libbase \
+ libbinder \
+ libcutils \
+ libgui \
+ liblog \
+ libhardware \
+ libui \
+ libutils \
+
+static_libraries := \
+ libdvr \
+ libbufferhubqueue \
+ libbufferhub \
+ libchrome \
+ libdvrcommon \
+ libpdx_default_transport \
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := dvr_buffer_queue-test.cpp
+LOCAL_STATIC_LIBRARIES := $(static_libraries)
+LOCAL_SHARED_LIBRARIES := $(shared_libraries)
+LOCAL_EXPORT_C_INCLUDE_DIRS := ${LOCAL_C_INCLUDES}
+LOCAL_CFLAGS := -DLOG_TAG=\"dvr_buffer_queue-test\" -DTRACE=0 -O0 -g
+LOCAL_MODULE := dvr_buffer_queue-test
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_NATIVE_TEST)
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
new file mode 100644
index 0000000..f344a24
--- /dev/null
+++ b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
@@ -0,0 +1,149 @@
+#include <dvr/dvr_buffer_queue.h>
+#include <private/dvr/buffer_hub_queue_client.h>
+
+#include <base/logging.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace dvr {
+
+namespace {
+
+static constexpr int kBufferWidth = 100;
+static constexpr int kBufferHeight = 1;
+static constexpr int kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
+static constexpr int kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY;
+static constexpr int kBufferSliceCount = 1; // number of slices in each buffer
+static constexpr size_t kQueueCapacity = 3;
+
+typedef uint64_t TestMeta;
+
+class DvrBufferQueueTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ write_queue_ = new DvrWriteBufferQueue;
+ write_queue_->producer_queue_ = ProducerQueue::Create<TestMeta>(0, 0, 0, 0);
+ ASSERT_NE(nullptr, write_queue_->producer_queue_);
+ }
+
+ void TearDown() override {
+ if (write_queue_ != nullptr) {
+ dvrWriteBufferQueueDestroy(write_queue_);
+ write_queue_ = nullptr;
+ }
+ }
+
+ void AllocateBuffers(size_t buffer_count) {
+ size_t out_slot;
+ for (size_t i = 0; i < buffer_count; i++) {
+ int ret = write_queue_->producer_queue_->AllocateBuffer(
+ kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage,
+ kBufferSliceCount, &out_slot);
+ ASSERT_EQ(0, ret);
+ }
+ }
+
+ DvrWriteBufferQueue* write_queue_{nullptr};
+};
+
+TEST_F(DvrBufferQueueTest, TestWrite_QueueDestroy) {
+ dvrWriteBufferQueueDestroy(write_queue_);
+ write_queue_ = nullptr;
+}
+
+TEST_F(DvrBufferQueueTest, TestWrite_QueueGetCapacity) {
+ AllocateBuffers(kQueueCapacity);
+ size_t capacity = dvrWriteBufferQueueGetCapacity(write_queue_);
+
+ ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity);
+ ASSERT_EQ(kQueueCapacity, capacity);
+}
+
+TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromWriteQueue) {
+ DvrReadBufferQueue* read_queue = nullptr;
+ int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
+
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, read_queue);
+
+ dvrReadBufferQueueDestroy(read_queue);
+}
+
+TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromReadQueue) {
+ DvrReadBufferQueue* read_queue1 = nullptr;
+ DvrReadBufferQueue* read_queue2 = nullptr;
+ int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue1);
+
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, read_queue1);
+
+ ret = dvrReadBufferQueueCreateReadQueue(read_queue1, &read_queue2);
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, read_queue2);
+ ASSERT_NE(read_queue1, read_queue2);
+
+ dvrReadBufferQueueDestroy(read_queue1);
+ dvrReadBufferQueueDestroy(read_queue2);
+}
+
+TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) {
+ static constexpr int kTimeout = 0;
+ DvrReadBufferQueue* read_queue = nullptr;
+ DvrReadBuffer* rb = nullptr;
+ DvrWriteBuffer* wb = nullptr;
+ int fence_fd = -1;
+
+ int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
+
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, read_queue);
+
+ AllocateBuffers(kQueueCapacity);
+
+ // Gain buffer for writing.
+ ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, &wb, &fence_fd);
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, wb);
+ ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d",
+ wb, fence_fd);
+ pdx::LocalHandle release_fence(fence_fd);
+
+ // Post buffer to the read_queue.
+ TestMeta seq = 42U;
+ ret = dvrWriteBufferPost(wb, /* fence */ -1, &seq, sizeof(seq));
+ ASSERT_EQ(0, ret);
+ dvrWriteBufferDestroy(wb);
+ wb = nullptr;
+
+ // Acquire buffer for reading.
+ TestMeta acquired_seq = 0U;
+ ret = dvrReadBufferQueueDequeue(read_queue, kTimeout, &rb, &fence_fd,
+ &acquired_seq, sizeof(acquired_seq));
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, rb);
+ ASSERT_EQ(seq, acquired_seq);
+ ALOGD_IF(TRACE,
+ "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb,
+ fence_fd);
+ pdx::LocalHandle acquire_fence(fence_fd);
+
+ // Release buffer to the write_queue.
+ ret = dvrReadBufferRelease(rb, -1);
+ ASSERT_EQ(0, ret);
+ dvrReadBufferDestroy(rb);
+ rb = nullptr;
+
+ // TODO(b/34387835) Currently buffer allocation has to happen after all queues
+ // are initialized.
+ size_t capacity = dvrReadBufferQueueGetCapacity(read_queue);
+
+ ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, capacity=%zu", capacity);
+ ASSERT_EQ(kQueueCapacity, capacity);
+
+ dvrReadBufferQueueDestroy(read_queue);
+}
+
+} // namespace
+
+} // namespace dvr
+} // namespace android