Monado OpenXR Runtime
Loading...
Searching...
No Matches
comp_multi_private.h
Go to the documentation of this file.
1// Copyright 2021, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief System compositor capable of supporting multiple clients: internal structs.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 * @ingroup comp_multi
8 */
9
10#pragma once
11
12#include "xrt/xrt_compiler.h"
13#include "xrt/xrt_defines.h"
14#include "xrt/xrt_limits.h"
15#include "xrt/xrt_compositor.h"
16
17#include "os/os_time.h"
18#include "os/os_threading.h"
19
20#include "util/u_pacing.h"
21
23
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29
30/*!
31 * Number of max active clients.
32 *
33 * @todo Move to `xrt_limits.h`, or make dynamic to remove limit.
34 * @ingroup comp_multi
35 */
36#define MULTI_MAX_CLIENTS 64
37
38/*!
39 * Number of max active layers per @ref multi_compositor.
40 *
41 * @todo Move to `xrt_limits.h` and share.
42 * @ingroup comp_multi
43 */
44#define MULTI_MAX_LAYERS XRT_MAX_LAYERS
45
46
47/*
48 *
49 * Native compositor.
50 *
51 */
52
53/*!
54 * Data for a single composition layer.
55 *
56 * Similar in function to @ref comp_layer
57 *
58 * @ingroup comp_multi
59 */
61{
62 /*!
63 * Device to get pose from.
64 */
66
67 /*!
68 * Pointers to swapchains.
69 *
70 * How many are actually used depends on the value of @p data.type
71 */
72 struct xrt_swapchain *xscs[2 * XRT_MAX_VIEWS];
73
74 /*!
75 * All basic (trivially-serializable) data associated with a layer,
76 * aside from which swapchain(s) are used.
77 */
79};
80
81/*!
82 * Render state for a single client, including all layers.
83 *
84 * @ingroup comp_multi
85 */
87{
88 struct xrt_layer_frame_data data;
89 uint32_t layer_count;
91 bool active;
92};
93
94/*!
95 * A single compositor for feeding the layers from one session/app into
96 * the multi-client-capable system compositor.
97 *
98 * An instance (usually an IPC server instance) might have several of
99 * these at once, feeding layers to a single multi-client-capable system
100 * compositor.
101 *
102 * @ingroup comp_multi
103 * @implements xrt_compositor_native
104 */
106{
107 struct xrt_compositor_native base;
108
109 // Client info.
110 struct xrt_session_info xsi;
111
112 //! Where events for this compositor should go.
114
115 //! Owning system compositor.
117
118 //! Used to implement wait frame, only used for in process.
120
121 //! Used when waiting for the scheduled frame to complete.
123
124 struct
125 {
126 bool visible;
127 bool focused;
128
129 int64_t z_order;
130
131 bool session_active;
132 bool is_base_session;
133 } state;
134
135 struct
136 {
137 //! Fence to wait for.
139
140 //! Timeline semaphore to wait for.
142
143 //! Timeline semaphore value to wait for.
144 uint64_t value;
145
146 //! Frame id of frame being waited on.
147 int64_t frame_id;
148
149 //! The wait thread itself
151
152 //! Have we gotten to the loop?
153 bool alive;
154
155 //! Is the thread waiting, if so the client should block.
157
158 /*!
159 * Is the client thread blocked?
160 *
161 * Set to true by the client thread,
162 * cleared by the wait thread to release the client thread.
163 */
165 } wait_thread;
166
167 //! Lock for all of the slots.
169
170 /*!
171 * The next which the next frames to be picked up will be displayed.
172 */
174
175 /*!
176 * Currently being transferred or waited on.
177 * Not protected by the slot lock as it is only touched by the client thread.
178 */
180
181 //! Scheduled frames for a future timepoint.
183
184 /*!
185 * Fully ready to be used.
186 * Not protected by the slot lock as it is only touched by the main render loop thread.
187 */
189
190 struct u_pacing_app *upa;
191
192 float current_refresh_rate_hz;
193};
194
195/*!
196 * Small helper go from @ref xrt_compositor to @ref multi_compositor.
197 *
198 * @ingroup comp_multi
199 */
200static inline struct multi_compositor *
202{
203 return (struct multi_compositor *)xc;
204}
205
206/*!
207 * Create a multi client wrapper compositor.
208 *
209 * @ingroup comp_multi
210 */
213 const struct xrt_session_info *xsi,
215 struct xrt_compositor_native **out_xcn);
216
217/*!
218 * Push a event to be delivered to the session that corresponds
219 * to the given @ref multi_compositor.
220 *
221 * @ingroup comp_multi
222 * @private @memberof multi_compositor
223 */
224XRT_CHECK_RESULT xrt_result_t
225multi_compositor_push_event(struct multi_compositor *mc, const union xrt_session_event *xse);
226
227/*!
228 * Deliver any scheduled frames at that is to be display at or after the given @p display_time_ns. Called by the render
229 * thread and copies data from multi_compositor::scheduled to multi_compositor::delivered while holding the slot_lock.
230 *
231 * @ingroup comp_multi
232 * @private @memberof multi_compositor
233 */
234void
235multi_compositor_deliver_any_frames(struct multi_compositor *mc, int64_t display_time_ns);
236
237/*!
238 * Makes the current delivered frame as latched, called by the render thread.
239 * The list_and_timing_lock is held when this function is called.
240 *
241 * @ingroup comp_multi
242 * @private @memberof multi_compositor
243 */
244void
245multi_compositor_latch_frame_locked(struct multi_compositor *mc, int64_t when_ns, int64_t system_frame_id);
246
247/*!
248 * Clears and retires the delivered frame, called by the render thread.
249 * The list_and_timing_lock is held when this function is called.
250 *
251 * @ingroup comp_multi
252 * @private @memberof multi_compositor
253 */
254void
255multi_compositor_retire_delivered_locked(struct multi_compositor *mc, int64_t when_ns);
256
257
258/*
259 *
260 * Multi-client-capable system compositor
261 *
262 */
263
264/*!
265 * State of the multi-client system compositor. Use to track the calling of native
266 * compositor methods @ref xrt_comp_begin_session and @ref xrt_comp_end_session.
267 *
268 * It is driven by the number of active app sessions.
269 *
270 * @ingroup comp_multi
271 */
273{
274 /*!
275 * Invalid state, never used.
276 */
278
279 /*!
280 * One of the initial states, the multi-client system compositor will
281 * make sure that its @ref xrt_compositor_native submits one frame.
282 *
283 * The session hasn't been started yet.
284 */
286
287 /*!
288 * One of the initial state and post stopping state.
289 *
290 * The multi-client system compositor has called @ref xrt_comp_end_session
291 * on its @ref xrt_compositor_native.
292 */
294
295 /*!
296 * The main session is running.
297 *
298 * The multi-client system compositor has called @ref xrt_comp_begin_session
299 * on its @ref xrt_compositor_native.
300 */
302
303 /*!
304 * There are no active sessions and the multi-client system compositor is
305 * instructing the native compositor to draw one or more clear frames.
306 *
307 * The multi-client system compositor has not yet called @ref xrt_comp_begin_session
308 * on its @ref xrt_compositor_native.
309 */
311};
312
313/*!
314 * The multi-client module (aka multi compositor) is system compositor that
315 * multiplexes access to a single @ref xrt_compositor_native, merging layers
316 * from one or more client apps/sessions. This object implements the
317 * @ref xrt_system_compositor, and gives each session a @ref multi_compositor,
318 * which implements @ref xrt_compositor_native.
319 *
320 * @ingroup comp_multi
321 * @implements xrt_system_compositor
322 */
324{
325 //! Base interface.
327
328 comp_multi_view_config_callback_func_t get_view_config_callback;
329
330 //! Extra functions to handle multi client.
332
333 /*!
334 * Real native compositor, which this multi client module submits the
335 * combined layers of active @ref multi_compositor objects.
336 */
338
339 /*!
340 * App pacer factory, when a new @ref multi_compositor is created a
341 * pacer is created from this factory.
342 */
344
345 //! Render loop thread.
347
348 struct
349 {
350 /*!
351 * The state of the multi-client system compositor.
352 * This is updated on the multi_system_compositor::oth
353 * thread, aka multi-client system compositor main thread.
354 * It is driven by the active_count field.
355 */
357
358 //! Number of active sessions, protected by oth.
359 uint64_t active_count;
360 } sessions;
361
362 /*!
363 * This mutex protects the list of client compositor
364 * and the rendering timings on it.
365 */
367
368 struct
369 {
370 int64_t predicted_display_time_ns;
371 int64_t predicted_display_period_ns;
372 int64_t diff_ns;
373 } last_timings;
374
375 //! List of active clients.
377
378 //! Chroma key parameters in HSV space
380};
381
382/*!
383 * Cast helper
384 *
385 * @ingroup comp_multi
386 * @private @memberof multi_system_compositor
387 */
388static inline struct multi_system_compositor *
390{
391 return (struct multi_system_compositor *)xsc;
392}
393
394/*!
395 * The client compositor calls this function to update when its session is
396 * started or stopped.
397 *
398 * @ingroup comp_multi
399 * @private @memberof multi_system_compositor
400 */
401void
402multi_system_compositor_update_session_status(struct multi_system_compositor *msc, bool active);
403
404
405#ifdef __cplusplus
406}
407#endif
Interface for the multi-client layer code.
#define MULTI_MAX_LAYERS
Number of max active layers per multi_compositor.
Definition comp_multi_private.h:44
xrt_result_t multi_compositor_create(struct multi_system_compositor *msc, const struct xrt_session_info *xsi, struct xrt_session_event_sink *xses, struct xrt_compositor_native **out_xcn)
Create a multi client wrapper compositor.
Definition comp_multi_compositor.c:971
#define MULTI_MAX_CLIENTS
Number of max active clients.
Definition comp_multi_private.h:36
multi_system_state
State of the multi-client system compositor.
Definition comp_multi_private.h:273
@ MULTI_SYSTEM_STATE_INVALID
Invalid state, never used.
Definition comp_multi_private.h:277
@ MULTI_SYSTEM_STATE_RUNNING
The main session is running.
Definition comp_multi_private.h:301
@ MULTI_SYSTEM_STATE_STOPPING
There are no active sessions and the multi-client system compositor is instructing the native composi...
Definition comp_multi_private.h:310
@ MULTI_SYSTEM_STATE_INIT_WARM_START
One of the initial states, the multi-client system compositor will make sure that its xrt_compositor_...
Definition comp_multi_private.h:285
@ MULTI_SYSTEM_STATE_STOPPED
One of the initial state and post stopping state.
Definition comp_multi_private.h:293
enum xrt_result xrt_result_t
Result type used across Monado.
Wrapper around OS threading native functions.
Wrapper around OS native time functions.
A single compositor for feeding the layers from one session/app into the multi-client-capable system ...
Definition comp_multi_private.h:106
struct multi_layer_slot scheduled
Scheduled frames for a future timepoint.
Definition comp_multi_private.h:182
struct os_precise_sleeper scheduled_sleeper
Used when waiting for the scheduled frame to complete.
Definition comp_multi_private.h:122
struct multi_system_compositor * msc
Owning system compositor.
Definition comp_multi_private.h:116
uint64_t value
Timeline semaphore value to wait for.
Definition comp_multi_private.h:144
int64_t slot_next_frame_display
The next which the next frames to be picked up will be displayed.
Definition comp_multi_private.h:173
struct xrt_session_event_sink * xses
Where events for this compositor should go.
Definition comp_multi_private.h:113
struct xrt_compositor_semaphore * xcsem
Timeline semaphore to wait for.
Definition comp_multi_private.h:141
struct os_mutex slot_lock
Lock for all of the slots.
Definition comp_multi_private.h:168
struct os_thread_helper oth
The wait thread itself.
Definition comp_multi_private.h:150
int64_t frame_id
Frame id of frame being waited on.
Definition comp_multi_private.h:147
bool blocked
Is the client thread blocked?
Definition comp_multi_private.h:164
struct multi_layer_slot delivered
Fully ready to be used.
Definition comp_multi_private.h:188
struct os_precise_sleeper frame_sleeper
Used to implement wait frame, only used for in process.
Definition comp_multi_private.h:119
struct xrt_compositor_fence * xcf
Fence to wait for.
Definition comp_multi_private.h:138
bool alive
Have we gotten to the loop?
Definition comp_multi_private.h:153
bool waiting
Is the thread waiting, if so the client should block.
Definition comp_multi_private.h:156
struct multi_layer_slot progress
Currently being transferred or waited on.
Definition comp_multi_private.h:179
Data for a single composition layer.
Definition comp_multi_private.h:61
struct xrt_layer_data data
All basic (trivially-serializable) data associated with a layer, aside from which swapchain(s) are us...
Definition comp_multi_private.h:78
struct xrt_swapchain * xscs[2 *XRT_MAX_VIEWS]
Pointers to swapchains.
Definition comp_multi_private.h:72
struct xrt_device * xdev
Device to get pose from.
Definition comp_multi_private.h:65
Render state for a single client, including all layers.
Definition comp_multi_private.h:87
The multi-client module (aka multi compositor) is system compositor that multiplexes access to a sing...
Definition comp_multi_private.h:324
struct xrt_layer_chroma_key_data chroma_key
Chroma key parameters in HSV space.
Definition comp_multi_private.h:379
struct xrt_multi_compositor_control xmcc
Extra functions to handle multi client.
Definition comp_multi_private.h:331
struct multi_compositor * clients[64]
List of active clients.
Definition comp_multi_private.h:376
enum multi_system_state state
The state of the multi-client system compositor.
Definition comp_multi_private.h:356
struct os_thread_helper oth
Render loop thread.
Definition comp_multi_private.h:346
struct u_pacing_app_factory * upaf
App pacer factory, when a new multi_compositor is created a pacer is created from this factory.
Definition comp_multi_private.h:343
struct os_mutex list_and_timing_lock
This mutex protects the list of client compositor and the rendering timings on it.
Definition comp_multi_private.h:366
uint64_t active_count
Number of active sessions, protected by oth.
Definition comp_multi_private.h:359
struct xrt_compositor_native * xcn
Real native compositor, which this multi client module submits the combined layers of active multi_co...
Definition comp_multi_private.h:337
struct xrt_system_compositor base
Base interface.
Definition comp_multi_private.h:326
A wrapper around a native mutex.
Definition os_threading.h:69
Definition os_time.h:219
All in one helper that handles locking, waiting for change and starting a thread.
Definition os_threading.h:499
Small helper that creates a app pacers, allows timing information to be collected and controlled to a...
Definition u_pacing.h:619
This application pacing helper is designed to schedule the rendering time of clients that submit fram...
Definition u_pacing.h:348
Compositor fence used for synchronization.
Definition xrt_compositor.h:759
Main compositor server interface.
Definition xrt_compositor.h:2260
Compositor semaphore used for synchronization, needs to be as capable as a Vulkan pipeline semaphore.
Definition xrt_compositor.h:816
Common compositor client interface/base.
Definition xrt_compositor.h:1016
A single HMD or input device.
Definition xrt_device.h:310
Chroma key parameters in HSV space.
Definition xrt_compositor.h:190
All the pure data values associated with a composition layer.
Definition xrt_compositor.h:419
Per frame data for the layer submission calls, used in xrt_compositor::layer_begin.
Definition xrt_compositor.h:505
Special functions to control multi session/clients.
Definition xrt_compositor.h:2410
Used internally from producers of events to push events into session, some sinks might multiplex even...
Definition xrt_session.h:237
Session information, mostly overlay extension data.
Definition xrt_compositor.h:949
Common swapchain interface/base.
Definition xrt_compositor.h:564
The system compositor handles composition for a system.
Definition xrt_compositor.h:2488
Shared pacing code.
Union of all session events, used to return multiple events through one call.
Definition xrt_session.h:215
Header holding common defines.
Header declaring XRT graphics interfaces.
Common defines and enums for XRT.
Header for limits of the XRT interfaces.