diff options
author | Simon Ser <contact@emersion.fr> | 2022-09-16 20:44:46 +0200 |
---|---|---|
committer | Simon Zeni <simon@bl4ckb0ne.ca> | 2022-09-19 10:04:47 +0000 |
commit | 5206cea566953a81788627a6c01533d579edc71a (patch) | |
tree | 2b50cf53a9a101d5a81adc2f750b3403f7947375 | |
parent | 2ad25b1460400e66ea26bd6489b04072be7d9dbb (diff) |
render/egl: add support for EGL_KHR_display_reference
See the spec at [1]. tl;dr EGL has terrible defaults: eglTerminate()
may have side-effects on completely unrelated EGLDisplay objects.
This extension allows us to opt-in to get the sane behavior:
eglTerminate() only free's our own EGLDisplay without affecting
others.
[1]: https://registry.khronos.org/EGL/extensions/KHR/EGL_KHR_display_reference.txt
-rw-r--r-- | include/render/egl.h | 1 | ||||
-rw-r--r-- | render/egl.c | 16 |
2 files changed, 15 insertions, 2 deletions
diff --git a/include/render/egl.h b/include/render/egl.h index f77e1147..36b70ae3 100644 --- a/include/render/egl.h +++ b/include/render/egl.h @@ -24,6 +24,7 @@ struct wlr_egl { bool EXT_device_query; bool KHR_platform_gbm; bool EXT_platform_device; + bool KHR_display_reference; } exts; struct { diff --git a/render/egl.c b/render/egl.c index 445dfe14..2ba57a92 100644 --- a/render/egl.c +++ b/render/egl.c @@ -207,9 +207,10 @@ static struct wlr_egl *egl_create(void) { egl->exts.KHR_platform_gbm = check_egl_ext(client_exts_str, "EGL_KHR_platform_gbm"); - egl->exts.EXT_platform_device = check_egl_ext(client_exts_str, "EGL_EXT_platform_device"); + egl->exts.KHR_display_reference = check_egl_ext(client_exts_str, + "EGL_KHR_display_reference"); if (check_egl_ext(client_exts_str, "EGL_EXT_device_base") || check_egl_ext(client_exts_str, "EGL_EXT_device_enumeration")) { load_egl_proc(&egl->procs.eglQueryDevicesEXT, "eglQueryDevicesEXT"); @@ -351,8 +352,19 @@ static bool egl_init_display(struct wlr_egl *egl, EGLDisplay display) { static bool egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display) { + EGLint display_attribs[3] = {0}; + size_t display_attribs_len = 0; + + if (egl->exts.KHR_display_reference) { + display_attribs[display_attribs_len++] = EGL_TRACK_REFERENCES_KHR; + display_attribs[display_attribs_len++] = EGL_TRUE; + } + + display_attribs[display_attribs_len++] = EGL_NONE; + assert(display_attribs_len < sizeof(display_attribs) / sizeof(display_attribs[0])); + EGLDisplay display = egl->procs.eglGetPlatformDisplayEXT(platform, - remote_display, NULL); + remote_display, display_attribs); if (display == EGL_NO_DISPLAY) { wlr_log(WLR_ERROR, "Failed to create EGL display"); return false; |