2020-04-11 00:28:35 +00:00
|
|
|
// Copyright 2020, Collabora, Ltd.
|
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
|
|
/*!
|
|
|
|
* @file
|
|
|
|
* @brief IPC Client HMD device.
|
|
|
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
|
|
|
* @ingroup ipc_client
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include "xrt/xrt_device.h"
|
|
|
|
|
|
|
|
#include "os/os_time.h"
|
|
|
|
|
|
|
|
#include "math/m_api.h"
|
|
|
|
|
|
|
|
#include "util/u_var.h"
|
|
|
|
#include "util/u_misc.h"
|
|
|
|
#include "util/u_debug.h"
|
|
|
|
#include "util/u_device.h"
|
|
|
|
|
|
|
|
#include "ipc_client.h"
|
|
|
|
#include "ipc_client_generated.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Structs and defines.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2020-06-03 16:43:30 +00:00
|
|
|
/*!
|
|
|
|
* An IPC client proxy for an HMD @ref xrt_device.
|
|
|
|
* @implements xrt_device
|
|
|
|
*/
|
2020-04-11 00:28:35 +00:00
|
|
|
struct ipc_client_hmd
|
|
|
|
{
|
|
|
|
struct xrt_device base;
|
|
|
|
|
2020-07-07 17:24:52 +00:00
|
|
|
struct ipc_connection *ipc_c;
|
2020-04-11 00:28:35 +00:00
|
|
|
|
|
|
|
uint32_t device_id;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Functions
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
static inline struct ipc_client_hmd *
|
|
|
|
ipc_client_hmd(struct xrt_device *xdev)
|
|
|
|
{
|
|
|
|
return (struct ipc_client_hmd *)xdev;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
ipc_client_hmd_destroy(struct xrt_device *xdev)
|
|
|
|
{
|
|
|
|
struct ipc_client_hmd *ich = ipc_client_hmd(xdev);
|
|
|
|
|
|
|
|
// Remove the variable tracking.
|
|
|
|
u_var_remove_root(ich);
|
|
|
|
|
|
|
|
// We do not own these, so don't free them.
|
|
|
|
ich->base.inputs = NULL;
|
|
|
|
ich->base.outputs = NULL;
|
|
|
|
|
|
|
|
// Free this device with the helper.
|
|
|
|
u_device_free(&ich->base);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
ipc_client_hmd_update_inputs(struct xrt_device *xdev)
|
|
|
|
{
|
|
|
|
struct ipc_client_hmd *ich = ipc_client_hmd(xdev);
|
|
|
|
|
2020-06-04 11:48:49 +00:00
|
|
|
xrt_result_t r =
|
2020-04-11 00:28:35 +00:00
|
|
|
ipc_call_device_update_input(ich->ipc_c, ich->device_id);
|
2020-06-04 11:48:49 +00:00
|
|
|
if (r != XRT_SUCCESS) {
|
2020-04-11 00:28:35 +00:00
|
|
|
IPC_DEBUG(ich->ipc_c, "IPC: Error calling input update!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
ipc_client_hmd_get_tracked_pose(struct xrt_device *xdev,
|
|
|
|
enum xrt_input_name name,
|
|
|
|
uint64_t at_timestamp_ns,
|
|
|
|
uint64_t *out_relation_timestamp_ns,
|
|
|
|
struct xrt_space_relation *out_relation)
|
|
|
|
{
|
|
|
|
struct ipc_client_hmd *ich = ipc_client_hmd(xdev);
|
|
|
|
|
2020-06-04 11:48:49 +00:00
|
|
|
xrt_result_t r = ipc_call_device_get_tracked_pose(
|
2020-04-11 00:28:35 +00:00
|
|
|
ich->ipc_c, ich->device_id, name, at_timestamp_ns,
|
|
|
|
out_relation_timestamp_ns, out_relation);
|
2020-06-04 11:48:49 +00:00
|
|
|
if (r != XRT_SUCCESS) {
|
2020-04-11 00:28:35 +00:00
|
|
|
IPC_DEBUG(ich->ipc_c, "IPC: Error calling tracked pose!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
ipc_client_hmd_get_view_pose(struct xrt_device *xdev,
|
|
|
|
struct xrt_vec3 *eye_relation,
|
|
|
|
uint32_t view_index,
|
|
|
|
struct xrt_pose *out_pose)
|
|
|
|
{
|
|
|
|
struct ipc_client_hmd *ich = ipc_client_hmd(xdev);
|
|
|
|
|
2020-06-04 11:48:49 +00:00
|
|
|
xrt_result_t r = ipc_call_device_get_view_pose(
|
2020-04-11 00:28:35 +00:00
|
|
|
ich->ipc_c, ich->device_id, eye_relation, view_index, out_pose);
|
2020-06-04 11:48:49 +00:00
|
|
|
if (r != XRT_SUCCESS) {
|
2020-04-11 00:28:35 +00:00
|
|
|
IPC_DEBUG(ich->ipc_c, "IPC: Error calling view pose!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-03 16:43:30 +00:00
|
|
|
/*!
|
|
|
|
* @public @memberof ipc_client_hmd
|
|
|
|
*/
|
2020-04-11 00:28:35 +00:00
|
|
|
struct xrt_device *
|
2020-07-07 17:24:52 +00:00
|
|
|
ipc_client_hmd_create(struct ipc_connection *ipc_c,
|
2020-05-07 15:24:14 +00:00
|
|
|
struct xrt_tracking_origin *xtrack,
|
|
|
|
uint32_t device_id)
|
2020-04-11 00:28:35 +00:00
|
|
|
{
|
|
|
|
struct ipc_shared_memory *ism = ipc_c->ism;
|
2020-08-18 16:05:43 +00:00
|
|
|
struct ipc_shared_device *isdev = &ism->isdevs[device_id];
|
2020-04-11 00:28:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2020-05-07 15:24:14 +00:00
|
|
|
enum u_device_alloc_flags flags =
|
|
|
|
(enum u_device_alloc_flags)(U_DEVICE_ALLOC_HMD);
|
2020-04-11 00:28:35 +00:00
|
|
|
struct ipc_client_hmd *ich =
|
|
|
|
U_DEVICE_ALLOCATE(struct ipc_client_hmd, flags, 0, 0);
|
|
|
|
ich->ipc_c = ipc_c;
|
|
|
|
ich->device_id = device_id;
|
|
|
|
ich->base.update_inputs = ipc_client_hmd_update_inputs;
|
|
|
|
ich->base.get_tracked_pose = ipc_client_hmd_get_tracked_pose;
|
|
|
|
ich->base.get_view_pose = ipc_client_hmd_get_view_pose;
|
|
|
|
ich->base.destroy = ipc_client_hmd_destroy;
|
|
|
|
|
2020-08-18 16:05:43 +00:00
|
|
|
// Start copying the information from the isdev.
|
2020-05-07 15:24:14 +00:00
|
|
|
ich->base.tracking_origin = xtrack;
|
2020-08-18 16:05:43 +00:00
|
|
|
ich->base.name = isdev->name;
|
2020-04-11 00:28:35 +00:00
|
|
|
ich->device_id = device_id;
|
2020-05-07 15:24:14 +00:00
|
|
|
|
2020-04-11 00:28:35 +00:00
|
|
|
// Print name.
|
2020-08-18 16:05:43 +00:00
|
|
|
snprintf(ich->base.str, XRT_DEVICE_NAME_LEN, "%s", isdev->str);
|
2020-04-11 00:28:35 +00:00
|
|
|
|
|
|
|
// Setup inputs, by pointing directly to the shared memory.
|
2020-08-18 16:05:43 +00:00
|
|
|
assert(isdev->num_inputs > 0);
|
|
|
|
ich->base.inputs = &ism->inputs[isdev->first_input_index];
|
|
|
|
ich->base.num_inputs = isdev->num_inputs;
|
2020-04-11 00:28:35 +00:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
// Setup info.
|
|
|
|
struct u_device_simple_info info;
|
|
|
|
info.display.w_pixels = 1920;
|
|
|
|
info.display.h_pixels = 1080;
|
|
|
|
info.display.w_meters = 0.13f;
|
|
|
|
info.display.h_meters = 0.07f;
|
|
|
|
info.lens_horizontal_separation_meters = 0.13f / 2.0f;
|
|
|
|
info.lens_vertical_position_meters = 0.07f / 2.0f;
|
|
|
|
info.views[0].fov = 85.0f * (M_PI / 180.0f);
|
|
|
|
info.views[1].fov = 85.0f * (M_PI / 180.0f);
|
|
|
|
|
|
|
|
if (!u_device_setup_split_side_by_side(&ich->base, &info)) {
|
|
|
|
IPC_ERROR(ich->ipc_c, "Failed to setup basic device info");
|
|
|
|
ipc_client_hmd_destroy(&ich->base);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// clang-foramt off
|
|
|
|
ich->base.hmd->blend_mode = XRT_BLEND_MODE_OPAQUE;
|
|
|
|
ich->base.hmd->distortion.models = XRT_DISTORTION_MODEL_NONE;
|
|
|
|
ich->base.hmd->distortion.preferred = XRT_DISTORTION_MODEL_NONE;
|
|
|
|
ich->base.hmd->views[0].display.w_pixels =
|
|
|
|
ipc_c->ism->hmd.views[0].display.w_pixels;
|
|
|
|
ich->base.hmd->views[0].display.h_pixels =
|
|
|
|
ipc_c->ism->hmd.views[0].display.h_pixels;
|
|
|
|
ich->base.hmd->views[0].fov = ipc_c->ism->hmd.views[0].fov;
|
|
|
|
ich->base.hmd->views[1].display.w_pixels =
|
|
|
|
ipc_c->ism->hmd.views[1].display.w_pixels;
|
|
|
|
ich->base.hmd->views[1].display.h_pixels =
|
|
|
|
ipc_c->ism->hmd.views[1].display.h_pixels;
|
|
|
|
ich->base.hmd->views[1].fov = ipc_c->ism->hmd.views[1].fov;
|
|
|
|
// clang-foramt on
|
|
|
|
|
|
|
|
// Setup variable tracker.
|
|
|
|
u_var_add_root(ich, ich->base.str, true);
|
|
|
|
u_var_add_ro_u32(ich, &ich->device_id, "device_id");
|
|
|
|
|
2020-06-28 21:45:30 +00:00
|
|
|
ich->base.orientation_tracking_supported =
|
2020-08-18 16:05:43 +00:00
|
|
|
isdev->orientation_tracking_supported;
|
2020-06-28 21:45:30 +00:00
|
|
|
ich->base.position_tracking_supported =
|
2020-08-18 16:05:43 +00:00
|
|
|
isdev->position_tracking_supported;
|
|
|
|
ich->base.device_type = isdev->device_type;
|
2020-06-28 21:45:30 +00:00
|
|
|
|
2020-04-11 00:28:35 +00:00
|
|
|
return &ich->base;
|
|
|
|
}
|