OSDN Git Service

Overhual DvrBuffer and DvrBufferQueue API: Step 1
authorJiwen 'Steve' Cai <jwcai@google.com>
Fri, 8 Sep 2017 18:10:29 +0000 (11:10 -0700)
committerJiwen 'Steve' Cai <jwcai@google.com>
Tue, 12 Sep 2017 22:56:52 +0000 (15:56 -0700)
Adding new APIs:

dvrWriteBufferQueueGainBuffer
dvrWriteBufferQueuePostBuffer
dvrReadBufferQueueAcquireBuffer
dvrReadBufferQueueReleaseBuffer

Those new APIs streamlines DVR buffer operations:
1/ It allows static Dvr{Read,Write}Buffer objects to be statically
allocated with the queue.
2/ Symentric Gain/Post on WriteBufferQueue and Acquire/Release on
ReadBufferQueue.
3/ Use fixed buffer metadata.
4/ This is also a prerequisite to using shared memory based metadata and
async buffer IPC.

More details and discussion at: go/gvr-async-bufferhub

Special note regarding DVR API order in this CL: The new buffer queue
API entries are inserted before new PoseClient API as the PoseClient is
still blocked from being released and the new BufferQueue APIs are
expected to be released sooner than that.

Bug: 65455724
Bug: 65468551
Bug: 65458332
Bug: 65165821
Test: dvr_api-test
Change-Id: Iae8e7787d696d72ebf7457df9f98f4467cd20932

libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
libs/vr/libdvr/dvr_buffer.cpp
libs/vr/libdvr/dvr_buffer_queue.cpp
libs/vr/libdvr/dvr_buffer_queue_internal.h
libs/vr/libdvr/dvr_internal.h
libs/vr/libdvr/include/dvr/dvr_api.h
libs/vr/libdvr/include/dvr/dvr_api_entries.h
libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
libs/vr/libdvr/tests/Android.bp
libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp

index 3e93788..0699fef 100644 (file)
@@ -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};
index 4d9b215..1a99234 100644 (file)
@@ -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;
index 4adb5d2..035252d 100644 (file)
@@ -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(
index 795d6cd..f9c0bfd 100644 (file)
@@ -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_
index 28b6c28..de8bb96 100644 (file)
@@ -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;
 };
 
index 6daf157..8f45ce7 100644 (file)
@@ -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,
index 9036773..cce8c7e 100644 (file)
@@ -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);
index 8b9e048..bf695c7 100644 (file)
@@ -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.
 //
index ab2ee75..a9302a7 100644 (file)
@@ -47,6 +47,7 @@ cc_test {
     cflags: [
         "-DLOG_TAG=\"dvr_api-test\"",
         "-DTRACE=0",
+        "-Wno-missing-field-initializers",
         "-O0",
         "-g",
     ],
index 0b30c38..f1c5e48 100644 (file)
@@ -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