Convert the pose buffer into a more generic named buffer

* It's likely that we'll have more than one pose buffer
* It's cleaner to separate the vsync info into a separate buffer

Bug: 37001881
Bug: 37240552
Test: Added and manually ran TestNamedBuffersSetup
Change-Id: I76621d3cfa8c21c9d5d1e6e648854067673be9ab
diff --git a/libs/vr/libbufferhub/buffer_hub_client.cpp b/libs/vr/libbufferhub/buffer_hub_client.cpp
index 62db7f4..a1f952e 100644
--- a/libs/vr/libbufferhub/buffer_hub_client.cpp
+++ b/libs/vr/libbufferhub/buffer_hub_client.cpp
@@ -20,6 +20,7 @@
 
 namespace {
 
+// TODO(hendrikw): These flags can not be hard coded.
 constexpr int kUncachedBlobUsageFlags = GRALLOC_USAGE_SW_READ_RARELY |
                                         GRALLOC_USAGE_SW_WRITE_RARELY |
                                         GRALLOC_USAGE_PRIVATE_UNCACHED;
@@ -110,6 +111,7 @@
 int BufferHubBuffer::GetBlobReadWritePointer(size_t size, void** addr) {
   int width = static_cast<int>(size);
   int height = 1;
+  // TODO(hendrikw): These flags can not be hard coded.
   constexpr int usage = GRALLOC_USAGE_SW_READ_RARELY |
                         GRALLOC_USAGE_SW_WRITE_RARELY |
                         GRALLOC_USAGE_PRIVATE_UNCACHED;
diff --git a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
index 05af7c0..b6302f1 100644
--- a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
+++ b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
@@ -38,6 +38,7 @@
     }
   }
   NativeBufferHandle(NativeBufferHandle&& other) = default;
+  NativeBufferHandle& operator=(NativeBufferHandle&& other) = default;
 
   // Imports the native handle into the given IonBuffer instance.
   int Import(IonBuffer* buffer) {
@@ -93,6 +94,9 @@
   void operator=(const NativeBufferHandle&) = delete;
 };
 
+using BorrowedNativeBufferHandle = NativeBufferHandle<pdx::BorrowedHandle>;
+using LocalNativeBufferHandle = NativeBufferHandle<pdx::LocalHandle>;
+
 template <typename FileHandleType>
 class FenceHandle {
  public:
diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp
index 6d39cdb..ef50a0f 100644
--- a/libs/vr/libdisplay/display_client.cpp
+++ b/libs/vr/libdisplay/display_client.cpp
@@ -216,7 +216,8 @@
   return 0;
 }
 
-pdx::Status<void> DisplayClient::SetViewerParams(const ViewerParams& viewer_params) {
+pdx::Status<void> DisplayClient::SetViewerParams(
+    const ViewerParams& viewer_params) {
   auto status = InvokeRemoteMethod<DisplayRPC::SetViewerParams>(viewer_params);
   if (!status) {
     ALOGE("DisplayClient::SetViewerParams: Failed to set viewer params: %s",
@@ -252,16 +253,20 @@
   return DisplaySurfaceClient::Create(width, height, format, usage, flags);
 }
 
-std::unique_ptr<BufferConsumer> DisplayClient::GetPoseBuffer() {
-  auto status = InvokeRemoteMethod<DisplayRPC::GetPoseBuffer>();
+std::unique_ptr<IonBuffer> DisplayClient::GetNamedBuffer(
+    const std::string& name) {
+  auto status = InvokeRemoteMethod<DisplayRPC::GetNamedBuffer>(name);
   if (!status) {
     ALOGE(
-        "DisplayClient::GetPoseBuffer: Failed to get pose buffer %s",
-        status.GetErrorMessage().c_str());
+        "DisplayClient::GetNamedBuffer: Failed to get pose buffer. name=%s, "
+        "error=%s",
+        name.c_str(), status.GetErrorMessage().c_str());
     return nullptr;
   }
 
-  return BufferConsumer::Import(std::move(status));
+  auto ion_buffer = std::make_unique<IonBuffer>();
+  status.take().Import(ion_buffer.get());
+  return ion_buffer;
 }
 
 bool DisplayClient::IsVrAppRunning() {
diff --git a/libs/vr/libdisplay/display_manager_client_impl.cpp b/libs/vr/libdisplay/display_manager_client_impl.cpp
index 7993fce..44b3c4b 100644
--- a/libs/vr/libdisplay/display_manager_client_impl.cpp
+++ b/libs/vr/libdisplay/display_manager_client_impl.cpp
@@ -31,19 +31,22 @@
   return 0;
 }
 
-std::unique_ptr<BufferProducer> DisplayManagerClient::SetupPoseBuffer(
-    size_t extended_region_size, int usage) {
-  auto status = InvokeRemoteMethod<DisplayManagerRPC::SetupPoseBuffer>(
-      extended_region_size, usage);
+std::unique_ptr<IonBuffer> DisplayManagerClient::SetupNamedBuffer(
+    const std::string& name, size_t size, uint64_t producer_usage,
+    uint64_t consumer_usage) {
+  auto status = InvokeRemoteMethod<DisplayManagerRPC::SetupNamedBuffer>(
+      name, size, producer_usage, consumer_usage);
   if (!status) {
     ALOGE(
-        "DisplayManagerClient::SetupPoseBuffer: Failed to create the pose "
-        "buffer %s",
-        status.GetErrorMessage().c_str());
+        "DisplayManagerClient::SetupNamedBuffer: Failed to create the named "
+        "buffer: name=%s, error=%s",
+        name.c_str(), status.GetErrorMessage().c_str());
     return {};
   }
 
-  return BufferProducer::Import(std::move(status));
+  auto ion_buffer = std::make_unique<IonBuffer>();
+  status.take().Import(ion_buffer.get());
+  return ion_buffer;
 }
 
 }  // namespace dvr
diff --git a/libs/vr/libdisplay/include/private/dvr/display_client.h b/libs/vr/libdisplay/include/private/dvr/display_client.h
index 378f67c..fec2ea5 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_client.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_client.h
@@ -108,7 +108,7 @@
   std::unique_ptr<DisplaySurfaceClient> CreateDisplaySurface(
       int width, int height, int format, int usage, int flags);
 
-  std::unique_ptr<BufferConsumer> GetPoseBuffer();
+  std::unique_ptr<IonBuffer> GetNamedBuffer(const std::string& name);
 
   // Temporary query for current VR status. Will be removed later.
   bool IsVrAppRunning();
diff --git a/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h b/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h
index 144cd3b..b0a7d13 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h
@@ -17,8 +17,10 @@
 
   int GetSurfaceList(std::vector<DisplaySurfaceInfo>* surface_list);
 
-  std::unique_ptr<BufferProducer> SetupPoseBuffer(size_t extended_region_size,
-                                                  int usage);
+  std::unique_ptr<IonBuffer> SetupNamedBuffer(const std::string& name,
+                                              size_t size,
+                                              uint64_t producer_usage,
+                                              uint64_t consumer_usage);
 
   using Client::event_fd;
   using Client::GetChannel;
diff --git a/libs/vr/libdisplay/include/private/dvr/display_rpc.h b/libs/vr/libdisplay/include/private/dvr/display_rpc.h
index ac08650..c12b090 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_rpc.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_rpc.h
@@ -9,6 +9,7 @@
 #include <pdx/rpc/remote_method.h>
 #include <pdx/rpc/serializable.h>
 #include <pdx/rpc/variant.h>
+#include <private/dvr/bufferhub_rpc.h>
 #include <private/dvr/display_types.h>
 
 namespace android {
@@ -218,7 +219,7 @@
     kOpCreateVideoMeshSurface,
     kOpVideoMeshSurfaceCreateProducerQueue,
     kOpSetViewerParams,
-    kOpGetPoseBuffer,
+    kOpGetNamedBuffer,
     kOpIsVrAppRunning,
   };
 
@@ -247,8 +248,8 @@
                     LocalChannelHandle(Void));
   PDX_REMOTE_METHOD(SetViewerParams, kOpSetViewerParams,
                     void(const ViewerParams& viewer_params));
-  PDX_REMOTE_METHOD(GetPoseBuffer, kOpGetPoseBuffer,
-                    LocalChannelHandle(Void));
+  PDX_REMOTE_METHOD(GetNamedBuffer, kOpGetNamedBuffer,
+                    LocalNativeBufferHandle(const std::string& name));
   PDX_REMOTE_METHOD(IsVrAppRunning, kOpIsVrAppRunning, int(Void));
 };
 
