Monado OpenXR Runtime
xrt_compositor.h
Go to the documentation of this file.
1 // Copyright 2019, Collabora, Ltd.
2 // SPDX-License-Identifier: BSL-1.0
3 /*!
4  * @file
5  * @brief Header defining a XRT graphics provider.
6  * @author Jakob Bornecrantz <jakob@collabora.com>
7  * @ingroup xrt_iface
8  */
9 
10 #pragma once
11 
12 #include "xrt/xrt_defines.h"
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 
19 /*!
20  * Max swapchain images, artificial limit.
21  *
22  * @ingroup xrt_iface
23  */
24 #define XRT_MAX_SWAPCHAIN_IMAGES 8
25 
26 /*!
27  * Max formats supported by a compositor, artificial limit.
28  *
29  * @ingroup xrt_iface
30  */
31 #define XRT_MAX_SWAPCHAIN_FORMATS 8
32 
33 /*!
34  * Special flags for creating swapchain images.
35  *
36  * @ingroup xrt_iface
37  */
39 {
41 };
42 
43 /*!
44  * Usage of the swapchain images.
45  *
46  * @ingroup xrt_iface
47  */
49 {
57 };
58 
59 /*!
60  * View type to be rendered to by the compositor.
61  *
62  * @ingroup xrt_iface
63  */
65 {
68 };
69 
70 /*!
71  * Common swapchain base.
72  *
73  * @ingroup xrt_iface
74  */
76 {
77  /*!
78  * Number of images, the images themselves are on the subclasses.
79  */
80  uint32_t num_images;
81 
82  /*!
83  * Number of array layers per image.
84  */
85  uint32_t array_size;
86 
87  /*!
88  * Must have called release_image before calling this function.
89  */
90  void (*destroy)(struct xrt_swapchain *xsc);
91 
92  /*!
93  * See xrWaitSwapchainImage, must make sure that no image is acquired
94  * before calling acquire_image.
95  */
96  bool (*acquire_image)(struct xrt_swapchain *xsc, uint32_t *index);
97 
98  /*!
99  * See xrWaitSwapchainImage, state tracker needs to track index.
100  */
101  bool (*wait_image)(struct xrt_swapchain *xsc,
102  uint64_t timeout,
103  uint32_t index);
104 
105  /*!
106  * See xrReleaseSwapchainImage, state tracker needs to track index.
107  */
108  bool (*release_image)(struct xrt_swapchain *xsc, uint32_t index);
109 };
110 
111 /*!
112  * Helper for xrt_swapchain::acquire_image.
113  *
114  * @ingroup xrt_iface
115  */
116 static inline bool
117 xrt_swapchain_acquire_image(struct xrt_swapchain *xsc, uint32_t *index)
118 {
119  return xsc->acquire_image(xsc, index);
120 }
121 
122 /*!
123  * Helper for xrt_swapchain::wait_image.
124  *
125  * @ingroup xrt_iface
126  */
127 static inline bool
128 xrt_swapchain_wait_image(struct xrt_swapchain *xsc,
129  uint64_t timeout,
130  uint32_t index)
131 {
132  return xsc->wait_image(xsc, timeout, index);
133 }
134 
135 /*!
136  * Helper for xrt_swapchain::release_image.
137  *
138  * @ingroup xrt_iface
139  */
140 static inline bool
141 xrt_swapchain_release_image(struct xrt_swapchain *xsc, uint32_t index)
142 {
143  return xsc->release_image(xsc, index);
144 }
145 
146 /*!
147  * Helper for xrt_swapchain::destroy, does a null check and sets xc_ptr to
148  * null if freed.
149  *
150  * @ingroup xrt_iface
151  */
152 static inline void
153 xrt_swapchain_destroy(struct xrt_swapchain **xsc_ptr)
154 {
155  struct xrt_swapchain *xsc = *xsc_ptr;
156  if (xsc == NULL) {
157  return;
158  }
159 
160  xsc->destroy(xsc);
161  *xsc_ptr = NULL;
162 }
163 
164 /*!
165  * Common compositor base.
166  *
167  * @ingroup xrt_iface
168  */
170 {
171  /*!
172  * Number of formats.
173  */
174  uint32_t num_formats;
175 
176  /*!
177  * Supported formats.
178  */
179  int64_t formats[XRT_MAX_SWAPCHAIN_FORMATS];
180 
181  /*!
182  * Create a swapchain with a set of images.
183  */
184  struct xrt_swapchain *(*create_swapchain)(
185  struct xrt_compositor *xc,
186  enum xrt_swapchain_create_flags create,
187  enum xrt_swapchain_usage_bits bits,
188  int64_t format,
189  uint32_t sample_count,
190  uint32_t width,
191  uint32_t height,
192  uint32_t face_count,
193  uint32_t array_size,
194  uint32_t mip_count);
195 
196  /*!
197  * Poll events from this compositor.
198  *
199  * This function is very much WIP.
200  */
201  void (*poll_events)(struct xrt_compositor *xc, uint64_t *WIP);
202 
203  /*!
204  * This function is implicit in the OpenXR spec but made explicit here.
205  */
206  void (*prepare_session)(struct xrt_compositor *xc);
207 
208  /*!
209  * See xrBeginSession.
210  */
211  void (*begin_session)(struct xrt_compositor *xc,
212  enum xrt_view_type view_type);
213 
214  /*!
215  * See xrEndSession, unlike the OpenXR one the state tracker is
216  * responsible to call discard frame before calling this function. See
217  * discard_frame.
218  */
219  void (*end_session)(struct xrt_compositor *xc);
220 
221  /*!
222  * See xrWaitFrame.
223  */
224  void (*wait_frame)(struct xrt_compositor *xc,
225  uint64_t *predicted_display_time,
226  uint64_t *predicted_display_period);
227 
228  /*!
229  * See xrBeginFrame.
230  */
231  void (*begin_frame)(struct xrt_compositor *xc);
232 
233  /*!
234  * This isn't in the OpenXR API but is explicit in the XRT interfaces.
235  *
236  * Two calls to xrBeginFrame will cause the state tracker to call.
237  *
238  * ```c
239  * xc->begin_frame(xc)
240  * xc->discard_frame(xc)
241  * xc->begin_frame(xc)
242  * ```
243  */
244  void (*discard_frame)(struct xrt_compositor *xc);
245 
246  /*!
247  * See xrEndFrame.
248  */
249  void (*end_frame)(struct xrt_compositor *xc,
250  enum xrt_blend_mode blend_mode,
251  struct xrt_swapchain **xscs,
252  const uint32_t *image_index,
253  uint32_t *layers,
254  uint32_t num_swapchains);
255 
256  /*!
257  * Teardown the compositor.
258  *
259  * The state tracker must have made sure that no frames or sessions are
260  * currently pending. See discard_frame, end_frame, end_session.
261  */
262  void (*destroy)(struct xrt_compositor *xc);
263 };
264 
265 /*!
266  * Helper for xrt_compositor::create_swapchain
267  *
268  * @ingroup xrt_iface
269  */
270 static inline struct xrt_swapchain *
271 xrt_comp_create_swapchain(struct xrt_compositor *xc,
272  enum xrt_swapchain_create_flags create,
273  enum xrt_swapchain_usage_bits bits,
274  int64_t format,
275  uint32_t sample_count,
276  uint32_t width,
277  uint32_t height,
278  uint32_t face_count,
279  uint32_t array_size,
280  uint32_t mip_count)
281 {
282  return xc->create_swapchain(xc, create, bits, format, sample_count,
283  width, height, face_count, array_size,
284  mip_count);
285 }
286 
287 /*!
288  * Helper for xrt_compositor::poll_events
289  *
290  * @ingroup xrt_iface
291  */
292 static inline void
293 xrt_comp_poll_events(struct xrt_compositor *xc, uint64_t *WIP)
294 {
295  xc->poll_events(xc, WIP);
296 }
297 
298 /*!
299  * Helper for xrt_compositor::prepare_session
300  *
301  * @ingroup xrt_iface
302  */
303 static inline void
304 xrt_comp_prepare_session(struct xrt_compositor *xc)
305 {
306  xc->prepare_session(xc);
307 }
308 
309 /*!
310  * Helper for xrt_compositor::begin_session
311  *
312  * @ingroup xrt_iface
313  */
314 static inline void
315 xrt_comp_begin_session(struct xrt_compositor *xc, enum xrt_view_type view_type)
316 {
317  xc->begin_session(xc, view_type);
318 }
319 
320 /*!
321  * Helper for xrt_compositor::end_session
322  *
323  * @ingroup xrt_iface
324  */
325 static inline void
326 xrt_comp_end_session(struct xrt_compositor *xc)
327 {
328  xc->end_session(xc);
329 }
330 
331 /*!
332  * Helper for xrt_compositor::wait_frame
333  *
334  * @ingroup xrt_iface
335  */
336 static inline void
337 xrt_comp_wait_frame(struct xrt_compositor *xc,
338  uint64_t *predicted_display_time,
339  uint64_t *predicted_display_period)
340 {
341  xc->wait_frame(xc, predicted_display_time, predicted_display_period);
342 }
343 
344 /*!
345  * Helper for xrt_compositor::begin_frame
346  *
347  * @ingroup xrt_iface
348  */
349 static inline void
350 xrt_comp_begin_frame(struct xrt_compositor *xc)
351 {
352  xc->begin_frame(xc);
353 }
354 
355 /*!
356  * Helper for xrt_compositor::discard_frame
357  *
358  * @ingroup xrt_iface
359  */
360 static inline void
361 xrt_comp_discard_frame(struct xrt_compositor *xc)
362 {
363  xc->discard_frame(xc);
364 }
365 
366 /*!
367  * Helper for xrt_compositor::end_frame
368  *
369  * @ingroup xrt_iface
370  */
371 static inline void
372 xrt_comp_end_frame(struct xrt_compositor *xc,
373  enum xrt_blend_mode blend_mode,
374  struct xrt_swapchain **xscs,
375  const uint32_t *image_index,
376  uint32_t *layers,
377  uint32_t num_swapchains)
378 {
379  xc->end_frame(xc, blend_mode, xscs, image_index, layers,
380  num_swapchains);
381 }
382 
383 /*!
384  * Helper for xrt_compositor::destroy, does a null check and sets xc_ptr to
385  * null if freed.
386  *
387  * @ingroup xrt_iface
388  */
389 static inline void
390 xrt_comp_destroy(struct xrt_compositor **xc_ptr)
391 {
392  struct xrt_compositor *xc = *xc_ptr;
393  if (xc == NULL) {
394  return;
395  }
396 
397  xc->destroy(xc);
398  *xc_ptr = NULL;
399 }
400 
401 
402 /*
403  *
404  * OpenGL interface.
405  *
406  */
407 
408 /*!
409  * @ingroup xrt_iface comp_client
410  */
412 {
413  struct xrt_swapchain base;
414 
415  // GLuint
416  unsigned int images[XRT_MAX_SWAPCHAIN_IMAGES];
417  // GLuint
418  unsigned int memory[XRT_MAX_SWAPCHAIN_IMAGES];
419 };
420 
421 /*!
422  * @ingroup xrt_iface comp_client
423  */
425 {
426  struct xrt_compositor base;
427 };
428 
429 static inline struct xrt_swapchain_gl *
430 xrt_swapchain_gl(struct xrt_swapchain *xsc)
431 {
432  return (struct xrt_swapchain_gl *)xsc;
433 }
434 
435 static inline struct xrt_compositor_gl *
437 {
438  return (struct xrt_compositor_gl *)xc;
439 }
440 
441 
442 /*
443  *
444  * Vulkan interface.
445  *
446  */
447 
448 #ifdef XRT_64_BIT
449 typedef struct VkImage_T *VkImage;
450 typedef struct VkDeviceMemory_T *VkDeviceMemory;
451 #else
452 typedef uint64_t VkImage;
453 typedef uint64_t VkDeviceMemory;
454 #endif
455 
456 /*!
457  * Base class for a Vulkan client swapchain.
458  *
459  * @ingroup xrt_iface comp_client
460  */
462 {
463  struct xrt_swapchain base;
464 
465  VkImage images[XRT_MAX_SWAPCHAIN_IMAGES];
466  VkDeviceMemory mems[XRT_MAX_SWAPCHAIN_IMAGES];
467 };
468 
469 /*!
470  * Base class for a Vulkan client compositor.
471  *
472  * @ingroup xrt_iface comp_client
473  */
475 {
476  struct xrt_compositor base;
477 };
478 
479 static inline struct xrt_swapchain_vk *
480 xrt_swapchain_vk(struct xrt_swapchain *xsc)
481 {
482  return (struct xrt_swapchain_vk *)xsc;
483 }
484 
485 static inline struct xrt_compositor_vk *
487 {
488  return (struct xrt_compositor_vk *)xc;
489 }
490 
491 
492 /*
493  *
494  * FD interface, aka DMABUF.
495  *
496  */
497 
498 /*!
499  * A single image of a fd based swapchain.
500  *
501  * @ingroup xrt_iface comp
502  */
504 {
505  size_t size;
506  int fd;
507  int _pad;
508 };
509 
510 /*!
511  * A swapchain that exposes fd to be imported into a client API.
512  *
513  * @ingroup xrt_iface comp
514  */
516 {
517  struct xrt_swapchain base;
518 
520 };
521 
522 /*!
523  * Main compositor.
524  *
525  * @ingroup xrt_iface comp
526  */
528 {
529  struct xrt_compositor base;
530 };
531 
532 static inline struct xrt_swapchain_fd *
533 xrt_swapchain_fd(struct xrt_swapchain *xsc)
534 {
535  return (struct xrt_swapchain_fd *)xsc;
536 }
537 
538 static inline struct xrt_compositor_fd *
540 {
541  return (struct xrt_compositor_fd *)xc;
542 }
543 
544 
545 #ifdef __cplusplus
546 }
547 #endif
void(* begin_session)(struct xrt_compositor *xc, enum xrt_view_type view_type)
See xrBeginSession.
Definition: xrt_compositor.h:211
void(* destroy)(struct xrt_swapchain *xsc)
Must have called release_image before calling this function.
Definition: xrt_compositor.h:90
void(* end_session)(struct xrt_compositor *xc)
See xrEndSession, unlike the OpenXR one the state tracker is responsible to call discard frame before...
Definition: xrt_compositor.h:219
Main compositor.
Definition: xrt_compositor.h:527
Base class for a Vulkan client compositor.
Definition: xrt_compositor.h:474
int _pad
Definition: xrt_compositor.h:507
void(* poll_events)(struct xrt_compositor *xc, uint64_t *WIP)
Poll events from this compositor.
Definition: xrt_compositor.h:201
Definition: xrt_compositor.h:56
uint64_t VkImage
Definition: xrt_compositor.h:452
#define XRT_MAX_SWAPCHAIN_FORMATS
Max formats supported by a compositor, artificial limit.
Definition: xrt_compositor.h:31
Definition: xrt_compositor.h:51
A swapchain that exposes fd to be imported into a client API.
Definition: xrt_compositor.h:515
void(* discard_frame)(struct xrt_compositor *xc)
This isn&#39;t in the OpenXR API but is explicit in the XRT interfaces.
Definition: xrt_compositor.h:244
Definition: xrt_compositor.h:411
Base class for a Vulkan client swapchain.
Definition: xrt_compositor.h:461
xrt_swapchain_usage_bits
Usage of the swapchain images.
Definition: xrt_compositor.h:48
Definition: xrt_compositor.h:50
Definition: xrt_compositor.h:53
Definition: xrt_compositor.h:54
Definition: xrt_compositor.h:52
void(* end_frame)(struct xrt_compositor *xc, enum xrt_blend_mode blend_mode, struct xrt_swapchain **xscs, const uint32_t *image_index, uint32_t *layers, uint32_t num_swapchains)
See xrEndFrame.
Definition: xrt_compositor.h:249
Common defines and enums for XRT.
int fd
Definition: xrt_compositor.h:506
Common swapchain base.
Definition: xrt_compositor.h:75
Definition: xrt_compositor.h:424
uint64_t VkDeviceMemory
Definition: xrt_compositor.h:453
xrt_blend_mode
Which blend mode does the device support, used as both a bitfield and value.
Definition: xrt_defines.h:35
void(* wait_frame)(struct xrt_compositor *xc, uint64_t *predicted_display_time, uint64_t *predicted_display_period)
See xrWaitFrame.
Definition: xrt_compositor.h:224
bool(* acquire_image)(struct xrt_swapchain *xsc, uint32_t *index)
See xrWaitSwapchainImage, must make sure that no image is acquired before calling acquire_image...
Definition: xrt_compositor.h:96
Definition: xrt_compositor.h:67
void(* prepare_session)(struct xrt_compositor *xc)
This function is implicit in the OpenXR spec but made explicit here.
Definition: xrt_compositor.h:206
Definition: xrt_compositor.h:66
uint32_t array_size
Number of array layers per image.
Definition: xrt_compositor.h:85
Common compositor base.
Definition: xrt_compositor.h:169
Definition: xrt_compositor.h:55
#define XRT_MAX_SWAPCHAIN_IMAGES
Max swapchain images, artificial limit.
Definition: xrt_compositor.h:24
void(* destroy)(struct xrt_compositor *xc)
Teardown the compositor.
Definition: xrt_compositor.h:262
bool(* release_image)(struct xrt_swapchain *xsc, uint32_t index)
See xrReleaseSwapchainImage, state tracker needs to track index.
Definition: xrt_compositor.h:108
xrt_view_type
View type to be rendered to by the compositor.
Definition: xrt_compositor.h:64
Definition: xrt_compositor.h:40
struct xrt_swapchain *(* create_swapchain)(struct xrt_compositor *xc, enum xrt_swapchain_create_flags create, enum xrt_swapchain_usage_bits bits, int64_t format, uint32_t sample_count, uint32_t width, uint32_t height, uint32_t face_count, uint32_t array_size, uint32_t mip_count)
Create a swapchain with a set of images.
Definition: xrt_compositor.h:184
uint32_t num_formats
Number of formats.
Definition: xrt_compositor.h:174
size_t size
Definition: xrt_compositor.h:505
bool(* wait_image)(struct xrt_swapchain *xsc, uint64_t timeout, uint32_t index)
See xrWaitSwapchainImage, state tracker needs to track index.
Definition: xrt_compositor.h:101
xrt_swapchain_create_flags
Special flags for creating swapchain images.
Definition: xrt_compositor.h:38
uint32_t num_images
Number of images, the images themselves are on the subclasses.
Definition: xrt_compositor.h:80
void(* begin_frame)(struct xrt_compositor *xc)
See xrBeginFrame.
Definition: xrt_compositor.h:231
A single image of a fd based swapchain.
Definition: xrt_compositor.h:503