Loading libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h +6 −1 Original line number Diff line number Diff line Loading @@ -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]; } Loading Loading @@ -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}; Loading libs/vr/libdvr/dvr_buffer.cpp +16 −2 Original line number Diff line number Diff line Loading @@ -44,8 +44,14 @@ void dvrWriteBufferCreateEmpty(DvrWriteBuffer** write_buffer) { } void dvrWriteBufferDestroy(DvrWriteBuffer* 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) { return write_buffer && write_buffer->write_buffer; Loading Loading @@ -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; Loading libs/vr/libdvr/dvr_buffer_queue.cpp +224 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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, Loading Loading @@ -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), " Loading @@ -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; } Loading @@ -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); }); } } Loading Loading @@ -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( Loading libs/vr/libdvr/dvr_buffer_queue_internal.h +22 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading @@ -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( Loading @@ -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( Loading @@ -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_ libs/vr/libdvr/dvr_internal.h +10 −0 Original line number Diff line number Diff line Loading @@ -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; }; Loading Loading
libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h +6 −1 Original line number Diff line number Diff line Loading @@ -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]; } Loading Loading @@ -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}; Loading
libs/vr/libdvr/dvr_buffer.cpp +16 −2 Original line number Diff line number Diff line Loading @@ -44,8 +44,14 @@ void dvrWriteBufferCreateEmpty(DvrWriteBuffer** write_buffer) { } void dvrWriteBufferDestroy(DvrWriteBuffer* 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) { return write_buffer && write_buffer->write_buffer; Loading Loading @@ -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; Loading
libs/vr/libdvr/dvr_buffer_queue.cpp +224 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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, Loading Loading @@ -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), " Loading @@ -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; } Loading @@ -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); }); } } Loading Loading @@ -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( Loading
libs/vr/libdvr/dvr_buffer_queue_internal.h +22 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. Loading @@ -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( Loading @@ -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( Loading @@ -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_
libs/vr/libdvr/dvr_internal.h +10 −0 Original line number Diff line number Diff line Loading @@ -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; }; Loading