@@ -260,7 +261,7 @@
   enum {
     kOpGetSurfaceList = 0,
     kOpUpdateSurfaces,
-    kOpSetupPoseBuffer,
+    kOpSetupNamedBuffer,
   };
 
   // Aliases.
@@ -273,8 +274,11 @@
   PDX_REMOTE_METHOD(
       UpdateSurfaces, kOpUpdateSurfaces,
       int(const std::map<int, DisplaySurfaceAttributes>& updates));
-  PDX_REMOTE_METHOD(SetupPoseBuffer, kOpSetupPoseBuffer,
-                    LocalChannelHandle(size_t extended_region_size, int usage));
+  PDX_REMOTE_METHOD(SetupNamedBuffer, kOpSetupNamedBuffer,
+                    LocalNativeBufferHandle(const std::string& name,
+                                            size_t size,
+                                            uint64_t producer_usage,
+                                            uint64_t consumer_usage));
 };
 
 struct ScreenshotData {
diff --git a/libs/vr/libdvr/display_manager_client.cpp b/libs/vr/libdvr/display_manager_client.cpp
index 7cbfc21..9247d53 100644
--- a/libs/vr/libdvr/display_manager_client.cpp
+++ b/libs/vr/libdvr/display_manager_client.cpp
@@ -42,14 +42,16 @@
   delete client;
 }
 
-DvrWriteBuffer* dvrDisplayManagerSetupPoseBuffer(
-    DvrDisplayManagerClient* client, size_t extended_region_size,
-    uint64_t usage0, uint64_t usage1) {
-  // TODO(hendrikw): When we move to gralloc1, pass both usage0 and usage1 down.
-  auto buffer_producer = client->client->SetupPoseBuffer(
-      extended_region_size, static_cast<int>(usage0));
-  if (buffer_producer) {
-    return CreateDvrWriteBufferFromBufferProducer(std::move(buffer_producer));
+DvrBuffer* dvrDisplayManagerSetupNamedBuffer(DvrDisplayManagerClient* client,
+                                             const char* name, size_t size,
+                                             uint64_t producer_usage,
+                                             uint64_t consumer_usage) {
+  // TODO(hendrikw): When we move to gralloc1, pass both producer_usage and
+  // consumer_usage down.
+  auto ion_buffer = client->client->SetupNamedBuffer(name, size, producer_usage,
+                                                     consumer_usage);
+  if (ion_buffer) {
+    return CreateDvrBufferFromIonBuffer(std::move(ion_buffer));
   }
   return nullptr;
 }
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
index 49702fd..b91de8f 100644
--- a/libs/vr/libdvr/dvr_api.cpp
+++ b/libs/vr/libdvr/dvr_api.cpp
@@ -31,8 +31,8 @@
         dvrDisplayManagerClientGetSurfaceList;
     dvr_api->display_manager_client_surface_list_destroy =
         dvrDisplayManagerClientSurfaceListDestroy;
-    dvr_api->display_manager_setup_pose_buffer =
-        dvrDisplayManagerSetupPoseBuffer;
+    dvr_api->display_manager_setup_named_buffer =
+        dvrDisplayManagerSetupNamedBuffer;
     dvr_api->display_manager_client_surface_list_get_size =
         dvrDisplayManagerClientSurfaceListGetSize;
     dvr_api->display_manager_client_surface_list_get_surface_id =
@@ -48,7 +48,6 @@
 
     // dvr_buffer.h
     dvr_api->write_buffer_destroy = dvrWriteBufferDestroy;
-    dvr_api->write_buffer_get_blob_fds = dvrWriteBufferGetBlobFds;
     dvr_api->write_buffer_get_ahardwarebuffer =
         dvrWriteBufferGetAHardwareBuffer;
     dvr_api->write_buffer_post = dvrWriteBufferPost;
@@ -56,11 +55,12 @@
     dvr_api->write_buffer_gain_async = dvrWriteBufferGainAsync;
 
     dvr_api->read_buffer_destroy = dvrReadBufferDestroy;
-    dvr_api->read_buffer_get_blob_fds = dvrReadBufferGetBlobFds;
     dvr_api->read_buffer_get_ahardwarebuffer = dvrReadBufferGetAHardwareBuffer;
     dvr_api->read_buffer_acquire = dvrReadBufferAcquire;
     dvr_api->read_buffer_release = dvrReadBufferRelease;
     dvr_api->read_buffer_release_async = dvrReadBufferReleaseAsync;
+    dvr_api->buffer_destroy = dvrBufferDestroy;
+    dvr_api->buffer_get_ahardwarebuffer = dvrBufferGetAHardwareBuffer;
 
     // dvr_buffer_queue.h
     dvr_api->write_buffer_queue_destroy = dvrWriteBufferQueueDestroy;
@@ -77,7 +77,7 @@
     dvr_api->read_buffer_queue_dequeue = dvrReadBufferQueueDequeue;
 
     // dvr_surface.h
-    dvr_api->get_pose_buffer = dvrGetPoseBuffer;
+    dvr_api->get_named_buffer = dvrGetNamedBuffer;
     dvr_api->surface_create = dvrSurfaceCreate;
     dvr_api->surface_get_write_buffer_queue = dvrSurfaceGetWriteBufferQueue;
 
diff --git a/libs/vr/libdvr/dvr_buffer.cpp b/libs/vr/libdvr/dvr_buffer.cpp
index 25128a6..0942b3d 100644
--- a/libs/vr/libdvr/dvr_buffer.cpp
+++ b/libs/vr/libdvr/dvr_buffer.cpp
@@ -6,13 +6,15 @@
 using namespace android;
 
 struct DvrWriteBuffer {
-  std::shared_ptr<dvr::BufferProducer> write_buffer_;
-  sp<GraphicBuffer> graphic_buffer_;
+  std::shared_ptr<dvr::BufferProducer> write_buffer;
 };
 
 struct DvrReadBuffer {
-  std::shared_ptr<dvr::BufferConsumer> read_buffer_;
-  sp<GraphicBuffer> graphic_buffer_;
+  std::shared_ptr<dvr::BufferConsumer> read_buffer;
+};
+
+struct DvrBuffer {
+  std::shared_ptr<dvr::IonBuffer> buffer;
 };
 
 namespace android {
@@ -20,16 +22,23 @@
 
 DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
     const std::shared_ptr<dvr::BufferProducer>& buffer_producer) {
-  DvrWriteBuffer* write_buffer = new DvrWriteBuffer;
-  write_buffer->write_buffer_ = std::move(buffer_producer);
-  return write_buffer;
+  if (!buffer_producer)
+    return nullptr;
+  return new DvrWriteBuffer{std::move(buffer_producer)};
 }
 
 DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
     const std::shared_ptr<dvr::BufferConsumer>& buffer_consumer) {
-  DvrReadBuffer* read_buffer = new DvrReadBuffer;
-  read_buffer->read_buffer_ = std::move(buffer_consumer);
-  return read_buffer;
+  if (!buffer_consumer)
+    return nullptr;
+  return new DvrReadBuffer{std::move(buffer_consumer)};
+}
+
+DvrBuffer* CreateDvrBufferFromIonBuffer(
+    const std::shared_ptr<IonBuffer>& ion_buffer) {
+  if (!ion_buffer)
+    return nullptr;
+  return new DvrBuffer{std::move(ion_buffer)};
 }
 
 }  // namespace dvr
