monado/src/xrt/state_trackers/oxr/oxr_api_session.c

411 lines
11 KiB
C
Raw Normal View History

// Copyright 2019-2020, Collabora, Ltd.
2019-03-18 05:52:32 +00:00
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Session entrypoints for the OpenXR state tracker.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup oxr_api
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
2019-03-18 05:52:32 +00:00
#include "xrt/xrt_compiler.h"
#include "util/u_debug.h"
#include "oxr_objects.h"
#include "oxr_logger.h"
#include "oxr_two_call.h"
#include "oxr_api_funcs.h"
#include "oxr_api_verify.h"
#include "oxr_handle.h"
#include "oxr_chain.h"
2019-03-18 05:52:32 +00:00
XrResult
oxr_xrCreateSession(XrInstance instance,
const XrSessionCreateInfo *createInfo,
XrSession *out_session)
2019-03-18 05:52:32 +00:00
{
XrResult ret;
struct oxr_instance *inst;
struct oxr_session *sess, **link;
2019-03-18 05:52:32 +00:00
struct oxr_logger log;
OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst,
"xrCreateSession");
2019-03-23 01:11:14 +00:00
ret = oxr_verify_XrSessionCreateInfo(&log, inst, createInfo);
2019-03-18 05:52:32 +00:00
if (ret != XR_SUCCESS) {
return ret;
}
ret = oxr_session_create(&log, &inst->system, createInfo, &sess);
2019-03-18 05:52:32 +00:00
if (ret != XR_SUCCESS) {
return ret;
}
*out_session = oxr_session_to_openxr(sess);
/* Add to session list */
link = &inst->sessions;
while (*link) {
link = &(*link)->next;
}
*link = sess;
2019-03-18 05:52:32 +00:00
return XR_SUCCESS;
}
XrResult
oxr_xrDestroySession(XrSession session)
{
struct oxr_session *sess, **link;
struct oxr_instance *inst;
2019-03-18 05:52:32 +00:00
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess,
"xrDestroySession");
/* Remove from session list */
inst = sess->sys->inst;
link = &inst->sessions;
while (*link != sess) {
link = &(*link)->next;
}
*link = sess->next;
return oxr_handle_destroy(&log, &sess->handle);
2019-03-18 05:52:32 +00:00
}
XrResult
oxr_xrBeginSession(XrSession session, const XrSessionBeginInfo *beginInfo)
2019-03-18 05:52:32 +00:00
{
struct oxr_session *sess;
2019-03-18 05:52:32 +00:00
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrBeginSession");
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, beginInfo,
XR_TYPE_SESSION_BEGIN_INFO);
OXR_VERIFY_VIEW_CONFIG_TYPE(&log, sess->sys->inst,
beginInfo->primaryViewConfigurationType);
2019-03-18 05:52:32 +00:00
return oxr_session_begin(&log, sess, beginInfo);
}
XrResult
oxr_xrEndSession(XrSession session)
{
struct oxr_session *sess;
2019-03-18 05:52:32 +00:00
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrEndSession");
return oxr_session_end(&log, sess);
}
XrResult
oxr_xrWaitFrame(XrSession session,
const XrFrameWaitInfo *frameWaitInfo,
XrFrameState *frameState)
2019-03-18 05:52:32 +00:00
{
struct oxr_session *sess;
2019-03-18 05:52:32 +00:00
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrWaitFrame");
OXR_VERIFY_ARG_TYPE_CAN_BE_NULL(&log, frameWaitInfo,
XR_TYPE_FRAME_WAIT_INFO);
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, frameState, XR_TYPE_FRAME_STATE);
2019-03-18 05:52:32 +00:00
OXR_VERIFY_ARG_NOT_NULL(&log, frameState);
return oxr_session_frame_wait(&log, sess, frameState);
}
XrResult
oxr_xrBeginFrame(XrSession session, const XrFrameBeginInfo *frameBeginInfo)
2019-03-18 05:52:32 +00:00
{
struct oxr_session *sess;
2019-03-18 05:52:32 +00:00
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrBeginFrame");
// NULL explicitly allowed here because it's a basically empty struct.
OXR_VERIFY_ARG_TYPE_CAN_BE_NULL(&log, frameBeginInfo,
XR_TYPE_FRAME_BEGIN_INFO);
2019-03-18 05:52:32 +00:00
return oxr_session_frame_begin(&log, sess);
}
XrResult
oxr_xrEndFrame(XrSession session, const XrFrameEndInfo *frameEndInfo)
2019-03-18 05:52:32 +00:00
{
struct oxr_session *sess;
2019-03-18 05:52:32 +00:00
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrEndFrame");
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, frameEndInfo,
XR_TYPE_FRAME_END_INFO);
2019-03-18 05:52:32 +00:00
return oxr_session_frame_end(&log, sess, frameEndInfo);
}
2019-07-13 16:17:57 +00:00
XrResult
oxr_xrRequestExitSession(XrSession session)
{
struct oxr_session *sess;
2019-07-13 16:17:57 +00:00
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess,
"xrRequestExitSession");
return oxr_session_request_exit(&log, sess);
2019-07-13 16:17:57 +00:00
}
2019-03-18 05:52:32 +00:00
XrResult
oxr_xrLocateViews(XrSession session,
const XrViewLocateInfo *viewLocateInfo,
XrViewState *viewState,
2019-03-18 05:52:32 +00:00
uint32_t viewCapacityInput,
uint32_t *viewCountOutput,
XrView *views)
2019-03-18 05:52:32 +00:00
{
struct oxr_session *sess;
struct oxr_space *spc;
2019-03-18 05:52:32 +00:00
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrLocateViews");
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, viewLocateInfo,
XR_TYPE_VIEW_LOCATE_INFO);
2019-03-18 05:52:32 +00:00
OXR_VERIFY_SPACE_NOT_NULL(&log, viewLocateInfo->space, spc);
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, viewState, XR_TYPE_VIEW_STATE);
2019-03-18 05:52:32 +00:00
if (viewCapacityInput == 0) {
OXR_VERIFY_ARG_NOT_NULL(&log, viewCountOutput);
} else {
OXR_VERIFY_ARG_NOT_NULL(&log, views);
}
return oxr_session_views(&log, sess, viewLocateInfo, viewState,
viewCapacityInput, viewCountOutput, views);
}
/*
*
* XR_KHR_visibility_mask
*
*/
#ifdef XR_KHR_visibility_mask
XrResult
oxr_xrGetVisibilityMaskKHR(XrSession session,
XrViewConfigurationType viewConfigurationType,
uint32_t viewIndex,
XrVisibilityMaskTypeKHR visibilityMaskType,
XrVisibilityMaskKHR *visibilityMask)
2019-03-18 05:52:32 +00:00
{
struct oxr_session *sess;
2019-03-18 05:52:32 +00:00
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess,
"xrGetVisibilityMaskKHR");
return oxr_error(&log, XR_ERROR_HANDLE_INVALID, "Not implemented");
2019-03-18 05:52:32 +00:00
}
#endif
/*
*
* XR_EXT_performance_settings
*
*/
#ifdef XR_EXT_performance_settings
XrResult
oxr_xrPerfSettingsSetPerformanceLevelEXT(XrSession session,
XrPerfSettingsDomainEXT domain,
XrPerfSettingsLevelEXT level)
{
struct oxr_session *sess;
2019-03-18 05:52:32 +00:00
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess,
"xrPerfSettingsSetPerformanceLevelEXT");
return oxr_error(&log, XR_ERROR_HANDLE_INVALID, "Not implemented");
2019-03-18 05:52:32 +00:00
}
#endif
/*
*
* XR_EXT_thermal_query
*
*/
#ifdef XR_EXT_thermal_query
XrResult
oxr_xrThermalGetTemperatureTrendEXT(
XrSession session,
XrPerfSettingsDomainEXT domain,
XrPerfSettingsNotificationLevelEXT *notificationLevel,
float *tempHeadroom,
float *tempSlope)
2019-03-18 05:52:32 +00:00
{
struct oxr_session *sess;
2019-03-18 05:52:32 +00:00
struct oxr_logger log;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess,
"xrThermalGetTemperatureTrendEXT");
return oxr_error(&log, XR_ERROR_HANDLE_INVALID, "Not implemented");
2019-03-18 05:52:32 +00:00
}
/*
*
* XR_EXT_hand_tracking
*
*/
static XrResult
oxr_hand_tracker_destroy_cb(struct oxr_logger *log, struct oxr_handle_base *hb)
{
struct oxr_hand_tracker *hand_tracker = (struct oxr_hand_tracker *)hb;
free(hand_tracker);
return XR_SUCCESS;
}
XrResult
oxr_hand_tracker_create(struct oxr_logger *log,
struct oxr_session *sess,
const XrHandTrackerCreateInfoEXT *createInfo,
struct oxr_hand_tracker **out_hand_tracker)
{
if (!oxr_system_get_hand_tracking_support(log, sess->sys->inst)) {
return oxr_error(log, XR_ERROR_FEATURE_UNSUPPORTED,
"System does not support hand tracking");
}
struct oxr_hand_tracker *hand_tracker = NULL;
OXR_ALLOCATE_HANDLE_OR_RETURN(log, hand_tracker, OXR_XR_DEBUG_HTRACKER,
oxr_hand_tracker_destroy_cb,
&sess->handle);
hand_tracker->sess = sess;
hand_tracker->hand = createInfo->hand;
hand_tracker->hand_joint_set = createInfo->handJointSet;
*out_hand_tracker = hand_tracker;
return XR_SUCCESS;
}
XrResult
oxr_xrCreateHandTrackerEXT(XrSession session,
const XrHandTrackerCreateInfoEXT *createInfo,
XrHandTrackerEXT *handTracker)
{
struct oxr_hand_tracker *hand_tracker = NULL;
struct oxr_session *sess = NULL;
struct oxr_logger log;
XrResult ret;
OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess,
"xrCreateHandTrackerEXT");
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, createInfo,
XR_TYPE_HAND_TRACKER_CREATE_INFO_EXT);
OXR_VERIFY_ARG_NOT_NULL(&log, handTracker);
OXR_VERIFY_EXTENSION(&log, sess->sys->inst, EXT_hand_tracking);
if (createInfo->hand != XR_HAND_LEFT_EXT &&
createInfo->hand != XR_HAND_RIGHT_EXT) {
return oxr_error(&log, XR_ERROR_VALIDATION_FAILURE,
"Invalid hand value %d\n", createInfo->hand);
}
if (createInfo->handJointSet != XR_HAND_JOINT_SET_DEFAULT_EXT) {
return oxr_error(&log, XR_ERROR_VALIDATION_FAILURE,
"Invalid handJointSet value %d\n",
createInfo->handJointSet);
}
ret = oxr_hand_tracker_create(&log, sess, createInfo, &hand_tracker);
if (ret != XR_SUCCESS) {
return ret;
}
*handTracker = oxr_hand_tracker_to_openxr(hand_tracker);
return XR_SUCCESS;
}
XrResult
oxr_xrDestroyHandTrackerEXT(XrHandTrackerEXT handTracker)
{
struct oxr_hand_tracker *hand_tracker;
struct oxr_logger log;
OXR_VERIFY_HAND_TRACKER_AND_INIT_LOG(&log, handTracker, hand_tracker,
"xrDestroyHandTrackerEXT");
return oxr_handle_destroy(&log, &hand_tracker->handle);
}
XrResult
oxr_xrLocateHandJointsEXT(XrHandTrackerEXT handTracker,
const XrHandJointsLocateInfoEXT *locateInfo,
XrHandJointLocationsEXT *locations)
{
struct oxr_hand_tracker *hand_tracker;
struct oxr_space *spc;
struct oxr_logger log;
OXR_VERIFY_HAND_TRACKER_AND_INIT_LOG(&log, handTracker, hand_tracker,
"xrLocateHandJointsEXT");
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, locateInfo,
XR_TYPE_HAND_JOINTS_LOCATE_INFO_EXT);
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, locations,
XR_TYPE_HAND_JOINT_LOCATIONS_EXT);
OXR_VERIFY_SPACE_NOT_NULL(&log, locateInfo->baseSpace, spc);
if (locateInfo->time <= (XrTime)0) {
return oxr_error(&log, XR_ERROR_TIME_INVALID,
"(time == %" PRIi64 ") is not a valid time.",
locateInfo->time);
}
if (hand_tracker->hand_joint_set == XR_HAND_JOINT_SET_DEFAULT_EXT) {
if (locations->jointCount != XR_HAND_JOINT_COUNT_EXT) {
return oxr_error(&log, XR_ERROR_VALIDATION_FAILURE,
"joint count must be %d, not %d\n",
XR_HAND_JOINT_COUNT_EXT,
locations->jointCount);
}
};
XrHandJointVelocitiesEXT *vel = OXR_GET_OUTPUT_FROM_CHAIN(
locations, XR_TYPE_HAND_JOINT_VELOCITIES_EXT,
XrHandJointVelocitiesEXT);
if (vel) {
if (vel->jointCount <= 0) {
return oxr_error(&log, XR_ERROR_VALIDATION_FAILURE,
"XrHandJointVelocitiesEXT joint count "
"must be >0, is %d\n",
vel->jointCount);
}
if (hand_tracker->hand_joint_set ==
XR_HAND_JOINT_SET_DEFAULT_EXT) {
if (vel->jointCount != XR_HAND_JOINT_COUNT_EXT) {
return oxr_error(
&log, XR_ERROR_VALIDATION_FAILURE,
"XrHandJointVelocitiesEXT joint count must "
"be %d, not %d\n",
XR_HAND_JOINT_COUNT_EXT,
locations->jointCount);
}
}
}
return oxr_session_hand_joints(&log, hand_tracker, locateInfo,
locations);
}
2019-03-18 05:52:32 +00:00
#endif