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