Monado OpenXR Runtime
sdl_internal.h
Go to the documentation of this file.
1// Copyright 2020-2023, Collabora, Ltd.
2// SPDX-License-Identifier: BSL-1.0
3/*!
4 * @file
5 * @brief Internal header for SDL XR system.
6 * @author Jakob Bornecrantz <jakob@collabora.com>
7 * @ingroup sdl_test
8 */
9
10#include "xrt/xrt_system.h"
11#include "xrt/xrt_device.h"
12#include "xrt/xrt_instance.h"
13#include "xrt/xrt_tracking.h"
14#include "xrt/xrt_compositor.h"
15
16#include "util/u_pacing.h"
17#include "util/u_logging.h"
18#include "util/comp_base.h"
19#include "util/comp_swapchain.h"
20
21#include "SDL2/SDL.h"
22
23#include "ogl/ogl_api.h"
24
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30struct sdl_program;
31
32/*!
33 * Sub-class of @ref comp_swapchain, used to do OpenGL rendering.
34 *
35 * @ingroup sdl_test
36 */
38{
39 struct comp_swapchain base;
40
41 //! Pointer back to main program.
42 struct sdl_program *sp;
43
44 //! Cached width and height.
45 int w, h;
46
47 //! Number of textures in base.base.base.image_count.
49
50 //! Same number of images as textures.
52};
53
54/*!
55 * Tracking frame state.
56 *
57 * @ingroup sdl_test
58 */
60{
61 int64_t id;
62 uint64_t predicted_display_time_ns;
63 uint64_t desired_present_time_ns;
64 uint64_t present_slop_ns;
65};
66
67/*!
68 * Split out for convenience.
69 *
70 * This ultimately implements @ref xrt_compositor_native but does so by
71 * extending @ref comp_base, similar to how @ref comp_compositor works.
72 *
73 * @extends comp_base
74 * @ingroup sdl_test
75 */
77{
78 //! Base native compositor.
80
81 //! Pacing helper to drive us forward.
83
84 struct
85 {
86 //! Frame interval that we are using.
88 } settings;
89
90 // Kept here for convenience.
91 struct xrt_system_compositor_info sys_info;
92
93
94 //! @todo Insert your own required members here
95
96 struct
97 {
98 struct sdl_comp_frame waited;
99 struct sdl_comp_frame rendering;
101};
102
103struct sdl_program_plus;
104
105/*!
106 * C base class for the SDL program.
107 *
108 * @implements xrt_instance
109 * @implements xrt_device
110 * @implements xrt_system_devices
111 * @extends sdl_compositor
112 * @ingroup sdl_test
113 */
115{
116 //! Base class for devices.
118
119 //! Instance base.
121
122 //! System, implemented for now using helper code.
123 struct u_system *usys;
124
125 //! System devices base.
127
128 //! Space overseer, implemented for now using helper code.
130
131 //! SDL compositor struct.
133
134 //! Created system compositor.
136
137 //! Inputs exposed by the SDL device.
138 struct xrt_input inputs[1];
139
140 //! HMD parts exposed by the SDL device to become a HMD.
142
143 //! Tracking origin that the device is located in.
145
146 //! The current log level.
148
149 struct
150 {
151 struct
152 {
153 //! The pose of the head, only used for view space.
155 } head;
156
157 struct
158 {
159 //! Pose of each individual eye.
160 struct xrt_pose pose;
161
162 //! Fov of each individual eye.
163 struct xrt_fov fov;
164 } left, right;
165 } state;
166
167 //! The main window.
168 SDL_Window *win;
169
170 //! Main OpenGL context.
171 SDL_GLContext ctx;
172
173 //! Protects the OpenGL context.
175
176 //! Pointer back to the C++ part of the program.
178};
179
180
181static inline struct sdl_program *
182from_xinst(struct xrt_instance *xinst)
183{
184 return container_of(xinst, struct sdl_program, xinst_base);
185}
186
187static inline struct sdl_program *
188from_xsysd(struct xrt_system_devices *xsysd)
189{
190 return container_of(xsysd, struct sdl_program, xsysd_base);
191}
192
193static inline struct sdl_program *
194from_xdev(struct xrt_device *xdev)
195{
196 return container_of(xdev, struct sdl_program, xdev_base);
197}
198
199static inline struct sdl_program *
200from_comp(struct xrt_compositor *xc)
201{
202 return container_of(xc, struct sdl_program, c.base.base);
203}
204
205
206/*!
207 * Spew level logging.
208 *
209 * @relates sdl_program
210 * @ingroup sdl_test
211 */
212#define ST_TRACE(sp, ...) U_LOG_IFL_T(sp->log_level, __VA_ARGS__);
213
214/*!
215 * Debug level logging.
216 *
217 * @relates sdl_program
218 */
219#define ST_DEBUG(sp, ...) U_LOG_IFL_D(sp->log_level, __VA_ARGS__);
220
221/*!
222 * Info level logging.
223 *
224 * @relates sdl_program
225 * @ingroup sdl_test
226 */
227#define ST_INFO(sp, ...) U_LOG_IFL_I(sp->log_level, __VA_ARGS__);
228
229/*!
230 * Warn level logging.
231 *
232 * @relates sdl_program
233 * @ingroup sdl_test
234 */
235#define ST_WARN(sp, ...) U_LOG_IFL_W(sp->log_level, __VA_ARGS__);
236
237/*!
238 * Error level logging.
239 *
240 * @relates sdl_program
241 * @ingroup sdl_test
242 */
243#define ST_ERROR(sp, ...) U_LOG_IFL_E(sp->log_level, __VA_ARGS__);
244
245/*!
246 * Check for OpenGL errors, context needs to be current.
247 *
248 * @ingroup sdl_test
249 */
250#define CHECK_GL() \
251 do { \
252 GLint err = glGetError(); \
253 if (err != 0) { \
254 U_LOG_RAW("%s:%u: error: 0x%04x", __func__, __LINE__, err); \
255 } \
256 } while (false)
257
258/*!
259 * Makes the OpenGL context current in this thread, takes lock.
260 *
261 * @ingroup sdl_test
262 */
263static inline void
265{
267 SDL_GL_MakeCurrent(sp->win, sp->ctx);
268}
269
270/*!
271 * Unmakes the any OpenGL context current in this thread, releases the lock.
272 *
273 * @ingroup sdl_test
274 */
275static inline void
277{
278 SDL_GL_MakeCurrent(NULL, NULL);
280}
281
282
283/*
284 *
285 * sdl_device.c
286 *
287 */
288
289/*!
290 * Init the @ref xrt_device sub struct.
291 *
292 * In sdl_device.c
293 *
294 * @ingroup sdl_test
295 */
296void
297sdl_device_init(struct sdl_program *sp);
298
299
300/*
301 *
302 * sdl_swapchain.c
303 *
304 */
305
306/*!
307 * Implementation of @ref xrt_compositor::create_swapchain.
308 *
309 * @ingroup sdl_test
310 */
313 const struct xrt_swapchain_create_info *info,
314 struct xrt_swapchain **out_xsc);
315
316/*!
317 * Implementation of @ref xrt_compositor::import_swapchain.
318 *
319 * @ingroup sdl_test
320 */
323 const struct xrt_swapchain_create_info *info,
324 struct xrt_image_native *native_images,
325 uint32_t native_image_count,
326 struct xrt_swapchain **out_xsc);
327
328
329/*
330 *
331 * sdl_compositor.c
332 *
333 */
334
335/*!
336 * Initializes the compositor part of the SDL program.
337 *
338 * @ingroup sdl_test
339 */
340void
342
343/*!
344 * Creates the system compositor that wraps the native compositor.
345 *
346 * @ingroup sdl_test
347 */
350
351
352/*
353 *
354 * sdl_instance.c
355 *
356 */
357
358/*!
359 * Init the @ref xrt_system (and @ref u_system) struct.
360 *
361 * @ingroup sdl_test
362 */
363void
364sdl_system_init(struct sdl_program *sp);
365
366/*!
367 * Init the @ref xrt_system_devices sub struct.
368 *
369 * @ingroup sdl_test
370 */
371void
373
374/*!
375 * Init the @ref xrt_instance sub struct.
376 *
377 * @ingroup sdl_test
378 */
379void
381
382
383/*
384 *
385 * sdl_program.cpp
386 *
387 */
388
389/*!
390 * Create the SDL program.
391 *
392 * @ingroup sdl_test
393 */
394struct sdl_program *
396
397/*!
398 * Render a frame, called by the compositor when layers have been committed.
399 *
400 * @ingroup sdl_test
401 */
402void
404
405/*!
406 * Destroy the SDL program.
407 *
408 * @ingroup sdl_test
409 */
410void
412
413
414#ifdef __cplusplus
415}
416#endif
Helper implementation for native compositors.
Independent swapchain implementation.
u_logging_level
Logging level enum.
Definition: u_logging.h:43
static void os_mutex_lock(struct os_mutex *om)
Lock.
Definition: os_threading.h:86
static void os_mutex_unlock(struct os_mutex *om)
Unlock.
Definition: os_threading.h:110
#define XRT_MAX_SWAPCHAIN_IMAGES
Max swapchain images, artificial limit.
Definition: xrt_limits.h:34
enum xrt_result xrt_result_t
Result type used across Monado.
#define container_of(ptr, type, field)
Get the holder from a pointer to a field.
Definition: xrt_compiler.h:149
OpenGL API wrapper header.
void sdl_compositor_init(struct sdl_program *sp)
Initializes the compositor part of the SDL program.
Definition: sdl_compositor.c:518
xrt_result_t sdl_compositor_create_system(struct sdl_program *sp, struct xrt_system_compositor **out_xsysc)
Creates the system compositor that wraps the native compositor.
Definition: sdl_compositor.c:568
void sdl_system_init(struct sdl_program *sp)
Init the xrt_system (and u_system) struct.
Definition: sdl_instance.c:123
void sdl_program_plus_destroy(struct sdl_program_plus *spp)
Destroy the SDL program.
Definition: sdl_program.cpp:174
void sdl_instance_init(struct sdl_program *sp)
Init the xrt_instance sub struct.
Definition: sdl_instance.c:162
void sdl_device_init(struct sdl_program *sp)
Init the xrt_device sub struct.
Definition: sdl_device.c:70
void sdl_program_plus_render(struct sdl_program_plus *spp)
Render a frame, called by the compositor when layers have been committed.
Definition: sdl_program.cpp:102
xrt_result_t sdl_swapchain_create(struct xrt_compositor *xc, const struct xrt_swapchain_create_info *info, struct xrt_swapchain **out_xsc)
Implementation of xrt_compositor::create_swapchain.
Definition: sdl_swapchain.c:82
static void sdl_make_current(struct sdl_program *sp)
Makes the OpenGL context current in this thread, takes lock.
Definition: sdl_internal.h:264
xrt_result_t sdl_swapchain_import(struct xrt_compositor *xc, const struct xrt_swapchain_create_info *info, struct xrt_image_native *native_images, uint32_t native_image_count, struct xrt_swapchain **out_xsc)
Implementation of xrt_compositor::import_swapchain.
Definition: sdl_swapchain.c:120
void sdl_system_devices_init(struct sdl_program *sp)
Init the xrt_system_devices sub struct.
Definition: sdl_instance.c:132
static void sdl_make_uncurrent(struct sdl_program *sp)
Unmakes the any OpenGL context current in this thread, releases the lock.
Definition: sdl_internal.h:276
struct sdl_program * sdl_program_plus_create(void)
Create the SDL program.
Definition: sdl_program.cpp:77
A simple compositor base that handles a lot of things for you.
Definition: comp_base.h:69
struct xrt_compositor_native base
Base native compositor.
Definition: comp_base.h:71
A swapchain that is almost a one to one mapping to a OpenXR swapchain.
Definition: comp_swapchain.h:92
A wrapper around a native mutex.
Definition: os_threading.h:55
Tracking frame state.
Definition: sdl_internal.h:60
Split out for convenience.
Definition: sdl_internal.h:77
uint64_t frame_interval_ns
Frame interval that we are using.
Definition: sdl_internal.h:87
struct sdl_compositor::@284 frame
struct comp_base base
Base native compositor.
Definition: sdl_internal.h:79
struct u_pacing_compositor * upc
Pacing helper to drive us forward.
Definition: sdl_internal.h:82
C++ version of the sdl_program struct, where you place C++ only things.
Definition: sdl_internal.hpp:25
C base class for the SDL program.
Definition: sdl_internal.h:115
struct xrt_tracking_origin origin
Tracking origin that the device is located in.
Definition: sdl_internal.h:144
struct xrt_system_compositor * xsysc
Created system compositor.
Definition: sdl_internal.h:135
SDL_GLContext ctx
Main OpenGL context.
Definition: sdl_internal.h:171
struct os_mutex current_mutex
Protects the OpenGL context.
Definition: sdl_internal.h:174
struct xrt_device xdev_base
Base class for devices.
Definition: sdl_internal.h:117
SDL_Window * win
The main window.
Definition: sdl_internal.h:168
struct xrt_system_devices xsysd_base
System devices base.
Definition: sdl_internal.h:126
struct xrt_fov fov
Fov of each individual eye.
Definition: sdl_internal.h:163
struct xrt_input inputs[1]
Inputs exposed by the SDL device.
Definition: sdl_internal.h:138
enum u_logging_level log_level
The current log level.
Definition: sdl_internal.h:147
struct xrt_space_overseer * xso
Space overseer, implemented for now using helper code.
Definition: sdl_internal.h:129
struct sdl_program_plus * spp
Pointer back to the C++ part of the program.
Definition: sdl_internal.h:177
struct xrt_pose pose
The pose of the head, only used for view space.
Definition: sdl_internal.h:154
struct u_system * usys
System, implemented for now using helper code.
Definition: sdl_internal.h:123
struct xrt_hmd_parts hmd
HMD parts exposed by the SDL device to become a HMD.
Definition: sdl_internal.h:141
struct sdl_compositor c
SDL compositor struct.
Definition: sdl_internal.h:132
struct xrt_instance xinst_base
Instance base.
Definition: sdl_internal.h:120
Sub-class of comp_swapchain, used to do OpenGL rendering.
Definition: sdl_internal.h:38
int w
Cached width and height.
Definition: sdl_internal.h:45
GLuint memory[XRT_MAX_SWAPCHAIN_IMAGES]
Same number of images as textures.
Definition: sdl_internal.h:51
struct sdl_program * sp
Pointer back to main program.
Definition: sdl_internal.h:42
GLuint textures[XRT_MAX_SWAPCHAIN_IMAGES]
Number of textures in base.base.base.image_count.
Definition: sdl_internal.h:48
Compositor pacing helper interface.
Definition: u_pacing.h:68
A helper to implement a xrt_system, takes care of multiplexing events to sessions.
Definition: u_system.h:43
Common compositor client interface/base.
Definition: xrt_compositor.h:988
struct xrt_compositor_info info
Capabilities and recommended values information.
Definition: xrt_compositor.h:992
A single HMD or input device.
Definition: xrt_device.h:241
Describes a projection matrix fov.
Definition: xrt_defines.h:486
All of the device components that deals with interfacing to a users head.
Definition: xrt_device.h:90
A single image of a swapchain based on native buffer handles.
Definition: xrt_compositor.h:2150
A single named input, that sits on a xrt_device.
Definition: xrt_device.h:161
This interface acts as a root object for Monado.
Definition: xrt_instance.h:114
A pose composed of a position and orientation.
Definition: xrt_defines.h:465
Object that oversees and manages spaces, one created for each XR system.
Definition: xrt_space.h:96
Swapchain creation info.
Definition: xrt_compositor.h:876
Common swapchain interface/base.
Definition: xrt_compositor.h:536
Capabilities and information about the system compositor (and its wrapped native compositor,...
Definition: xrt_compositor.h:2295
The system compositor handles composition for a system.
Definition: xrt_compositor.h:2414
A collection of xrt_device, and an interface for identifying the roles they have been assigned.
Definition: xrt_system.h:219
A tracking system or device origin.
Definition: xrt_tracking.h:71
Basic logging functionality.
Shared pacing code.
Header declaring XRT graphics interfaces.
Header defining an xrt display or controller device.
Header for xrt_instance object.
Header for system objects.
Header defining the tracking system integration in Monado.