From b5e847c8144547b0057ee856e67fb31716b4609a Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz <jakob@collabora.com> Date: Tue, 3 Nov 2020 21:39:20 +0000 Subject: [PATCH] ipc: Add support for device provided bindings --- src/xrt/ipc/client/ipc_client_device.c | 26 +++++++++++ src/xrt/ipc/server/ipc_server_process.c | 59 +++++++++++++++++++++++++ src/xrt/ipc/shared/ipc_protocol.h | 47 ++++++++++++++++++-- 3 files changed, 129 insertions(+), 3 deletions(-) diff --git a/src/xrt/ipc/client/ipc_client_device.c b/src/xrt/ipc/client/ipc_client_device.c index b07005e2a..a9dc7fc12 100644 --- a/src/xrt/ipc/client/ipc_client_device.c +++ b/src/xrt/ipc/client/ipc_client_device.c @@ -188,6 +188,32 @@ ipc_client_device_create(struct ipc_connection *ipc_c, icd->base.outputs = NULL; } + if (isdev->num_binding_profiles > 0) { + icd->base.binding_profiles = U_TYPED_ARRAY_CALLOC( + struct xrt_binding_profile, isdev->num_binding_profiles); + icd->base.num_binding_profiles = isdev->num_binding_profiles; + } + + for (size_t i = 0; i < isdev->num_binding_profiles; i++) { + struct xrt_binding_profile *xbp = + &icd->base.binding_profiles[i]; + struct ipc_shared_binding_profile *isbp = + &ism->binding_profiles[isdev->first_binding_profile_index + + i]; + + xbp->name = isbp->name; + if (isbp->num_inputs > 0) { + xbp->inputs = + &ism->input_pairs[isbp->first_input_index]; + xbp->num_inputs = isbp->num_inputs; + } + if (isbp->num_outputs > 0) { + xbp->outputs = + &ism->output_pairs[isbp->first_output_index]; + xbp->num_outputs = isbp->num_inputs; + } + } + // Setup variable tracker. u_var_add_root(icd, icd->base.str, true); u_var_add_ro_u32(icd, &icd->device_id, "device_id"); diff --git a/src/xrt/ipc/server/ipc_server_process.c b/src/xrt/ipc/server/ipc_server_process.c index 50b15405f..e65e22a27 100644 --- a/src/xrt/ipc/server/ipc_server_process.c +++ b/src/xrt/ipc/server/ipc_server_process.c @@ -138,6 +138,46 @@ init_tracking_origins(struct ipc_server *s) return 0; } +static void +handle_binding(struct ipc_shared_memory *ism, + struct xrt_binding_profile *xbp, + struct ipc_shared_binding_profile *isbp, + uint32_t *input_pair_index_ptr, + uint32_t *output_pair_index_ptr) +{ + uint32_t input_pair_index = *input_pair_index_ptr; + uint32_t output_pair_index = *output_pair_index_ptr; + + isbp->name = xbp->name; + + // Copy the initial state and also count the number in input_pairs. + size_t input_pair_start = input_pair_index; + for (size_t k = 0; k < xbp->num_inputs; k++) { + ism->input_pairs[input_pair_index++] = xbp->inputs[k]; + } + + // Setup the 'offsets' and number of input_pairs. + if (input_pair_start != input_pair_index) { + isbp->num_inputs = input_pair_index - input_pair_start; + isbp->first_input_index = input_pair_start; + } + + // Copy the initial state and also count the number in outputs. + size_t output_pair_start = output_pair_index; + for (size_t k = 0; k < xbp->num_outputs; k++) { + ism->output_pairs[output_pair_index++] = xbp->outputs[k]; + } + + // Setup the 'offsets' and number of output_pairs. + if (output_pair_start != output_pair_index) { + isbp->num_outputs = output_pair_index - output_pair_start; + isbp->first_output_index = output_pair_start; + } + + *input_pair_index_ptr = input_pair_index; + *output_pair_index_ptr = output_pair_index; +} + static int init_shm(struct ipc_server *s) { @@ -185,6 +225,10 @@ init_shm(struct ipc_server *s) count = 0; uint32_t input_index = 0; uint32_t output_index = 0; + uint32_t binding_index = 0; + uint32_t input_pair_index = 0; + uint32_t output_pair_index = 0; + for (size_t i = 0; i < IPC_SERVER_NUM_XDEVS; i++) { struct xrt_device *xdev = s->idevs[i].xdev; if (xdev == NULL) { @@ -233,6 +277,21 @@ init_shm(struct ipc_server *s) // Initial update. xrt_device_update_inputs(xdev); + // Bindings + size_t binding_start = binding_index; + for (size_t k = 0; k < xdev->num_binding_profiles; k++) { + handle_binding(ism, &xdev->binding_profiles[k], + &ism->binding_profiles[binding_index++], + &input_pair_index, &output_pair_index); + } + + // Setup the 'offsets' and number of bindings. + if (binding_start != binding_index) { + isdev->num_binding_profiles = + binding_index - binding_start; + isdev->first_binding_profile_index = binding_start; + } + // Copy the initial state and also count the number in inputs. size_t input_start = input_index; for (size_t k = 0; k < xdev->num_inputs; k++) { diff --git a/src/xrt/ipc/shared/ipc_protocol.h b/src/xrt/ipc/shared/ipc_protocol.h index 592e3e007..a5559397d 100644 --- a/src/xrt/ipc/shared/ipc_protocol.h +++ b/src/xrt/ipc/shared/ipc_protocol.h @@ -35,6 +35,8 @@ #define IPC_SHARED_MAX_DEVICES 8 #define IPC_SHARED_MAX_INPUTS 1024 #define IPC_SHARED_MAX_OUTPUTS 128 +#define IPC_SHARED_MAX_BINDINGS 64 + /* * @@ -42,6 +44,11 @@ * */ +/*! + * A tracking in the shared memory area. + * + * @ingroup ipc + */ struct ipc_shared_tracking_origin { //! For debugging. @@ -54,6 +61,31 @@ struct ipc_shared_tracking_origin struct xrt_pose offset; }; +/*! + * A binding in the shared memory area. + * + * @ingroup ipc + */ +struct ipc_shared_binding_profile +{ + enum xrt_device_name name; + + //! Number of inputs. + uint32_t num_inputs; + //! Offset into the array of pairs where this input bindings starts. + uint32_t first_input_index; + + //! Number of outputs. + uint32_t num_outputs; + //! Offset into the array of pairs where this output bindings starts. + uint32_t first_output_index; +}; + +/*! + * A device in the shared memory area. + * + * @ingroup ipc + */ struct ipc_shared_device { //! Enum identifier of the device. @@ -66,15 +98,19 @@ struct ipc_shared_device //! A string describing the device. char str[XRT_DEVICE_NAME_LEN]; + //! Number of bindings. + uint32_t num_binding_profiles; + //! 'Offset' into the array of bindings where the bindings starts. + uint32_t first_binding_profile_index; + //! Number of inputs. uint32_t num_inputs; - //! 'Offset' into the array of inputs where this devices inputs starts. + //! 'Offset' into the array of inputs where the inputs starts. uint32_t first_input_index; //! Number of outputs. uint32_t num_outputs; - //! 'Offset' into the array of outputs where this devices outputs - //! starts. + //! 'Offset' into the array of outputs where the outputs starts. uint32_t first_output_index; bool orientation_tracking_supported; @@ -194,6 +230,11 @@ struct ipc_shared_memory struct xrt_output outputs[IPC_SHARED_MAX_OUTPUTS]; + struct ipc_shared_binding_profile + binding_profiles[IPC_SHARED_MAX_BINDINGS]; + struct xrt_binding_input_pair input_pairs[IPC_SHARED_MAX_INPUTS]; + struct xrt_binding_output_pair output_pairs[IPC_SHARED_MAX_OUTPUTS]; + struct ipc_layer_slot slots[IPC_MAX_SLOTS]; };