@@ -49,79 +58,82 @@
 
 extern "C" {
 
-void dvrWriteBufferDestroy(DvrWriteBuffer* client) { delete client; }
-
-void dvrWriteBufferGetBlobFds(DvrWriteBuffer* client, int* fds,
-                              size_t* fds_count, size_t max_fds_count) {
-  client->write_buffer_->GetBlobFds(fds, fds_count, max_fds_count);
+void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer) {
+  delete write_buffer;
 }
 
-int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* client,
+int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer) {
+  return write_buffer->write_buffer->id();
+}
+
+int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
                                      AHardwareBuffer** hardware_buffer) {
-  if (!client->graphic_buffer_.get()) {
-    InitializeGraphicBuffer(client->write_buffer_.get(),
-                            &client->graphic_buffer_);
-  }
-  *hardware_buffer =
-      reinterpret_cast<AHardwareBuffer*>(client->graphic_buffer_.get());
+  *hardware_buffer = reinterpret_cast<AHardwareBuffer*>(
+      write_buffer->write_buffer->buffer()->buffer().get());
   return 0;
 }
 
-int dvrWriteBufferPost(DvrWriteBuffer* client, int ready_fence_fd,
+int dvrWriteBufferPost(DvrWriteBuffer* write_buffer, int ready_fence_fd,
                        const void* meta, size_t meta_size_bytes) {
   pdx::LocalHandle fence(ready_fence_fd);
-  int result = client->write_buffer_->Post(fence, meta, meta_size_bytes);
-  fence.Release();
+  int result = write_buffer->write_buffer->Post(fence, meta, meta_size_bytes);
   return result;
 }
 
-int dvrWriteBufferGain(DvrWriteBuffer* client, int* release_fence_fd) {
+int dvrWriteBufferGain(DvrWriteBuffer* write_buffer, int* release_fence_fd) {
   pdx::LocalHandle release_fence;
-  int result = client->write_buffer_->Gain(&release_fence);
+  int result = write_buffer->write_buffer->Gain(&release_fence);
   *release_fence_fd = release_fence.Release();
   return result;
 }
 
-int dvrWriteBufferGainAsync(DvrWriteBuffer* client) {
-  return client->write_buffer_->GainAsync();
+int dvrWriteBufferGainAsync(DvrWriteBuffer* write_buffer) {
+  return write_buffer->write_buffer->GainAsync();
 }
 
-void dvrReadBufferDestroy(DvrReadBuffer* client) { delete client; }
+void dvrReadBufferDestroy(DvrReadBuffer* read_buffer) { delete read_buffer; }
 
-void dvrReadBufferGetBlobFds(DvrReadBuffer* client, int* fds, size_t* fds_count,
-                             size_t max_fds_count) {
-  client->read_buffer_->GetBlobFds(fds, fds_count, max_fds_count);
+int dvrReadBufferGetId(DvrReadBuffer* read_buffer) {
+  return read_buffer->read_buffer->id();
 }
 
-int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* client,
+int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
                                     AHardwareBuffer** hardware_buffer) {
-  if (!client->graphic_buffer_.get()) {
-    InitializeGraphicBuffer(client->read_buffer_.get(),
-                            &client->graphic_buffer_);
-  }
-  *hardware_buffer =
-      reinterpret_cast<AHardwareBuffer*>(client->graphic_buffer_.get());
+  *hardware_buffer = reinterpret_cast<AHardwareBuffer*>(
+      read_buffer->read_buffer->buffer()->buffer().get());
   return 0;
 }
 
-int dvrReadBufferAcquire(DvrReadBuffer* client, int* ready_fence_fd, void* meta,
-                         size_t meta_size_bytes) {
+int dvrReadBufferAcquire(DvrReadBuffer* read_buffer, int* ready_fence_fd,
+                         void* meta, size_t meta_size_bytes) {
   pdx::LocalHandle ready_fence;
   int result =
-      client->read_buffer_->Acquire(&ready_fence, meta, meta_size_bytes);
+      read_buffer->read_buffer->Acquire(&ready_fence, meta, meta_size_bytes);
   *ready_fence_fd = ready_fence.Release();
   return result;
 }
 
-int dvrReadBufferRelease(DvrReadBuffer* client, int release_fence_fd) {
+int dvrReadBufferRelease(DvrReadBuffer* read_buffer, int release_fence_fd) {
   pdx::LocalHandle fence(release_fence_fd);
-  int result = client->read_buffer_->Release(fence);
-  fence.Release();
+  int result = read_buffer->read_buffer->Release(fence);
   return result;
 }
 
-int dvrReadBufferReleaseAsync(DvrReadBuffer* client) {
-  return client->read_buffer_->ReleaseAsync();
+int dvrReadBufferReleaseAsync(DvrReadBuffer* read_buffer) {
+  return read_buffer->read_buffer->ReleaseAsync();
+}
+
+void dvrBufferDestroy(DvrBuffer* buffer) { delete buffer; }
+
+int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
+                                AHardwareBuffer** hardware_buffer) {
+  if (!hardware_buffer) {
+    return -EINVAL;
+  }
+
+  *hardware_buffer =
+      reinterpret_cast<AHardwareBuffer*>(buffer->buffer->buffer().get());
+  return 0;
 }
 
 }  // extern "C"
diff --git a/libs/vr/libdvr/dvr_surface.cpp b/libs/vr/libdvr/dvr_surface.cpp
index a3cbba5..a04ed50 100644
--- a/libs/vr/libdvr/dvr_surface.cpp
+++ b/libs/vr/libdvr/dvr_surface.cpp
@@ -58,14 +58,25 @@
   return 0;
 }
 
-int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer) {
+int dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer) {
   auto client = android::dvr::DisplayClient::Create();
   if (!client) {
-    ALOGE("Failed to create display client!");
+    ALOGE("dvrGetNamedBuffer: Failed to create display client!");
     return -ECOMM;
   }
 
-  *pose_buffer = CreateDvrReadBufferFromBufferConsumer(client->GetPoseBuffer());
+  if (out_buffer == nullptr || name == nullptr) {
+    ALOGE("dvrGetNamedBuffer: Invalid inputs: name=%p, out_buffer=%p.", name,
+          out_buffer);
+    return -EINVAL;
+  }
+
+  auto named_buffer = client->GetNamedBuffer(name);
+  if (!named_buffer) {
+    ALOGE("dvrGetNamedBuffer: Failed to find named buffer: %s.", name);
+    return -EINVAL;
+  }
+  *out_buffer = CreateDvrBufferFromIonBuffer(std::move(named_buffer));
   return 0;
 }
 
diff --git a/libs/vr/libdvr/include/dvr/display_manager_client.h b/libs/vr/libdvr/include/dvr/display_manager_client.h
index 0928d43..4e1f227 100644
--- a/libs/vr/libdvr/include/dvr/display_manager_client.h
+++ b/libs/vr/libdvr/include/dvr/display_manager_client.h
@@ -14,15 +14,16 @@
     DvrDisplayManagerClientSurfaceList;
 typedef struct DvrDisplayManagerClientSurfaceBuffers
     DvrDisplayManagerClientSurfaceBuffers;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
+typedef struct DvrBuffer DvrBuffer;
 
 DvrDisplayManagerClient* dvrDisplayManagerClientCreate();
 
 void dvrDisplayManagerClientDestroy(DvrDisplayManagerClient* client);
 
-DvrWriteBuffer* dvrDisplayManagerSetupPoseBuffer(
-    DvrDisplayManagerClient* client, size_t extended_region_size,
-    uint64_t usage0, uint64_t usage1);
+DvrBuffer* dvrDisplayManagerSetupNamedBuffer(DvrDisplayManagerClient* client,
+                                             const char* name, size_t size,
+                                             uint64_t producer_usage,
+                                             uint64_t consumer_usage);
 
 // Return an event fd for checking if there was an event on the server
 // Note that the only event which will be flagged is POLLIN. You must use
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index a4fef19..c46684b 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -30,6 +30,7 @@
 
 typedef struct DvrWriteBuffer DvrWriteBuffer;
 typedef struct DvrReadBuffer DvrReadBuffer;
+typedef struct DvrBuffer DvrBuffer;
 typedef struct AHardwareBuffer AHardwareBuffer;
 
 typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
@@ -43,9 +44,9 @@
     DvrDisplayManagerClientSurfaceList** surface_list);
 typedef void (*DvrDisplayManagerClientSurfaceListDestroyPtr)(
     DvrDisplayManagerClientSurfaceList* surface_list);
-typedef DvrWriteBuffer* (*DvrDisplayManagerSetupPoseBufferPtr)(
-    DvrDisplayManagerClient* client, size_t extended_region_size,
-    uint64_t usage0, uint64_t usage1);
+typedef DvrBuffer* (*DvrDisplayManagerSetupNamedBufferPtr)(
+    DvrDisplayManagerClient* client, const char* name, size_t size,
+    uint64_t producer_usage, uint64_t consumer_usage);
 typedef size_t (*DvrDisplayManagerClientSurfaceListGetSizePtr)(
     DvrDisplayManagerClientSurfaceList* surface_list);
 typedef int (*DvrDisplayManagerClientSurfaceListGetSurfaceIdPtr)(
@@ -62,9 +63,6 @@
 
 // dvr_buffer.h
 typedef void (*DvrWriteBufferDestroyPtr)(DvrWriteBuffer* client);
-typedef void (*DvrWriteBufferGetBlobFdsPtr)(DvrWriteBuffer* client, int* fds,
-                                            size_t* fds_count,
-                                            size_t max_fds_count);
 typedef int (*DvrWriteBufferGetAHardwareBufferPtr)(
     DvrWriteBuffer* client, AHardwareBuffer** hardware_buffer);
 typedef int (*DvrWriteBufferPostPtr)(DvrWriteBuffer* client, int ready_fence_fd,
@@ -74,9 +72,6 @@
 typedef int (*DvrWriteBufferGainAsyncPtr)(DvrWriteBuffer* client);
 
 typedef void (*DvrReadBufferDestroyPtr)(DvrReadBuffer* client);
-typedef void (*DvrReadBufferGetBlobFdsPtr)(DvrReadBuffer* client, int* fds,
-                                           size_t* fds_count,
-                                           size_t max_fds_count);
 typedef int (*DvrReadBufferGetAHardwareBufferPtr)(
     DvrReadBuffer* client, AHardwareBuffer** hardware_buffer);
 typedef int (*DvrReadBufferAcquirePtr)(DvrReadBuffer* client,
@@ -85,6 +80,9 @@
 typedef int (*DvrReadBufferReleasePtr)(DvrReadBuffer* client,
                                        int release_fence_fd);
 typedef int (*DvrReadBufferReleaseAsyncPtr)(DvrReadBuffer* client);
+typedef void (*DvrBufferDestroy)(DvrBuffer* buffer);
+typedef int (*DvrBufferGetAHardwareBuffer)(DvrBuffer* buffer,
+                                           AHardwareBuffer** hardware_buffer);
 
 // dvr_buffer_queue.h
 typedef void (*DvrWriteBufferQueueDestroyPtr)(DvrWriteBufferQueue* write_queue);
@@ -110,7 +108,7 @@
                                             size_t meta_size_bytes);
 
 // dvr_surface.h
-typedef int (*DvrGetPoseBufferPtr)(DvrReadBuffer** pose_buffer);
+typedef int (*DvrGetNamedBufferPtr)(const char* name, DvrBuffer** out_buffer);
 typedef int (*DvrSurfaceCreatePtr)(int width, int height, int format,
                                    uint64_t usage0, uint64_t usage1, int flags,
                                    DvrSurface** out_surface);
@@ -149,7 +147,7 @@
 // dvr_hardware_composer_client.h
 typedef struct DvrHwcClient DvrHwcClient;
 typedef struct DvrHwcFrame DvrHwcFrame;
-typedef int(*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
+typedef int (*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
 typedef DvrHwcClient* (*DvrHwcClientCreatePtr)(DvrHwcOnFrameCallback callback,
                                                void* client_state);
 typedef void (*DvrHwcClientDestroyPtr)(DvrHwcClient* client);
@@ -159,7 +157,8 @@
 typedef int32_t (*DvrHwcFrameGetDisplayHeightPtr)(DvrHwcFrame* frame);
 typedef bool (*DvrHwcFrameGetDisplayRemovedPtr)(DvrHwcFrame* frame);
 typedef size_t (*DvrHwcFrameGetLayerCountPtr)(DvrHwcFrame* frame);
-typedef Layer (*DvrHwcFrameGetLayerIdPtr)(DvrHwcFrame* frame, size_t layer_index);
+typedef Layer (*DvrHwcFrameGetLayerIdPtr)(DvrHwcFrame* frame,
+                                          size_t layer_index);
 typedef AHardwareBuffer* (*DvrHwcFrameGetLayerBufferPtr)(DvrHwcFrame* frame,
                                                          size_t layer_index);
 typedef int (*DvrHwcFrameGetLayerFencePtr)(DvrHwcFrame* frame,
@@ -185,7 +184,7 @@
       display_manager_client_get_surface_list;
   DvrDisplayManagerClientSurfaceListDestroyPtr
       display_manager_client_surface_list_destroy;
-  DvrDisplayManagerSetupPoseBufferPtr display_manager_setup_pose_buffer;
+  DvrDisplayManagerSetupNamedBufferPtr display_manager_setup_named_buffer;
   DvrDisplayManagerClientSurfaceListGetSizePtr
       display_manager_client_surface_list_get_size;
   DvrDisplayManagerClientSurfaceListGetSurfaceIdPtr
@@ -201,7 +200,6 @@
 
   // Write buffer
   DvrWriteBufferDestroyPtr write_buffer_destroy;
-  DvrWriteBufferGetBlobFdsPtr write_buffer_get_blob_fds;
   DvrWriteBufferGetAHardwareBufferPtr write_buffer_get_ahardwarebuffer;
   DvrWriteBufferPostPtr write_buffer_post;
   DvrWriteBufferGainPtr write_buffer_gain;
@@ -209,11 +207,12 @@
 
   // Read buffer
   DvrReadBufferDestroyPtr read_buffer_destroy;
-  DvrReadBufferGetBlobFdsPtr read_buffer_get_blob_fds;
   DvrReadBufferGetAHardwareBufferPtr read_buffer_get_ahardwarebuffer;
   DvrReadBufferAcquirePtr read_buffer_acquire;
   DvrReadBufferReleasePtr read_buffer_release;
   DvrReadBufferReleaseAsyncPtr read_buffer_release_async;
+  DvrBufferDestroy buffer_destroy;
+  DvrBufferGetAHardwareBuffer buffer_get_ahardwarebuffer;
 
   // Write buffer queue
   DvrWriteBufferQueueDestroyPtr write_buffer_queue_destroy;
@@ -235,7 +234,7 @@
   DvrVSyncClientGetSchedInfoPtr vsync_client_get_sched_info;
 
   // Display surface
-  DvrGetPoseBufferPtr get_pose_buffer;
+  DvrGetNamedBufferPtr get_named_buffer;
   DvrSurfaceCreatePtr surface_create;
   DvrSurfaceGetWriteBufferQueuePtr surface_get_write_buffer_queue;
 
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer.h b/libs/vr/libdvr/include/dvr/dvr_buffer.h
index bbfbb00..6c9c4d3 100644
--- a/libs/vr/libdvr/include/dvr/dvr_buffer.h
+++ b/libs/vr/libdvr/include/dvr/dvr_buffer.h
@@ -1,9 +1,9 @@
 #ifndef ANDROID_DVR_BUFFER_H_
 #define ANDROID_DVR_BUFFER_H_
 
-#include <memory>
 #include <stdbool.h>
 #include <stdint.h>
+#include <memory>
 
 #ifdef __cplusplus
 extern "C" {
@@ -11,29 +11,33 @@
 
 typedef struct DvrWriteBuffer DvrWriteBuffer;
 typedef struct DvrReadBuffer DvrReadBuffer;
+typedef struct DvrBuffer DvrBuffer;
 typedef struct AHardwareBuffer AHardwareBuffer;
 
 // Write buffer
-void dvrWriteBufferDestroy(DvrWriteBuffer* client);
-void dvrWriteBufferGetBlobFds(DvrWriteBuffer* client, int* fds,
-                              size_t* fds_count, size_t max_fds_count);
-int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* client,
+void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer);
+int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer);
+int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
                                      AHardwareBuffer** hardware_buffer);
-int dvrWriteBufferPost(DvrWriteBuffer* client, int ready_fence_fd,
+int dvrWriteBufferPost(DvrWriteBuffer* write_buffer, int ready_fence_fd,
                        const void* meta, size_t meta_size_bytes);
-int dvrWriteBufferGain(DvrWriteBuffer* client, int* release_fence_fd);
-int dvrWriteBufferGainAsync(DvrWriteBuffer* client);
+int dvrWriteBufferGain(DvrWriteBuffer* write_buffer, int* release_fence_fd);
+int dvrWriteBufferGainAsync(DvrWriteBuffer* write_buffer);
 
 // Read buffer
-void dvrReadBufferDestroy(DvrReadBuffer* client);
-void dvrReadBufferGetBlobFds(DvrReadBuffer* client, int* fds, size_t* fds_count,
-                             size_t max_fds_count);
-int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* client,
+void dvrReadBufferDestroy(DvrReadBuffer* read_buffer);
+int dvrReadBufferGetId(DvrReadBuffer* read_buffer);
+int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
                                     AHardwareBuffer** hardware_buffer);
-int dvrReadBufferAcquire(DvrReadBuffer* client, int* ready_fence_fd, void* meta,
-                         size_t meta_size_bytes);
-int dvrReadBufferRelease(DvrReadBuffer* client, int release_fence_fd);
-int dvrReadBufferReleaseAsync(DvrReadBuffer* client);
+int dvrReadBufferAcquire(DvrReadBuffer* read_buffer, int* ready_fence_fd,
+                         void* meta, size_t meta_size_bytes);
+int dvrReadBufferRelease(DvrReadBuffer* read_buffer, int release_fence_fd);
+int dvrReadBufferReleaseAsync(DvrReadBuffer* read_buffer);
+
+// Buffer
+void dvrBufferDestroy(DvrBuffer* buffer);
+int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
+                                AHardwareBuffer** hardware_buffer);
 
 #ifdef __cplusplus
 }  // extern "C"
@@ -44,11 +48,14 @@
 
 class BufferProducer;
 class BufferConsumer;
+class IonBuffer;
 
 DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
     const std::shared_ptr<BufferProducer>& buffer_producer);
 DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
     const std::shared_ptr<BufferConsumer>& buffer_consumer);
