diff options
| -rw-r--r-- | libs/vr/libdvr/dvr_buffer_queue.cpp | 32 | ||||
| -rw-r--r-- | libs/vr/libdvr/include/dvr/dvr_api.h | 6 | ||||
| -rw-r--r-- | libs/vr/libdvr/include/dvr/dvr_api_entries.h | 3 | ||||
| -rw-r--r-- | libs/vr/libdvr/include/dvr/dvr_buffer_queue.h | 30 | ||||
| -rw-r--r-- | libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp | 169 |
5 files changed, 163 insertions, 77 deletions
diff --git a/libs/vr/libdvr/dvr_buffer_queue.cpp b/libs/vr/libdvr/dvr_buffer_queue.cpp index 018abbb2a7..e4e20f9700 100644 --- a/libs/vr/libdvr/dvr_buffer_queue.cpp +++ b/libs/vr/libdvr/dvr_buffer_queue.cpp @@ -14,6 +14,8 @@ using android::dvr::BufferHubQueueProducer; using android::dvr::BufferProducer; using android::dvr::ConsumerQueue; using android::dvr::ProducerQueue; +using android::dvr::ProducerQueueConfigBuilder; +using android::dvr::UsagePolicy; extern "C" { @@ -156,6 +158,36 @@ int DvrWriteBufferQueue::ResizeBuffer(uint32_t width, uint32_t height) { return 0; } +int dvrWriteBufferQueueCreate(uint32_t width, uint32_t height, uint32_t format, + uint32_t layer_count, uint64_t usage, + size_t capacity, size_t metadata_size, + DvrWriteBufferQueue** out_write_queue) { + if (!out_write_queue) + return -EINVAL; + + auto config_builder = ProducerQueueConfigBuilder() + .SetDefaultWidth(width) + .SetDefaultHeight(height) + .SetDefaultFormat(format) + .SetMetadataSize(metadata_size); + std::unique_ptr<ProducerQueue> producer_queue = + ProducerQueue::Create(config_builder.Build(), UsagePolicy{}); + if (!producer_queue) { + ALOGE("dvrWriteBufferQueueCreate: Failed to create producer queue."); + return -ENOMEM; + } + + auto status = producer_queue->AllocateBuffers(width, height, layer_count, + format, usage, capacity); + if (!status.ok()) { + ALOGE("dvrWriteBufferQueueCreate: Failed to allocate buffers."); + return -ENOMEM; + } + + *out_write_queue = new DvrWriteBufferQueue(std::move(producer_queue)); + return 0; +} + void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue) { delete write_queue; } diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h index d0dbd8d390..451d037352 100644 --- a/libs/vr/libdvr/include/dvr/dvr_api.h +++ b/libs/vr/libdvr/include/dvr/dvr_api.h @@ -159,6 +159,12 @@ typedef const struct native_handle* (*DvrBufferGetNativeHandlePtr)( DvrBuffer* buffer); // dvr_buffer_queue.h +typedef int (*DvrWriteBufferQueueCreatePtr)(uint32_t width, uint32_t height, + uint32_t format, + uint32_t layer_count, + uint64_t usage, size_t capacity, + size_t metadata_size, + DvrWriteBufferQueue** queue_out); typedef void (*DvrWriteBufferQueueDestroyPtr)(DvrWriteBufferQueue* write_queue); typedef ssize_t (*DvrWriteBufferQueueGetCapacityPtr)( DvrWriteBufferQueue* write_queue); diff --git a/libs/vr/libdvr/include/dvr/dvr_api_entries.h b/libs/vr/libdvr/include/dvr/dvr_api_entries.h index 72e0f674f4..da12c13065 100644 --- a/libs/vr/libdvr/include/dvr/dvr_api_entries.h +++ b/libs/vr/libdvr/include/dvr/dvr_api_entries.h @@ -160,3 +160,6 @@ DVR_V1_API_ENTRY(PoseClientSensorsEnable); // Read buffer queue DVR_V1_API_ENTRY(ReadBufferQueueGetEventFd); + +// Create write buffer queue locally +DVR_V1_API_ENTRY(WriteBufferQueueCreate); diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h index e2127f8e31..b3b41e2373 100644 --- a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h +++ b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h @@ -12,6 +12,36 @@ typedef struct ANativeWindow ANativeWindow; typedef struct DvrWriteBufferQueue DvrWriteBufferQueue; typedef struct DvrReadBufferQueue DvrReadBufferQueue; +// Creates a write buffer queue to be used locally. +// +// Note that this API is mostly for testing purpose. For now there is no +// mechanism to send a DvrWriteBufferQueue cross process. Use +// dvrSurfaceCreateWriteBufferQueue if cross-process buffer transport is +// intended. +// +// @param width The width of the buffers that this queue will produce. +// @param height The height of buffers that this queue will produce. +// @param format The format of the buffers that this queue will produce. This +// must be one of the AHARDWAREBUFFER_FORMAT_XXX enums. +// @param layer_count The number of layers of the buffers that this queue will +// produce. +// @param usage The usage of the buffers that this queue will produce. This +// must a combination of the AHARDWAREBUFFER_USAGE_XXX flags. +// @param capacity The number of buffer that this queue will allocate. Note that +// all buffers will be allocated on create. Currently, the number of buffers +// is the queue cannot be changed after creation though DVR API. However, +// ANativeWindow can choose to reallocate, attach, or detach buffers from +// a DvrWriteBufferQueue through Android platform logic. +// @param metadata_size The size of metadata in bytes. +// @param out_write_queue The pointer of a DvrWriteBufferQueue will be filled +// here if the method call succeeds. The metadata size must match +// the metadata size in dvrWriteBufferPost/dvrReadBufferAcquire. +// @return Zero on success, or negative error code. +int dvrWriteBufferQueueCreate(uint32_t width, uint32_t height, uint32_t format, + uint32_t layer_count, uint64_t usage, + size_t capacity, size_t metadata_size, + DvrWriteBufferQueue** out_write_queue); + // Destroy a write buffer queue. // // @param write_queue The DvrWriteBufferQueue of interest. diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp index f75283d6e0..7520eee70e 100644 --- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp +++ b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp @@ -1,24 +1,30 @@ +#include <android/log.h> +#include <android/native_window.h> +#include <android-base/unique_fd.h> #include <dvr/dvr_api.h> #include <dvr/dvr_buffer_queue.h> -#include <gui/Surface.h> -#include <private/dvr/buffer_hub_queue_client.h> -#include <base/logging.h> #include <gtest/gtest.h> -#include "../dvr_internal.h" -#include "../dvr_buffer_queue_internal.h" +#include <array> +#include <unordered_map> -namespace android { -namespace dvr { +#ifndef ALOGD +#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) +#endif + +#ifndef ALOGD_IF +#define ALOGD_IF(cond, ...) \ + ((__predict_false(cond)) ? ((void)ALOGD(__VA_ARGS__)) : (void)0) +#endif namespace { static constexpr uint32_t kBufferWidth = 100; static constexpr uint32_t kBufferHeight = 1; static constexpr uint32_t kLayerCount = 1; -static constexpr uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB; -static constexpr uint64_t kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY; +static constexpr uint32_t kBufferFormat = AHARDWAREBUFFER_FORMAT_BLOB; +static constexpr uint64_t kBufferUsage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN; static constexpr size_t kQueueCapacity = 3; typedef uint64_t TestMeta; @@ -36,14 +42,6 @@ class DvrBufferQueueTest : public ::testing::Test { } protected: - void SetUp() override { - config_builder_ = ProducerQueueConfigBuilder() - .SetDefaultWidth(kBufferWidth) - .SetDefaultHeight(kBufferHeight) - .SetDefaultFormat(kBufferFormat) - .SetMetadata<TestMeta>(); - } - void TearDown() override { if (write_queue_ != nullptr) { dvrWriteBufferQueueDestroy(write_queue_); @@ -51,19 +49,6 @@ class DvrBufferQueueTest : public ::testing::Test { } } - void CreateWriteBufferQueue() { - write_queue_ = new DvrWriteBufferQueue( - ProducerQueue::Create(config_builder_.Build(), UsagePolicy{})); - ASSERT_NE(nullptr, write_queue_); - } - - void AllocateBuffers(size_t buffer_count) { - auto status = write_queue_->producer_queue()->AllocateBuffers( - kBufferWidth, kBufferHeight, kLayerCount, kBufferFormat, kBufferUsage, - buffer_count); - ASSERT_TRUE(status.ok()); - } - void HandleBufferAvailable() { buffer_available_count_ += 1; ALOGD_IF(TRACE, "Buffer avaiable, count=%d", buffer_available_count_); @@ -75,22 +60,26 @@ class DvrBufferQueueTest : public ::testing::Test { buffer_removed_count_); } - ProducerQueueConfigBuilder config_builder_; DvrWriteBufferQueue* write_queue_{nullptr}; int buffer_available_count_{0}; int buffer_removed_count_{0}; }; TEST_F(DvrBufferQueueTest, TestWrite_QueueCreateDestroy) { - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + /*capacity=*/0, sizeof(TestMeta), &write_queue_); + ASSERT_EQ(0, ret); dvrWriteBufferQueueDestroy(write_queue_); write_queue_ = nullptr; } TEST_F(DvrBufferQueueTest, TestWrite_QueueGetCapacity) { - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); - ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity)); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + kQueueCapacity, sizeof(TestMeta), &write_queue_); + ASSERT_EQ(0, ret); size_t capacity = dvrWriteBufferQueueGetCapacity(write_queue_); @@ -99,10 +88,13 @@ TEST_F(DvrBufferQueueTest, TestWrite_QueueGetCapacity) { } TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromWriteQueue) { - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + /*capacity=*/0, sizeof(TestMeta), &write_queue_); + ASSERT_EQ(0, ret); DvrReadBufferQueue* read_queue = nullptr; - int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue); + ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue); ASSERT_EQ(0, ret); ASSERT_NE(nullptr, read_queue); @@ -111,11 +103,14 @@ TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromWriteQueue) { } TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromReadQueue) { - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + /*capacity=*/0, sizeof(TestMeta), &write_queue_); + ASSERT_EQ(0, ret); DvrReadBufferQueue* read_queue1 = nullptr; DvrReadBufferQueue* read_queue2 = nullptr; - int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue1); + ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue1); ASSERT_EQ(0, ret); ASSERT_NE(nullptr, read_queue1); @@ -130,8 +125,10 @@ TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromReadQueue) { } TEST_F(DvrBufferQueueTest, CreateEmptyBuffer) { - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); - ASSERT_NO_FATAL_FAILURE(AllocateBuffers(3)); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + kQueueCapacity, sizeof(TestMeta), &write_queue_); + ASSERT_EQ(0, ret); DvrReadBuffer* read_buffer = nullptr; DvrWriteBuffer* write_buffer = nullptr; @@ -164,8 +161,10 @@ TEST_F(DvrBufferQueueTest, CreateEmptyBuffer) { } TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) { - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); - ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity)); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + kQueueCapacity, sizeof(TestMeta), &write_queue_); + ASSERT_EQ(0, ret); static constexpr int kTimeout = 0; DvrReadBufferQueue* read_queue = nullptr; @@ -173,7 +172,7 @@ TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) { DvrWriteBuffer* wb = nullptr; int fence_fd = -1; - int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue); + ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue); ASSERT_EQ(0, ret); ASSERT_NE(nullptr, read_queue); @@ -193,7 +192,7 @@ TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) { ASSERT_TRUE(dvrWriteBufferIsValid(wb)); ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d", wb, fence_fd); - pdx::LocalHandle release_fence(fence_fd); + android::base::unique_fd release_fence(fence_fd); // Post buffer to the read_queue. TestMeta seq = 42U; @@ -215,7 +214,7 @@ TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) { ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb, fence_fd); - pdx::LocalHandle acquire_fence(fence_fd); + android::base::unique_fd acquire_fence(fence_fd); // Release buffer to the write_queue. ret = dvrReadBufferRelease(rb, -1); @@ -234,40 +233,52 @@ TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) { } TEST_F(DvrBufferQueueTest, TestGetExternalSurface) { - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + /*capacity=*/0, sizeof(TestMeta), &write_queue_); + ASSERT_EQ(0, ret); ANativeWindow* window = nullptr; // The |write_queue_| doesn't have proper metadata (must be // DvrNativeBufferMetadata) configured during creation. - int ret = dvrWriteBufferQueueGetExternalSurface(write_queue_, &window); + ret = dvrWriteBufferQueueGetExternalSurface(write_queue_, &window); ASSERT_EQ(-EINVAL, ret); ASSERT_EQ(nullptr, window); + dvrWriteBufferQueueDestroy(write_queue_); + write_queue_ = nullptr; // A write queue with DvrNativeBufferMetadata should work fine. - auto config = ProducerQueueConfigBuilder() - .SetMetadata<DvrNativeBufferMetadata>() - .Build(); - std::unique_ptr<DvrWriteBufferQueue, decltype(&dvrWriteBufferQueueDestroy)> - write_queue( - new DvrWriteBufferQueue(ProducerQueue::Create(config, UsagePolicy{})), - dvrWriteBufferQueueDestroy); - ASSERT_NE(nullptr, write_queue.get()); + ASSERT_EQ(nullptr, write_queue_); + + ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_); + ASSERT_EQ(0, ret); + ASSERT_NE(nullptr, write_queue_); - ret = dvrWriteBufferQueueGetExternalSurface(write_queue.get(), &window); + ret = dvrWriteBufferQueueGetExternalSurface(write_queue_, &window); ASSERT_EQ(0, ret); ASSERT_NE(nullptr, window); - sp<Surface> surface = static_cast<Surface*>(window); - ASSERT_TRUE(Surface::isValid(surface)); + // TODO(b/64723700): Remove dependencies of Android platform bits so that we + // can run dvr_buffer_queue-test in DTS. + uint32_t width = ANativeWindow_getWidth(window); + uint32_t height = ANativeWindow_getHeight(window); + uint32_t format = ANativeWindow_getFormat(window); + ASSERT_EQ(kBufferWidth, width); + ASSERT_EQ(kBufferHeight, height); + ASSERT_EQ(kBufferFormat, format); } // Create buffer queue of three buffers and dequeue three buffers out of it. // Before each dequeue operation, we resize the buffer queue and expect the // queue always return buffer with desired dimension. TEST_F(DvrBufferQueueTest, TestResizeBuffer) { - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); - ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity)); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + kQueueCapacity, sizeof(TestMeta), &write_queue_); + ASSERT_EQ(0, ret); static constexpr int kTimeout = 0; int fence_fd = -1; @@ -281,7 +292,7 @@ TEST_F(DvrBufferQueueTest, TestResizeBuffer) { AHardwareBuffer* ahb3 = nullptr; AHardwareBuffer_Desc buffer_desc; - int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue); + ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue); ASSERT_EQ(0, ret); ASSERT_NE(nullptr, read_queue); @@ -314,7 +325,7 @@ TEST_F(DvrBufferQueueTest, TestResizeBuffer) { ASSERT_EQ(0, ret); ASSERT_TRUE(dvrWriteBufferIsValid(wb1)); ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p", wb1); - pdx::LocalHandle release_fence1(fence_fd); + android::base::unique_fd release_fence1(fence_fd); // Check the buffer dimension. ret = dvrWriteBufferGetAHardwareBuffer(wb1, &ahb1); @@ -341,7 +352,7 @@ TEST_F(DvrBufferQueueTest, TestResizeBuffer) { ASSERT_TRUE(dvrWriteBufferIsValid(wb2)); ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb2, fence_fd); - pdx::LocalHandle release_fence2(fence_fd); + android::base::unique_fd release_fence2(fence_fd); // Check the buffer dimension, should be new width ret = dvrWriteBufferGetAHardwareBuffer(wb2, &ahb2); @@ -367,7 +378,7 @@ TEST_F(DvrBufferQueueTest, TestResizeBuffer) { ASSERT_TRUE(dvrWriteBufferIsValid(wb3)); ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb3, fence_fd); - pdx::LocalHandle release_fence3(fence_fd); + android::base::unique_fd release_fence3(fence_fd); // Check the buffer dimension, should be new width ret = dvrWriteBufferGetAHardwareBuffer(wb3, &ahb3); @@ -387,9 +398,10 @@ TEST_F(DvrBufferQueueTest, TestResizeBuffer) { TEST_F(DvrBufferQueueTest, DequeueEmptyMetadata) { // Overrides default queue parameters: Empty metadata. - config_builder_.SetMetadata<void>(); - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); - ASSERT_NO_FATAL_FAILURE(AllocateBuffers(1)); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + /*capacity=*/1, /*metadata_size=*/0, &write_queue_); + ASSERT_EQ(0, ret); DvrReadBuffer* rb = nullptr; DvrWriteBuffer* wb = nullptr; @@ -416,8 +428,10 @@ TEST_F(DvrBufferQueueTest, DequeueEmptyMetadata) { } TEST_F(DvrBufferQueueTest, DequeueMismatchMetadata) { - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); - ASSERT_NO_FATAL_FAILURE(AllocateBuffers(1)); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + /*capacity=*/1, sizeof(TestMeta), &write_queue_); + ASSERT_EQ(0, ret); DvrReadBuffer* rb = nullptr; DvrWriteBuffer* wb = nullptr; @@ -451,11 +465,13 @@ TEST_F(DvrBufferQueueTest, DequeueMismatchMetadata) { } TEST_F(DvrBufferQueueTest, TestReadQueueEventFd) { - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); - ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity)); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + kQueueCapacity, sizeof(TestMeta), &write_queue_); + ASSERT_EQ(0, ret); DvrReadBufferQueue* read_queue = nullptr; - int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue); + ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue); ASSERT_EQ(0, ret); ASSERT_NE(nullptr, read_queue); @@ -468,8 +484,10 @@ TEST_F(DvrBufferQueueTest, TestReadQueueEventFd) { // Dvr{Read,Write}Buffer(s) during their lifecycles. And for the same buffer_id, // the corresponding AHardwareBuffer handle stays the same. TEST_F(DvrBufferQueueTest, TestStableBufferIdAndHardwareBuffer) { - ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue()); - ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity)); + int ret = dvrWriteBufferQueueCreate( + kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, + kQueueCapacity, sizeof(TestMeta), &write_queue_); + ASSERT_EQ(0, ret); int fence_fd = -1; DvrReadBufferQueue* read_queue = nullptr; @@ -621,6 +639,3 @@ TEST_F(DvrBufferQueueTest, TestStableBufferIdAndHardwareBuffer) { } } // namespace - -} // namespace dvr -} // namespace android |