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
diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp
index 7fe9825..9fe161d 100644
--- a/libs/vr/libdvr/Android.bp
+++ b/libs/vr/libdvr/Android.bp
@@ -32,6 +32,7 @@
"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 ffbe7a5..795d6cd 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 0000000..2ac3c0c
--- /dev/null
+++ b/libs/vr/libdvr/dvr_pose.cpp
@@ -0,0 +1,30 @@
+#include "include/dvr/dvr_pose.h"
+
+#include <memory>
+
+#include <private/dvr/buffer_hub_queue_client.h>
+#include <private/dvr/pose_client_internal.h>
+
+#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<ConsumerQueue> 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 e1dc58c..8d4995a 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -23,6 +23,7 @@
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 @@
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 f65bd1c..9036773 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 @@
// 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 b3df028..85631f7 100644
--- a/libs/vr/libdvr/include/dvr/dvr_pose.h
+++ b/libs/vr/libdvr/include/dvr/dvr_pose.h
@@ -15,6 +15,9 @@
#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 @@
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 d684ddc..d69d825 100644
--- a/libs/vr/libvrsensor/include/dvr/pose_client.h
+++ b/libs/vr/libvrsensor/include/dvr/pose_client.h
@@ -157,6 +157,19 @@
// @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 e4455f1..7bf1cd4 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 @@
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 0000000..7198fe8
--- /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 <private/dvr/buffer_hub_queue_client.h>
+
+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 546c2b6..4e23e25 100644
--- a/libs/vr/libvrsensor/pose_client.cpp
+++ b/libs/vr/libvrsensor/pose_client.cpp
@@ -9,10 +9,12 @@
#include <pdx/default_transport/client_channel_factory.h>
#include <pdx/file_handle.h>
#include <private/dvr/buffer_hub_client.h>
+#include <private/dvr/buffer_hub_queue_client.h>
#include <private/dvr/display_client.h>
#include <private/dvr/pose-ipc.h>
#include <private/dvr/shared_buffer_helpers.h>
+using android::dvr::ConsumerQueue;
using android::pdx::LocalHandle;
using android::pdx::LocalChannelHandle;
using android::pdx::Status;
@@ -139,6 +141,44 @@
return ReturnStatusOrError(status);
}
+ int GetTangoReaderHandle(DvrPoseRawDataType data_type, ConsumerQueue** queue_out) {
+ // Get buffer.
+ Transaction trans{*this};
+ Status<LocalChannelHandle> status = trans.Send<LocalChannelHandle>(
+ 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<ConsumerQueue> consumer_queue =
+ ConsumerQueue::Import(status.take());
+ *queue_out = consumer_queue.release();
+ return 0;
+ }
+
+ int DataCapture(const DvrPoseDataCaptureRequest* request) {
+ Transaction trans{*this};
+ Status<int> status = trans.Send<int>(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<int> status = trans.Send<int>(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 @@
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 @@
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"