diff --git a/src/xrt/compositor/client/comp_egl_client.c b/src/xrt/compositor/client/comp_egl_client.c index 60bdcd726..384e862a2 100644 --- a/src/xrt/compositor/client/comp_egl_client.c +++ b/src/xrt/compositor/client/comp_egl_client.c @@ -417,10 +417,15 @@ client_egl_insert_fence(struct xrt_compositor *xc, xrt_graphics_sync_handle_t *o } static xrt_result_t -client_egl_context_begin(struct xrt_compositor *xc) +client_egl_context_begin(struct xrt_compositor *xc, enum client_gl_context_reason reason) { struct client_egl_compositor *eglc = client_egl_compositor(xc); + //! @todo Handle this better, don't just assume that the context is current. + if (reason == CLIENT_GL_CONTEXT_REASON_SYNCHRONIZE) { + return XRT_SUCCESS; + } + save_context(&eglc->previous); struct client_egl_context *cur = &eglc->current; @@ -431,10 +436,15 @@ client_egl_context_begin(struct xrt_compositor *xc) } static void -client_egl_context_end(struct xrt_compositor *xc) +client_egl_context_end(struct xrt_compositor *xc, enum client_gl_context_reason reason) { struct client_egl_compositor *eglc = client_egl_compositor(xc); + //! @todo Handle this better, don't just assume that the context is current. + if (reason == CLIENT_GL_CONTEXT_REASON_SYNCHRONIZE) { + return; + } + restore_context(&eglc->previous); } diff --git a/src/xrt/compositor/client/comp_gl_client.c b/src/xrt/compositor/client/comp_gl_client.c index 1bc5931d8..ae291afd4 100644 --- a/src/xrt/compositor/client/comp_gl_client.c +++ b/src/xrt/compositor/client/comp_gl_client.c @@ -386,10 +386,10 @@ client_gl_compositor_layer_commit(struct xrt_compositor *xc, xrt_graphics_sync_h sync_handle = XRT_GRAPHICS_SYNC_HANDLE_INVALID; - xrt_result_t xret = client_gl_compositor_context_begin(xc); + xrt_result_t xret = client_gl_compositor_context_begin(xc, CLIENT_GL_CONTEXT_REASON_SYNCHRONIZE); if (xret == XRT_SUCCESS) { sync_handle = handle_fencing_or_finish(c); - client_gl_compositor_context_end(xc); + client_gl_compositor_context_end(xc, CLIENT_GL_CONTEXT_REASON_SYNCHRONIZE); } COMP_TRACE_IDENT(layer_commit); @@ -439,7 +439,7 @@ client_gl_swapchain_create(struct xrt_compositor *xc, return XRT_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED; } - xret = client_gl_compositor_context_begin(xc); + xret = client_gl_compositor_context_begin(xc, CLIENT_GL_CONTEXT_REASON_OTHER); if (xret != XRT_SUCCESS) { return xret; } @@ -448,7 +448,7 @@ client_gl_swapchain_create(struct xrt_compositor *xc, const char *version_str = (const char *)glGetString(GL_VERSION); if (strstr(version_str, "OpenGL ES 2.") == version_str) { U_LOG_E("Only one array layer is supported with OpenGL ES 2"); - client_gl_compositor_context_end(xc); + client_gl_compositor_context_end(xc, CLIENT_GL_CONTEXT_REASON_OTHER); return XRT_ERROR_SWAPCHAIN_FLAG_VALID_BUT_UNSUPPORTED; } } @@ -465,7 +465,7 @@ client_gl_swapchain_create(struct xrt_compositor *xc, xret = xrt_comp_native_create_swapchain(c->xcn, &vkinfo, &xscn); if (xret != XRT_SUCCESS) { - client_gl_compositor_context_end(xc); + client_gl_compositor_context_end(xc, CLIENT_GL_CONTEXT_REASON_OTHER); return xret; } assert(xscn != NULL); @@ -484,13 +484,13 @@ client_gl_swapchain_create(struct xrt_compositor *xc, if (NULL == c->create_swapchain(xc, &xinfo, xscn, &sc)) { // Drop our reference, does NULL checking. xrt_swapchain_reference(&xsc, NULL); - client_gl_compositor_context_end(xc); + client_gl_compositor_context_end(xc, CLIENT_GL_CONTEXT_REASON_OTHER); return XRT_ERROR_OPENGL; } if (sc == NULL) { U_LOG_E("Could not create OpenGL swapchain."); - client_gl_compositor_context_end(xc); + client_gl_compositor_context_end(xc, CLIENT_GL_CONTEXT_REASON_OTHER); return XRT_ERROR_OPENGL; } @@ -512,7 +512,7 @@ client_gl_swapchain_create(struct xrt_compositor *xc, glBindTexture(tex_target, prev_texture); - client_gl_compositor_context_end(xc); + client_gl_compositor_context_end(xc, CLIENT_GL_CONTEXT_REASON_OTHER); *out_xsc = &sc->base.base; return XRT_SUCCESS; diff --git a/src/xrt/compositor/client/comp_gl_client.h b/src/xrt/compositor/client/comp_gl_client.h index 0c61c3025..205f59a73 100644 --- a/src/xrt/compositor/client/comp_gl_client.h +++ b/src/xrt/compositor/client/comp_gl_client.h @@ -52,6 +52,27 @@ struct client_gl_swapchain struct client_gl_compositor *gl_compositor; }; +/*! + * What's the reason to make the context current, this is needed currently for + * EGL where we have to create a shared context in some cases. But when we + * want to synchronize (insert a fence or call glFinish) we can not use the + * shared context and must use the context that the app provided on creation. + */ +enum client_gl_context_reason +{ + /*! + * Used when the compositor needs to insert a fence in the command + * stream of the apps context, this needs to be done in the given + * context and not the shared one that may be created. + */ + CLIENT_GL_CONTEXT_REASON_SYNCHRONIZE, + /*! + * Any other reason to make the context current, + * the shared may be used by now. + */ + CLIENT_GL_CONTEXT_REASON_OTHER, +}; + /*! * Fetches the OpenGL context that is current on this thread and makes the * OpenGL context given in the graphics binding current instead. Only one thread @@ -67,7 +88,8 @@ struct client_gl_swapchain * If the return value is not XRT_SUCCESS, * @ref client_gl_context_end_locked_func_t should not be called. */ -typedef xrt_result_t (*client_gl_context_begin_locked_func_t)(struct xrt_compositor *xc); +typedef xrt_result_t (*client_gl_context_begin_locked_func_t)(struct xrt_compositor *xc, + enum client_gl_context_reason reason); /*! * Makes the OpenGL context current that was current before @@ -78,7 +100,7 @@ typedef xrt_result_t (*client_gl_context_begin_locked_func_t)(struct xrt_composi * not released by this function, but @ref client_gl_compositor_context_end does * release it. */ -typedef void (*client_gl_context_end_locked_func_t)(struct xrt_compositor *xc); +typedef void (*client_gl_context_end_locked_func_t)(struct xrt_compositor *xc, enum client_gl_context_reason reason); /*! * The type of a swapchain create constructor. @@ -207,13 +229,13 @@ client_gl_compositor_close(struct client_gl_compositor *c); * @public @memberof client_gl_compositor */ static inline xrt_result_t -client_gl_compositor_context_begin(struct xrt_compositor *xc) +client_gl_compositor_context_begin(struct xrt_compositor *xc, enum client_gl_context_reason reason) { struct client_gl_compositor *cgc = client_gl_compositor(xc); os_mutex_lock(&cgc->context_mutex); - xrt_result_t xret = cgc->context_begin_locked(xc); + xrt_result_t xret = cgc->context_begin_locked(xc, reason); if (xret != XRT_SUCCESS) { os_mutex_unlock(&cgc->context_mutex); } @@ -229,11 +251,11 @@ client_gl_compositor_context_begin(struct xrt_compositor *xc) * @public @memberof client_gl_compositor */ static inline void -client_gl_compositor_context_end(struct xrt_compositor *xc) +client_gl_compositor_context_end(struct xrt_compositor *xc, enum client_gl_context_reason reason) { struct client_gl_compositor *cgc = client_gl_compositor(xc); - cgc->context_end_locked(xc); + cgc->context_end_locked(xc, reason); os_mutex_unlock(&cgc->context_mutex); } diff --git a/src/xrt/compositor/client/comp_gl_memobj_swapchain.c b/src/xrt/compositor/client/comp_gl_memobj_swapchain.c index 977e9d52f..d7b93f1c2 100644 --- a/src/xrt/compositor/client/comp_gl_memobj_swapchain.c +++ b/src/xrt/compositor/client/comp_gl_memobj_swapchain.c @@ -50,7 +50,7 @@ client_gl_memobj_swapchain_destroy(struct xrt_swapchain *xsc) uint32_t image_count = sc->base.base.base.image_count; struct client_gl_compositor *c = sc->base.gl_compositor; - enum xrt_result xret = client_gl_compositor_context_begin(&c->base.base); + enum xrt_result xret = client_gl_compositor_context_begin(&c->base.base, CLIENT_GL_CONTEXT_REASON_OTHER); if (image_count > 0) { if (xret == XRT_SUCCESS) { @@ -64,7 +64,7 @@ client_gl_memobj_swapchain_destroy(struct xrt_swapchain *xsc) } if (xret == XRT_SUCCESS) { - client_gl_compositor_context_end(&c->base.base); + client_gl_compositor_context_end(&c->base.base, CLIENT_GL_CONTEXT_REASON_OTHER); } // Drop our reference, does NULL checking. diff --git a/src/xrt/compositor/client/comp_gl_win32_client.c b/src/xrt/compositor/client/comp_gl_win32_client.c index d28972ef8..a2c3598db 100644 --- a/src/xrt/compositor/client/comp_gl_win32_client.c +++ b/src/xrt/compositor/client/comp_gl_win32_client.c @@ -76,7 +76,7 @@ client_gl_win32_compositor_destroy(struct xrt_compositor *xc) } static xrt_result_t -client_gl_context_begin_locked(struct xrt_compositor *xc) +client_gl_context_begin_locked(struct xrt_compositor *xc, enum client_gl_context_reason reason) { struct client_gl_win32_compositor *c = client_gl_win32_compositor(xc); @@ -99,7 +99,7 @@ client_gl_context_begin_locked(struct xrt_compositor *xc) } static void -client_gl_context_end_locked(struct xrt_compositor *xc) +client_gl_context_end_locked(struct xrt_compositor *xc, enum client_gl_context_reason reason) { struct client_gl_win32_compositor *c = client_gl_win32_compositor(xc); diff --git a/src/xrt/compositor/client/comp_gl_xlib_client.c b/src/xrt/compositor/client/comp_gl_xlib_client.c index cd85de67d..4540f4a7c 100644 --- a/src/xrt/compositor/client/comp_gl_xlib_client.c +++ b/src/xrt/compositor/client/comp_gl_xlib_client.c @@ -74,7 +74,7 @@ client_gl_xlib_compositor_destroy(struct xrt_compositor *xc) } static xrt_result_t -client_gl_context_begin_locked(struct xrt_compositor *xc) +client_gl_context_begin_locked(struct xrt_compositor *xc, enum client_gl_context_reason reason) { struct client_gl_xlib_compositor *c = client_gl_xlib_compositor(xc); @@ -97,7 +97,7 @@ client_gl_context_begin_locked(struct xrt_compositor *xc) } static void -client_gl_context_end_locked(struct xrt_compositor *xc) +client_gl_context_end_locked(struct xrt_compositor *xc, enum client_gl_context_reason reason) { struct client_gl_xlib_compositor *c = client_gl_xlib_compositor(xc);