The open source OpenXR runtime
at main 245 lines 7.3 kB view raw
1// Copyright 2019-2024, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Helper implementation for native compositors. 6 * @author Jakob Bornecrantz <jakob@collabora.com> 7 * @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com> 8 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 9 * @ingroup comp_util 10 */ 11 12#include "util/comp_layer_accum.h" 13#include "util/comp_sync.h" 14#include "util/u_wait.h" 15#include "util/u_trace_marker.h" 16 17#include "util/comp_base.h" 18#include "util/comp_semaphore.h" 19#include "xrt/xrt_compositor.h" 20 21 22/* 23 * 24 * Helper function. 25 * 26 */ 27 28 29/* 30 * 31 * xrt_compositor functions. 32 * 33 */ 34 35//! Delegates to code in `comp_swapchain` 36static xrt_result_t 37base_get_swapchain_create_properties(struct xrt_compositor *xc, 38 const struct xrt_swapchain_create_info *info, 39 struct xrt_swapchain_create_properties *xsccp) 40{ 41 return comp_swapchain_get_create_properties(info, xsccp); 42} 43 44//! Delegates to code in `comp_swapchain` 45static xrt_result_t 46base_create_swapchain(struct xrt_compositor *xc, 47 const struct xrt_swapchain_create_info *info, 48 struct xrt_swapchain **out_xsc) 49{ 50 struct comp_base *cb = comp_base(xc); 51 52 /* 53 * In case the default get properties function have been overridden 54 * make sure to correctly dispatch the call to get the properties. 55 */ 56 struct xrt_swapchain_create_properties xsccp = {0}; 57 xrt_comp_get_swapchain_create_properties(xc, info, &xsccp); 58 59 return comp_swapchain_create(&cb->vk, &cb->cscs, info, &xsccp, out_xsc); 60} 61 62//! Delegates to code in `comp_swapchain` 63static xrt_result_t 64base_import_swapchain(struct xrt_compositor *xc, 65 const struct xrt_swapchain_create_info *info, 66 struct xrt_image_native *native_images, 67 uint32_t image_count, 68 struct xrt_swapchain **out_xsc) 69{ 70 struct comp_base *cb = comp_base(xc); 71 72 return comp_swapchain_import(&cb->vk, &cb->cscs, info, native_images, image_count, out_xsc); 73} 74 75//! Delegates to code in `comp_sync` 76static xrt_result_t 77base_import_fence(struct xrt_compositor *xc, xrt_graphics_sync_handle_t handle, struct xrt_compositor_fence **out_xcf) 78{ 79 struct comp_base *cb = comp_base(xc); 80 81 return comp_fence_import(&cb->vk, handle, out_xcf); 82} 83 84//! Delegates to code in `comp_semaphore` 85static xrt_result_t 86base_create_semaphore(struct xrt_compositor *xc, 87 xrt_graphics_sync_handle_t *out_handle, 88 struct xrt_compositor_semaphore **out_xcsem) 89{ 90 struct comp_base *cb = comp_base(xc); 91 92 return comp_semaphore_create(&cb->vk, out_handle, out_xcsem); 93} 94 95static xrt_result_t 96base_layer_begin(struct xrt_compositor *xc, const struct xrt_layer_frame_data *data) 97{ 98 struct comp_base *cb = comp_base(xc); 99 return comp_layer_accum_begin(&cb->layer_accum, data); 100} 101 102static xrt_result_t 103base_layer_projection(struct xrt_compositor *xc, 104 struct xrt_device *xdev, 105 struct xrt_swapchain *xsc[XRT_MAX_VIEWS], 106 const struct xrt_layer_data *data) 107{ 108 struct comp_base *cb = comp_base(xc); 109 return comp_layer_accum_projection(&cb->layer_accum, xsc, data); 110} 111 112static xrt_result_t 113base_layer_projection_depth(struct xrt_compositor *xc, 114 struct xrt_device *xdev, 115 struct xrt_swapchain *xsc[XRT_MAX_VIEWS], 116 struct xrt_swapchain *d_xsc[XRT_MAX_VIEWS], 117 const struct xrt_layer_data *data) 118{ 119 struct comp_base *cb = comp_base(xc); 120 return comp_layer_accum_projection_depth(&cb->layer_accum, xsc, d_xsc, data); 121} 122 123static xrt_result_t 124base_layer_quad(struct xrt_compositor *xc, 125 struct xrt_device *xdev, 126 struct xrt_swapchain *xsc, 127 const struct xrt_layer_data *data) 128{ 129 struct comp_base *cb = comp_base(xc); 130 return comp_layer_accum_quad(&cb->layer_accum, xsc, data); 131} 132 133static xrt_result_t 134base_layer_cube(struct xrt_compositor *xc, 135 struct xrt_device *xdev, 136 struct xrt_swapchain *xsc, 137 const struct xrt_layer_data *data) 138{ 139 struct comp_base *cb = comp_base(xc); 140 return comp_layer_accum_cube(&cb->layer_accum, xsc, data); 141} 142 143static xrt_result_t 144base_layer_cylinder(struct xrt_compositor *xc, 145 struct xrt_device *xdev, 146 struct xrt_swapchain *xsc, 147 const struct xrt_layer_data *data) 148{ 149 struct comp_base *cb = comp_base(xc); 150 return comp_layer_accum_cylinder(&cb->layer_accum, xsc, data); 151} 152 153static xrt_result_t 154base_layer_equirect1(struct xrt_compositor *xc, 155 struct xrt_device *xdev, 156 struct xrt_swapchain *xsc, 157 const struct xrt_layer_data *data) 158{ 159 struct comp_base *cb = comp_base(xc); 160 return comp_layer_accum_equirect1(&cb->layer_accum, xsc, data); 161} 162 163static xrt_result_t 164base_layer_equirect2(struct xrt_compositor *xc, 165 struct xrt_device *xdev, 166 struct xrt_swapchain *xsc, 167 const struct xrt_layer_data *data) 168{ 169 struct comp_base *cb = comp_base(xc); 170 return comp_layer_accum_equirect2(&cb->layer_accum, xsc, data); 171} 172 173static xrt_result_t 174base_wait_frame(struct xrt_compositor *xc, 175 int64_t *out_frame_id, 176 int64_t *out_predicted_display_time_ns, 177 int64_t *out_predicted_display_period_ns) 178{ 179 COMP_TRACE_MARKER(); 180 181 struct comp_base *cb = comp_base(xc); 182 183 int64_t frame_id = -1; 184 int64_t wake_up_time_ns = 0; 185 int64_t predicted_gpu_time_ns = 0; 186 187 xrt_comp_predict_frame( // 188 xc, // 189 &frame_id, // 190 &wake_up_time_ns, // 191 &predicted_gpu_time_ns, // 192 out_predicted_display_time_ns, // 193 out_predicted_display_period_ns); // 194 195 // Wait until the given wake up time. 196 u_wait_until(&cb->sleeper, wake_up_time_ns); 197 198 int64_t now_ns = os_monotonic_get_ns(); 199 200 // Signal that we woke up. 201 xrt_comp_mark_frame(xc, frame_id, XRT_COMPOSITOR_FRAME_POINT_WOKE, now_ns); 202 203 *out_frame_id = frame_id; 204 205 return XRT_SUCCESS; 206} 207 208 209/* 210 * 211 * 'Exported' functions. 212 * 213 */ 214 215void 216comp_base_init(struct comp_base *cb) 217{ 218 struct xrt_compositor *iface = &cb->base.base; 219 iface->get_swapchain_create_properties = base_get_swapchain_create_properties; 220 iface->create_swapchain = base_create_swapchain; 221 iface->import_swapchain = base_import_swapchain; 222 iface->create_semaphore = base_create_semaphore; 223 iface->import_fence = base_import_fence; 224 iface->layer_begin = base_layer_begin; 225 iface->layer_projection = base_layer_projection; 226 iface->layer_projection_depth = base_layer_projection_depth; 227 iface->layer_quad = base_layer_quad; 228 iface->layer_cube = base_layer_cube; 229 iface->layer_cylinder = base_layer_cylinder; 230 iface->layer_equirect1 = base_layer_equirect1; 231 iface->layer_equirect2 = base_layer_equirect2; 232 iface->wait_frame = base_wait_frame; 233 234 u_threading_stack_init(&cb->cscs.destroy_swapchains); 235 236 os_precise_sleeper_init(&cb->sleeper); 237} 238 239void 240comp_base_fini(struct comp_base *cb) 241{ 242 os_precise_sleeper_deinit(&cb->sleeper); 243 244 u_threading_stack_fini(&cb->cscs.destroy_swapchains); 245}