#ifndef ANDROID_DVR_POSE_CLIENT_H_ #define ANDROID_DVR_POSE_CLIENT_H_ #ifdef __ARM_NEON #include #else #ifndef __FLOAT32X4T_86 #define __FLOAT32X4T_86 typedef float float32x4_t __attribute__ ((__vector_size__ (16))); typedef struct float32x4x4_t { float32x4_t val[4]; }; #endif #endif #include #include #ifdef __cplusplus extern "C" { #endif typedef struct DvrPose DvrPose; // Represents the current state provided by the pose service, containing a // rotation and translation. typedef struct __attribute__((packed, aligned(8))) DvrPoseState { // A quaternion representing the rotation of the HMD in Start Space. struct __attribute__((packed)) { float x, y, z, w; } head_from_start_rotation; // The position of the HMD in Start Space. struct __attribute__((packed)) { float x, y, z; } head_from_start_translation; // Time in nanoseconds for the current pose. uint64_t timestamp_ns; // The rotational velocity of the HMD. struct __attribute__((packed)) { float x, y, z; } sensor_from_start_rotation_velocity; } DvrPoseState; enum { DVR_POSE_FLAG_VALID = (1UL << 0), // This pose is valid. DVR_POSE_FLAG_HEAD = (1UL << 1), // This pose is the head. DVR_POSE_FLAG_CONTROLLER = (1UL << 2), // This pose is a controller. }; // 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. typedef struct __attribute__((packed, aligned(16))) DvrPoseAsync { // Left eye head-from-start orientation quaternion x,y,z,w. float32x4_t orientation; // Left eye head-from-start translation x,y,z,pad in meters. float32x4_t translation; // Right eye head-from-start orientation quaternion x,y,z,w. float32x4_t right_orientation; // Right eye head-from-start translation x,y,z,pad in meters. float32x4_t right_translation; // Start-space angular velocity x,y,z,pad in radians per second. float32x4_t angular_velocity; // Start-space positional velocity x,y,z,pad in meters per second. float32x4_t velocity; // Timestamp of when this pose is predicted for, typically halfway through // scanout. int64_t timestamp_ns; // Bitmask of DVR_POSE_FLAG_* constants that apply to this pose. // // If DVR_POSE_FLAG_VALID is not set, the pose is indeterminate. uint64_t flags; // Reserved padding to 128 bytes. uint8_t pad[16]; } DvrPoseAsync; // Returned by the async pose ring buffer access API. typedef struct DvrPoseRingBufferInfo { // Read-only pointer to the pose ring buffer. The current pose is in this // buffer at element buffer[current_frame & (buffer_size - 1)]. The next // frame's forecasted pose is at element // ((current_frame + 1) & (buffer_size - 1)). And so on. The poses are // predicted for when 50% of the corresponding frame's pixel data is visible // to the user. // The last value returned by dvrPresent is the count for the next frame, // which is the earliest that the application could display something if they // were to render promptly. (TODO(jbates) move this comment to dvrPresent). volatile const DvrPoseAsync* buffer; // Minimum number of accurate forecasted poses including the current frame's // pose. This is the number of poses that are udpated by the pose service. // If the application reads past this count, they will get a stale prediction // from a previous frame. Guaranteed to be at least 2. uint32_t min_future_count; // Number of elements in buffer. At least 8 and greater than min_future_count. // Guaranteed to be a power of two. The total size of the buffer in bytes is: // total_count * sizeof(DvrPoseAsync) uint32_t total_count; } DvrPoseRingBufferInfo; typedef enum DvrPoseMode { DVR_POSE_MODE_6DOF = 0, DVR_POSE_MODE_3DOF, DVR_POSE_MODE_MOCK_FROZEN, DVR_POSE_MODE_MOCK_HEAD_TURN_SLOW, DVR_POSE_MODE_MOCK_HEAD_TURN_FAST, DVR_POSE_MODE_MOCK_ROTATE_SLOW, DVR_POSE_MODE_MOCK_ROTATE_MEDIUM, DVR_POSE_MODE_MOCK_ROTATE_FAST, DVR_POSE_MODE_MOCK_CIRCLE_STRAFE, // Always last. DVR_POSE_MODE_COUNT, } DvrPoseMode; typedef enum DvrControllerId { DVR_CONTROLLER_0 = 0, DVR_CONTROLLER_1 = 1, } DvrControllerId; // Creates a new pose client. // // @return Pointer to the created pose client, nullptr on failure. DvrPose* dvrPoseCreate(); // Destroys a pose client. // // @param client Pointer to the pose client to be destroyed. void dvrPoseDestroy(DvrPose* client); // Gets the pose for the given vsync count. // // @param client Pointer to the pose client. // @param vsync_count Vsync that this pose should be forward-predicted to. // Typically this is the count returned by dvrGetNextVsyncCount. // @param out_pose Struct to store pose state. // @return Zero on success, negative error code on failure. int dvrPoseGet(DvrPose* client, uint32_t vsync_count, DvrPoseAsync* out_pose); // Gets the current vsync count. uint32_t dvrPoseGetVsyncCount(DvrPose* client); // Gets the pose for the given controller at the given vsync count. // // @param client Pointer to the pose client. // @param controller_id The controller id. // @param vsync_count Vsync that this pose should be forward-predicted to. // Typically this is the count returned by dvrGetNextVsyncCount. // @param out_pose Struct to store pose state. // @return Zero on success, negative error code on failure. int dvrPoseGetController(DvrPose* client, int32_t controller_id, uint32_t vsync_count, DvrPoseAsync* out_pose); // Enables/disables logging for the controller fusion. // // @param client Pointer to the pose client. // @param enable True starts logging, False stops. // @return Zero on success, negative error code on failure. int dvrPoseLogController(DvrPose* client, bool enable); // DEPRECATED // Polls current pose state. // // @param client Pointer to the pose client. // @param state Struct to store polled state. // @return Zero on success, negative error code on failure. int dvrPosePoll(DvrPose* client, DvrPoseState* state); // Freezes the pose to the provided state. // // Future poll operations will return this state until a different state is // frozen or dvrPoseSetMode() is called with a different mode. The timestamp is // not frozen. // // @param client Pointer to the pose client. // @param frozen_state State pose to be frozen to. // @return Zero on success, negative error code on failure. int dvrPoseFreeze(DvrPose* client, const DvrPoseState* frozen_state); // Sets the pose service mode. // // @param mode The requested pose mode. // @return Zero on success, negative error code on failure. int dvrPoseSetMode(DvrPose* client, DvrPoseMode mode); // Gets the pose service mode. // // @param mode Return value for the current pose mode. // @return Zero on success, negative error code on failure. int dvrPoseGetMode(DvrPose* client, DvrPoseMode* mode); // Get access to the shared memory pose ring buffer. // A future pose at vsync + is accessed at index: // index = ( + ) % out_buffer_size // Where was the last value returned by dvrPresent and // is less than or equal to |out_min_future_count|. // |out_buffer| will be set to a pointer to the buffer. // |out_fd| will be set to the gralloc buffer file descriptor, which is // required for binding this buffer for GPU use. // Returns 0 on success. int dvrPoseGetRingBuffer(DvrPose* client, DvrPoseRingBufferInfo* out_info); #ifdef __cplusplus } // extern "C" #endif #endif // ANDROID_DVR_POSE_CLIENT_H_