+DvrBuffer* CreateDvrBufferFromIonBuffer(
+    const std::shared_ptr<IonBuffer>& ion_buffer);
 
 }  // namespace dvr
 }  // namespace android
diff --git a/libs/vr/libdvr/include/dvr/dvr_surface.h b/libs/vr/libdvr/include/dvr/dvr_surface.h
index 2712f24..e5228d6 100644
--- a/libs/vr/libdvr/include/dvr/dvr_surface.h
+++ b/libs/vr/libdvr/include/dvr/dvr_surface.h
@@ -12,7 +12,7 @@
 typedef struct DvrSurfaceParameter DvrSurfaceParameter;
 
 // Get a pointer to the global pose buffer.
-int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer);
+int dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer);
 
 int dvrSurfaceCreate(int width, int height, int format, uint64_t usage0,
                      uint64_t usage1, int flags, DvrSurface** out_surface);
diff --git a/libs/vr/libdvr/tests/Android.mk b/libs/vr/libdvr/tests/Android.mk
index 75e2a7d..29cdc13 100644
--- a/libs/vr/libdvr/tests/Android.mk
+++ b/libs/vr/libdvr/tests/Android.mk
@@ -17,14 +17,18 @@
     libbufferhub \
     libchrome \
     libdvrcommon \
