The open source OpenXR runtime

c/client: implement EGL context begin and end

authored by

Simon Zeni and committed by
Jakob Bornecrantz
c8b4f7c6 f91ada32

+50 -50
+42 -47
src/xrt/compositor/client/comp_egl_client.c
··· 72 72 * 73 73 */ 74 74 75 - struct old_helper 75 + static inline void 76 + save_context(struct client_egl_context *ctx) 76 77 { 77 - EGLDisplay dpy; 78 - EGLContext ctx; 79 - EGLSurface read, draw; 80 - }; 78 + ctx->dpy = eglGetCurrentDisplay(); 79 + ctx->ctx = EGL_NO_CONTEXT; 80 + ctx->read = EGL_NO_SURFACE; 81 + ctx->draw = EGL_NO_SURFACE; 81 82 82 - static inline struct old_helper 83 - old_save(void) 84 - { 85 - struct old_helper old = { 86 - .dpy = eglGetCurrentDisplay(), 87 - .ctx = EGL_NO_CONTEXT, 88 - .read = EGL_NO_SURFACE, 89 - .draw = EGL_NO_SURFACE, 90 - }; 91 - 92 - // Do we have a valid display? 93 - if (old.dpy != EGL_NO_DISPLAY) { 94 - old.ctx = eglGetCurrentContext(); 95 - old.read = eglGetCurrentSurface(EGL_READ); 96 - old.draw = eglGetCurrentSurface(EGL_DRAW); 83 + if (ctx->dpy != EGL_NO_DISPLAY) { 84 + ctx->ctx = eglGetCurrentContext(); 85 + ctx->read = eglGetCurrentSurface(EGL_READ); 86 + ctx->draw = eglGetCurrentSurface(EGL_DRAW); 97 87 } 98 - 99 - return old; 100 88 } 101 89 102 - static inline void 103 - old_restore(struct old_helper *old, EGLDisplay current_dpy) 90 + static inline bool 91 + restore_context(struct client_egl_context *ctx) 104 92 { 105 - if (old->dpy == EGL_NO_DISPLAY) { 106 - // There were no display, just unbind the context. 107 - if (eglMakeCurrent(current_dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE)) { 108 - return; 109 - } 110 - } else { 111 - if (eglMakeCurrent(old->dpy, old->draw, old->read, old->ctx)) { 112 - return; 113 - } 93 + /* We're using the current display if we're trying to restore a null context */ 94 + EGLDisplay dpy = ctx->dpy == EGL_NO_DISPLAY ? eglGetCurrentDisplay() : ctx->dpy; 95 + 96 + if (dpy == EGL_NO_DISPLAY) { 97 + /* If the current display is also null then the call is a no-op */ 98 + return true; 114 99 } 115 100 116 - EGL_ERROR("Failed to make old EGL context current! (%p, %p, %p, %p)", old->dpy, old->draw, old->read, old->ctx); 101 + return eglMakeCurrent(dpy, ctx->draw, ctx->read, ctx->ctx); 117 102 } 118 - 119 103 120 104 /* 121 105 * ··· 207 191 struct client_egl_compositor *ceglc = client_egl_compositor(xc); 208 192 209 193 *out_handle = XRT_GRAPHICS_SYNC_HANDLE_INVALID; 210 - EGLDisplay dpy = ceglc->dpy; 194 + EGLDisplay dpy = ceglc->current.dpy; 211 195 212 196 #ifdef XRT_GRAPHICS_SYNC_HANDLE_IS_FD 213 197 ··· 239 223 static xrt_result_t 240 224 client_egl_context_begin(struct xrt_compositor *xc) 241 225 { 242 - //! @todo Implement 226 + struct client_egl_compositor *eglc = client_egl_compositor(xc); 227 + 228 + save_context(&eglc->previous); 229 + struct client_egl_context *cur = &eglc->current; 230 + 231 + if (!eglMakeCurrent(cur->dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, cur->ctx)) { 232 + return XRT_ERROR_OPENGL; 233 + } 243 234 return XRT_SUCCESS; 244 235 } 245 236 246 237 static void 247 238 client_egl_context_end(struct xrt_compositor *xc) 248 239 { 249 - //! @todo Implement 240 + struct client_egl_compositor *eglc = client_egl_compositor(xc); 241 + 242 + restore_context(&eglc->previous); 250 243 } 251 244 252 245 static void ··· 286 279 // On Android this extension is 'hidden'. 287 280 ensure_native_fence_is_loaded(display, get_gl_procaddr); 288 281 289 - // Save old display, context and drawables. 290 - struct old_helper old = old_save(); 282 + // Save old EGL display, context and drawables. 283 + struct client_egl_context old = {0}; 284 + save_context(&old); 291 285 292 286 if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context)) { 293 287 EGL_ERROR("eglMakeCurrent: %s\n\tFailed to make EGL context current", egl_error_str(eglGetError())); ··· 297 291 298 292 EGLint egl_client_type; 299 293 if (!eglQueryContext(display, context, EGL_CONTEXT_CLIENT_TYPE, &egl_client_type)) { 300 - old_restore(&old, display); 294 + restore_context(&old); 301 295 return XRT_ERROR_OPENGL; 302 296 } 303 297 ··· 308 302 break; 309 303 #else 310 304 EGL_ERROR("OpenGL support not including in this runtime build"); 311 - old_restore(&old, display); 305 + restore_context(&old); 312 306 return XRT_ERROR_OPENGL; 313 307 #endif 314 308 ··· 318 312 break; 319 313 #else 320 314 EGL_ERROR("OpenGL|ES support not including in this runtime build"); 321 - old_restore(&old, display); 315 + restore_context(&old); 322 316 return XRT_ERROR_OPENGL; 323 317 #endif 324 318 default: EGL_ERROR("Unsupported EGL client type"); return XRT_ERROR_OPENGL; 325 319 } 326 320 327 321 struct client_egl_compositor *ceglc = U_TYPED_CALLOC(struct client_egl_compositor); 328 - ceglc->dpy = display; 322 + ceglc->current.dpy = display; 323 + ceglc->current.ctx = context; 329 324 330 325 client_gl_swapchain_create_func_t sc_create = NULL; 331 326 ··· 365 360 EGL_ERROR( 366 361 "Could not find a required extension: need either EGL_EXT_image_dma_buf_import or " 367 362 "GL_EXT_memory_object_fd"); 368 - old_restore(&old, display); 363 + restore_context(&old); 369 364 return XRT_ERROR_OPENGL; 370 365 } 371 366 ··· 396 391 if (!bret) { 397 392 free(ceglc); 398 393 EGL_ERROR("Failed to initialize compositor"); 399 - old_restore(&old, display); 394 + restore_context(&old); 400 395 return XRT_ERROR_OPENGL; 401 396 } 402 397 403 398 ceglc->base.base.base.destroy = client_egl_compositor_destroy; 404 - old_restore(&old, display); 399 + restore_context(&old); 405 400 *out_xcgl = &ceglc->base.base; 406 401 407 402 return XRT_SUCCESS;
+7 -2
src/xrt/compositor/client/comp_egl_client.h
··· 20 20 extern "C" { 21 21 #endif 22 22 23 + struct client_egl_context 24 + { 25 + EGLDisplay dpy; 26 + EGLContext ctx; 27 + EGLSurface read, draw; 28 + }; 23 29 24 30 /*! 25 31 * EGL based compositor, carries the extra needed EGL information needed by the ··· 30 36 struct client_egl_compositor 31 37 { 32 38 struct client_gl_compositor base; 33 - 34 - EGLDisplay dpy; 39 + struct client_egl_context current, previous; 35 40 }; 36 41 37 42 /*!
+1 -1
src/xrt/compositor/client/comp_gl_eglimage_swapchain.c
··· 200 200 sc->base.base.base.image_count = 201 201 native_xsc->image_count; // Fetch the number of images from the native swapchain. 202 202 sc->base.xscn = xscn; 203 - sc->display = ceglc->dpy; 203 + sc->display = ceglc->current.dpy; 204 204 205 205 struct xrt_swapchain_gl *xscgl = &sc->base.base; 206 206