blob: 37b12978536bb00f8f6ca9e6858dc1cbc7c88da1 [file] [log] [blame]
#ifndef ANDROID_DVR_EDS_H_
#define ANDROID_DVR_EDS_H_
#include <stdbool.h>
#include <stdint.h>
#include <sys/cdefs.h>
#include <sys/types.h>
__BEGIN_DECLS
// This struct aligns with GLSL uniform blocks with std140 layout.
// std140 allows padding between certain types, so padding must be explicitly
// added as struct members.
struct __attribute__((__packed__)) DvrLateLatchData {
// Column-major order.
float view_proj_matrix[16];
// Column-major order.
float view_matrix[16];
float pose_quaternion[4];
float pose_position[4];
};
//
// These APIs are not thread safe and must be called on a single thread with an
// actively bound GL context corresponding to a display surface.
//
// Prepares EDS and Late Latching system. Idempotent if called more than once.
// The target GL context must be created and bound.
//
// If |with_late_latch| is true, a thread will be created that asynchronously
// updates the pose in memory.
//
// The following GL states are modified as follows:
// glBindBuffer(GL_ARRAY_BUFFER, 0);
// glBindBuffer(GL_UNIFORM_BUFFER, 0);
//
// Returns 0 on success, negative error code on failure.
// Check GL errors with glGetError for other error conditions.
int dvrEdsInit(bool with_late_latch);
// Stops and destroys the EDS Late Latching system.
void dvrEdsDeinit();
// Submits GL draw command that will capture the latest head pose into a uniform
// buffer object. This should be called twice per frame, before the app begins
// drawing for each eye.
// For each eye, a later call to dvrEdsBlitPose will write this pose into
// the application framebuffer corner so that the EDS service knows what pose
// the frame was rendered with.
//
// |eye| is 0 for left eye and 1 for right eye.
//
// The following GL states are modified as follows:
// glUseProgram(0);
// glBindBuffer(GL_UNIFORM_BUFFER, 0);
// glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, id);
// glDisable(GL_RASTERIZER_DISCARD);
//
// Returns 0 on success, negative error code on failure:
// EPERM - dvrEdsInit(true) was not called.
// Check GL errors with glGetError for other error conditions.
int dvrEdsCapturePoseAsync(int eye, uint32_t target_vsync_count,
const float* projection_matrix,
const float* eye_from_head_matrix,
const float* pose_offset_matrix);
// Binds the late-latch output data as a GL_UNIFORM_BUFFER so that your vertex
// shaders can use the latest head pose. For example, to bind just the
// view_matrix from the output:
//
// dvrEdsBindPose(eye, BINDING,
// offsetof(DvrLateLatchData, view_matrix),
// sizeof(DvrLateLatchData::view_matrix));
//
// Or more commonly, bind the view projection matrix:
//
// dvrEdsBindPose(eye, BINDING,
// offsetof(DvrLateLatchData, view_proj_matrix),
// sizeof(DvrLateLatchData::view_proj_matrix));
//
// BINDING in the above examples is the binding location of the uniform
// interface block in the GLSL shader.
//
// Shader example (3 would be the |ubo_binding| passed to this function):
// layout(binding = 3, std140) uniform LateLatchData {
// mat4 uViewProjection;
// };
//
// |eye| is 0 for left eye and 1 for right eye.
//
// The following GL states are modified as follows:
// glBindBuffer(GL_UNIFORM_BUFFER, ...);
// glBindBufferRange(GL_UNIFORM_BUFFER, ...);
//
// To clear the binding, call glBindBuffer(GL_UNIFORM_BUFFER, 0);
//
// Returns 0 on success, negative error code on failure:
// EPERM - dvrEdsInit(true) was not called.
// Check GL errors with glGetError for other error conditions.
int dvrEdsBindPose(int eye, uint32_t ubo_binding, intptr_t offset,
ssize_t size);
// DEPRECATED
//
// Blits the pose captured previously into the currently bound framebuffer.
// The current framebuffer is assumed to be the default framebuffer 0, the
// surface that will be sent to the display and have EDS and lens warp applied
// to it.
//
// |eye| is 0 for left eye and 1 for right eye.
// |viewport_width| is the width of the viewport for this eye, which is
// usually half the width of the framebuffer.
// |viewport_height| is the height of the viewport for this eye, which is
// usually the height of the framebuffer.
//
// The following GL states are modified as follows:
// glUseProgram(0);
// glBindBuffer(GL_UNIFORM_BUFFER, 0);
// glBindBufferRange(GL_UNIFORM_BUFFER, 23, ...);
//
// Returns 0 on success, negative error code on failure:
// EPERM - dvrEdsInit was not called.
// Check GL errors with glGetError for other error conditions.
int dvrEdsBlitPose(int eye, int viewport_width, int viewport_height);
// DEPRECATED
//
// Same as dvrEdsBlitPose except that the pose is provided as an
// parameter instead of getting it from dvrEdsBindPose. This is for
// applications that want EDS but do not want late-latching.
//
// |pose_quaternion| should point to 4 floats that represent a quaternion.
// |pose_position| should point to 3 floats that represent x,y,z position.
//
// GL states are modified as follows:
// glUseProgram(0);
// glBindBuffer(GL_UNIFORM_BUFFER, 0);
// glBindBufferBase(GL_UNIFORM_BUFFER, 23, ...);
//
// Returns 0 on success, negative error code on failure:
// EPERM - dvrEdsInit was not called.
// Check GL errors with glGetError for other error conditions.
int dvrEdsBlitPoseFromCpu(int eye, int viewport_width, int viewport_height,
const float* pose_quaternion,
const float* pose_position);
__END_DECLS
#endif // ANDROID_DVR_EDS_H_