From 5096c652aa19a501ce28177076de89e58e15b4b3 Mon Sep 17 00:00:00 2001 From: Marie White Date: Tue, 8 Aug 2017 22:23:45 -0700 Subject: [PATCH] Add api's to dvr_pose to retrieve data from sensord Bug: 63683612 Test: Manually tested through VrCore cl/164799996. To retrieve raw data from Tango, added below api's to dvr_api: - dvrPoseClientGetDataReader - dvrPoseClientDataCapture - dvrPoseClientDataReaderDestroy Note: These changes have already been reviewed in branch oc-dr1-daydream-dev branch. See change 2729572. Changes tested on Pixel XL with and without 02 rendering path. Daydream Home rendering in VR Mode correctly. Pixel functioning as normal. Change-Id: Ia934d6a1a0b89edfd4408dde19d38e757d44f785 --- libs/vr/libdvr/Android.bp | 1 + libs/vr/libdvr/dvr_buffer_queue_internal.h | 7 +++ libs/vr/libdvr/dvr_pose.cpp | 30 ++++++++++++ libs/vr/libdvr/include/dvr/dvr_api.h | 10 ++++ libs/vr/libdvr/include/dvr/dvr_api_entries.h | 5 ++ libs/vr/libdvr/include/dvr/dvr_pose.h | 55 +++++++++++++++++++++ libs/vr/libvrsensor/include/dvr/pose_client.h | 13 +++++ libs/vr/libvrsensor/include/private/dvr/pose-ipc.h | 3 ++ .../include/private/dvr/pose_client_internal.h | 20 ++++++++ libs/vr/libvrsensor/pose_client.cpp | 57 +++++++++++++++++++++- 10 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 libs/vr/libdvr/dvr_pose.cpp create mode 100644 libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp index 7fe9825eb7..9fe161db6a 100644 --- a/libs/vr/libdvr/Android.bp +++ b/libs/vr/libdvr/Android.bp @@ -32,6 +32,7 @@ srcs = [ "dvr_display_manager.cpp", "dvr_hardware_composer_client.cpp", "dvr_performance.cpp", + "dvr_pose.cpp", "dvr_surface.cpp", "dvr_vsync.cpp", ] diff --git a/libs/vr/libdvr/dvr_buffer_queue_internal.h b/libs/vr/libdvr/dvr_buffer_queue_internal.h index ffbe7a5836..795d6cdc25 100644 --- a/libs/vr/libdvr/dvr_buffer_queue_internal.h +++ b/libs/vr/libdvr/dvr_buffer_queue_internal.h @@ -9,6 +9,13 @@ struct ANativeWindow; +typedef struct DvrReadBuffer DvrReadBuffer; +typedef struct DvrReadBufferQueue DvrReadBufferQueue; +typedef struct DvrWriteBuffer DvrWriteBuffer; +typedef void (*DvrReadBufferQueueBufferAvailableCallback)(void* context); +typedef void (*DvrReadBufferQueueBufferRemovedCallback)(DvrReadBuffer* buffer, + void* context); + struct DvrWriteBufferQueue { using ProducerQueue = android::dvr::ProducerQueue; diff --git a/libs/vr/libdvr/dvr_pose.cpp b/libs/vr/libdvr/dvr_pose.cpp new file mode 100644 index 0000000000..2ac3c0c4aa --- /dev/null +++ b/libs/vr/libdvr/dvr_pose.cpp @@ -0,0 +1,30 @@ +#include "include/dvr/dvr_pose.h" + +#include + +#include +#include + +#include "dvr_buffer_queue_internal.h" + +using android::dvr::ConsumerQueue; + +int dvrPoseClientGetDataReader(DvrPoseClient* client, + DvrPoseRawDataType data_type, + DvrReadBufferQueue** queue_out) { + if (!client || !queue_out) + return -EINVAL; + + ConsumerQueue* consumer_queue; + int status = android::dvr::dvrPoseClientGetDataReaderHandle(client, + data_type, + &consumer_queue); + if (status != 0) { + ALOGE("dvrPoseClientGetDataReader: Failed to get queue: %d", status); + return status; + } + + std::shared_ptr consumer_queue_ptr{consumer_queue}; + *queue_out = new DvrReadBufferQueue(consumer_queue_ptr); + return 0; +} diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h index e1dc58c2e2..8d4995a9ec 100644 --- a/libs/vr/libdvr/include/dvr/dvr_api.h +++ b/libs/vr/libdvr/include/dvr/dvr_api.h @@ -23,6 +23,7 @@ typedef uint64_t DvrSurfaceUpdateFlags; typedef struct DvrDisplayManager DvrDisplayManager; typedef struct DvrSurfaceState DvrSurfaceState; typedef struct DvrPoseClient DvrPoseClient; +typedef struct DvrPoseDataCaptureRequest DvrPoseDataCaptureRequest; typedef struct DvrVSyncClient DvrVSyncClient; typedef struct DvrVirtualTouchpad DvrVirtualTouchpad; @@ -246,6 +247,15 @@ typedef int (*DvrPoseClientGetControllerPtr)(DvrPoseClient* client, DvrPoseAsync* out_pose); typedef int (*DvrPoseClientSensorsEnablePtr)(DvrPoseClient* client, bool enabled); +typedef int (*DvrPoseClientDataCapturePtr)(DvrPoseClient* client, + const DvrPoseDataCaptureRequest* request); +typedef int (*DvrPoseClientDataReaderDestroyPtr)(DvrPoseClient* client, + DvrPoseRawDataType data_type); + +// dvr_pose.h +typedef int (*DvrPoseClientGetDataReaderPtr)(DvrPoseClient* client, + DvrPoseRawDataType data_type, + DvrReadBufferQueue** read_queue); // services/vr/virtual_touchpad/include/dvr/virtual_touchpad_client.h diff --git a/libs/vr/libdvr/include/dvr/dvr_api_entries.h b/libs/vr/libdvr/include/dvr/dvr_api_entries.h index f65bd1c919..9036773464 100644 --- a/libs/vr/libdvr/include/dvr/dvr_api_entries.h +++ b/libs/vr/libdvr/include/dvr/dvr_api_entries.h @@ -166,3 +166,8 @@ DVR_V1_API_ENTRY(WriteBufferQueueCreate); // Gets an ANativeWindow from DvrWriteBufferQueue. DVR_V1_API_ENTRY(WriteBufferQueueGetANativeWindow); + +// Pose client +DVR_V1_API_ENTRY(PoseClientGetDataReader); +DVR_V1_API_ENTRY(PoseClientDataCapture); +DVR_V1_API_ENTRY(PoseClientDataReaderDestroy); diff --git a/libs/vr/libdvr/include/dvr/dvr_pose.h b/libs/vr/libdvr/include/dvr/dvr_pose.h index b3df0285d7..85631f7199 100644 --- a/libs/vr/libdvr/include/dvr/dvr_pose.h +++ b/libs/vr/libdvr/include/dvr/dvr_pose.h @@ -15,6 +15,9 @@ typedef float float32x4_t __attribute__((__vector_size__(16))); #endif #endif +typedef struct DvrPoseClient DvrPoseClient; +typedef struct DvrReadBufferQueue DvrReadBufferQueue; + // Represents an estimated pose, accessed asynchronously through a shared ring // buffer. No assumptions should be made about the data in padding space. // The size of this struct is 128 bytes. @@ -95,6 +98,58 @@ typedef struct __attribute__((packed, aligned(16))) DvrPose { uint8_t padding[12]; } DvrPose; +// Represents a data type that can be streamed from pose service. +typedef enum DvrPoseRawDataType { + DVR_POSE_RAW_DATA_STEREO_IMAGE, + DVR_POSE_RAW_DATA_POINT_CLOUD, + DVR_POSE_RAW_DATA_FEATURES, + + // Always last. + DVR_POSE_RAW_DATA_COUNT, +} DvrPoseRawDataType; + +// A request to retrieve data from the pose service. Expects that a buffer +// queue has been initialized through dvrPoseClientGetDataReader(). +typedef struct DvrPoseDataCaptureRequest { + // The type of data to capture. Refer to enum DvrPoseRawDataType for types. + DvrPoseRawDataType data_type; + // The sample interval. This can be used to skip samples. For example, a + // value of 5 will capture every fifth frame and discard the 4 frames in + // between. Set to 1 to capture all frames. + uint32_t sample_interval; + // The length of time to capture samples in milliseconds. Set to 0 to capture + // indefinitely. + uint32_t capture_time_ms; + // Reserved fields. + uint32_t reserved0; + uint32_t reserved1; + uint32_t reserved2; + uint32_t reserved3; + uint32_t reserved4; +} DvrPoseDataCaptureRequest; + +// Gets a read buffer queue for the data type |data_type|. Each call returns a +// different read buffer queue connected to the same write buffer queue. A +// separate write buffer queue exists for each |data_type|. +// +// PoseService supports a single consumer per write buffer queue. The consumer +// is expected to hold a single DvrReadBufferQueue at a time. Callers should +// cache these instead of requesting new ones when possible. If the consumer +// disconnects from the queue, it can regain a read buffer queue for the same +// producer by calling this function. +// +// For data_type DVR_POSE_RAW_DATA_STEREO_IMAGE, each buffer consists of two +// images formatted as a AHARDWAREBUFFER_FORMAT_BLOB, where height is 1 and +// width is the total size of both images. The size of an individual image can +// be found in the metadata struct DvrNativeBufferMetadata, where width is +// |crop_right| and height is |crop_bottom|/2. Each image is contiguous in +// memory with stride equal to width. +int dvrPoseClientGetDataReader(DvrPoseClient* client, + DvrPoseRawDataType data_type, + DvrReadBufferQueue** queue_out); + +// TODO(b/65067592): Move pose api's from pose_client.h to here. + __END_DECLS #endif // ANDROID_DVR_PUBLIC_POSE_H_ diff --git a/libs/vr/libvrsensor/include/dvr/pose_client.h b/libs/vr/libvrsensor/include/dvr/pose_client.h index d684ddcc57..d69d8253cb 100644 --- a/libs/vr/libvrsensor/include/dvr/pose_client.h +++ b/libs/vr/libvrsensor/include/dvr/pose_client.h @@ -157,6 +157,19 @@ int dvrPoseClientGetRingBuffer(DvrPoseClient* client, // @return Zero on success int dvrPoseClientSensorsEnable(DvrPoseClient* client, bool enabled); +// Requests a burst of data samples from pose service. The data samples are +// passed through a shared memory buffer obtained by calling +// dvrPoseClientGetDataReader(). +// +// @param DvrPoseDataCaptureRequest Parameters on how to capture data. +// @return Zero on success. +int dvrPoseClientDataCapture(DvrPoseClient* client, + const DvrPoseDataCaptureRequest* request); + +// Destroys the write buffer queue for the given |data_type|. +int dvrPoseClientDataReaderDestroy(DvrPoseClient* client, + DvrPoseRawDataType data_type); + #ifdef __cplusplus } // extern "C" #endif diff --git a/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h b/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h index e4455f1840..7bf1cd4d29 100644 --- a/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h +++ b/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h @@ -17,6 +17,9 @@ enum { DVR_POSE_GET_CONTROLLER_RING_BUFFER, DVR_POSE_LOG_CONTROLLER, DVR_POSE_SENSORS_ENABLE, + DVR_POSE_GET_TANGO_READER, + DVR_POSE_DATA_CAPTURE, + DVR_POSE_TANGO_READER_DESTROY, }; #ifdef __cplusplus diff --git a/libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h b/libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h new file mode 100644 index 0000000000..7198fe88d7 --- /dev/null +++ b/libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h @@ -0,0 +1,20 @@ +#ifndef ANDROID_DVR_POSE_CLIENT_INTERNAL_H_ +#define ANDROID_DVR_POSE_CLIENT_INTERNAL_H_ + +#include + +using android::dvr::ConsumerQueue; + +typedef struct DvrPoseClient DvrPoseClient; + +namespace android { +namespace dvr { + +int dvrPoseClientGetDataReaderHandle(DvrPoseClient *client, + DvrPoseRawDataType data_type, + ConsumerQueue **queue_out); + +} // namespace dvr +} // namespace android + +#endif // ANDROID_DVR_POSE_CLIENT_INTERNAL_H_ diff --git a/libs/vr/libvrsensor/pose_client.cpp b/libs/vr/libvrsensor/pose_client.cpp index 546c2b6996..4e23e25079 100644 --- a/libs/vr/libvrsensor/pose_client.cpp +++ b/libs/vr/libvrsensor/pose_client.cpp @@ -9,10 +9,12 @@ #include #include #include +#include #include #include #include +using android::dvr::ConsumerQueue; using android::pdx::LocalHandle; using android::pdx::LocalChannelHandle; using android::pdx::Status; @@ -139,6 +141,44 @@ class PoseClient : public pdx::ClientBase { return ReturnStatusOrError(status); } + int GetTangoReaderHandle(DvrPoseRawDataType data_type, ConsumerQueue** queue_out) { + // Get buffer. + Transaction trans{*this}; + Status status = trans.Send( + DVR_POSE_GET_TANGO_READER, &data_type, sizeof(data_type), nullptr, 0); + + if (!status) { + ALOGE("PoseClient GetTangoReaderHandle() failed because: %s", + status.GetErrorMessage().c_str()); + *queue_out = nullptr; + return -status.error(); + } + + std::unique_ptr consumer_queue = + ConsumerQueue::Import(status.take()); + *queue_out = consumer_queue.release(); + return 0; + } + + int DataCapture(const DvrPoseDataCaptureRequest* request) { + Transaction trans{*this}; + Status status = trans.Send(DVR_POSE_DATA_CAPTURE, request, + sizeof(*request), nullptr, 0); + ALOGE_IF(!status, "PoseClient DataCapture() failed because: %s\n", + status.GetErrorMessage().c_str()); + return ReturnStatusOrError(status); + } + + int DataReaderDestroy(DvrPoseRawDataType data_type) { + Transaction trans{*this}; + Status status = trans.Send(DVR_POSE_TANGO_READER_DESTROY, + &data_type, sizeof(data_type), nullptr, + 0); + ALOGE_IF(!status, "PoseClient DataReaderDestroy() failed because: %s\n", + status.GetErrorMessage().c_str()); + return ReturnStatusOrError(status); + } + // Enables or disables all pose processing from sensors int EnableSensors(bool enabled) { Transaction trans{*this}; @@ -256,6 +296,12 @@ class PoseClient : public pdx::ClientBase { ControllerClientState controllers_[MAX_CONTROLLERS]; }; +int dvrPoseClientGetDataReaderHandle(DvrPoseClient* client, + DvrPoseRawDataType type, + ConsumerQueue** queue_out) { + return PoseClient::FromC(client)->GetTangoReaderHandle(type, queue_out); +} + } // namespace dvr } // namespace android @@ -307,9 +353,18 @@ int dvrPoseClientModeGet(DvrPoseClient* client, DvrPoseMode* mode) { return PoseClient::FromC(client)->GetMode(mode); } - int dvrPoseClientSensorsEnable(DvrPoseClient* client, bool enabled) { return PoseClient::FromC(client)->EnableSensors(enabled); } +int dvrPoseClientDataCapture(DvrPoseClient* client, + const DvrPoseDataCaptureRequest* request) { + return PoseClient::FromC(client)->DataCapture(request); +} + +int dvrPoseClientDataReaderDestroy(DvrPoseClient* client, + DvrPoseRawDataType data_type) { + return PoseClient::FromC(client)->DataReaderDestroy(data_type); +} + } // extern "C" -- 2.11.0