mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06:18 +00:00
ipc: Add variable number of views get function
This commit is contained in:
parent
7251417569
commit
cec787ba0f
|
@ -21,6 +21,7 @@
|
|||
#include "util/u_distortion_mesh.h"
|
||||
|
||||
#include "client/ipc_client.h"
|
||||
#include "client/ipc_client_connection.h"
|
||||
#include "ipc_client_generated.h"
|
||||
|
||||
#include <math.h>
|
||||
|
@ -48,7 +49,7 @@ typedef struct ipc_client_xdev ipc_client_hmd_t;
|
|||
|
||||
/*
|
||||
*
|
||||
* Functions
|
||||
* Helpers.
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -58,6 +59,78 @@ ipc_client_hmd(struct xrt_device *xdev)
|
|||
return (ipc_client_hmd_t *)xdev;
|
||||
}
|
||||
|
||||
static void
|
||||
call_get_view_poses_raw(ipc_client_hmd_t *ich,
|
||||
const struct xrt_vec3 *default_eye_relation,
|
||||
uint64_t at_timestamp_ns,
|
||||
uint32_t view_count,
|
||||
struct xrt_space_relation *out_head_relation,
|
||||
struct xrt_fov *out_fovs,
|
||||
struct xrt_pose *out_poses)
|
||||
{
|
||||
struct ipc_connection *ipc_c = ich->ipc_c;
|
||||
xrt_result_t xret = XRT_SUCCESS;
|
||||
|
||||
ipc_client_connection_lock(ipc_c);
|
||||
|
||||
// Using the raw send helper is the only one that is required.
|
||||
xret = ipc_send_device_get_view_poses_locked( //
|
||||
ipc_c, //
|
||||
ich->device_id, //
|
||||
default_eye_relation, //
|
||||
at_timestamp_ns, //
|
||||
view_count); //
|
||||
if (xret != XRT_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
// This is the data we get back in the provided reply.
|
||||
uint32_t returned_view_count = 0;
|
||||
struct xrt_space_relation head_relation = XRT_SPACE_RELATION_ZERO;
|
||||
|
||||
// Get the reply, use the raw function helper.
|
||||
xret = ipc_receive_device_get_view_poses_locked( //
|
||||
ipc_c, //
|
||||
&head_relation, //
|
||||
&returned_view_count); //
|
||||
if (xret != XRT_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (view_count != returned_view_count) {
|
||||
IPC_ERROR(ich->ipc_c, "Wrong view counts (sent: %u != got: %u)", view_count, returned_view_count);
|
||||
assert(false);
|
||||
}
|
||||
|
||||
// We can read directly to the output variables.
|
||||
xret = ipc_receive(&ipc_c->imc, out_fovs, sizeof(struct xrt_fov) * view_count);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
// We can read directly to the output variables.
|
||||
xret = ipc_receive(&ipc_c->imc, out_poses, sizeof(struct xrt_pose) * view_count);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally set the head_relation that we got in the reply, mostly to
|
||||
* demonstrate that you can use the reply struct in such a way.
|
||||
*/
|
||||
*out_head_relation = head_relation;
|
||||
|
||||
out:
|
||||
ipc_client_connection_unlock(ipc_c);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Member functions
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
ipc_client_hmd_destroy(struct xrt_device *xdev)
|
||||
{
|
||||
|
@ -114,6 +187,7 @@ ipc_client_hmd_get_view_poses(struct xrt_device *xdev,
|
|||
struct ipc_info_get_view_poses_2 info = {0};
|
||||
|
||||
if (view_count == 2) {
|
||||
// Fast path.
|
||||
xrt_result_t r = ipc_call_device_get_view_poses_2( //
|
||||
ich->ipc_c, //
|
||||
ich->device_id, //
|
||||
|
@ -129,9 +203,22 @@ ipc_client_hmd_get_view_poses(struct xrt_device *xdev,
|
|||
out_fovs[i] = info.fovs[i];
|
||||
out_poses[i] = info.poses[i];
|
||||
}
|
||||
|
||||
} else if (view_count <= IPC_MAX_RAW_VIEWS) {
|
||||
// Artificial limit.
|
||||
|
||||
call_get_view_poses_raw( //
|
||||
ich, //
|
||||
default_eye_relation, //
|
||||
at_timestamp_ns, //
|
||||
view_count, //
|
||||
out_head_relation, //
|
||||
out_fovs, //
|
||||
out_poses); //
|
||||
} else {
|
||||
IPC_ERROR(ich->ipc_c, "Cannot handle %u view_count, only 2 supported.", view_count);
|
||||
assert(false && !"Can only handle view_count of 2.");
|
||||
IPC_ERROR(ich->ipc_c, "Cannot handle %u view_count, %u or less supported.", view_count,
|
||||
(uint32_t)IPC_MAX_RAW_VIEWS);
|
||||
assert(false && !"Too large view_count!");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1419,6 +1419,85 @@ ipc_handle_device_get_hand_tracking(volatile struct ipc_client_state *ics,
|
|||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
ipc_handle_device_get_view_poses(volatile struct ipc_client_state *ics,
|
||||
uint32_t id,
|
||||
const struct xrt_vec3 *fallback_eye_relation,
|
||||
uint64_t at_timestamp_ns,
|
||||
uint32_t view_count)
|
||||
{
|
||||
struct ipc_message_channel *imc = (struct ipc_message_channel *)&ics->imc;
|
||||
struct ipc_device_get_view_poses_reply reply = XRT_STRUCT_INIT;
|
||||
struct ipc_server *s = ics->server;
|
||||
xrt_result_t xret;
|
||||
|
||||
// To make the code a bit more readable.
|
||||
uint32_t device_id = id;
|
||||
struct xrt_device *xdev = get_xdev(ics, device_id);
|
||||
|
||||
|
||||
if (view_count == 0 || view_count > IPC_MAX_RAW_VIEWS) {
|
||||
IPC_ERROR(s, "Client asked for zero or too many views! (%u)", view_count);
|
||||
|
||||
reply.result = XRT_ERROR_IPC_FAILURE;
|
||||
// Send the full reply, the client expects it.
|
||||
return ipc_send(imc, &reply, sizeof(reply));
|
||||
}
|
||||
|
||||
// Data to get.
|
||||
struct xrt_fov fovs[IPC_MAX_RAW_VIEWS];
|
||||
struct xrt_pose poses[IPC_MAX_RAW_VIEWS];
|
||||
|
||||
xrt_device_get_view_poses( //
|
||||
xdev, //
|
||||
fallback_eye_relation, //
|
||||
at_timestamp_ns, //
|
||||
view_count, //
|
||||
&reply.head_relation, //
|
||||
fovs, //
|
||||
poses); //
|
||||
|
||||
/*
|
||||
* Operation ok, head_relation has already been put in the reply
|
||||
* struct, so we don't need to send that manually.
|
||||
*/
|
||||
reply.result = XRT_SUCCESS;
|
||||
|
||||
/*
|
||||
* This isn't really needed, but demonstrates the server sending the
|
||||
* length back in the reply, a common pattern for other functions.
|
||||
*/
|
||||
reply.view_count = view_count;
|
||||
|
||||
/*
|
||||
* Send the reply first isn't required for functions in general, but it
|
||||
* will need to match what the client expects. This demonstrates the
|
||||
* server sending the length back in the reply, a common pattern for
|
||||
* other functions.
|
||||
*/
|
||||
xret = ipc_send(imc, &reply, sizeof(reply));
|
||||
if (xret != XRT_SUCCESS) {
|
||||
IPC_ERROR(s, "Failed to send reply!");
|
||||
return xret;
|
||||
}
|
||||
|
||||
// Send the fovs that we got.
|
||||
xret = ipc_send(imc, fovs, sizeof(struct xrt_fov) * view_count);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
IPC_ERROR(s, "Failed to send fovs!");
|
||||
return xret;
|
||||
}
|
||||
|
||||
// And finally the poses.
|
||||
xret = ipc_send(imc, poses, sizeof(struct xrt_pose) * view_count);
|
||||
if (xret != XRT_SUCCESS) {
|
||||
IPC_ERROR(s, "Failed to send poses!");
|
||||
return xret;
|
||||
}
|
||||
|
||||
return XRT_SUCCESS;
|
||||
}
|
||||
|
||||
xrt_result_t
|
||||
ipc_handle_device_get_view_poses_2(volatile struct ipc_client_state *ics,
|
||||
uint32_t id,
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#define IPC_MAX_LAYERS 16
|
||||
#define IPC_MAX_SLOTS 128
|
||||
#define IPC_MAX_CLIENTS 8
|
||||
#define IPC_MAX_RAW_VIEWS 32 // Max views that we can get, artificial limit.
|
||||
#define IPC_EVENT_QUEUE_SIZE 32
|
||||
|
||||
#define IPC_SHARED_MAX_INPUTS 1024
|
||||
|
|
|
@ -307,6 +307,20 @@
|
|||
]
|
||||
},
|
||||
|
||||
"device_get_view_poses": {
|
||||
"varlen": true,
|
||||
"in": [
|
||||
{"name": "id", "type": "uint32_t"},
|
||||
{"name": "fallback_eye_relation", "type": "struct xrt_vec3"},
|
||||
{"name": "at_timestamp_ns", "type": "uint64_t"},
|
||||
{"name": "view_count", "type": "uint32_t"}
|
||||
],
|
||||
"out": [
|
||||
{"name": "head_relation", "type": "struct xrt_space_relation"},
|
||||
{"name": "view_count", "type": "uint32_t"}
|
||||
]
|
||||
},
|
||||
|
||||
"device_get_view_poses_2": {
|
||||
"in": [
|
||||
{"name": "id", "type": "uint32_t"},
|
||||
|
|
Loading…
Reference in a new issue