1#ifndef ANDROID_DVR_POSE_CLIENT_H_ 2#define ANDROID_DVR_POSE_CLIENT_H_ 3 4#ifdef __ARM_NEON 5#include <arm_neon.h> 6#else 7#ifndef __FLOAT32X4T_86 8#define __FLOAT32X4T_86 9typedef float float32x4_t __attribute__ ((__vector_size__ (16))); 10typedef struct float32x4x4_t { float32x4_t val[4]; }; 11#endif 12#endif 13 14#include <stdbool.h> 15#include <stdint.h> 16 17#ifdef __cplusplus 18extern "C" { 19#endif 20 21typedef struct DvrPose DvrPose; 22 23// Represents the current state provided by the pose service, containing a 24// rotation and translation. 25typedef struct __attribute__((packed, aligned(8))) DvrPoseState { 26 // A quaternion representing the rotation of the HMD in Start Space. 27 struct __attribute__((packed)) { 28 float x, y, z, w; 29 } head_from_start_rotation; 30 // The position of the HMD in Start Space. 31 struct __attribute__((packed)) { 32 float x, y, z; 33 } head_from_start_translation; 34 // Time in nanoseconds for the current pose. 35 uint64_t timestamp_ns; 36 // The rotational velocity of the HMD. 37 struct __attribute__((packed)) { 38 float x, y, z; 39 } sensor_from_start_rotation_velocity; 40} DvrPoseState; 41 42enum { 43 DVR_POSE_FLAG_VALID = (1UL << 0), // This pose is valid. 44 DVR_POSE_FLAG_HEAD = (1UL << 1), // This pose is the head. 45 DVR_POSE_FLAG_CONTROLLER = (1UL << 2), // This pose is a controller. 46}; 47 48// Represents an estimated pose, accessed asynchronously through a shared ring 49// buffer. No assumptions should be made about the data in padding space. 50// The size of this struct is 128 bytes. 51typedef struct __attribute__((packed, aligned(16))) DvrPoseAsync { 52 // Left eye head-from-start orientation quaternion x,y,z,w. 53 float32x4_t orientation; 54 // Left eye head-from-start translation x,y,z,pad in meters. 55 float32x4_t translation; 56 // Right eye head-from-start orientation quaternion x,y,z,w. 57 float32x4_t right_orientation; 58 // Right eye head-from-start translation x,y,z,pad in meters. 59 float32x4_t right_translation; 60 // Start-space angular velocity x,y,z,pad in radians per second. 61 float32x4_t angular_velocity; 62 // Start-space positional velocity x,y,z,pad in meters per second. 63 float32x4_t velocity; 64 // Timestamp of when this pose is predicted for, typically halfway through 65 // scanout. 66 int64_t timestamp_ns; 67 // Bitmask of DVR_POSE_FLAG_* constants that apply to this pose. 68 // 69 // If DVR_POSE_FLAG_VALID is not set, the pose is indeterminate. 70 uint64_t flags; 71 // Reserved padding to 128 bytes. 72 uint8_t pad[16]; 73} DvrPoseAsync; 74 75// Returned by the async pose ring buffer access API. 76typedef struct DvrPoseRingBufferInfo { 77 // Read-only pointer to the pose ring buffer. The current pose is in this 78 // buffer at element buffer[current_frame & (buffer_size - 1)]. The next 79 // frame's forecasted pose is at element 80 // ((current_frame + 1) & (buffer_size - 1)). And so on. The poses are 81 // predicted for when 50% of the corresponding frame's pixel data is visible 82 // to the user. 83 // The last value returned by dvrPresent is the count for the next frame, 84 // which is the earliest that the application could display something if they 85 // were to render promptly. (TODO(jbates) move this comment to dvrPresent). 86 volatile const DvrPoseAsync* buffer; 87 // Minimum number of accurate forecasted poses including the current frame's 88 // pose. This is the number of poses that are udpated by the pose service. 89 // If the application reads past this count, they will get a stale prediction 90 // from a previous frame. Guaranteed to be at least 2. 91 uint32_t min_future_count; 92 // Number of elements in buffer. At least 8 and greater than min_future_count. 93 // Guaranteed to be a power of two. The total size of the buffer in bytes is: 94 // total_count * sizeof(DvrPoseAsync) 95 uint32_t total_count; 96} DvrPoseRingBufferInfo; 97 98typedef enum DvrPoseMode { 99 DVR_POSE_MODE_6DOF = 0, 100 DVR_POSE_MODE_3DOF, 101 DVR_POSE_MODE_MOCK_FROZEN, 102 DVR_POSE_MODE_MOCK_HEAD_TURN_SLOW, 103 DVR_POSE_MODE_MOCK_HEAD_TURN_FAST, 104 DVR_POSE_MODE_MOCK_ROTATE_SLOW, 105 DVR_POSE_MODE_MOCK_ROTATE_MEDIUM, 106 DVR_POSE_MODE_MOCK_ROTATE_FAST, 107 DVR_POSE_MODE_MOCK_CIRCLE_STRAFE, 108 109 // Always last. 110 DVR_POSE_MODE_COUNT, 111} DvrPoseMode; 112 113typedef enum DvrControllerId { 114 DVR_CONTROLLER_0 = 0, 115 DVR_CONTROLLER_1 = 1, 116} DvrControllerId; 117 118// Creates a new pose client. 119// 120// @return Pointer to the created pose client, nullptr on failure. 121DvrPose* dvrPoseCreate(); 122 123// Destroys a pose client. 124// 125// @param client Pointer to the pose client to be destroyed. 126void dvrPoseDestroy(DvrPose* client); 127 128// Gets the pose for the given vsync count. 129// 130// @param client Pointer to the pose client. 131// @param vsync_count Vsync that this pose should be forward-predicted to. 132// Typically this is the count returned by dvrGetNextVsyncCount. 133// @param out_pose Struct to store pose state. 134// @return Zero on success, negative error code on failure. 135int dvrPoseGet(DvrPose* client, uint32_t vsync_count, DvrPoseAsync* out_pose); 136 137// Gets the current vsync count. 138uint32_t dvrPoseGetVsyncCount(DvrPose* client); 139 140// Gets the pose for the given controller at the given vsync count. 141// 142// @param client Pointer to the pose client. 143// @param controller_id The controller id. 144// @param vsync_count Vsync that this pose should be forward-predicted to. 145// Typically this is the count returned by dvrGetNextVsyncCount. 146// @param out_pose Struct to store pose state. 147// @return Zero on success, negative error code on failure. 148int dvrPoseGetController(DvrPose* client, int32_t controller_id, 149 uint32_t vsync_count, DvrPoseAsync* out_pose); 150 151// Enables/disables logging for the controller fusion. 152// 153// @param client Pointer to the pose client. 154// @param enable True starts logging, False stops. 155// @return Zero on success, negative error code on failure. 156int dvrPoseLogController(DvrPose* client, bool enable); 157 158// DEPRECATED 159// Polls current pose state. 160// 161// @param client Pointer to the pose client. 162// @param state Struct to store polled state. 163// @return Zero on success, negative error code on failure. 164int dvrPosePoll(DvrPose* client, DvrPoseState* state); 165 166// Freezes the pose to the provided state. 167// 168// Future poll operations will return this state until a different state is 169// frozen or dvrPoseSetMode() is called with a different mode. The timestamp is 170// not frozen. 171// 172// @param client Pointer to the pose client. 173// @param frozen_state State pose to be frozen to. 174// @return Zero on success, negative error code on failure. 175int dvrPoseFreeze(DvrPose* client, const DvrPoseState* frozen_state); 176 177// Sets the pose service mode. 178// 179// @param mode The requested pose mode. 180// @return Zero on success, negative error code on failure. 181int dvrPoseSetMode(DvrPose* client, DvrPoseMode mode); 182 183// Gets the pose service mode. 184// 185// @param mode Return value for the current pose mode. 186// @return Zero on success, negative error code on failure. 187int dvrPoseGetMode(DvrPose* client, DvrPoseMode* mode); 188 189// Get access to the shared memory pose ring buffer. 190// A future pose at vsync <current> + <offset> is accessed at index: 191// index = (<current> + <offset>) % out_buffer_size 192// Where <current> was the last value returned by dvrPresent and 193// <offset> is less than or equal to |out_min_future_count|. 194// |out_buffer| will be set to a pointer to the buffer. 195// |out_fd| will be set to the gralloc buffer file descriptor, which is 196// required for binding this buffer for GPU use. 197// Returns 0 on success. 198int dvrPoseGetRingBuffer(DvrPose* client, DvrPoseRingBufferInfo* out_info); 199 200 201#ifdef __cplusplus 202} // extern "C" 203#endif 204 205#endif // ANDROID_DVR_POSE_CLIENT_H_ 206