The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

c/client: Insert fence and give sync handle on layer_commit (EGL for now only)

+141 -34
+88 -23
src/xrt/compositor/client/comp_egl_glue.c
··· 1 - // Copyright 2019, Collabora, Ltd. 1 + // Copyright 2019-2020, Collabora, Ltd. 2 2 // SPDX-License-Identifier: BSL-1.0 3 3 /*! 4 4 * @file 5 5 * @brief Glue code to EGL client side glue code. 6 6 * @author Drew DeVault <sir@cmpwn.com> 7 7 * @author Simon Ser <contact@emersion.fr> 8 + * @author Jakob Bornecrantz <jakob@collabora.com> 8 9 * @ingroup comp_client 9 10 */ 10 11 11 - #include <xrt/xrt_config_os.h> 12 - #include <xrt/xrt_config_have.h> 12 + #include "xrt/xrt_config_os.h" 13 + #include "xrt/xrt_config_have.h" 14 + #include "xrt/xrt_gfx_egl.h" 15 + #include "xrt/xrt_handles.h" 16 + 17 + #include "util/u_misc.h" 18 + #include "util/u_logging.h" 19 + #include "util/u_debug.h" 13 20 14 21 #include "ogl/egl_api.h" 15 22 #include "ogl/ogl_api.h" 16 23 17 - #include <stdio.h> 18 - #include <stdlib.h> 19 - 20 24 #include "client/comp_gl_client.h" 21 25 #include "client/comp_gl_memobj_swapchain.h" 22 26 #include "client/comp_gl_eglimage_swapchain.h" 23 - #include "util/u_misc.h" 24 - #include "util/u_logging.h" 25 - #include "util/u_debug.h" 26 - #include "xrt/xrt_gfx_egl.h" 27 - #include "xrt/xrt_handles.h" 28 27 28 + #include <stdio.h> 29 + #include <stdlib.h> 29 30 30 31 #ifndef XRT_HAVE_EGL 31 32 #error "This file shouldn't be compiled without EGL" ··· 39 40 #define EGL_WARN(...) U_LOG_IFL_W(ll, __VA_ARGS__) 40 41 #define EGL_ERROR(...) U_LOG_IFL_E(ll, __VA_ARGS__) 41 42 42 - DEBUG_GET_ONCE_LOG_OPTION(egl_log, "EGL_LOG", U_LOGGING_WARN) 43 + DEBUG_GET_ONCE_LOG_OPTION(egl_log, "EGL_LOG", U_LOGGING_INFO) 43 44 44 45 // Not forward declared by mesa 45 46 typedef EGLBoolean EGLAPIENTRY (*PFNEGLMAKECURRENTPROC)(EGLDisplay dpy, ··· 47 48 EGLSurface read, 48 49 EGLContext ctx); 49 50 51 + /*! 52 + * EGL based compositor. 53 + */ 54 + struct client_egl_compositor 55 + { 56 + struct client_gl_compositor base; 57 + 58 + EGLDisplay dpy; 59 + }; 60 + 61 + /*! 62 + * Down-cast helper. 63 + * @protected @memberof client_egl_compositor 64 + */ 65 + static inline struct client_egl_compositor * 66 + client_egl_compositor(struct xrt_compositor *xc) 67 + { 68 + return (struct client_egl_compositor *)xc; 69 + } 70 + 50 71 51 72 /* 52 73 * ··· 92 113 * 93 114 */ 94 115 116 + static xrt_result_t 117 + insert_fence(struct xrt_compositor *xc, xrt_graphics_sync_handle_t *out_handle) 118 + { 119 + struct client_egl_compositor *ceglc = client_egl_compositor(xc); 120 + 121 + *out_handle = XRT_GRAPHICS_SYNC_HANDLE_INVALID; 122 + EGLDisplay dpy = ceglc->dpy; 123 + 124 + #ifdef XRT_GRAPHICS_SYNC_HANDLE_IS_FD 125 + 126 + EGLSyncKHR sync = 127 + eglCreateSyncKHR(dpy, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); 128 + if (sync == EGL_NO_SYNC_KHR) { 129 + EGL_ERROR("Failed to insert fence!"); 130 + return XRT_ERROR_FENCE_CREATE_FAILED; 131 + } 132 + 133 + glFlush(); 134 + 135 + int fence_fd = eglDupNativeFenceFDANDROID(dpy, sync); 136 + eglDestroySyncKHR(dpy, sync); 137 + 138 + if (fence_fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { 139 + EGL_ERROR("Failed to get FD from fence!"); 140 + return XRT_ERROR_NATIVE_HANDLE_FENCE_ERROR; 141 + } 142 + 143 + *out_handle = fence_fd; 144 + #else 145 + (void)cglc; 146 + #endif 147 + 148 + return XRT_SUCCESS; 149 + } 150 + 95 151 static void 96 152 client_egl_compositor_destroy(struct xrt_compositor *xc) 97 153 { 98 - struct client_gl_compositor *c = client_gl_compositor(xc); 154 + struct client_egl_compositor *ceglc = client_egl_compositor(xc); 99 155 100 - free(c); 156 + free(ceglc); 101 157 } 102 158 103 159 struct xrt_compositor_gl * ··· 151 207 default: EGL_ERROR("Unsupported EGL client type"); return NULL; 152 208 } 153 209 154 - struct client_gl_compositor *c = 155 - U_TYPED_CALLOC(struct client_gl_compositor); 210 + struct client_egl_compositor *ceglc = 211 + U_TYPED_CALLOC(struct client_egl_compositor); 212 + ceglc->dpy = display; 156 213 157 214 client_gl_swapchain_create_func sc_create = NULL; 158 215 ··· 163 220 DUMP_EXTENSION_STATUS(GL_EXT_memory_object); 164 221 DUMP_EXTENSION_STATUS(GL_EXT_memory_object_fd); 165 222 DUMP_EXTENSION_STATUS(GL_EXT_memory_object_win32); 166 - DUMP_EXTENSION_STATUS(EGL_EXT_image_dma_buf_import); 167 223 DUMP_EXTENSION_STATUS(GL_OES_EGL_image_external); 224 + 225 + DUMP_EXTENSION_STATUS(EGL_ANDROID_get_native_client_buffer); 226 + DUMP_EXTENSION_STATUS(EGL_ANDROID_native_fence_sync); 227 + DUMP_EXTENSION_STATUS(EGL_EXT_image_dma_buf_import_modifiers); 228 + DUMP_EXTENSION_STATUS(EGL_KHR_fence_sync); 168 229 DUMP_EXTENSION_STATUS(EGL_KHR_image); 169 - // DUMP_EXTENSION_STATUS(EGL_KHR_image_base); 230 + DUMP_EXTENSION_STATUS(EGL_KHR_image_base); 231 + DUMP_EXTENSION_STATUS(EGL_KHR_reusable_sync); 232 + DUMP_EXTENSION_STATUS(EGL_KHR_wait_sync); 233 + 170 234 171 235 #if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_FD) 172 236 if (GLAD_GL_EXT_memory_object && GLAD_GL_EXT_memory_object_fd) { ··· 178 242 sc_create = client_gl_eglimage_swapchain_create; 179 243 } 180 244 if (sc_create == NULL) { 181 - free(c); 245 + free(ceglc); 182 246 EGL_ERROR( 183 247 "Could not find a required extension: need either " 184 248 "EGL_EXT_image_dma_buf_import or " ··· 192 256 sc_create = client_gl_eglimage_swapchain_create; 193 257 #endif 194 258 195 - if (!client_gl_compositor_init(c, xcn, sc_create)) { 196 - free(c); 259 + if (!client_gl_compositor_init(&ceglc->base, xcn, sc_create, 260 + insert_fence)) { 261 + free(ceglc); 197 262 U_LOG_E("Failed to initialize compositor"); 198 263 old_restore(&old); 199 264 return NULL; 200 265 } 201 266 202 - c->base.base.destroy = client_egl_compositor_destroy; 267 + ceglc->base.base.base.destroy = client_egl_compositor_destroy; 203 268 old_restore(&old); 204 - return &c->base; 269 + return &ceglc->base.base; 205 270 }
+22 -7
src/xrt/compositor/client/comp_gl_client.c
··· 305 305 int64_t frame_id, 306 306 xrt_graphics_sync_handle_t sync_handle) 307 307 { 308 - //! @hack: The swapchain images should have been externally synchronized 309 - glFlush(); 310 - 311 308 struct client_gl_compositor *c = client_gl_compositor(xc); 312 309 313 - //! @todo We should be creating the handle ourselves in the future. 310 + // We make the sync object, not st/oxr which is our user. 314 311 assert(!xrt_graphics_sync_handle_is_valid(sync_handle)); 315 312 316 - return xrt_comp_layer_commit(&c->xcn->base, frame_id, 317 - XRT_GRAPHICS_SYNC_HANDLE_INVALID); 313 + xrt_result_t xret = XRT_SUCCESS; 314 + sync_handle = XRT_GRAPHICS_SYNC_HANDLE_INVALID; 315 + 316 + if (c->insert_fence != NULL) { 317 + xret = c->insert_fence(xc, &sync_handle); 318 + } else { 319 + /*! 320 + * @hack: The swapchain images should have been externally 321 + * synchronized. 322 + */ 323 + glFlush(); 324 + } 325 + 326 + if (xret != XRT_SUCCESS) { 327 + return XRT_SUCCESS; 328 + } 329 + 330 + return xrt_comp_layer_commit(&c->xcn->base, frame_id, sync_handle); 318 331 } 319 332 320 333 static int64_t ··· 450 463 bool 451 464 client_gl_compositor_init(struct client_gl_compositor *c, 452 465 struct xrt_compositor_native *xcn, 453 - client_gl_swapchain_create_func create_swapchain) 466 + client_gl_swapchain_create_func create_swapchain, 467 + client_gl_insert_fence_func insert_fence) 454 468 { 455 469 c->base.base.create_swapchain = client_gl_swapchain_create; 456 470 c->base.base.prepare_session = client_gl_compositor_prepare_session; ··· 473 487 c->base.base.destroy = client_gl_compositor_destroy; 474 488 c->base.base.poll_events = client_gl_compositor_poll_events; 475 489 c->create_swapchain = create_swapchain; 490 + c->insert_fence = insert_fence; 476 491 c->xcn = xcn; 477 492 478 493 // Passthrough our formats from the native compositor to the client.
+20 -1
src/xrt/compositor/client/comp_gl_client.h
··· 21 21 * 22 22 */ 23 23 24 + struct client_gl_compositor; 25 + 24 26 /*! 25 27 * @class client_gl_swapchain 26 28 * ··· 61 63 struct client_gl_swapchain **out_sc); 62 64 63 65 /*! 66 + * The type of a fence insertion function. 67 + * 68 + * This function is called in xrt_compositor::layer_commit. 69 + * 70 + * The returned graphics sync handle is given to xrt_compositor::layer_commit. 71 + */ 72 + typedef xrt_result_t (*client_gl_insert_fence_func)( 73 + struct xrt_compositor *xc, xrt_graphics_sync_handle_t *out_handle); 74 + 75 + /*! 64 76 * @class client_gl_compositor 65 77 * 66 78 * Wraps the real compositor providing a OpenGL based interface. ··· 78 90 * Function pointer for creating the client swapchain. 79 91 */ 80 92 client_gl_swapchain_create_func create_swapchain; 93 + 94 + /*! 95 + * Function pointer for inserting fences on 96 + * xrt_compositor::layer_commit. 97 + */ 98 + client_gl_insert_fence_func insert_fence; 81 99 }; 82 100 83 101 ··· 114 132 bool 115 133 client_gl_compositor_init(struct client_gl_compositor *c, 116 134 struct xrt_compositor_native *xcn, 117 - client_gl_swapchain_create_func create_swapchain); 135 + client_gl_swapchain_create_func create_swapchain, 136 + client_gl_insert_fence_func insert_fence); 118 137 119 138 120 139 #ifdef __cplusplus
+2 -2
src/xrt/compositor/client/comp_gl_xlib_client.c
··· 78 78 struct client_gl_xlib_compositor *c = 79 79 U_TYPED_CALLOC(struct client_gl_xlib_compositor); 80 80 81 - if (!client_gl_compositor_init(&c->base, xcn, 82 - client_gl_memobj_swapchain_create)) { 81 + if (!client_gl_compositor_init( 82 + &c->base, xcn, client_gl_memobj_swapchain_create, NULL)) { 83 83 free(c); 84 84 return NULL; 85 85 }
+9 -1
src/xrt/include/xrt/xrt_results.h
··· 31 31 * Could not allocate native image buffer(s). 32 32 */ 33 33 XRT_ERROR_ALLOCATION = -7, 34 - /* 34 + /*! 35 35 * The pose is no longer active, this happens when the application 36 36 * tries to access a pose that is no longer active. 37 37 */ 38 38 XRT_ERROR_POSE_NOT_ACTIVE = -8, 39 + /*! 40 + * Creating a fence failed. 41 + */ 42 + XRT_ERROR_FENCE_CREATE_FAILED = -9, 43 + /*! 44 + * Getting or giving the native fence handle caused a error. 45 + */ 46 + XRT_ERROR_NATIVE_HANDLE_FENCE_ERROR = -10, 39 47 } xrt_result_t;