diff options
author | Jiwen 'Steve' Cai <jwcai@google.com> | 2017-09-14 04:15:08 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-09-14 04:15:08 +0000 |
commit | 64418b3b4502946d0154e7b10674c2816f2e2343 (patch) | |
tree | 56085f14295c0304255f76a482e18391ec081cb8 /libs/vr | |
parent | be4410cdeba05668d36fa5fd30706d3496b9fa7a (diff) | |
parent | fcc70bdc9e380ef1a652b229910c6e333cf575c5 (diff) | |
download | native-64418b3b4502946d0154e7b10674c2816f2e2343.tar.gz |
Merge "Overhual DvrBuffer and DvrBufferQueue API: Step 1" into oc-mr1-dev
am: fcc70bdc9e
Change-Id: Ica3fd8703c0db53dd84e20d3bd7a70489ba08afc
Diffstat (limited to 'libs/vr')
-rw-r--r-- | libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h | 7 | ||||
-rw-r--r-- | libs/vr/libdvr/dvr_buffer.cpp | 18 | ||||
-rw-r--r-- | libs/vr/libdvr/dvr_buffer_queue.cpp | 233 | ||||
-rw-r--r-- | libs/vr/libdvr/dvr_buffer_queue_internal.h | 24 | ||||
-rw-r--r-- | libs/vr/libdvr/dvr_internal.h | 10 | ||||
-rw-r--r-- | libs/vr/libdvr/include/dvr/dvr_api.h | 15 | ||||
-rw-r--r-- | libs/vr/libdvr/include/dvr/dvr_api_entries.h | 6 | ||||
-rw-r--r-- | libs/vr/libdvr/include/dvr/dvr_buffer_queue.h | 72 | ||||
-rw-r--r-- | libs/vr/libdvr/tests/Android.bp | 1 | ||||
-rw-r--r-- | libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp | 273 |
10 files changed, 434 insertions, 225 deletions
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h index 3e93788521..0699fefd38 100644 --- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h +++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h @@ -66,6 +66,11 @@ class BufferHubQueue : public pdx::Client { explicit operator bool() const { return epoll_fd_.IsValid(); } + int GetBufferId(size_t slot) const { + return (slot < buffers_.size() && buffers_[slot]) ? buffers_[slot]->id() + : -1; + } + std::shared_ptr<BufferHubBuffer> GetBuffer(size_t slot) const { return buffers_[slot]; } @@ -218,7 +223,7 @@ class BufferHubQueue : public pdx::Client { // Tracks the buffers belonging to this queue. Buffers are stored according to // "slot" in this vector. Each slot is a logical id of the buffer within this // queue regardless of its queue position or presence in the ring buffer. - std::vector<std::shared_ptr<BufferHubBuffer>> buffers_{kMaxQueueCapacity}; + std::array<std::shared_ptr<BufferHubBuffer>, kMaxQueueCapacity> buffers_; // Buffers and related data that are available for dequeue. RingBuffer<Entry> available_buffers_{kMaxQueueCapacity}; diff --git a/libs/vr/libdvr/dvr_buffer.cpp b/libs/vr/libdvr/dvr_buffer.cpp index 4d9b215361..1a9923444e 100644 --- a/libs/vr/libdvr/dvr_buffer.cpp +++ b/libs/vr/libdvr/dvr_buffer.cpp @@ -44,7 +44,13 @@ void dvrWriteBufferCreateEmpty(DvrWriteBuffer** write_buffer) { } void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer) { - delete write_buffer; + if (write_buffer != nullptr) { + ALOGW_IF( + write_buffer->slot != -1, + "dvrWriteBufferDestroy: Destroying a buffer associated with a valid " + "buffer queue slot. This may indicate possible leaks."); + delete write_buffer; + } } int dvrWriteBufferIsValid(DvrWriteBuffer* write_buffer) { @@ -107,7 +113,15 @@ void dvrReadBufferCreateEmpty(DvrReadBuffer** read_buffer) { *read_buffer = new DvrReadBuffer; } -void dvrReadBufferDestroy(DvrReadBuffer* read_buffer) { delete read_buffer; } +void dvrReadBufferDestroy(DvrReadBuffer* read_buffer) { + if (read_buffer != nullptr) { + ALOGW_IF( + read_buffer->slot != -1, + "dvrReadBufferDestroy: Destroying a buffer associated with a valid " + "buffer queue slot. This may indicate possible leaks."); + delete read_buffer; + } +} int dvrReadBufferIsValid(DvrReadBuffer* read_buffer) { return read_buffer && read_buffer->read_buffer; diff --git a/libs/vr/libdvr/dvr_buffer_queue.cpp b/libs/vr/libdvr/dvr_buffer_queue.cpp index 4adb5d2da1..035252d0b9 100644 --- a/libs/vr/libdvr/dvr_buffer_queue.cpp +++ b/libs/vr/libdvr/dvr_buffer_queue.cpp @@ -63,7 +63,7 @@ int DvrWriteBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) { } int DvrWriteBufferQueue::Dequeue(int timeout, DvrWriteBuffer* write_buffer, - int* out_fence_fd) { + int* out_fence_fd, size_t* out_slot) { size_t slot; pdx::LocalHandle fence; std::shared_ptr<BufferProducer> buffer_producer; @@ -141,6 +141,86 @@ int DvrWriteBufferQueue::Dequeue(int timeout, DvrWriteBuffer* write_buffer, write_buffer->write_buffer = std::move(buffer_producer); *out_fence_fd = fence.Release(); + if (out_slot) { + // TODO(b/65469368): Remove this null check once dvrWriteBufferQueueDequeue + // is deprecated. + *out_slot = slot; + } + return 0; +} + +int DvrWriteBufferQueue::GainBuffer(int timeout, + DvrWriteBuffer** out_write_buffer, + DvrNativeBufferMetadata* out_meta, + int* out_fence_fd) { + DvrWriteBuffer write_buffer; + int fence_fd; + size_t slot; + const int ret = Dequeue(timeout, &write_buffer, &fence_fd, &slot); + if (ret < 0) { + ALOGE_IF( + ret != -ETIMEDOUT, + "DvrWriteBufferQueue::GainBuffer: Failed to dequeue buffer, ret=%d", + ret); + return ret; + } + + if (write_buffers_[slot] == nullptr) { + // Lazy initialization of a write_buffers_ slot. Note that a slot will only + // be dynamically allocated once during the entire cycle life of a queue. + write_buffers_[slot] = std::make_unique<DvrWriteBuffer>(); + write_buffers_[slot]->slot = slot; + } + + LOG_ALWAYS_FATAL_IF( + write_buffers_[slot]->write_buffer, + "DvrWriteBufferQueue::GainBuffer: Buffer slot is not empty: %zu", slot); + write_buffers_[slot]->write_buffer = std::move(write_buffer.write_buffer); + + *out_write_buffer = write_buffers_[slot].release(); + *out_fence_fd = fence_fd; + + return 0; +} + +int DvrWriteBufferQueue::PostBuffer(DvrWriteBuffer* write_buffer, + const DvrNativeBufferMetadata* meta, + int ready_fence_fd) { + LOG_FATAL_IF( + (write_buffers->slot < 0 || write_buffers->slot >= write_buffers_.size()), + "DvrWriteBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot); + + // Some basic sanity checks before we put the buffer back into a slot. + size_t slot = static_cast<size_t>(write_buffer->slot); + if (write_buffers_[slot] != nullptr) { + ALOGE("DvrWriteBufferQueue::PostBuffer: Slot is not empty: %zu", slot); + return -EINVAL; + } + if (write_buffer->write_buffer == nullptr) { + ALOGE("DvrWriteBufferQueue::PostBuffer: Invalid write buffer."); + return -EINVAL; + } + if (write_buffer->write_buffer->id() != producer_queue_->GetBufferId(slot)) { + ALOGE( + "DvrWriteBufferQueue::PostBuffer: Buffer to be released does not " + "belong to this buffer queue."); + return -EINVAL; + } + + pdx::LocalHandle fence(ready_fence_fd); + // TODO(b/65455724): All BufferHub operations should be async. + const int ret = write_buffer->write_buffer->Post(fence, meta, sizeof(*meta)); + if (ret < 0) { + ALOGE("DvrWriteBufferQueue::PostBuffer: Failed to post buffer, ret=%d", + ret); + return ret; + } + + // Put the DvrWriteBuffer pointer back into its slot for reuse. + write_buffers_[slot].reset(write_buffer); + // It's import to reset the write buffer client now. It should stay invalid + // until next GainBuffer on the same slot. + write_buffers_[slot]->write_buffer = nullptr; return 0; } @@ -236,7 +316,29 @@ int dvrWriteBufferQueueDequeue(DvrWriteBufferQueue* write_queue, int timeout, if (!write_queue || !write_buffer || !out_fence_fd) return -EINVAL; - return write_queue->Dequeue(timeout, write_buffer, out_fence_fd); + // TODO(b/65469368): Deprecate this API once new GainBuffer API is in use. + return write_queue->Dequeue(timeout, write_buffer, out_fence_fd, nullptr); +} + +int dvrWriteBufferQueueGainBuffer(DvrWriteBufferQueue* write_queue, int timeout, + DvrWriteBuffer** out_write_buffer, + DvrNativeBufferMetadata* out_meta, + int* out_fence_fd) { + if (!write_queue || !out_write_buffer || !out_meta || !out_fence_fd) + return -EINVAL; + + return write_queue->GainBuffer(timeout, out_write_buffer, out_meta, + out_fence_fd); +} + +int dvrWriteBufferQueuePostBuffer(DvrWriteBufferQueue* write_queue, + DvrWriteBuffer* write_buffer, + const DvrNativeBufferMetadata* meta, + int ready_fence_fd) { + if (!write_queue || !write_buffer || !write_buffer->write_buffer || !meta) + return -EINVAL; + + return write_queue->PostBuffer(write_buffer, meta, ready_fence_fd); } int dvrWriteBufferQueueResizeBuffer(DvrWriteBufferQueue* write_queue, @@ -268,8 +370,8 @@ int DvrReadBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) { } int DvrReadBufferQueue::Dequeue(int timeout, DvrReadBuffer* read_buffer, - int* out_fence_fd, void* out_meta, - size_t meta_size_bytes) { + int* out_fence_fd, size_t* out_slot, + void* out_meta, size_t meta_size_bytes) { if (meta_size_bytes != consumer_queue_->metadata_size()) { ALOGE( "DvrReadBufferQueue::Dequeue: Invalid metadata size, expected (%zu), " @@ -291,6 +393,95 @@ int DvrReadBufferQueue::Dequeue(int timeout, DvrReadBuffer* read_buffer, read_buffer->read_buffer = buffer_status.take(); *out_fence_fd = acquire_fence.Release(); + + if (out_slot) { + // TODO(b/65469368): Remove this null check once dvrReadBufferQueueDequeue + // is deprecated. + *out_slot = slot; + } + return 0; +} + +int DvrReadBufferQueue::AcquireBuffer(int timeout, + DvrReadBuffer** out_read_buffer, + DvrNativeBufferMetadata* out_meta, + int* out_fence_fd) { + DvrReadBuffer read_buffer; + int fence_fd; + size_t slot; + const int ret = Dequeue(timeout, &read_buffer, &fence_fd, &slot, out_meta, + sizeof(*out_meta)); + if (ret < 0) { + ALOGE_IF( + ret != -ETIMEDOUT, + "DvrReadBufferQueue::AcquireBuffer: Failed to dequeue buffer, error=%d", + ret); + return ret; + } + + if (read_buffers_[slot] == nullptr) { + // Lazy initialization of a read_buffers_ slot. Note that a slot will only + // be dynamically allocated once during the entire cycle life of a queue. + read_buffers_[slot] = std::make_unique<DvrReadBuffer>(); + read_buffers_[slot]->slot = slot; + } + + LOG_FATAL_IF( + read_buffers_[slot]->read_buffer, + "DvrReadBufferQueue::AcquireBuffer: Buffer slot is not empty: %zu", slot); + read_buffers_[slot]->read_buffer = std::move(read_buffer.read_buffer); + + *out_read_buffer = read_buffers_[slot].release(); + *out_fence_fd = fence_fd; + + return 0; +} + +int DvrReadBufferQueue::ReleaseBuffer(DvrReadBuffer* read_buffer, + const DvrNativeBufferMetadata* meta, + int release_fence_fd) { + LOG_FATAL_IF( + (read_buffers->slot < 0 || read_buffers->slot >= read_buffers_size()), + "DvrReadBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot); + + // Some basic sanity checks before we put the buffer back into a slot. + size_t slot = static_cast<size_t>(read_buffer->slot); + if (read_buffers_[slot] != nullptr) { + ALOGE("DvrReadBufferQueue::ReleaseBuffer: Slot is not empty: %zu", slot); + return -EINVAL; + } + if (read_buffer->read_buffer == nullptr) { + ALOGE("DvrReadBufferQueue::ReleaseBuffer: Invalid read buffer."); + return -EINVAL; + } + if (read_buffer->read_buffer->id() != consumer_queue_->GetBufferId(slot)) { + ALOGE( + "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released does not " + "belong to this buffer queue."); + return -EINVAL; + } + + pdx::LocalHandle fence(release_fence_fd); + int ret = 0; + if (fence) { + ret = read_buffer->read_buffer->Release(fence); + } else { + // TODO(b/65458354): Send metadata back to producer once shared memory based + // metadata is implemented. + // TODO(b/65455724): All BufferHub operations should be async. + ret = read_buffer->read_buffer->ReleaseAsync(); + } + if (ret < 0) { + ALOGE("DvrReadBufferQueue::ReleaseBuffer: Failed to release buffer, ret=%d", + ret); + return ret; + } + + // Put the DvrReadBuffer pointer back into its slot for reuse. + read_buffers_[slot].reset(read_buffer); + // It's import to reset the read buffer client now. It should stay invalid + // until next AcquireBuffer on the same slot. + read_buffers_[slot]->read_buffer = nullptr; return 0; } @@ -311,9 +502,11 @@ void DvrReadBufferQueue::SetBufferRemovedCallback( } else { consumer_queue_->SetBufferRemovedCallback( [callback, context](const std::shared_ptr<BufferHubBuffer>& buffer) { - DvrReadBuffer read_buffer{ - std::static_pointer_cast<BufferConsumer>(buffer)}; - callback(&read_buffer, context); + // When buffer is removed from the queue, the slot is already invalid. + auto read_buffer = std::make_unique<DvrReadBuffer>(); + read_buffer->read_buffer = + std::static_pointer_cast<BufferConsumer>(buffer); + callback(read_buffer.release(), context); }); } } @@ -366,8 +559,30 @@ int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout, if (meta_size_bytes != 0 && !out_meta) return -EINVAL; - return read_queue->Dequeue(timeout, read_buffer, out_fence_fd, out_meta, - meta_size_bytes); + // TODO(b/65469368): Deprecate this API once new AcquireBuffer API is in use. + return read_queue->Dequeue(timeout, read_buffer, out_fence_fd, nullptr, + out_meta, meta_size_bytes); +} + +int dvrReadBufferQueueAcquireBuffer(DvrReadBufferQueue* read_queue, int timeout, + DvrReadBuffer** out_read_buffer, + DvrNativeBufferMetadata* out_meta, + int* out_fence_fd) { + if (!read_queue || !out_read_buffer || !out_meta || !out_fence_fd) + return -EINVAL; + + return read_queue->AcquireBuffer(timeout, out_read_buffer, out_meta, + out_fence_fd); +} + +int dvrReadBufferQueueReleaseBuffer(DvrReadBufferQueue* read_queue, + DvrReadBuffer* read_buffer, + const DvrNativeBufferMetadata* meta, + int release_fence_fd) { + if (!read_queue || !read_buffer || !read_buffer->read_buffer || !meta) + return -EINVAL; + + return read_queue->ReleaseBuffer(read_buffer, meta, release_fence_fd); } int dvrReadBufferQueueSetBufferAvailableCallback( diff --git a/libs/vr/libdvr/dvr_buffer_queue_internal.h b/libs/vr/libdvr/dvr_buffer_queue_internal.h index 795d6cdc25..f9c0bfd7c7 100644 --- a/libs/vr/libdvr/dvr_buffer_queue_internal.h +++ b/libs/vr/libdvr/dvr_buffer_queue_internal.h @@ -5,10 +5,14 @@ #include <private/dvr/buffer_hub_queue_client.h> #include <sys/cdefs.h> +#include <array> #include <memory> +#include "dvr_internal.h" + struct ANativeWindow; +typedef struct DvrNativeBufferMetadata DvrNativeBufferMetadata; typedef struct DvrReadBuffer DvrReadBuffer; typedef struct DvrReadBufferQueue DvrReadBufferQueue; typedef struct DvrWriteBuffer DvrWriteBuffer; @@ -17,6 +21,7 @@ typedef void (*DvrReadBufferQueueBufferRemovedCallback)(DvrReadBuffer* buffer, void* context); struct DvrWriteBufferQueue { + using BufferHubQueue = android::dvr::BufferHubQueue; using ProducerQueue = android::dvr::ProducerQueue; // Create a concrete object for DvrWriteBufferQueue. @@ -37,19 +42,28 @@ struct DvrWriteBufferQueue { int GetNativeWindow(ANativeWindow** out_window); int CreateReadQueue(DvrReadBufferQueue** out_read_queue); - int Dequeue(int timeout, DvrWriteBuffer* write_buffer, int* out_fence_fd); + int Dequeue(int timeout, DvrWriteBuffer* write_buffer, int* out_fence_fd, + size_t* out_slot); + int GainBuffer(int timeout, DvrWriteBuffer** out_write_buffer, + DvrNativeBufferMetadata* out_meta, int* out_fence_fd); + int PostBuffer(DvrWriteBuffer* write_buffer, + const DvrNativeBufferMetadata* meta, int ready_fence_fd); int ResizeBuffer(uint32_t width, uint32_t height); private: std::shared_ptr<ProducerQueue> producer_queue_; + std::array<std::unique_ptr<DvrWriteBuffer>, BufferHubQueue::kMaxQueueCapacity> + write_buffers_; uint32_t width_; uint32_t height_; uint32_t format_; + android::sp<android::Surface> native_window_; }; struct DvrReadBufferQueue { + using BufferHubQueue = android::dvr::BufferHubQueue; using ConsumerQueue = android::dvr::ConsumerQueue; explicit DvrReadBufferQueue( @@ -61,7 +75,11 @@ struct DvrReadBufferQueue { int CreateReadQueue(DvrReadBufferQueue** out_read_queue); int Dequeue(int timeout, DvrReadBuffer* read_buffer, int* out_fence_fd, - void* out_meta, size_t meta_size_bytes); + size_t* out_slot, void* out_meta, size_t meta_size_bytes); + int AcquireBuffer(int timeout, DvrReadBuffer** out_read_buffer, + DvrNativeBufferMetadata* out_meta, int* out_fence_fd); + int ReleaseBuffer(DvrReadBuffer* read_buffer, + const DvrNativeBufferMetadata* meta, int release_fence_fd); void SetBufferAvailableCallback( DvrReadBufferQueueBufferAvailableCallback callback, void* context); void SetBufferRemovedCallback( @@ -70,6 +88,8 @@ struct DvrReadBufferQueue { private: std::shared_ptr<ConsumerQueue> consumer_queue_; + std::array<std::unique_ptr<DvrReadBuffer>, BufferHubQueue::kMaxQueueCapacity> + read_buffers_; }; #endif // ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_ diff --git a/libs/vr/libdvr/dvr_internal.h b/libs/vr/libdvr/dvr_internal.h index 28b6c28e9f..de8bb96aec 100644 --- a/libs/vr/libdvr/dvr_internal.h +++ b/libs/vr/libdvr/dvr_internal.h @@ -34,10 +34,20 @@ DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer( extern "C" { struct DvrWriteBuffer { + // The slot nubmer of the buffer, a valid slot number must be in the range of + // [0, android::BufferQueueDefs::NUM_BUFFER_SLOTS). This is only valid for + // DvrWriteBuffer acquired from a DvrWriteBufferQueue. + int32_t slot = -1; + std::shared_ptr<android::dvr::BufferProducer> write_buffer; }; struct DvrReadBuffer { + // The slot nubmer of the buffer, a valid slot number must be in the range of + // [0, android::BufferQueueDefs::NUM_BUFFER_SLOTS). This is only valid for + // DvrReadBuffer acquired from a DvrReadBufferQueue. + int32_t slot = -1; + std::shared_ptr<android::dvr::BufferConsumer> read_buffer; }; diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h index 6daf157f36..8f45ce7e40 100644 --- a/libs/vr/libdvr/include/dvr/dvr_api.h +++ b/libs/vr/libdvr/include/dvr/dvr_api.h @@ -34,6 +34,7 @@ typedef struct AHardwareBuffer AHardwareBuffer; typedef struct DvrReadBufferQueue DvrReadBufferQueue; typedef struct DvrWriteBufferQueue DvrWriteBufferQueue; +typedef struct DvrNativeBufferMetadata DvrNativeBufferMetadata; typedef struct DvrSurface DvrSurface; typedef uint64_t DvrSurfaceAttributeType; @@ -180,6 +181,13 @@ typedef int (*DvrWriteBufferQueueDequeuePtr)(DvrWriteBufferQueue* write_queue, int timeout, DvrWriteBuffer* out_buffer, int* out_fence_fd); +typedef int (*DvrWriteBufferQueueGainBufferPtr)( + DvrWriteBufferQueue* write_queue, int timeout, + DvrWriteBuffer** out_write_buffer, DvrNativeBufferMetadata* out_meta, + int* out_fence_fd); +typedef int (*DvrWriteBufferQueuePostBufferPtr)( + DvrWriteBufferQueue* write_queue, DvrWriteBuffer* write_buffer, + const DvrNativeBufferMetadata* meta, int ready_fence_fd); typedef int (*DvrWriteBufferQueueResizeBufferPtr)( DvrWriteBufferQueue* write_queue, uint32_t width, uint32_t height); typedef void (*DvrReadBufferQueueDestroyPtr)(DvrReadBufferQueue* read_queue); @@ -194,6 +202,13 @@ typedef int (*DvrReadBufferQueueDequeuePtr)(DvrReadBufferQueue* read_queue, DvrReadBuffer* out_buffer, int* out_fence_fd, void* out_meta, size_t meta_size_bytes); +typedef int (*DvrReadBufferQueueAcquireBufferPtr)( + DvrReadBufferQueue* read_queue, int timeout, + DvrReadBuffer** out_read_buffer, DvrNativeBufferMetadata* out_meta, + int* out_fence_fd); +typedef int (*DvrReadBufferQueueReleaseBufferPtr)( + DvrReadBufferQueue* read_queue, DvrReadBuffer* read_buffer, + const DvrNativeBufferMetadata* meta, int release_fence_fd); typedef void (*DvrReadBufferQueueBufferAvailableCallback)(void* context); typedef int (*DvrReadBufferQueueSetBufferAvailableCallbackPtr)( DvrReadBufferQueue* read_queue, diff --git a/libs/vr/libdvr/include/dvr/dvr_api_entries.h b/libs/vr/libdvr/include/dvr/dvr_api_entries.h index 9036773464..cce8c7ee40 100644 --- a/libs/vr/libdvr/include/dvr/dvr_api_entries.h +++ b/libs/vr/libdvr/include/dvr/dvr_api_entries.h @@ -167,6 +167,12 @@ DVR_V1_API_ENTRY(WriteBufferQueueCreate); // Gets an ANativeWindow from DvrWriteBufferQueue. DVR_V1_API_ENTRY(WriteBufferQueueGetANativeWindow); +// Dvr{Read,Write}BufferQueue API for asynchronous IPC. +DVR_V1_API_ENTRY(WriteBufferQueueGainBuffer); +DVR_V1_API_ENTRY(WriteBufferQueuePostBuffer); +DVR_V1_API_ENTRY(ReadBufferQueueAcquireBuffer); +DVR_V1_API_ENTRY(ReadBufferQueueReleaseBuffer); + // Pose client DVR_V1_API_ENTRY(PoseClientGetDataReader); DVR_V1_API_ENTRY(PoseClientDataCapture); diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h index 8b9e0482d9..bf695c7dbc 100644 --- a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h +++ b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h @@ -89,21 +89,44 @@ int dvrWriteBufferQueueGetExternalSurface(DvrWriteBufferQueue* write_queue, int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue, DvrReadBufferQueue** out_read_queue); -// Dequeue a buffer to write into. +// @deprecated Please use dvrWriteBufferQueueGainBuffer instead. +int dvrWriteBufferQueueDequeue(DvrWriteBufferQueue* write_queue, int timeout, + DvrWriteBuffer* out_buffer, int* out_fence_fd); + +// Gains a buffer to write into. // -// @param write_queue The DvrWriteBufferQueue of interest. +// @param write_queue The DvrWriteBufferQueue to gain buffer from. // @param timeout Specifies the number of milliseconds that the method will // block. Specifying a timeout of -1 causes it to block indefinitely, // while specifying a timeout equal to zero cause it to return immediately, // even if no buffers are available. // @param out_buffer A targeting DvrWriteBuffer object to hold the output of the -// dequeue operation. Must be created by |dvrWriteBufferCreateEmpty|. +// dequeue operation. +// @param out_meta A DvrNativeBufferMetadata object populated by the +// corresponding dvrReadBufferQueueReleaseBuffer API. // @param out_fence_fd A sync fence fd defined in NDK's sync.h API, which // signals the release of underlying buffer. The producer should wait until // this fence clears before writing data into it. // @return Zero on success, or negative error code. -int dvrWriteBufferQueueDequeue(DvrWriteBufferQueue* write_queue, int timeout, - DvrWriteBuffer* out_buffer, int* out_fence_fd); +int dvrWriteBufferQueueGainBuffer(DvrWriteBufferQueue* write_queue, int timeout, + DvrWriteBuffer** out_write_buffer, + DvrNativeBufferMetadata* out_meta, + int* out_fence_fd); + +// Posts a buffer and signals its readiness to be read from. +// +// @param write_queue The DvrWriteBufferQueue to post buffer into. +// @param write_buffer The buffer to be posted. +// @param meta The buffer metadata describing the buffer. +// @param ready_fence_fd A sync fence fd defined in NDK's sync.h API, which +// signals the readdiness of underlying buffer. When a valid fence gets +// passed in, the consumer will wait the fence to be ready before it starts +// to ready from the buffer. +// @return Zero on success, or negative error code. +int dvrWriteBufferQueuePostBuffer(DvrWriteBufferQueue* write_queue, + DvrWriteBuffer* write_buffer, + const DvrNativeBufferMetadata* meta, + int ready_fence_fd); // Overrides buffer dimension with new width and height. // @@ -153,28 +176,45 @@ int dvrReadBufferQueueGetEventFd(DvrReadBufferQueue* read_queue); int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue, DvrReadBufferQueue** out_read_queue); -// Dequeue a buffer to read from. +// @deprecated Please use dvrReadBufferQueueAcquireBuffer instead. +int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout, + DvrReadBuffer* out_buffer, int* out_fence_fd, + void* out_meta, size_t meta_size_bytes); + +// Dequeues a buffer to read from. // -// @param read_queue The DvrReadBufferQueue of interest. +// @param read_queue The DvrReadBufferQueue to acquire buffer from. // @param timeout Specifies the number of milliseconds that the method will // block. Specifying a timeout of -1 causes it to block indefinitely, // while specifying a timeout equal to zero cause it to return immediately, // even if no buffers are available. // @param out_buffer A targeting DvrReadBuffer object to hold the output of the // dequeue operation. Must be created by |dvrReadBufferCreateEmpty|. +// @param out_meta A DvrNativeBufferMetadata object populated by the +// corresponding dvrWriteBufferQueuePostBuffer API. // @param out_fence_fd A sync fence fd defined in NDK's sync.h API, which // signals the release of underlying buffer. The consumer should wait until // this fence clears before reading data from it. -// @param out_meta The memory area where a metadata object will be filled. -// Can be nullptr iff |meta_size_bytes| is zero (i.e., there is no -// metadata). -// @param meta_size_bytes Size of the metadata object caller expects. If it -// doesn't match the size of actually metadata transported by the buffer -// queue, the method returns -EINVAL. // @return Zero on success, or negative error code. -int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout, - DvrReadBuffer* out_buffer, int* out_fence_fd, - void* out_meta, size_t meta_size_bytes); +int dvrReadBufferQueueAcquireBuffer(DvrReadBufferQueue* read_queue, int timeout, + DvrReadBuffer** out_read_buffer, + DvrNativeBufferMetadata* out_meta, + int* out_fence_fd); + +// Releases a buffer and signals its readiness to be written into. +// +// @param read_queue The DvrReadBufferQueue to release buffer into. +// @param read_buffer The buffer to be released. +// @param meta The buffer metadata describing the buffer. +// @param release_fence_fd A sync fence fd defined in NDK's sync.h API, which +// signals the readdiness of underlying buffer. When a valid fence gets +// passed in, the producer will wait the fence to be ready before it starts +// to write into the buffer again. +// @return Zero on success, or negative error code. +int dvrReadBufferQueueReleaseBuffer(DvrReadBufferQueue* read_queue, + DvrReadBuffer* read_buffer, + const DvrNativeBufferMetadata* meta, + int release_fence_fd); // Callback function which will be called when a buffer is avaiable. // diff --git a/libs/vr/libdvr/tests/Android.bp b/libs/vr/libdvr/tests/Android.bp index ab2ee75a3e..a9302a7561 100644 --- a/libs/vr/libdvr/tests/Android.bp +++ b/libs/vr/libdvr/tests/Android.bp @@ -47,6 +47,7 @@ cc_test { cflags: [ "-DLOG_TAG=\"dvr_api-test\"", "-DTRACE=0", + "-Wno-missing-field-initializers", "-O0", "-g", ], diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp index 0b30c3869a..f1c5e48916 100644 --- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp +++ b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp @@ -27,8 +27,6 @@ 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; - class DvrBufferQueueTest : public ::testing::Test { public: static void BufferAvailableCallback(void* context) { @@ -65,20 +63,20 @@ class DvrBufferQueueTest : public ::testing::Test { int buffer_removed_count_{0}; }; -TEST_F(DvrBufferQueueTest, TestWrite_QueueCreateDestroy) { +TEST_F(DvrBufferQueueTest, WriteQueueCreateDestroy) { int ret = dvrWriteBufferQueueCreate( kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - /*capacity=*/0, sizeof(TestMeta), &write_queue_); + /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_); ASSERT_EQ(0, ret); dvrWriteBufferQueueDestroy(write_queue_); write_queue_ = nullptr; } -TEST_F(DvrBufferQueueTest, TestWrite_QueueGetCapacity) { +TEST_F(DvrBufferQueueTest, WriteQueueGetCapacity) { int ret = dvrWriteBufferQueueCreate( kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(TestMeta), &write_queue_); + kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); ASSERT_EQ(0, ret); size_t capacity = dvrWriteBufferQueueGetCapacity(write_queue_); @@ -87,10 +85,10 @@ TEST_F(DvrBufferQueueTest, TestWrite_QueueGetCapacity) { ASSERT_EQ(kQueueCapacity, capacity); } -TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromWriteQueue) { +TEST_F(DvrBufferQueueTest, CreateReadQueueFromWriteQueue) { int ret = dvrWriteBufferQueueCreate( kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - /*capacity=*/0, sizeof(TestMeta), &write_queue_); + /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_); ASSERT_EQ(0, ret); DvrReadBufferQueue* read_queue = nullptr; @@ -102,10 +100,10 @@ TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromWriteQueue) { dvrReadBufferQueueDestroy(read_queue); } -TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromReadQueue) { +TEST_F(DvrBufferQueueTest, CreateReadQueueFromReadQueue) { int ret = dvrWriteBufferQueueCreate( kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - /*capacity=*/0, sizeof(TestMeta), &write_queue_); + /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_); ASSERT_EQ(0, ret); DvrReadBufferQueue* read_queue1 = nullptr; @@ -124,102 +122,86 @@ TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromReadQueue) { dvrReadBufferQueueDestroy(read_queue2); } -TEST_F(DvrBufferQueueTest, CreateEmptyBuffer) { +TEST_F(DvrBufferQueueTest, GainBuffer) { 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; - - EXPECT_FALSE(dvrReadBufferIsValid(read_buffer)); - EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer)); - - dvrReadBufferCreateEmpty(&read_buffer); - ASSERT_NE(nullptr, read_buffer); - - dvrWriteBufferCreateEmpty(&write_buffer); - ASSERT_NE(nullptr, write_buffer); - - EXPECT_FALSE(dvrReadBufferIsValid(read_buffer)); - EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer)); + kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); + ASSERT_EQ(ret, 0); - DvrReadBufferQueue* read_queue = nullptr; - - ASSERT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue)); + DvrWriteBuffer* wb = nullptr; + EXPECT_FALSE(dvrWriteBufferIsValid(wb)); - const int kTimeoutMs = 0; + DvrNativeBufferMetadata meta = {0}; int fence_fd = -1; - ASSERT_EQ(0, dvrWriteBufferQueueDequeue(write_queue_, kTimeoutMs, - write_buffer, &fence_fd)); - EXPECT_EQ(-1, fence_fd); - EXPECT_TRUE(dvrWriteBufferIsValid(write_buffer)); - - ASSERT_EQ(0, dvrWriteBufferClear(write_buffer)); - EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer)); + ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta, + &fence_fd); + ASSERT_EQ(ret, 0); + EXPECT_EQ(fence_fd, -1); + EXPECT_NE(wb, nullptr); + EXPECT_TRUE(dvrWriteBufferIsValid(wb)); } -TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) { +TEST_F(DvrBufferQueueTest, AcquirePostGainRelease) { int ret = dvrWriteBufferQueueCreate( kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(TestMeta), &write_queue_); - ASSERT_EQ(0, ret); + kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); + ASSERT_EQ(ret, 0); - static constexpr int kTimeout = 0; DvrReadBufferQueue* read_queue = nullptr; DvrReadBuffer* rb = nullptr; DvrWriteBuffer* wb = nullptr; + DvrNativeBufferMetadata meta1 = {0}; + DvrNativeBufferMetadata meta2 = {0}; int fence_fd = -1; ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue); - ASSERT_EQ(0, ret); - ASSERT_NE(nullptr, read_queue); + ASSERT_EQ(ret, 0); + ASSERT_NE(read_queue, nullptr); dvrReadBufferQueueSetBufferAvailableCallback(read_queue, &BufferAvailableCallback, this); - dvrWriteBufferCreateEmpty(&wb); - ASSERT_NE(nullptr, wb); - - dvrReadBufferCreateEmpty(&rb); - ASSERT_NE(nullptr, rb); - // Gain buffer for writing. - ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wb, &fence_fd); - ASSERT_EQ(0, ret); + ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta1, + &fence_fd); + ASSERT_EQ(ret, 0); + ASSERT_NE(wb, nullptr); ASSERT_TRUE(dvrWriteBufferIsValid(wb)); ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d", wb, fence_fd); android::base::unique_fd 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); + meta1.timestamp = 42; + ret = dvrWriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1); + ASSERT_EQ(ret, 0); + ASSERT_FALSE(dvrWriteBufferIsValid(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); + ret = dvrReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/0, &rb, &meta2, + &fence_fd); + ASSERT_EQ(ret, 0); + ASSERT_NE(rb, nullptr); // Dequeue is successfully, BufferAvailableCallback should be fired once. - ASSERT_EQ(1, buffer_available_count_); + ASSERT_EQ(buffer_available_count_, 1); ASSERT_TRUE(dvrReadBufferIsValid(rb)); - ASSERT_EQ(seq, acquired_seq); + + // Metadata should be passed along from producer to consumer properly. + ASSERT_EQ(meta1.timestamp, meta2.timestamp); + ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb, fence_fd); android::base::unique_fd acquire_fence(fence_fd); // Release buffer to the write_queue. - ret = dvrReadBufferRelease(rb, -1); - ASSERT_EQ(0, ret); - dvrReadBufferDestroy(rb); + ret = dvrReadBufferQueueReleaseBuffer(read_queue, rb, &meta2, + /*release_fence_fd=*/-1); + ASSERT_EQ(ret, 0); + ASSERT_FALSE(dvrReadBufferIsValid(rb)); rb = nullptr; // TODO(b/34387835) Currently buffer allocation has to happen after all queues @@ -232,37 +214,18 @@ TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) { dvrReadBufferQueueDestroy(read_queue); } -TEST_F(DvrBufferQueueTest, TestGetANativeWindow) { +TEST_F(DvrBufferQueueTest, GetANativeWindow) { 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. - ret = dvrWriteBufferQueueGetANativeWindow(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. - 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_); + ANativeWindow* window = nullptr; ret = dvrWriteBufferQueueGetANativeWindow(write_queue_, &window); ASSERT_EQ(0, ret); ASSERT_NE(nullptr, window); - // 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); @@ -274,15 +237,15 @@ TEST_F(DvrBufferQueueTest, TestGetANativeWindow) { // 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) { +TEST_F(DvrBufferQueueTest, ResizeBuffer) { int ret = dvrWriteBufferQueueCreate( kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(TestMeta), &write_queue_); + kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); ASSERT_EQ(0, ret); - static constexpr int kTimeout = 0; int fence_fd = -1; + DvrNativeBufferMetadata meta = {0}; DvrReadBufferQueue* read_queue = nullptr; DvrWriteBuffer* wb1 = nullptr; DvrWriteBuffer* wb2 = nullptr; @@ -300,13 +263,6 @@ TEST_F(DvrBufferQueueTest, TestResizeBuffer) { dvrReadBufferQueueSetBufferRemovedCallback(read_queue, &BufferRemovedCallback, this); - dvrWriteBufferCreateEmpty(&wb1); - ASSERT_NE(nullptr, wb1); - dvrWriteBufferCreateEmpty(&wb2); - ASSERT_NE(nullptr, wb2); - dvrWriteBufferCreateEmpty(&wb3); - ASSERT_NE(nullptr, wb3); - // Handle all pending events on the read queue. ret = dvrReadBufferQueueHandleEvents(read_queue); ASSERT_EQ(0, ret); @@ -321,7 +277,8 @@ TEST_F(DvrBufferQueueTest, TestResizeBuffer) { ASSERT_EQ(0, ret); // Gain first buffer for writing. All buffers will be resized. - ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wb1, &fence_fd); + ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb1, &meta, + &fence_fd); ASSERT_EQ(0, ret); ASSERT_TRUE(dvrWriteBufferIsValid(wb1)); ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p", wb1); @@ -347,7 +304,8 @@ TEST_F(DvrBufferQueueTest, TestResizeBuffer) { ASSERT_EQ(0, ret); // The next buffer we dequeued should have new width. - ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wb2, &fence_fd); + ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb2, &meta, + &fence_fd); ASSERT_EQ(0, ret); ASSERT_TRUE(dvrWriteBufferIsValid(wb2)); ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb2, @@ -373,7 +331,8 @@ TEST_F(DvrBufferQueueTest, TestResizeBuffer) { ASSERT_EQ(0, ret); // The next buffer we dequeued should have new width. - ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wb3, &fence_fd); + ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb3, &meta, + &fence_fd); ASSERT_EQ(0, ret); ASSERT_TRUE(dvrWriteBufferIsValid(wb3)); ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb3, @@ -396,78 +355,10 @@ TEST_F(DvrBufferQueueTest, TestResizeBuffer) { dvrReadBufferQueueDestroy(read_queue); } -TEST_F(DvrBufferQueueTest, DequeueEmptyMetadata) { - // Overrides default queue parameters: Empty metadata. +TEST_F(DvrBufferQueueTest, ReadQueueEventFd) { 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; - dvrReadBufferCreateEmpty(&rb); - dvrWriteBufferCreateEmpty(&wb); - - DvrReadBufferQueue* read_queue = nullptr; - EXPECT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue)); - - const int kTimeoutMs = 0; - int fence_fd = -1; - EXPECT_EQ(0, dvrWriteBufferQueueDequeue(write_queue_, 0, wb, &fence_fd)); - - EXPECT_EQ(0, dvrWriteBufferPost(wb, /*fence=*/-1, nullptr, 0)); - EXPECT_EQ(0, dvrWriteBufferClear(wb)); - dvrWriteBufferDestroy(wb); - wb = nullptr; - - // When acquire buffer, it's legit to pass nullptr as out_meta iff metadata - // size is Zero. - EXPECT_EQ(0, dvrReadBufferQueueDequeue(read_queue, kTimeoutMs, rb, &fence_fd, - nullptr, 0)); - EXPECT_TRUE(dvrReadBufferIsValid(rb)); -} - -TEST_F(DvrBufferQueueTest, DequeueMismatchMetadata) { - int ret = dvrWriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - /*capacity=*/1, sizeof(TestMeta), &write_queue_); - ASSERT_EQ(0, ret); - - DvrReadBuffer* rb = nullptr; - DvrWriteBuffer* wb = nullptr; - dvrReadBufferCreateEmpty(&rb); - dvrWriteBufferCreateEmpty(&wb); - - DvrReadBufferQueue* read_queue = nullptr; - EXPECT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue)); - - const int kTimeoutMs = 0; - int fence_fd = -1; - EXPECT_EQ(0, dvrWriteBufferQueueDequeue(write_queue_, 0, wb, &fence_fd)); - - TestMeta seq = 42U; - EXPECT_EQ(0, dvrWriteBufferPost(wb, /*fence=*/-1, &seq, sizeof(seq))); - EXPECT_EQ(0, dvrWriteBufferClear(wb)); - dvrWriteBufferDestroy(wb); - wb = nullptr; - - // Dequeue with wrong metadata will cause EINVAL. - int8_t wrong_metadata; - EXPECT_EQ(-EINVAL, - dvrReadBufferQueueDequeue(read_queue, kTimeoutMs, rb, &fence_fd, - &wrong_metadata, sizeof(wrong_metadata))); - EXPECT_FALSE(dvrReadBufferIsValid(rb)); - - // Dequeue with empty metadata will cause EINVAL. - EXPECT_EQ(-EINVAL, dvrReadBufferQueueDequeue(read_queue, kTimeoutMs, rb, - &fence_fd, nullptr, 0)); - EXPECT_FALSE(dvrReadBufferIsValid(rb)); -} - -TEST_F(DvrBufferQueueTest, TestReadQueueEventFd) { - int ret = dvrWriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(TestMeta), &write_queue_); + kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); ASSERT_EQ(0, ret); DvrReadBufferQueue* read_queue = nullptr; @@ -483,10 +374,10 @@ TEST_F(DvrBufferQueueTest, TestReadQueueEventFd) { // Verifies a Dvr{Read,Write}BufferQueue contains the same set of // 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) { +TEST_F(DvrBufferQueueTest, StableBufferIdAndHardwareBuffer) { int ret = dvrWriteBufferQueueCreate( kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(TestMeta), &write_queue_); + kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); ASSERT_EQ(0, ret); int fence_fd = -1; @@ -497,25 +388,21 @@ TEST_F(DvrBufferQueueTest, TestStableBufferIdAndHardwareBuffer) { std::array<DvrReadBuffer*, kQueueCapacity> rbs; // Write buffers. std::array<DvrWriteBuffer*, kQueueCapacity> wbs; + // Buffer metadata. + std::array<DvrNativeBufferMetadata, kQueueCapacity> metas; // Hardware buffers for Read buffers. std::unordered_map<int, AHardwareBuffer*> rhbs; // Hardware buffers for Write buffers. std::unordered_map<int, AHardwareBuffer*> whbs; - for (size_t i = 0; i < kQueueCapacity; i++) { - dvrReadBufferCreateEmpty(&rbs[i]); - dvrWriteBufferCreateEmpty(&wbs[i]); - } - constexpr int kNumTests = 100; - constexpr int kTimeout = 0; - TestMeta seq = 0U; // This test runs the following operations many many times. Thus we prefer to // use ASSERT_XXX rather than EXPECT_XXX to avoid spamming the output. std::function<void(size_t i)> Gain = [&](size_t i) { - ASSERT_EQ(0, dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wbs[i], - &fence_fd)); + int ret = dvrWriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, + &wbs[i], &metas[i], &fence_fd); + ASSERT_EQ(ret, 0); ASSERT_LT(fence_fd, 0); // expect invalid fence. ASSERT_TRUE(dvrWriteBufferIsValid(wbs[i])); int buffer_id = dvrWriteBufferGetId(wbs[i]); @@ -540,15 +427,16 @@ TEST_F(DvrBufferQueueTest, TestStableBufferIdAndHardwareBuffer) { std::function<void(size_t i)> Post = [&](size_t i) { ASSERT_TRUE(dvrWriteBufferIsValid(wbs[i])); - seq++; - ASSERT_EQ(0, dvrWriteBufferPost(wbs[i], /*fence=*/-1, &seq, sizeof(seq))); + metas[i].timestamp++; + int ret = dvrWriteBufferQueuePostBuffer(write_queue_, wbs[i], &metas[i], + /*fence=*/-1); + ASSERT_EQ(ret, 0); }; std::function<void(size_t i)> Acquire = [&](size_t i) { - TestMeta out_seq = 0U; - ASSERT_EQ(0, - dvrReadBufferQueueDequeue(read_queue, kTimeout, rbs[i], &fence_fd, - &out_seq, sizeof(out_seq))); + int ret = dvrReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/0, + &rbs[i], &metas[i], &fence_fd); + ASSERT_EQ(ret, 0); ASSERT_LT(fence_fd, 0); // expect invalid fence. ASSERT_TRUE(dvrReadBufferIsValid(rbs[i])); @@ -574,8 +462,9 @@ TEST_F(DvrBufferQueueTest, TestStableBufferIdAndHardwareBuffer) { std::function<void(size_t i)> Release = [&](size_t i) { ASSERT_TRUE(dvrReadBufferIsValid(rbs[i])); - seq++; - ASSERT_EQ(0, dvrReadBufferRelease(rbs[i], /*fence=*/-1)); + int ret = dvrReadBufferQueueReleaseBuffer(read_queue, rbs[i], &metas[i], + /*release_fence_fd=*/-1); + ASSERT_EQ(ret, 0); }; // Scenario one: @@ -630,12 +519,6 @@ TEST_F(DvrBufferQueueTest, TestStableBufferIdAndHardwareBuffer) { ASSERT_NO_FATAL_FAILURE(Release(kQueueCapacity - 1 - i)); } } - - // Clean up all read buffers and write buffers. - for (size_t i = 0; i < kQueueCapacity; i++) { - dvrReadBufferDestroy(rbs[i]); - dvrWriteBufferDestroy(wbs[i]); - } } } // namespace |