+    libdisplay \
     libpdx_default_transport \
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := dvr_buffer_queue-test.cpp
+LOCAL_SRC_FILES := \
+    dvr_buffer_queue-test.cpp \
+    dvr_named_buffer-test.cpp \
+
 LOCAL_STATIC_LIBRARIES := $(static_libraries)
 LOCAL_SHARED_LIBRARIES := $(shared_libraries)
 LOCAL_EXPORT_C_INCLUDE_DIRS := ${LOCAL_C_INCLUDES}
-LOCAL_CFLAGS := -DLOG_TAG=\"dvr_buffer_queue-test\" -DTRACE=0 -O0 -g
-LOCAL_MODULE := dvr_buffer_queue-test
+LOCAL_CFLAGS := -DLOG_TAG=\"dvr_api-test\" -DTRACE=0 -O0 -g
+LOCAL_MODULE := dvr_api-test
 LOCAL_MODULE_TAGS := optional
 include $(BUILD_NATIVE_TEST)
diff --git a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
new file mode 100644
index 0000000..cd3285f
--- /dev/null
+++ b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
@@ -0,0 +1,122 @@
+#include <android/hardware_buffer.h>
+#include <dvr/display_manager_client.h>
+#include <dvr/dvr_buffer.h>
+#include <dvr/dvr_surface.h>
+#include <system/graphics.h>
+
+#include <base/logging.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace dvr {
+
+namespace {
+
+class DvrNamedBufferTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    client_ = dvrDisplayManagerClientCreate();
+    ASSERT_NE(nullptr, client_);
+  }
+
+  void TearDown() override {
+    if (client_ != nullptr) {
+      dvrDisplayManagerClientDestroy(client_);
+      client_ = nullptr;
+    }
+  }
+
+  DvrDisplayManagerClient* client_ = nullptr;
+};
+
+TEST_F(DvrNamedBufferTest, TestNamedBuffersSameName) {
+  const char* buffer_name = "same_name";
+  DvrBuffer* buffer1 =
+      dvrDisplayManagerSetupNamedBuffer(client_, buffer_name, 10, 0, 0);
+  ASSERT_NE(nullptr, buffer1);
+
+  DvrBuffer* buffer2 =
+      dvrDisplayManagerSetupNamedBuffer(client_, buffer_name, 10, 0, 0);
+  ASSERT_NE(nullptr, buffer2);
+
+  AHardwareBuffer* hardware_buffer1 = nullptr;
+  int e1 = dvrBufferGetAHardwareBuffer(buffer1, &hardware_buffer1);
+  ASSERT_EQ(0, e1);
+
+  AHardwareBuffer* hardware_buffer2 = nullptr;
+  int e2 = dvrBufferGetAHardwareBuffer(buffer2, &hardware_buffer2);
+  ASSERT_EQ(0, e2);
+  ASSERT_NE(nullptr, hardware_buffer1);
+
+  AHardwareBuffer_Desc desc1 = {};
+  AHardwareBuffer_describe(hardware_buffer1, &desc1);
+  AHardwareBuffer_Desc desc2 = {};
+  AHardwareBuffer_describe(hardware_buffer2, &desc2);
+  ASSERT_EQ(desc1.width, 10u);
+  ASSERT_EQ(desc1.height, 1u);
+  ASSERT_EQ(desc1.layers, 1u);
+  ASSERT_EQ(desc1.format, HAL_PIXEL_FORMAT_BLOB);
+  ASSERT_EQ(desc1.usage0, 0u);
+  ASSERT_EQ(desc1.usage1, 0u);
+  ASSERT_EQ(desc2.width, 10u);
+  ASSERT_EQ(desc2.height, 1u);
+  ASSERT_EQ(desc2.layers, 1u);
+  ASSERT_EQ(desc2.format, HAL_PIXEL_FORMAT_BLOB);
+  ASSERT_EQ(desc2.usage0, 0u);
+  ASSERT_EQ(desc2.usage1, 0u);
+
+  dvrBufferDestroy(buffer1);
+  dvrBufferDestroy(buffer2);
+
+  DvrBuffer* buffer3 = nullptr;
+  int e3 = dvrGetNamedBuffer(buffer_name, &buffer3);
+  ASSERT_NE(nullptr, buffer3);
+  ASSERT_EQ(0, e3);
+
+  AHardwareBuffer* hardware_buffer3 = nullptr;
+  int e4 = dvrBufferGetAHardwareBuffer(buffer2, &hardware_buffer3);
+  ASSERT_EQ(0, e4);
+  ASSERT_NE(nullptr, hardware_buffer3);
+
+  AHardwareBuffer_Desc desc3 = {};
+  AHardwareBuffer_describe(hardware_buffer3, &desc3);
+  ASSERT_EQ(desc3.width, 10u);
+  ASSERT_EQ(desc3.height, 1u);
+  ASSERT_EQ(desc3.layers, 1u);
+  ASSERT_EQ(desc3.format, HAL_PIXEL_FORMAT_BLOB);
+  ASSERT_EQ(desc3.usage0, 0u);
+  ASSERT_EQ(desc3.usage1, 0u);
+
+  dvrBufferDestroy(buffer3);
+}
+
+TEST_F(DvrNamedBufferTest, TestMultipleNamedBuffers) {
+  const char* buffer_name1 = "test1";
+  const char* buffer_name2 = "test2";
+  DvrBuffer* setup_buffer1 =
+      dvrDisplayManagerSetupNamedBuffer(client_, buffer_name1, 10, 0, 0);
+  ASSERT_NE(nullptr, setup_buffer1);
+  dvrBufferDestroy(setup_buffer1);
+
+  DvrBuffer* setup_buffer2 =
+      dvrDisplayManagerSetupNamedBuffer(client_, buffer_name2, 10, 0, 0);
+  ASSERT_NE(nullptr, setup_buffer2);
+  dvrBufferDestroy(setup_buffer2);
+
+  DvrBuffer* buffer1 = nullptr;
+  int e1 = dvrGetNamedBuffer(buffer_name1, &buffer1);
+  ASSERT_NE(nullptr, buffer1);
+  ASSERT_EQ(0, e1);
+  dvrBufferDestroy(buffer1);
+
+  DvrBuffer* buffer2 = nullptr;
+  int e2 = dvrGetNamedBuffer(buffer_name2, &buffer2);
+  ASSERT_NE(nullptr, buffer2);
+  ASSERT_EQ(0, e2);
+  dvrBufferDestroy(buffer2);
+}
+
+}  // namespace
+
+}  // namespace dvr
+}  // namespace android
diff --git a/libs/vr/libvrflinger/display_manager_service.cpp b/libs/vr/libvrflinger/display_manager_service.cpp
index 49b6f09..99f93bf 100644
--- a/libs/vr/libvrflinger/display_manager_service.cpp
+++ b/libs/vr/libvrflinger/display_manager_service.cpp
@@ -2,7 +2,9 @@
 
 #include <pdx/channel_handle.h>
 #include <pdx/default_transport/service_endpoint.h>
