Add dvr_buffer apis
Test: None
Bug: None
Change-Id: I234d7ef4dabb4453cdbc67d3112adf2ffbbadaf4
diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp
index 452bad0..e068469 100644
--- a/libs/vr/libbufferhub/Android.bp
+++ b/libs/vr/libbufferhub/Android.bp
@@ -15,6 +15,7 @@
sourceFiles = [
"buffer_hub_client.cpp",
"buffer_hub_rpc.cpp",
+ "dvr_buffer.cpp",
"ion_buffer.cpp",
]
diff --git a/libs/vr/libbufferhub/buffer_hub_client.cpp b/libs/vr/libbufferhub/buffer_hub_client.cpp
index 7268b76..2749fd1 100644
--- a/libs/vr/libbufferhub/buffer_hub_client.cpp
+++ b/libs/vr/libbufferhub/buffer_hub_client.cpp
@@ -130,6 +130,13 @@
return ret;
}
+void BufferHubBuffer::GetBlobFds(int* fds, size_t* fds_count,
+ size_t max_fds_count) const {
+ size_t numFds = static_cast<size_t>(native_handle()->numFds);
+ *fds_count = std::min(max_fds_count, numFds);
+ std::copy(native_handle()->data, native_handle()->data + *fds_count, fds);
+}
+
BufferConsumer::BufferConsumer(LocalChannelHandle channel)
: BASE(std::move(channel)) {
const int ret = ImportBuffer();
diff --git a/libs/vr/libbufferhub/dvr_buffer.cpp b/libs/vr/libbufferhub/dvr_buffer.cpp
new file mode 100644
index 0000000..3eb611f
--- /dev/null
+++ b/libs/vr/libbufferhub/dvr_buffer.cpp
@@ -0,0 +1,124 @@
+#include <private/dvr/buffer_hub_client.h>
+#include <private/dvr/dvr_buffer.h>
+#include <ui/GraphicBuffer.h>
+
+using namespace android;
+
+struct DvrWriteBuffer {
+ std::unique_ptr<dvr::BufferProducer> write_buffer_;
+ sp<GraphicBuffer> graphic_buffer_;
+};
+
+struct DvrReadBuffer {
+ std::unique_ptr<dvr::BufferConsumer> read_buffer_;
+ sp<GraphicBuffer> graphic_buffer_;
+};
+
+namespace android {
+namespace dvr {
+
+DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
+ std::unique_ptr<dvr::BufferProducer> buffer_producer) {
+ DvrWriteBuffer* write_buffer = new DvrWriteBuffer;
+ write_buffer->write_buffer_ = std::move(buffer_producer);
+ return write_buffer;
+}
+
+DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
+ std::unique_ptr<dvr::BufferConsumer> buffer_consumer) {
+ DvrReadBuffer* read_buffer = new DvrReadBuffer;
+ read_buffer->read_buffer_ = std::move(buffer_consumer);
+ return read_buffer;
+}
+
+} // namespace dvr
+} // namespace android
+
+namespace {
+
+void InitializeGraphicBuffer(const dvr::BufferHubBuffer* buffer,
+ sp<GraphicBuffer>* graphic_buffer) {
+ *graphic_buffer = sp<GraphicBuffer>(new GraphicBuffer(
+ buffer->width(), buffer->height(), buffer->format(), 1, /* layer count */
+ buffer->usage(), buffer->stride(), buffer->native_handle(),
+ false /* keep ownership */));
+}
+
+} // anonymous namespace
+
+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);
+}
+
+int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* client,
+ 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());
+ return 0;
+}
+
+int dvrWriteBufferPost(DvrWriteBuffer* client, 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();
+ return result;
+}
+
+int dvrWriteBufferGain(DvrWriteBuffer* client, int* release_fence_fd) {
+ pdx::LocalHandle release_fence;
+ int result = client->write_buffer_->Gain(&release_fence);
+ *release_fence_fd = release_fence.Release();
+ return result;
+}
+
+int dvrWriteBufferGainAsync(DvrWriteBuffer* client) {
+ return client->write_buffer_->GainAsync();
+}
+
+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 dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* client,
+ 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());
+ return 0;
+}
+
+int dvrReadBufferAcquire(DvrReadBuffer* client, 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);
+ *ready_fence_fd = ready_fence.Release();
+ return result;
+}
+
+int dvrReadBufferRelease(DvrReadBuffer* client, int release_fence_fd) {
+ pdx::LocalHandle fence(release_fence_fd);
+ int result = client->read_buffer_->Release(fence);
+ fence.Release();
+ return result;
+}
+
+int dvrReadBufferReleaseAsync(DvrReadBuffer* client) {
+ return client->read_buffer_->ReleaseAsync();
+}
+
+} // extern "C"
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
index cefde7b..aacc385 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
@@ -70,6 +70,10 @@
return LocalHandle(dup(native_handle()->data[0]));
}
+ // Get up to |max_fds_count| file descriptors for accessing the blob shared
+ // memory. |fds_count| will contain the actual number of file descriptors.
+ void GetBlobFds(int* fds, size_t* fds_count, size_t max_fds_count) const;
+
using Client::event_fd;
Status<int> GetEventMask(int events) {
diff --git a/libs/vr/libbufferhub/include/private/dvr/dvr_buffer.h b/libs/vr/libbufferhub/include/private/dvr/dvr_buffer.h
new file mode 100644
index 0000000..c14b1a3
--- /dev/null
+++ b/libs/vr/libbufferhub/include/private/dvr/dvr_buffer.h
@@ -0,0 +1,55 @@
+#ifndef ANDROID_DVR_BUFFER_H_
+#define ANDROID_DVR_BUFFER_H_
+
+#include <memory>
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct DvrWriteBuffer DvrWriteBuffer;
+typedef struct DvrReadBuffer DvrReadBuffer;
+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,
+ AHardwareBuffer** hardware_buffer);
+int dvrWriteBufferPost(DvrWriteBuffer* client, int ready_fence_fd,
+ const void* meta, size_t meta_size_bytes);
+int dvrWriteBufferGain(DvrWriteBuffer* client, int* release_fence_fd);
+int dvrWriteBufferGainAsync(DvrWriteBuffer* client);
+
+// Read buffer
+void dvrReadBufferGetBlobFds(DvrReadBuffer* client, int* fds, size_t* fds_count,
+ size_t max_fds_count);
+int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* client,
+ 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);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+namespace android {
+namespace dvr {
+
+class BufferProducer;
+class BufferConsumer;
+
+DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
+ std::unique_ptr<BufferProducer> buffer_producer);
+DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
+ std::unique_ptr<BufferConsumer> buffer_consumer);
+
+} // namespace dvr
+} // namespace android
+
+#endif // ANDROID_DVR_BUFFER_H_
diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp
index dcdd994..3a1cc72 100644
--- a/libs/vr/libdisplay/display_client.cpp
+++ b/libs/vr/libdisplay/display_client.cpp
@@ -276,5 +276,18 @@
return DisplaySurfaceClient::Create(width, height, format, usage, flags);
}
+std::unique_ptr<BufferConsumer> DisplayClient::GetPoseBuffer() {
+ auto status = InvokeRemoteMethod<DisplayRPC::GetPoseBuffer>();
+ if (!status) {
+ ALOGE(
+ "DisplayClient::GetPoseBuffer: Failed to get pose buffer %s",
+ status.GetErrorMessage().c_str());
+ return nullptr;
+ }
+
+ return BufferConsumer::Import(std::move(status));
+}
+
+
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/display_manager_client.cpp b/libs/vr/libdisplay/display_manager_client.cpp
index fe18619..d60d35b 100644
--- a/libs/vr/libdisplay/display_manager_client.cpp
+++ b/libs/vr/libdisplay/display_manager_client.cpp
@@ -2,6 +2,7 @@
#include <private/dvr/buffer_hub_client.h>
#include <private/dvr/display_manager_client_impl.h>
+#include <private/dvr/dvr_buffer.h>
using android::dvr::DisplaySurfaceAttributeEnum;
@@ -41,6 +42,18 @@
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));
+ }
+ return nullptr;
+}
+
int dvrDisplayManagerClientGetEventFd(DvrDisplayManagerClient* client) {
return client->client->event_fd();
}
diff --git a/libs/vr/libdisplay/display_manager_client_impl.cpp b/libs/vr/libdisplay/display_manager_client_impl.cpp
index 3fbd1e0..7993fce 100644
--- a/libs/vr/libdisplay/display_manager_client_impl.cpp
+++ b/libs/vr/libdisplay/display_manager_client_impl.cpp
@@ -31,5 +31,20 @@
return 0;
}
+std::unique_ptr<BufferProducer> DisplayManagerClient::SetupPoseBuffer(
+ size_t extended_region_size, int usage) {
+ auto status = InvokeRemoteMethod<DisplayManagerRPC::SetupPoseBuffer>(
+ extended_region_size, usage);
+ if (!status) {
+ ALOGE(
+ "DisplayManagerClient::SetupPoseBuffer: Failed to create the pose "
+ "buffer %s",
+ status.GetErrorMessage().c_str());
+ return {};
+ }
+
+ return BufferProducer::Import(std::move(status));
+}
+
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdisplay/graphics.cpp b/libs/vr/libdisplay/graphics.cpp
index 61f6fea..c2fbb8b 100644
--- a/libs/vr/libdisplay/graphics.cpp
+++ b/libs/vr/libdisplay/graphics.cpp
@@ -17,6 +17,7 @@
#include <private/dvr/clock_ns.h>
#include <private/dvr/debug.h>
#include <private/dvr/display_types.h>
+#include <private/dvr/dvr_buffer.h>
#include <private/dvr/frame_history.h>
#include <private/dvr/gl_fenced_flush.h>
#include <private/dvr/graphics/vr_gl_extensions.h>
@@ -1571,3 +1572,14 @@
};
}
}
+
+extern "C" int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer) {
+ auto client = android::dvr::DisplayClient::Create();
+ if (!client) {
+ ALOGE("Failed to create display client!");
+ return -ECOMM;
+ }
+
+ *pose_buffer = CreateDvrReadBufferFromBufferConsumer(client->GetPoseBuffer());
+ return 0;
+}
diff --git a/libs/vr/libdisplay/include/dvr/graphics.h b/libs/vr/libdisplay/include/dvr/graphics.h
index 19deec3..fc51d52 100644
--- a/libs/vr/libdisplay/include/dvr/graphics.h
+++ b/libs/vr/libdisplay/include/dvr/graphics.h
@@ -160,6 +160,8 @@
int dvrGetNativeDisplayDimensions(int* native_width, int* native_height);
+typedef struct DvrReadBuffer DvrReadBuffer;
+
// Opaque struct that represents a graphics context, the texture swap chain,
// and surfaces.
typedef struct DvrGraphicsContext DvrGraphicsContext;
@@ -440,6 +442,9 @@
const int eye,
const float* transform);
+// Get a pointer to the global pose buffer.
+int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer);
+
__END_DECLS
#endif // DVR_GRAPHICS_H_
diff --git a/libs/vr/libdisplay/include/private/dvr/display_client.h b/libs/vr/libdisplay/include/private/dvr/display_client.h
index e1471c3..bfc167e 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_client.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_client.h
@@ -111,6 +111,8 @@
std::unique_ptr<DisplaySurfaceClient> CreateDisplaySurface(
int width, int height, int format, int usage, int flags);
+ std::unique_ptr<BufferConsumer> GetPoseBuffer();
+
private:
friend BASE;
diff --git a/libs/vr/libdisplay/include/private/dvr/display_manager_client.h b/libs/vr/libdisplay/include/private/dvr/display_manager_client.h
index f515b8f..0928d43 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_manager_client.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_manager_client.h
@@ -14,11 +14,16 @@
DvrDisplayManagerClientSurfaceList;
typedef struct DvrDisplayManagerClientSurfaceBuffers
DvrDisplayManagerClientSurfaceBuffers;
+typedef struct DvrWriteBuffer DvrWriteBuffer;
DvrDisplayManagerClient* dvrDisplayManagerClientCreate();
void dvrDisplayManagerClientDestroy(DvrDisplayManagerClient* client);
+DvrWriteBuffer* dvrDisplayManagerSetupPoseBuffer(
+ DvrDisplayManagerClient* client, size_t extended_region_size,
+ uint64_t usage0, uint64_t usage1);
+
// 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
// dvrDisplayManagerClientTranslateEpollEventMask in order to get the real
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 0897126..144cd3b 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
@@ -9,7 +9,7 @@
namespace android {
namespace dvr {
-class BufferConsumer;
+class BufferProducer;
class DisplayManagerClient : public pdx::ClientBase<DisplayManagerClient> {
public:
@@ -17,6 +17,9 @@
int GetSurfaceList(std::vector<DisplaySurfaceInfo>* surface_list);
+ std::unique_ptr<BufferProducer> SetupPoseBuffer(size_t extended_region_size,
+ int 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 465fbae..e373123 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_rpc.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_rpc.h
@@ -219,7 +219,8 @@
kOpVideoMeshSurfaceCreateProducerQueue,
kOpEnterVrMode,
kOpExitVrMode,
- kOpSetViewerParams
+ kOpSetViewerParams,
+ kOpGetPoseBuffer,
};
// Aliases.
@@ -249,6 +250,8 @@
PDX_REMOTE_METHOD(ExitVrMode, kOpExitVrMode, int(Void));
PDX_REMOTE_METHOD(SetViewerParams, kOpSetViewerParams,
void(const ViewerParams& viewer_params));
+ PDX_REMOTE_METHOD(GetPoseBuffer, kOpGetPoseBuffer,
+ LocalChannelHandle(Void));
};
struct DisplayManagerRPC {
@@ -259,6 +262,7 @@
enum {
kOpGetSurfaceList = 0,
kOpUpdateSurfaces,
+ kOpSetupPoseBuffer,
};
// Aliases.
@@ -271,6 +275,8 @@
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));
};
struct ScreenshotData {
diff --git a/libs/vr/libvrflinger/display_manager_service.cpp b/libs/vr/libvrflinger/display_manager_service.cpp
index 6df1642..e07901d 100644
--- a/libs/vr/libvrflinger/display_manager_service.cpp
+++ b/libs/vr/libvrflinger/display_manager_service.cpp
@@ -82,6 +82,11 @@
*this, &DisplayManagerService::OnUpdateSurfaces, message);
return 0;
+ case DisplayManagerRPC::SetupPoseBuffer::Opcode:
+ DispatchRemoteMethod<DisplayManagerRPC::SetupPoseBuffer>(
+ *this, &DisplayManagerService::OnSetupPoseBuffer, message);
+ return 0;
+
default:
return Service::DefaultHandleMessage(message);
}
@@ -91,30 +96,31 @@
pdx::Message& /*message*/) {
std::vector<DisplaySurfaceInfo> items;
- display_service_->ForEachDisplaySurface([&items](
- const std::shared_ptr<DisplaySurface>& surface) mutable {
- DisplaySurfaceInfo item;
+ display_service_->ForEachDisplaySurface(
+ [&items](const std::shared_ptr<DisplaySurface>& surface) mutable {
+ DisplaySurfaceInfo item;
- item.surface_id = surface->surface_id();
- item.process_id = surface->process_id();
- item.type = surface->type();
- item.flags = 0; // TODO(eieio)
- item.client_attributes = DisplaySurfaceAttributes{
- {DisplaySurfaceAttributeEnum::Visible,
- DisplaySurfaceAttributeValue{surface->client_visible()}},
- {DisplaySurfaceAttributeEnum::ZOrder,
- DisplaySurfaceAttributeValue{surface->client_z_order()}},
- {DisplaySurfaceAttributeEnum::Blur, DisplaySurfaceAttributeValue{0.f}}};
- item.manager_attributes = DisplaySurfaceAttributes{
- {DisplaySurfaceAttributeEnum::Visible,
- DisplaySurfaceAttributeValue{surface->manager_visible()}},
- {DisplaySurfaceAttributeEnum::ZOrder,
- DisplaySurfaceAttributeValue{surface->manager_z_order()}},
- {DisplaySurfaceAttributeEnum::Blur,
- DisplaySurfaceAttributeValue{surface->manager_blur()}}};
+ item.surface_id = surface->surface_id();
+ item.process_id = surface->process_id();
+ item.type = surface->type();
+ item.flags = 0; // TODO(eieio)
+ item.client_attributes = DisplaySurfaceAttributes{
+ {DisplaySurfaceAttributeEnum::Visible,
+ DisplaySurfaceAttributeValue{surface->client_visible()}},
+ {DisplaySurfaceAttributeEnum::ZOrder,
+ DisplaySurfaceAttributeValue{surface->client_z_order()}},
+ {DisplaySurfaceAttributeEnum::Blur,
+ DisplaySurfaceAttributeValue{0.f}}};
+ item.manager_attributes = DisplaySurfaceAttributes{
+ {DisplaySurfaceAttributeEnum::Visible,
+ DisplaySurfaceAttributeValue{surface->manager_visible()}},
+ {DisplaySurfaceAttributeEnum::ZOrder,
+ DisplaySurfaceAttributeValue{surface->manager_z_order()}},
+ {DisplaySurfaceAttributeEnum::Blur,
+ DisplaySurfaceAttributeValue{surface->manager_blur()}}};
- items.push_back(item);
- });
+ items.push_back(item);
+ });
// The fact that we're in the message handler implies that display_manager_ is
// not nullptr. No check required, unless this service becomes multi-threaded.
@@ -182,6 +188,11 @@
return 0;
}
+pdx::BorrowedChannelHandle DisplayManagerService::OnSetupPoseBuffer(
+ pdx::Message& message, size_t extended_region_size, int usage) {
+ return display_service_->SetupPoseBuffer(extended_region_size, usage);
+}
+
void DisplayManagerService::OnDisplaySurfaceChange() {
if (display_manager_) {
display_manager_->SetNotificationsPending(true);
diff --git a/libs/vr/libvrflinger/display_manager_service.h b/libs/vr/libvrflinger/display_manager_service.h
index 3f83c7d..19098c2 100644
--- a/libs/vr/libvrflinger/display_manager_service.h
+++ b/libs/vr/libvrflinger/display_manager_service.h
@@ -54,6 +54,10 @@
int OnUpdateSurfaces(pdx::Message& message,
const std::map<int, DisplaySurfaceAttributes>& updates);
+ pdx::BorrowedChannelHandle OnSetupPoseBuffer(pdx::Message& message,
+ size_t extended_region_size,
+ int usage);
+
// Called by the display service to indicate changes to display surfaces that
// the display manager should evaluate.
void OnDisplaySurfaceChange();
diff --git a/libs/vr/libvrflinger/display_service.cpp b/libs/vr/libvrflinger/display_service.cpp
index fdb84c5..e3d7564 100644
--- a/libs/vr/libvrflinger/display_service.cpp
+++ b/libs/vr/libvrflinger/display_service.cpp
@@ -18,6 +18,15 @@
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 {
@@ -89,6 +98,11 @@
*this, &DisplayService::OnSetViewerParams, message);
return 0;
+ case DisplayRPC::GetPoseBuffer::Opcode:
+ DispatchRemoteMethod<DisplayRPC::GetPoseBuffer>(
+ *this, &DisplayService::OnGetPoseBuffer, message);
+ return 0;
+
// Direct the surface specific messages to the surface instance.
case DisplayRPC::CreateBufferQueue::Opcode:
case DisplayRPC::SetAttributes::Opcode:
@@ -254,6 +268,15 @@
compositor->UpdateHeadMountMetrics(head_mount_metrics);
}
+pdx::LocalChannelHandle DisplayService::OnGetPoseBuffer(pdx::Message& message) {
+ if (pose_buffer_) {
+ return pose_buffer_->CreateConsumer().take();
+ }
+
+ pdx::rpc::RemoteMethodError(message, EAGAIN);
+ return {};
+}
+
// Calls the message handler for the DisplaySurface associated with this
// channel.
int DisplayService::HandleSurfaceMessage(pdx::Message& message) {
@@ -324,6 +347,18 @@
return 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);
+ }
+
+ return pose_buffer_->GetChannelHandle().Borrow();
+}
+
void DisplayService::OnHardwareComposerRefresh() {
hardware_composer_.OnHardwareComposerRefresh();
}
diff --git a/libs/vr/libvrflinger/display_service.h b/libs/vr/libvrflinger/display_service.h
index 9d116c1..a2b3ed5 100644
--- a/libs/vr/libvrflinger/display_service.h
+++ b/libs/vr/libvrflinger/display_service.h
@@ -38,6 +38,9 @@
// any change to client/manager attributes that affect visibility or z order.
int UpdateActiveDisplaySurfaces();
+ pdx::BorrowedChannelHandle SetupPoseBuffer(size_t extended_region_size,
+ int usage);
+
template <class A>
void ForEachDisplaySurface(A action) const {
ForEachChannel([action](const ChannelIterator::value_type& pair) mutable {
@@ -80,14 +83,16 @@
DisplayService(android::Hwc2::Composer* hidl);
SystemDisplayMetrics OnGetMetrics(pdx::Message& message);
- int OnCreateSurface(pdx::Message& message, int width, int height,
- int format, int usage, DisplaySurfaceFlags flags);
+ int OnCreateSurface(pdx::Message& message, int width, int height, int format,
+ int usage, DisplaySurfaceFlags flags);
DisplayRPC::ByteBuffer OnGetEdsCapture(pdx::Message& message);
int OnEnterVrMode(pdx::Message& message);
int OnExitVrMode(pdx::Message& message);
- void OnSetViewerParams(pdx::Message& message, const ViewerParams& view_params);
+ void OnSetViewerParams(pdx::Message& message,
+ const ViewerParams& view_params);
+ pdx::LocalChannelHandle OnGetPoseBuffer(pdx::Message& message);
// Called by DisplaySurface to signal that a surface property has changed and
// the display manager should be notified.
@@ -100,6 +105,8 @@
HardwareComposer hardware_composer_;
DisplayConfigurationUpdateNotifier update_notifier_;
+
+ std::unique_ptr<BufferProducer> pose_buffer_;
};
} // namespace dvr