The open source OpenXR runtime
at main 296 lines 7.0 kB view raw
1// Copyright 2023-2024, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Special code for managing a variable tracked swapchain. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @ingroup aux_util 8 */ 9 10#pragma once 11 12#include "os/os_threading.h" 13#include "xrt/xrt_compositor.h" 14 15 16#ifdef __cplusplus 17extern "C" { 18#endif 19 20 21/*! 22 * A struct for debugging one or more native images. 23 * 24 * @ingroup aux_util 25 */ 26struct u_native_images_debug 27{ 28 //! Is initialised/destroyed when added or root is removed. 29 struct os_mutex mutex; 30 31 /*! 32 * Process unique id for the set of images, protected by @p mutex, 33 * allows caching of imports. Created by @ref u_limited_unique_id_get. 34 */ 35 xrt_limited_unique_id_t limited_unique_id; 36 37 //! List to current set of native images, protected by @p mutex. 38 struct xrt_image_native *native_images; 39 40 //! Count of @p native_images, protected by @p mutex. 41 uint32_t native_image_count; 42 43 /*! 44 * Information needed to import the native images, information in the 45 * struct is immutable, the pointer is protected by @p mutex. 46 */ 47 const struct xrt_swapchain_create_info *xscci; 48 49 /*! 50 * The native image that was last filled in by the source, only 51 * valid if @p native_images is non-null, protected by @p mutex. 52 */ 53 uint32_t active_index; 54 55 //! Should the image be flipped in y direction. 56 bool flip_y; 57}; 58 59/*! 60 * Must be called before variable is tracked. 61 * 62 * @ingroup aux_util 63 */ 64static inline void 65u_native_images_debug_init(struct u_native_images_debug *unid) 66{ 67 os_mutex_init(&unid->mutex); 68} 69 70/*! 71 * Must not be called while variable longer tracked, after @p u_var_remove_root. 72 * 73 * @ingroup aux_util 74 */ 75static inline void 76u_native_images_debug_destroy(struct u_native_images_debug *unid) 77{ 78 os_mutex_destroy(&unid->mutex); 79 unid->native_images = NULL; 80 unid->native_image_count = 0; 81 unid->xscci = NULL; 82 unid->active_index = 0; 83 unid->flip_y = false; 84} 85 86/*! 87 * Simple lock helper. 88 * 89 * @ingroup aux_util 90 */ 91static inline void 92u_native_images_debug_lock(struct u_native_images_debug *unid) 93{ 94 os_mutex_lock(&unid->mutex); 95} 96 97/*! 98 * Simple lock helper. 99 * 100 * @ingroup aux_util 101 */ 102static inline void 103u_native_images_debug_unlock(struct u_native_images_debug *unid) 104{ 105 os_mutex_unlock(&unid->mutex); 106} 107 108/*! 109 * Helper function to update all variables, must be called with the lock held. 110 * 111 * @ingroup aux_util 112 */ 113static inline void 114u_native_images_debug_set_locked(struct u_native_images_debug *unid, 115 xrt_limited_unique_id_t limited_unique_id, 116 struct xrt_image_native *native_images, 117 uint32_t native_image_count, 118 const struct xrt_swapchain_create_info *xscci, 119 uint32_t active_index, 120 bool flip_y) 121{ 122 unid->limited_unique_id = limited_unique_id; 123 unid->native_images = native_images; 124 unid->native_image_count = native_image_count; 125 unid->active_index = active_index; 126 unid->xscci = xscci; 127 unid->flip_y = flip_y; 128} 129 130/*! 131 * Updates all variables atomically by holding the lock. 132 * 133 * @ingroup aux_util 134 */ 135static inline void 136u_native_images_debug_set(struct u_native_images_debug *unid, 137 xrt_limited_unique_id_t limited_unique_id, 138 struct xrt_image_native *native_images, 139 uint32_t native_image_count, 140 const struct xrt_swapchain_create_info *xscci, 141 uint32_t active_index, 142 bool flip_y) 143{ 144 u_native_images_debug_lock(unid); 145 u_native_images_debug_set_locked( // 146 unid, // 147 limited_unique_id, // 148 native_images, // 149 native_image_count, // 150 xscci, // 151 active_index, // 152 flip_y); // 153 u_native_images_debug_unlock(unid); 154} 155 156/*! 157 * Clear all variables, must be called with the lock held. 158 * 159 * @ingroup aux_util 160 */ 161static inline void 162u_native_images_debug_clear_locked(struct u_native_images_debug *unid) 163{ 164 unid->limited_unique_id.data = 0; 165 unid->xscci = NULL; 166 unid->active_index = 0; 167 unid->native_images = NULL; 168 unid->native_image_count = 0; 169} 170 171/*! 172 * Clear all variables atomically by holding the lock, still valid to use. 173 * 174 * @ingroup aux_util 175 */ 176static inline void 177u_native_images_debug_clear(struct u_native_images_debug *unid) 178{ 179 u_native_images_debug_lock(unid); 180 u_native_images_debug_clear_locked(unid); 181 u_native_images_debug_unlock(unid); 182} 183 184 185/* 186 * 187 * Swapchain. 188 * 189 */ 190 191/*! 192 * Allows to debug image that is in GPU memory. 193 * 194 * @ingroup aux_util 195 */ 196struct u_swapchain_debug 197{ 198 //! Base for native image debugging. 199 struct u_native_images_debug base; 200 201 //! Protected by @p base::mutex. 202 struct xrt_swapchain_native *xscn; 203}; 204 205/*! 206 * Must be called before variable is tracked. 207 * 208 * @ingroup aux_util 209 */ 210static inline void 211u_swapchain_debug_init(struct u_swapchain_debug *uscd) 212{ 213 u_native_images_debug_init(&uscd->base); 214} 215 216/*! 217 * Updates all variables atomically by holding the lock. 218 * 219 * @ingroup aux_util 220 */ 221static inline void 222u_swapchain_debug_set(struct u_swapchain_debug *uscd, 223 struct xrt_swapchain_native *xscn, 224 const struct xrt_swapchain_create_info *xscci, 225 uint32_t active_index, 226 bool flip_y) 227{ 228 u_native_images_debug_lock(&uscd->base); 229 230 u_native_images_debug_set_locked( // 231 &uscd->base, // 232 xscn->limited_unique_id, // 233 xscn->images, // 234 xscn->base.image_count, // 235 xscci, // 236 active_index, // 237 flip_y); // 238 239 xrt_swapchain_native_reference(&uscd->xscn, xscn); 240 241 u_native_images_debug_unlock(&uscd->base); 242} 243 244/*! 245 * Clear all variables atomically by holding the lock, still valid to use. 246 * 247 * @ingroup aux_util 248 */ 249static inline void 250u_swapchain_debug_clear(struct u_swapchain_debug *uscd) 251{ 252 u_native_images_debug_lock(&uscd->base); 253 u_native_images_debug_clear_locked(&uscd->base); 254 xrt_swapchain_native_reference(&uscd->xscn, NULL); 255 u_native_images_debug_unlock(&uscd->base); 256} 257 258/*! 259 * Must not be called while variable longer tracked, after @p u_var_remove_root. 260 * 261 * @ingroup aux_util 262 */ 263static inline void 264u_swapchain_debug_destroy(struct u_swapchain_debug *uscd) 265{ 266 xrt_swapchain_native_reference(&uscd->xscn, NULL); 267 uscd->base.active_index = 0; 268 os_mutex_destroy(&uscd->base.mutex); 269} 270 271/*! 272 * Simple lock helper. 273 * 274 * @ingroup aux_util 275 */ 276static inline void 277u_swapchain_debug_lock(struct u_swapchain_debug *uscd) 278{ 279 u_native_images_debug_lock(&uscd->base); 280} 281 282/*! 283 * Simple lock helper. 284 * 285 * @ingroup aux_util 286 */ 287static inline void 288u_swapchain_debug_unlock(struct u_swapchain_debug *uscd) 289{ 290 u_native_images_debug_unlock(&uscd->base); 291} 292 293 294#ifdef __cplusplus 295} 296#endif