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