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 enum xrt_view_type session_view_type;
134 } state;
135
136 struct
137 {
138 //! Fence to wait for.
140
141 //! Timeline semaphore to wait for.
143
144 //! Timeline semaphore value to wait for.
145 uint64_t value;
146
147 //! Frame id of frame being waited on.
148 int64_t frame_id;
149
150 //! The wait thread itself
152
153 //! Have we gotten to the loop?
154 bool alive;
155
156 //! Is the thread waiting, if so the client should block.
158
159 /*!
160 * Is the client thread blocked?
161 *
162 * Set to true by the client thread,
163 * cleared by the wait thread to release the client thread.
164 */
166 } wait_thread;
167
168 //! Lock for all of the slots.
170
171 /*!
172 * The next which the next frames to be picked up will be displayed.
173 */
175
176 /*!
177 * Currently being transferred or waited on.
178 * Not protected by the slot lock as it is only touched by the client thread.
179 */
181
182 //! Scheduled frames for a future timepoint.
184
185 /*!
186 * Fully ready to be used.
187 * Not protected by the slot lock as it is only touched by the main render loop thread.
188 */
190
191 struct u_pacing_app *upa;
192
193 float current_refresh_rate_hz;
194};
195
196/*!
197 * Small helper go from @ref xrt_compositor to @ref multi_compositor.
198 *
199 * @ingroup comp_multi
200 */
201static inline struct multi_compositor *
203{
204 return (struct multi_compositor *)xc;
205}
206
207/*!
208 * Create a multi client wrapper compositor.
209 *
210 * @ingroup comp_multi
211 */
214 const struct xrt_session_info *xsi,
216 struct xrt_compositor_native **out_xcn);
217
218/*!
219 * Push a event to be delivered to the session that corresponds
220 * to the given @ref multi_compositor.
221 *
222 * @ingroup comp_multi
223 * @private @memberof multi_compositor
224 */
225XRT_CHECK_RESULT xrt_result_t
226multi_compositor_push_event(struct multi_compositor *mc, const union xrt_session_event *xse);
227
228/*!
229 * Deliver any scheduled frames at that is to be display at or after the given @p display_time_ns. Called by the render
230 * thread and copies data from multi_compositor::scheduled to multi_compositor::delivered while holding the slot_lock.
231 *
232 * @ingroup comp_multi
233 * @private @memberof multi_compositor
234 */
235void
236multi_compositor_deliver_any_frames(struct multi_compositor *mc, int64_t display_time_ns);
237
238/*!
239 * Makes the current delivered frame as latched, called by the render thread.
240 * The list_and_timing_lock is held when this function is called.
241 *
242 * @ingroup comp_multi
243 * @private @memberof multi_compositor
244 */
245void
246multi_compositor_latch_frame_locked(struct multi_compositor *mc, int64_t when_ns, int64_t system_frame_id);
247
248/*!
249 * Clears and retires the delivered frame, called by the render thread.
250 * The list_and_timing_lock is held when this function is called.
251 *
252 * @ingroup comp_multi
253 * @private @memberof multi_compositor
254 */
255void
256multi_compositor_retire_delivered_locked(struct multi_compositor *mc, int64_t when_ns);
257
258
259/*
260 *
261 * Multi-client-capable system compositor
262 *
263 */
264
265/*!
266 * State of the multi-client system compositor. Use to track the calling of native
267 * compositor methods @ref xrt_comp_begin_session and @ref xrt_comp_end_session.
268 *
269 * It is driven by the number of active app sessions.
270 *
271 * @ingroup comp_multi
272 */
274{
275 /*!
276 * Invalid state, never used.
277 */
279
280 /*!
281 * One of the initial states, the multi-client system compositor will
282 * make sure that its @ref xrt_compositor_native submits one frame.
283 *
284 * The session hasn't been started yet.
285 */
287
288 /*!
289 * One of the initial state and post stopping state.
290 *
291 * The multi-client system compositor has called @ref xrt_comp_end_session
292 * on its @ref xrt_compositor_native.
293 */
295
296 /*!
297 * The main session is running.
298 *
299 * The multi-client system compositor has called @ref xrt_comp_begin_session
300 * on its @ref xrt_compositor_native.
301 */
303
304 /*!
305 * There are no active sessions and the multi-client system compositor is
306 * instructing the native compositor to draw one or more clear frames.
307 *
308 * The multi-client system compositor has not yet called @ref xrt_comp_begin_session
309 * on its @ref xrt_compositor_native.
310 */
312};
313
314/*!
315 * The multi-client module (aka multi compositor) is system compositor that
316 * multiplexes access to a single @ref xrt_compositor_native, merging layers
317 * from one or more client apps/sessions. This object implements the
318 * @ref xrt_system_compositor, and gives each session a @ref multi_compositor,
319 * which implements @ref xrt_compositor_native.
320 *
321 * @ingroup comp_multi
322 * @implements xrt_system_compositor
323 */
325{
326 //! Base interface.
328
329 comp_multi_view_config_callback_func_t get_view_config_callback;
330
331 //! Extra functions to handle multi client.
333
334 /*!
335 * Real native compositor, which this multi client module submits the
336 * combined layers of active @ref multi_compositor objects.
337 */
339
340 /*!
341 * App pacer factory, when a new @ref multi_compositor is created a
342 * pacer is created from this factory.
343 */
345
346 //! Render loop thread.
348
349 struct
350 {
351 /*!
352 * The state of the multi-client system compositor.
353 * This is updated on the multi_system_compositor::oth
354 * thread, aka multi-client system compositor main thread.
355 * It is driven by the active_count field.
356 */
358
359 //! Number of active sessions, protected by oth.
360 uint64_t active_count;
361 } sessions;
362
363 /*!
364 * This mutex protects the list of client compositor
365 * and the rendering timings on it.
366 */
368
369 struct
370 {
371 int64_t predicted_display_time_ns;
372 int64_t predicted_display_period_ns;
373 int64_t diff_ns;
374 } last_timings;
375
376 //! List of active clients.
378
379 //! Chroma key parameters in HSV space
381};
382
383/*!
384 * Cast helper
385 *
386 * @ingroup comp_multi
387 * @private @memberof multi_system_compositor
388 */
389static inline struct multi_system_compositor *
391{
392 return (struct multi_system_compositor *)xsc;
393}
394
395/*!
396 * The client compositor calls this function to update when its session is
397 * started or stopped.
398 *
399 * @ingroup comp_multi
400 * @private @memberof multi_system_compositor
401 */
402void
403multi_system_compositor_update_session_status(struct multi_system_compositor *msc, bool active);
404
405
406#ifdef __cplusplus
407}
408#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:972
#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:274
@ MULTI_SYSTEM_STATE_INVALID
Invalid state, never used.
Definition comp_multi_private.h:278
@ MULTI_SYSTEM_STATE_RUNNING
The main session is running.
Definition comp_multi_private.h:302
@ 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:311
@ 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:286
@ MULTI_SYSTEM_STATE_STOPPED
One of the initial state and post stopping state.
Definition comp_multi_private.h:294
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:183
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:145
int64_t slot_next_frame_display
The next which the next frames to be picked up will be displayed.
Definition comp_multi_private.h:174
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:142
struct os_mutex slot_lock
Lock for all of the slots.
Definition comp_multi_private.h:169
struct os_thread_helper oth
The wait thread itself.
Definition comp_multi_private.h:151
int64_t frame_id
Frame id of frame being waited on.
Definition comp_multi_private.h:148
bool blocked
Is the client thread blocked?
Definition comp_multi_private.h:165
struct multi_layer_slot delivered
Fully ready to be used.
Definition comp_multi_private.h:189
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:139
bool alive
Have we gotten to the loop?
Definition comp_multi_private.h:154
bool waiting
Is the thread waiting, if so the client should block.
Definition comp_multi_private.h:157
struct multi_layer_slot progress
Currently being transferred or waited on.
Definition comp_multi_private.h:180
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:325
struct xrt_layer_chroma_key_data chroma_key
Chroma key parameters in HSV space.
Definition comp_multi_private.h:380
struct xrt_multi_compositor_control xmcc
Extra functions to handle multi client.
Definition comp_multi_private.h:332
struct multi_compositor * clients[64]
List of active clients.
Definition comp_multi_private.h:377
enum multi_system_state state
The state of the multi-client system compositor.
Definition comp_multi_private.h:357
struct os_thread_helper oth
Render loop thread.
Definition comp_multi_private.h:347
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:344
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:367
uint64_t active_count
Number of active sessions, protected by oth.
Definition comp_multi_private.h:360
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:338
struct xrt_system_compositor base
Base interface.
Definition comp_multi_private.h:327
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:500
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:788
Main compositor server interface.
Definition xrt_compositor.h:2218
Compositor semaphore used for synchronization, needs to be as capable as a Vulkan pipeline semaphore.
Definition xrt_compositor.h:845
Common compositor client interface/base.
Definition xrt_compositor.h:1046
A single HMD or input device.
Definition xrt_device.h:357
Chroma key parameters in HSV space.
Definition xrt_compositor.h:212
All the pure data values associated with a composition layer.
Definition xrt_compositor.h:441
Per frame data for the layer submission calls, used in xrt_compositor::layer_begin.
Definition xrt_compositor.h:527
Special functions to control multi session/clients.
Definition xrt_compositor.h:2394
Used internally from producers of events to push events into session, some sinks might multiplex even...
Definition xrt_session.h:224
Session information, mostly overlay extension data.
Definition xrt_compositor.h:978
Common swapchain interface/base.
Definition xrt_compositor.h:593
The system compositor handles composition for a system.
Definition xrt_compositor.h:2479
Shared pacing code.
Union of all session events, used to return multiple events through one call.
Definition xrt_session.h:203
Header holding common defines.
Header declaring XRT graphics interfaces.
Common defines and enums for XRT.
xrt_view_type
View type to be rendered to by the compositor.
Definition xrt_defines.h:2438
Header for limits of the XRT interfaces.