+#include <private/android_filesystem_config.h>
 #include <private/dvr/display_rpc.h>
+#include <private/dvr/trusted_uids.h>
 #include <sys/poll.h>
 
 #include <array>
@@ -82,9 +84,9 @@
           *this, &DisplayManagerService::OnUpdateSurfaces, message);
       return {};
 
-  case DisplayManagerRPC::SetupPoseBuffer::Opcode:
-      DispatchRemoteMethod<DisplayManagerRPC::SetupPoseBuffer>(
-          *this, &DisplayManagerService::OnSetupPoseBuffer, message);
+    case DisplayManagerRPC::SetupNamedBuffer::Opcode:
+      DispatchRemoteMethod<DisplayManagerRPC::SetupNamedBuffer>(
+          *this, &DisplayManagerService::OnSetupNamedBuffer, message);
       return {};
 
     default:
@@ -188,9 +190,20 @@
   return 0;
 }
 
-pdx::BorrowedChannelHandle DisplayManagerService::OnSetupPoseBuffer(
-    pdx::Message& /*message*/, size_t extended_region_size, int usage) {
-  return display_service_->SetupPoseBuffer(extended_region_size, usage);
+pdx::Status<BorrowedNativeBufferHandle>
+DisplayManagerService::OnSetupNamedBuffer(pdx::Message& message,
+                                          const std::string& name, size_t size,
+                                          uint64_t producer_usage,
+                                          uint64_t consumer_usage) {
+  if (message.GetEffectiveUserId() != AID_ROOT &&
+      !IsTrustedUid(message.GetEffectiveUserId())) {
+    // Only trusted users can setup named buffers.
+    ALOGE("DisplayService::SetupNamedBuffer: Called by untrusted user: uid=%d.",
+          message.GetEffectiveUserId());
+    return {};
+  }
+  return display_service_->SetupNamedBuffer(name, size, producer_usage,
+                                            consumer_usage);
 }
 
 void DisplayManagerService::OnDisplaySurfaceChange() {
diff --git a/libs/vr/libvrflinger/display_manager_service.h b/libs/vr/libvrflinger/display_manager_service.h
index 80324fd..7b037de 100644
--- a/libs/vr/libvrflinger/display_manager_service.h
+++ b/libs/vr/libvrflinger/display_manager_service.h
@@ -54,9 +54,9 @@
   int OnUpdateSurfaces(pdx::Message& message,
                        const std::map<int, DisplaySurfaceAttributes>& updates);
 
-  pdx::BorrowedChannelHandle OnSetupPoseBuffer(pdx::Message& message,
-                                               size_t extended_region_size,
-                                               int usage);
+  pdx::Status<BorrowedNativeBufferHandle> OnSetupNamedBuffer(
+      pdx::Message& message, const std::string& name, size_t size,
+      uint64_t producer_usage, uint64_t consumer_usage);
 
   // Called by the display service to indicate changes to display surfaces that
   // the display manager should evaluate.
diff --git a/libs/vr/libvrflinger/display_service.cpp b/libs/vr/libvrflinger/display_service.cpp
index bb8613c..8cf9d64 100644
--- a/libs/vr/libvrflinger/display_service.cpp
+++ b/libs/vr/libvrflinger/display_service.cpp
@@ -1,5 +1,6 @@
 #include "display_service.h"
 
+#include <unistd.h>
 #include <vector>
 
 #include <pdx/default_transport/service_endpoint.h>
@@ -18,20 +19,10 @@
 using android::pdx::rpc::DispatchRemoteMethod;
 using android::pdx::rpc::WrapBuffer;
 
-namespace {
-
-constexpr char kPersistentPoseBufferName[] = "DvrPersistentPoseBuffer";
-const int kPersistentPoseBufferUserId = 0;
-const int kPersistentPoseBufferGroupId = 0;
-const size_t kTimingDataSizeOffset = 128;
-
-}  // anonymous namespace
-
 namespace android {
 namespace dvr {
 
-DisplayService::DisplayService()
-    : DisplayService(nullptr) {}
+DisplayService::DisplayService() : DisplayService(nullptr) {}
 
 DisplayService::DisplayService(Hwc2::Composer* hidl)
     : BASE("DisplayService", Endpoint::Create(DisplayRPC::kClientPath)),
@@ -89,9 +80,9 @@
           *this, &DisplayService::OnSetViewerParams, message);
       return {};
 
-    case DisplayRPC::GetPoseBuffer::Opcode:
-      DispatchRemoteMethod<DisplayRPC::GetPoseBuffer>(
-          *this, &DisplayService::OnGetPoseBuffer, message);
+    case DisplayRPC::GetNamedBuffer::Opcode:
+      DispatchRemoteMethod<DisplayRPC::GetNamedBuffer>(
+          *this, &DisplayService::OnGetNamedBuffer, message);
       return {};
 
     case DisplayRPC::IsVrAppRunning::Opcode:
@@ -254,13 +245,14 @@
   compositor->UpdateHeadMountMetrics(head_mount_metrics);
 }
 
-pdx::LocalChannelHandle DisplayService::OnGetPoseBuffer(pdx::Message& message) {
-  if (pose_buffer_) {
-    return pose_buffer_->CreateConsumer().take();
+pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetNamedBuffer(
+    pdx::Message& /* message */, const std::string& name) {
+  auto named_buffer = named_buffers_.find(name);
+  if (named_buffer != named_buffers_.end()) {
+    return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
   }
 
-  pdx::rpc::RemoteMethodError(message, EAGAIN);
-  return {};
+  return pdx::ErrorStatus(EINVAL);
 }
 
 // Calls the message handler for the DisplaySurface associated with this
@@ -334,16 +326,22 @@
   hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
 }
 
-pdx::BorrowedChannelHandle DisplayService::SetupPoseBuffer(
-    size_t extended_region_size, int usage) {
-  if (!pose_buffer_) {
-    pose_buffer_ = BufferProducer::Create(
-        kPersistentPoseBufferName, kPersistentPoseBufferUserId,
-        kPersistentPoseBufferGroupId, usage,
-        extended_region_size + kTimingDataSizeOffset);
+pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupNamedBuffer(
+    const std::string& name, size_t size, int producer_usage,
+    int consumer_usage) {
+  auto named_buffer = named_buffers_.find(name);
+  if (named_buffer == named_buffers_.end()) {
+    // TODO(hendrikw): Update BufferProducer to take producer_usage and
+    // consumer_usage flags.
+    auto ion_buffer = std::make_unique<IonBuffer>(
+        static_cast<int>(size), 1, HAL_PIXEL_FORMAT_BLOB,
+        producer_usage | consumer_usage);
+    named_buffer =
+        named_buffers_.insert(std::make_pair(name, std::move(ion_buffer)))
+            .first;
   }
 
-  return pose_buffer_->GetChannelHandle().Borrow();
+  return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
 }
 
 void DisplayService::OnHardwareComposerRefresh() {
@@ -362,10 +360,11 @@
 
 int DisplayService::IsVrAppRunning(pdx::Message& message) {
   bool visible = false;
-  ForEachDisplaySurface([&visible](const std::shared_ptr<DisplaySurface>& surface) {
-    if (surface->client_z_order() == 0 && surface->IsVisible())
-      visible = true;
-  });
+  ForEachDisplaySurface(
+      [&visible](const std::shared_ptr<DisplaySurface>& surface) {
+        if (surface->client_z_order() == 0 && surface->IsVisible())
+          visible = true;
+      });
 
   REPLY_SUCCESS_RETURN(message, visible, 0);
 }
diff --git a/libs/vr/libvrflinger/display_service.h b/libs/vr/libvrflinger/display_service.h
index da80a84..db89064 100644
--- a/libs/vr/libvrflinger/display_service.h
+++ b/libs/vr/libvrflinger/display_service.h
@@ -3,6 +3,7 @@
 
 #include <pdx/service.h>
 #include <private/dvr/buffer_hub_client.h>
+#include <private/dvr/bufferhub_rpc.h>
 #include <private/dvr/display_rpc.h>
 #include <private/dvr/late_latch.h>
 
@@ -38,8 +39,9 @@
   // any change to client/manager attributes that affect visibility or z order.
   void UpdateActiveDisplaySurfaces();
 
-  pdx::BorrowedChannelHandle SetupPoseBuffer(size_t extended_region_size,
-                                             int usage);
+  pdx::Status<BorrowedNativeBufferHandle> SetupNamedBuffer(
+      const std::string& name, size_t size, int producer_usage,
+      int consumer_usage);
 
   template <class A>
   void ForEachDisplaySurface(A action) const {
@@ -85,7 +87,8 @@
 
   void OnSetViewerParams(pdx::Message& message,
                          const ViewerParams& view_params);
-  pdx::LocalChannelHandle OnGetPoseBuffer(pdx::Message& message);
+  pdx::Status<BorrowedNativeBufferHandle> OnGetNamedBuffer(
+      pdx::Message& message, const std::string& name);
 
   // Temporary query for current VR status. Will be removed later.
   int IsVrAppRunning(pdx::Message& message);
@@ -102,7 +105,7 @@
   HardwareComposer hardware_composer_;
   DisplayConfigurationUpdateNotifier update_notifier_;
 
-  std::unique_ptr<BufferProducer> pose_buffer_;
+  std::unordered_map<std::string, std::unique_ptr<IonBuffer>> named_buffers_;
 };
 
 }  // namespace dvr