diff --git a/src/xrt/ipc/ipc_client.h b/src/xrt/ipc/ipc_client.h index 15a8d590e..1576fdf05 100644 --- a/src/xrt/ipc/ipc_client.h +++ b/src/xrt/ipc/ipc_client.h @@ -120,7 +120,11 @@ ipc_client_compositor_create(ipc_connection_t *ipc_c, struct xrt_compositor_fd **out_xcfd); struct xrt_device * -ipc_client_hmd_create(ipc_connection_t *ipc_c, uint32_t device_id); +ipc_client_hmd_create(ipc_connection_t *ipc_c, + struct xrt_tracking_origin *xtrack, + uint32_t device_id); struct xrt_device * -ipc_client_device_create(ipc_connection_t *ipc_c, uint32_t device_id); +ipc_client_device_create(ipc_connection_t *ipc_c, + struct xrt_tracking_origin *xtrack, + uint32_t device_id); diff --git a/src/xrt/ipc/ipc_client_device.c b/src/xrt/ipc/ipc_client_device.c index 3a94ab928..052cfb2c9 100644 --- a/src/xrt/ipc/ipc_client_device.c +++ b/src/xrt/ipc/ipc_client_device.c @@ -126,15 +126,17 @@ ipc_client_device_set_output(struct xrt_device *xdev, } struct xrt_device * -ipc_client_device_create(ipc_connection_t *ipc_c, uint32_t device_id) +ipc_client_device_create(ipc_connection_t *ipc_c, + struct xrt_tracking_origin *xtrack, + uint32_t device_id) { // Helpers. struct ipc_shared_memory *ism = ipc_c->ism; struct ipc_shared_device *idev = &ism->idevs[device_id]; // Allocate and setup the basics. - enum u_device_alloc_flags flags = (enum u_device_alloc_flags)( - U_DEVICE_ALLOC_HMD | U_DEVICE_ALLOC_TRACKING_NONE); + enum u_device_alloc_flags flags = + (enum u_device_alloc_flags)(U_DEVICE_ALLOC_HMD); struct ipc_client_device *icd = U_DEVICE_ALLOCATE(struct ipc_client_device, flags, 0, 0); icd->ipc_c = ipc_c; @@ -145,6 +147,7 @@ ipc_client_device_create(ipc_connection_t *ipc_c, uint32_t device_id) icd->base.destroy = ipc_client_device_destroy; // Start copying the information from the idev. + icd->base.tracking_origin = xtrack; icd->base.name = idev->name; icd->device_id = device_id; diff --git a/src/xrt/ipc/ipc_client_hmd.c b/src/xrt/ipc/ipc_client_hmd.c index d77a229c3..bfe1b81f7 100644 --- a/src/xrt/ipc/ipc_client_hmd.c +++ b/src/xrt/ipc/ipc_client_hmd.c @@ -118,15 +118,17 @@ ipc_client_hmd_get_view_pose(struct xrt_device *xdev, } struct xrt_device * -ipc_client_hmd_create(ipc_connection_t *ipc_c, uint32_t device_id) +ipc_client_hmd_create(ipc_connection_t *ipc_c, + struct xrt_tracking_origin *xtrack, + uint32_t device_id) { struct ipc_shared_memory *ism = ipc_c->ism; struct ipc_shared_device *idev = &ism->idevs[device_id]; - enum u_device_alloc_flags flags = (enum u_device_alloc_flags)( - U_DEVICE_ALLOC_HMD | U_DEVICE_ALLOC_TRACKING_NONE); + enum u_device_alloc_flags flags = + (enum u_device_alloc_flags)(U_DEVICE_ALLOC_HMD); struct ipc_client_hmd *ich = U_DEVICE_ALLOCATE(struct ipc_client_hmd, flags, 0, 0); ich->ipc_c = ipc_c; @@ -137,8 +139,10 @@ ipc_client_hmd_create(ipc_connection_t *ipc_c, uint32_t device_id) ich->base.destroy = ipc_client_hmd_destroy; // Start copying the information from the idev. + ich->base.tracking_origin = xtrack; ich->base.name = idev->name; ich->device_id = device_id; + // Print name. snprintf(ich->base.str, XRT_DEVICE_NAME_LEN, "%s", idev->str); diff --git a/src/xrt/ipc/ipc_client_instance.c b/src/xrt/ipc/ipc_client_instance.c index 1fddb35eb..32b110698 100644 --- a/src/xrt/ipc/ipc_client_instance.c +++ b/src/xrt/ipc/ipc_client_instance.c @@ -39,6 +39,9 @@ struct ipc_client_instance ipc_connection_t ipc_c; + struct xrt_tracking_origin *xtracks[8]; + size_t num_xtracks; + struct xrt_device *xdevs[8]; size_t num_xdevs; }; @@ -146,8 +149,15 @@ ipc_client_instance_destroy(struct xrt_instance *xinst) struct ipc_client_instance *ii = ipc_client_instance(xinst); // service considers us to be connected until fd is closed - if (ii->ipc_c.socket_fd >= 0) + if (ii->ipc_c.socket_fd >= 0) { close(ii->ipc_c.socket_fd); + } + + for (size_t i = 0; i < ii->num_xtracks; i++) { + free(ii->xtracks[i]); + ii->xtracks[i] = NULL; + } + ii->num_xtracks = 0; os_mutex_destroy(&ii->ipc_c.mutex); @@ -213,18 +223,38 @@ ipc_instance_create(struct xrt_instance **out_xinst) return -1; } + uint32_t count = 0; + struct xrt_tracking_origin *xtrack = NULL; struct ipc_shared_memory *ism = ii->ipc_c.ism; + // Query the server for how many tracking origins it has. + count = 0; + for (uint32_t i = 0; i < ism->num_itracks; i++) { + fprintf(stderr, "%s\n", ism->itracks[i].name); + xtrack = U_TYPED_CALLOC(struct xrt_tracking_origin); + + memcpy(xtrack->name, ism->itracks[i].name, + sizeof(xtrack->name)); + + xtrack->type = ism->itracks[i].type; + xtrack->offset = ism->itracks[i].offset; + ii->xtracks[count++] = xtrack; + } + + ii->num_xtracks = count; - uint32_t count = 0; // Query the server for how many devices it has. + count = 0; for (uint32_t i = 0; i < ism->num_idevs; i++) { - if (ism->idevs[i].name == XRT_DEVICE_GENERIC_HMD) { + struct ipc_shared_device *idev = &ism->idevs[i]; + xtrack = ii->xtracks[idev->tracking_origin_index]; + + if (idev->name == XRT_DEVICE_GENERIC_HMD) { ii->xdevs[count++] = - ipc_client_hmd_create(&ii->ipc_c, i); + ipc_client_hmd_create(&ii->ipc_c, xtrack, i); } else { ii->xdevs[count++] = - ipc_client_device_create(&ii->ipc_c, i); + ipc_client_device_create(&ii->ipc_c, xtrack, i); } } diff --git a/src/xrt/ipc/ipc_protocol.h b/src/xrt/ipc/ipc_protocol.h index eef12744a..dafea2e2b 100644 --- a/src/xrt/ipc/ipc_protocol.h +++ b/src/xrt/ipc/ipc_protocol.h @@ -9,6 +9,7 @@ #pragma once +#include "xrt/xrt_tracking.h" #include "xrt/xrt_device.h" #include "xrt/xrt_compiler.h" @@ -32,11 +33,26 @@ * */ +struct ipc_shared_tracking_origin +{ + //! For debugging. + char name[XRT_TRACKING_NAME_LEN]; + + //! What can the state tracker expect from this tracking system. + enum xrt_tracking_type type; + + //! Initial offset of the tracking origin. + struct xrt_pose offset; +}; + struct ipc_shared_device { //! Enum identifier of the device. enum xrt_device_name name; + //! Which tracking system origin is this device attached to. + uint32_t tracking_origin_index; + //! A string describing the device. char str[XRT_DEVICE_NAME_LEN]; @@ -133,6 +149,9 @@ struct ipc_layer_slot */ struct ipc_shared_memory { + // This array may be sparse. + size_t num_itracks; + struct ipc_shared_tracking_origin itracks[IPC_SHARED_MAX_DEVICES]; size_t num_idevs; struct ipc_shared_device idevs[IPC_SHARED_MAX_DEVICES]; diff --git a/src/xrt/ipc/ipc_server.h b/src/xrt/ipc/ipc_server.h index 2eedae763..0676007c9 100644 --- a/src/xrt/ipc/ipc_server.h +++ b/src/xrt/ipc/ipc_server.h @@ -140,6 +140,7 @@ struct ipc_server struct xrt_compositor_fd *xcfd; struct xrt_device *xdevs[IPC_SERVER_NUM_XDEVS]; + struct xrt_tracking_origin *xtracks[IPC_SERVER_NUM_XDEVS]; struct ipc_shared_memory *ism; int ism_fd; diff --git a/src/xrt/ipc/ipc_server_process.c b/src/xrt/ipc/ipc_server_process.c index 8ed7ba894..8f9dad249 100644 --- a/src/xrt/ipc/ipc_server_process.c +++ b/src/xrt/ipc/ipc_server_process.c @@ -37,11 +37,13 @@ #include #include #include +#include #ifdef XRT_HAVE_SYSTEMD #include #endif + /* * * Defines and helpers. @@ -85,6 +87,31 @@ teardown_all(struct ipc_server *s) } } +static int +init_tracking_origins(struct ipc_server *s) +{ + for (size_t i = 0; i < IPC_SERVER_NUM_XDEVS; i++) { + if (s->xdevs[i] == NULL) { + continue; + } + + struct xrt_device *xdev = s->xdevs[i]; + struct xrt_tracking_origin *xtrack = xdev->tracking_origin; + size_t index = 0; + + for (; index < IPC_SERVER_NUM_XDEVS; index++) { + if (s->xtracks[index] == NULL) { + s->xtracks[index] = xtrack; + break; + } else if (s->xtracks[index] == xtrack) { + break; + } + } + } + + return 0; +} + static int init_shm(struct ipc_server *s) { @@ -121,11 +148,32 @@ init_shm(struct ipc_server *s) * */ - uint32_t input_index = 0; - uint32_t output_index = 0; uint32_t count = 0; struct ipc_shared_memory *ism = s->ism; + count = 0; + for (size_t i = 0; i < IPC_SERVER_NUM_XDEVS; i++) { + struct xrt_tracking_origin *xtrack = s->xtracks[i]; + if (xtrack == NULL) { + continue; + } + + // The position of the tracking origin matches that in the + // servers memory. + assert(i < IPC_SHARED_MAX_DEVICES); + + struct ipc_shared_tracking_origin *itrack = + &ism->itracks[count++]; + memcpy(itrack->name, xtrack->name, sizeof(itrack->name)); + itrack->type = xtrack->type; + itrack->offset = xtrack->offset; + } + + ism->num_itracks = count; + + count = 0; + uint32_t input_index = 0; + uint32_t output_index = 0; for (size_t i = 0; i < IPC_SERVER_NUM_XDEVS; i++) { struct xrt_device *xdev = s->xdevs[i]; if (xdev == NULL) { @@ -151,6 +199,19 @@ init_shm(struct ipc_server *s) ism->hmd.views[1].fov = xdev->hmd->views[1].fov; } + // Setup the tracking origin. + idev->tracking_origin_index = (uint32_t)-1; + for (size_t k = 0; k < IPC_SERVER_NUM_XDEVS; k++) { + if (xdev->tracking_origin != s->xtracks[i]) { + continue; + } + + idev->tracking_origin_index = i; + break; + } + + assert(idev->tracking_origin_index != (uint32_t)-1); + // Initial update. xrt_device_update_inputs(xdev); @@ -204,6 +265,7 @@ get_systemd_socket(struct ipc_server *s, int *out_fd) #endif return 0; } + static int create_listen_socket(struct ipc_server *s, int *out_fd) { @@ -334,6 +396,12 @@ init_all(struct ipc_server *s) return -1; } + ret = init_tracking_origins(s); + if (ret < 0) { + teardown_all(s); + return -1; + } + ret = xrt_instance_create_fd_compositor(s->xinst, s->xdevs[0], false, &s->xcfd); if (ret < 0) {