2020-04-11 00:28:35 +00:00
|
|
|
// Copyright 2020, Collabora, Ltd.
|
|
|
|
// SPDX-License-Identifier: BSL-1.0
|
|
|
|
/*!
|
|
|
|
* @file
|
|
|
|
* @brief Common server side code.
|
|
|
|
* @author Pete Black <pblack@collabora.com>
|
|
|
|
* @author Jakob Bornecrantz <jakob@collabora.com>
|
|
|
|
* @ingroup ipc_server
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "xrt/xrt_compiler.h"
|
|
|
|
|
2020-06-23 20:30:18 +00:00
|
|
|
#include "util/u_render_timing.h"
|
|
|
|
|
2020-04-11 00:28:35 +00:00
|
|
|
#include "os/os_threading.h"
|
|
|
|
|
2020-05-08 19:24:21 +00:00
|
|
|
#include "ipc_protocol.h"
|
2020-07-07 21:06:41 +00:00
|
|
|
#include "ipc_utils.h"
|
2020-05-08 19:24:21 +00:00
|
|
|
|
2020-04-11 00:28:35 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Logging
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Spew level logging.
|
|
|
|
*/
|
|
|
|
#define IPC_SPEW(c, ...) \
|
|
|
|
do { \
|
|
|
|
if (c->print_spew) { \
|
|
|
|
fprintf(stderr, "%s - ", __func__); \
|
|
|
|
fprintf(stderr, __VA_ARGS__); \
|
|
|
|
fprintf(stderr, "\n"); \
|
|
|
|
} \
|
|
|
|
} while (false)
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Debug level logging.
|
|
|
|
*/
|
|
|
|
#define IPC_DEBUG(c, ...) \
|
|
|
|
do { \
|
|
|
|
if (c->print_debug) { \
|
|
|
|
fprintf(stderr, "%s - ", __func__); \
|
|
|
|
fprintf(stderr, __VA_ARGS__); \
|
|
|
|
fprintf(stderr, "\n"); \
|
|
|
|
} \
|
|
|
|
} while (false)
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Structs
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define IPC_SERVER_NUM_XDEVS 8
|
2020-05-30 15:34:40 +00:00
|
|
|
#define IPC_MAX_CLIENT_SWAPCHAINS 32
|
2020-06-17 06:36:38 +00:00
|
|
|
//#define IPC_MAX_CLIENTS 8
|
2020-04-11 00:28:35 +00:00
|
|
|
|
|
|
|
struct xrt_instance;
|
|
|
|
struct xrt_compositor;
|
2020-07-14 22:13:07 +00:00
|
|
|
struct xrt_compositor_native;
|
2020-05-12 12:58:17 +00:00
|
|
|
|
2020-04-11 00:28:35 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* Information about a single swapchain.
|
|
|
|
*
|
|
|
|
* @ingroup ipc_server
|
|
|
|
*/
|
|
|
|
struct ipc_swapchain_data
|
|
|
|
{
|
|
|
|
uint32_t width;
|
|
|
|
uint32_t height;
|
|
|
|
uint64_t format;
|
|
|
|
uint32_t num_images;
|
2020-05-30 15:34:40 +00:00
|
|
|
|
|
|
|
bool active;
|
2020-04-11 00:28:35 +00:00
|
|
|
};
|
|
|
|
|
2020-06-17 06:36:38 +00:00
|
|
|
|
|
|
|
struct ipc_queued_event
|
|
|
|
{
|
|
|
|
bool pending;
|
|
|
|
uint64_t timestamp;
|
|
|
|
union xrt_compositor_event event;
|
|
|
|
};
|
|
|
|
|
2020-04-11 00:28:35 +00:00
|
|
|
/*!
|
|
|
|
* Holds the state for a single client.
|
|
|
|
*
|
|
|
|
* @ingroup ipc_server
|
|
|
|
*/
|
|
|
|
struct ipc_client_state
|
|
|
|
{
|
|
|
|
//! Link back to the main server.
|
|
|
|
struct ipc_server *server;
|
|
|
|
|
|
|
|
//! Compositor for this client.
|
|
|
|
struct xrt_compositor *xc;
|
|
|
|
|
|
|
|
//! Number of swapchains in use by client
|
|
|
|
uint32_t num_swapchains;
|
|
|
|
|
|
|
|
//! Ptrs to the swapchains
|
|
|
|
struct xrt_swapchain *xscs[IPC_MAX_CLIENT_SWAPCHAINS];
|
|
|
|
|
|
|
|
//! Data for the swapchains.
|
|
|
|
struct ipc_swapchain_data swapchain_data[IPC_MAX_CLIENT_SWAPCHAINS];
|
|
|
|
|
|
|
|
//! Socket fd used for client comms
|
2020-07-07 21:06:41 +00:00
|
|
|
struct ipc_message_channel imc;
|
2020-04-11 00:28:35 +00:00
|
|
|
|
|
|
|
//! State for rendering.
|
2020-06-09 22:04:06 +00:00
|
|
|
struct ipc_layer_slot render_state;
|
|
|
|
|
|
|
|
//! Whether we are currently rendering @ref render_state
|
|
|
|
bool rendering_state;
|
2020-04-11 00:28:35 +00:00
|
|
|
|
2020-06-17 06:36:38 +00:00
|
|
|
//! The frame timing state.
|
|
|
|
struct u_rt_helper urth;
|
|
|
|
|
|
|
|
struct ipc_app_state client_state;
|
|
|
|
struct ipc_queued_event queued_events[IPC_EVENT_QUEUE_SIZE];
|
|
|
|
|
|
|
|
int server_thread_index;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum ipc_thread_state
|
|
|
|
{
|
|
|
|
IPC_THREAD_READY,
|
|
|
|
IPC_THREAD_STARTING,
|
|
|
|
IPC_THREAD_RUNNING,
|
|
|
|
IPC_THREAD_STOPPING,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ipc_thread
|
|
|
|
{
|
|
|
|
struct os_thread thread;
|
|
|
|
volatile enum ipc_thread_state state;
|
|
|
|
volatile struct ipc_client_state ics;
|
2020-04-11 00:28:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Main IPC object for the server.
|
|
|
|
*
|
|
|
|
* @ingroup ipc_server
|
|
|
|
*/
|
|
|
|
struct ipc_server
|
|
|
|
{
|
|
|
|
struct xrt_instance *xinst;
|
|
|
|
|
|
|
|
struct xrt_compositor *xc;
|
2020-07-14 22:13:07 +00:00
|
|
|
struct xrt_compositor_native *xcn;
|
2020-04-11 00:28:35 +00:00
|
|
|
|
|
|
|
struct xrt_device *xdevs[IPC_SERVER_NUM_XDEVS];
|
2020-05-07 15:24:14 +00:00
|
|
|
struct xrt_tracking_origin *xtracks[IPC_SERVER_NUM_XDEVS];
|
2020-04-11 00:28:35 +00:00
|
|
|
|
|
|
|
struct ipc_shared_memory *ism;
|
2020-07-16 16:22:40 +00:00
|
|
|
xrt_shmem_handle_t ism_handle;
|
2020-04-11 00:28:35 +00:00
|
|
|
|
|
|
|
//! Socket that we accept connections on.
|
|
|
|
int listen_socket;
|
|
|
|
|
|
|
|
//! For waiting on various events in the main thread.
|
|
|
|
int epoll_fd;
|
|
|
|
|
|
|
|
// Is the mainloop supposed to run.
|
|
|
|
volatile bool running;
|
|
|
|
|
|
|
|
// Should we exit when a client disconnects.
|
|
|
|
bool exit_on_disconnect;
|
|
|
|
|
2020-05-01 20:55:12 +00:00
|
|
|
//! Were we launched by socket activation, instead of explicitly?
|
|
|
|
bool launched_by_socket;
|
|
|
|
|
2020-05-07 21:50:57 +00:00
|
|
|
//! The socket filename we bound to, if any.
|
|
|
|
char *socket_filename;
|
|
|
|
|
2020-04-11 00:28:35 +00:00
|
|
|
bool print_debug;
|
|
|
|
bool print_spew;
|
|
|
|
|
2020-06-17 06:36:38 +00:00
|
|
|
struct ipc_thread threads[IPC_MAX_CLIENTS];
|
2020-06-23 20:30:18 +00:00
|
|
|
|
2020-06-17 06:36:38 +00:00
|
|
|
volatile uint32_t current_slot_index;
|
2020-06-23 20:30:18 +00:00
|
|
|
|
2020-06-17 06:36:38 +00:00
|
|
|
int active_client_index;
|
|
|
|
int last_active_client_index;
|
|
|
|
struct os_mutex global_state_lock;
|
2020-04-11 00:28:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Main entrypoint to the compositor process.
|
|
|
|
*
|
|
|
|
* @ingroup ipc_server
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
ipc_server_main(int argc, char **argv);
|
|
|
|
|
2020-06-17 06:36:38 +00:00
|
|
|
/*!
|
|
|
|
* Called by client threads to manage global state
|
|
|
|
*
|
|
|
|
* @ingroup ipc_server
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
update_server_state(struct ipc_server *vs);
|
|
|
|
|
2020-04-11 00:28:35 +00:00
|
|
|
/*!
|
|
|
|
* Thread function for the client side dispatching.
|
|
|
|
*
|
|
|
|
* @ingroup ipc_server
|
|
|
|
*/
|
|
|
|
void *
|
|
|
|
ipc_server_client_thread(void *_cs);
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|