render/egl: make wlr_egl hold a wlr_egl_context

This commit is contained in:
Simon Zeni 2021-09-21 13:17:02 -04:00
parent 7ff1664030
commit 95928cec72
2 changed files with 33 additions and 40 deletions

View file

@ -5,8 +5,7 @@
#include <wlr/render/egl.h> #include <wlr/render/egl.h>
struct wlr_egl { struct wlr_egl {
EGLDisplay display; struct wlr_egl_context ctx;
EGLContext context;
EGLDeviceEXT device; // may be EGL_NO_DEVICE_EXT EGLDeviceEXT device; // may be EGL_NO_DEVICE_EXT
struct gbm_device *gbm_device; struct gbm_device *gbm_device;

View file

@ -223,20 +223,21 @@ static struct wlr_egl *egl_create(void) {
static bool egl_init(struct wlr_egl *egl, EGLenum platform, static bool egl_init(struct wlr_egl *egl, EGLenum platform,
void *remote_display) { void *remote_display) {
egl->display = egl->procs.eglGetPlatformDisplayEXT(platform, egl->ctx.display = egl->procs.eglGetPlatformDisplayEXT(platform,
remote_display, NULL); remote_display, NULL);
if (egl->display == EGL_NO_DISPLAY) { if (egl->ctx.display == EGL_NO_DISPLAY) {
wlr_log(WLR_ERROR, "Failed to create EGL display"); wlr_log(WLR_ERROR, "Failed to create EGL display");
return false; return false;
} }
EGLint major, minor; EGLint major, minor;
if (eglInitialize(egl->display, &major, &minor) == EGL_FALSE) { if (eglInitialize(egl->ctx.display, &major, &minor) == EGL_FALSE) {
wlr_log(WLR_ERROR, "Failed to initialize EGL"); wlr_log(WLR_ERROR, "Failed to initialize EGL");
return false; return false;
} }
const char *display_exts_str = eglQueryString(egl->display, EGL_EXTENSIONS); const char *display_exts_str =
eglQueryString(egl->ctx.display, EGL_EXTENSIONS);
if (display_exts_str == NULL) { if (display_exts_str == NULL) {
wlr_log(WLR_ERROR, "Failed to query EGL display extensions"); wlr_log(WLR_ERROR, "Failed to query EGL display extensions");
return false; return false;
@ -262,7 +263,7 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
const char *device_exts_str = NULL, *driver_name = NULL; const char *device_exts_str = NULL, *driver_name = NULL;
if (egl->exts.EXT_device_query) { if (egl->exts.EXT_device_query) {
EGLAttrib device_attrib; EGLAttrib device_attrib;
if (!egl->procs.eglQueryDisplayAttribEXT(egl->display, if (!egl->procs.eglQueryDisplayAttribEXT(egl->ctx.display,
EGL_DEVICE_EXT, &device_attrib)) { EGL_DEVICE_EXT, &device_attrib)) {
wlr_log(WLR_ERROR, "eglQueryDisplayAttribEXT(EGL_DEVICE_EXT) failed"); wlr_log(WLR_ERROR, "eglQueryDisplayAttribEXT(EGL_DEVICE_EXT) failed");
return false; return false;
@ -318,7 +319,8 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
wlr_log(WLR_INFO, "Supported EGL device extensions: %s", device_exts_str); wlr_log(WLR_INFO, "Supported EGL device extensions: %s", device_exts_str);
} }
wlr_log(WLR_INFO, "Using EGL %d.%d", (int)major, (int)minor); wlr_log(WLR_INFO, "Using EGL %d.%d", (int)major, (int)minor);
wlr_log(WLR_INFO, "EGL vendor: %s", eglQueryString(egl->display, EGL_VENDOR)); wlr_log(WLR_INFO, "EGL vendor: %s",
eglQueryString(egl->ctx.display, EGL_VENDOR));
if (driver_name != NULL) { if (driver_name != NULL) {
wlr_log(WLR_INFO, "EGL driver name: %s", driver_name); wlr_log(WLR_INFO, "EGL driver name: %s", driver_name);
} }
@ -347,16 +349,16 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
attribs[atti++] = EGL_NONE; attribs[atti++] = EGL_NONE;
assert(atti <= sizeof(attribs)/sizeof(attribs[0])); assert(atti <= sizeof(attribs)/sizeof(attribs[0]));
egl->context = eglCreateContext(egl->display, EGL_NO_CONFIG_KHR, egl->ctx.context = eglCreateContext(egl->ctx.display, EGL_NO_CONFIG_KHR,
EGL_NO_CONTEXT, attribs); EGL_NO_CONTEXT, attribs);
if (egl->context == EGL_NO_CONTEXT) { if (egl->ctx.context == EGL_NO_CONTEXT) {
wlr_log(WLR_ERROR, "Failed to create EGL context"); wlr_log(WLR_ERROR, "Failed to create EGL context");
return false; return false;
} }
if (request_high_priority) { if (request_high_priority) {
EGLint priority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG; EGLint priority = EGL_CONTEXT_PRIORITY_MEDIUM_IMG;
eglQueryContext(egl->display, egl->context, eglQueryContext(egl->ctx.display, egl->ctx.context,
EGL_CONTEXT_PRIORITY_LEVEL_IMG, &priority); EGL_CONTEXT_PRIORITY_LEVEL_IMG, &priority);
if (priority != EGL_CONTEXT_PRIORITY_HIGH_IMG) { if (priority != EGL_CONTEXT_PRIORITY_HIGH_IMG) {
wlr_log(WLR_INFO, "Failed to obtain a high priority context"); wlr_log(WLR_INFO, "Failed to obtain a high priority context");
@ -495,10 +497,10 @@ struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) {
error: error:
wlr_log(WLR_ERROR, "Failed to initialize EGL context"); wlr_log(WLR_ERROR, "Failed to initialize EGL context");
if (egl->display) { if (egl->ctx.display) {
eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, eglMakeCurrent(egl->ctx.display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT); EGL_NO_CONTEXT);
eglTerminate(egl->display); eglTerminate(egl->ctx.display);
} }
free(egl); free(egl);
eglReleaseThread(); eglReleaseThread();
@ -513,10 +515,11 @@ void wlr_egl_destroy(struct wlr_egl *egl) {
wlr_drm_format_set_finish(&egl->dmabuf_render_formats); wlr_drm_format_set_finish(&egl->dmabuf_render_formats);
wlr_drm_format_set_finish(&egl->dmabuf_texture_formats); wlr_drm_format_set_finish(&egl->dmabuf_texture_formats);
eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglMakeCurrent(egl->ctx.display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
eglDestroyContext(egl->display, egl->context); eglDestroyContext(egl->ctx.display, egl->ctx.context);
eglTerminate(egl->display); eglTerminate(egl->ctx.display);
eglReleaseThread(); eglReleaseThread();
if (egl->gbm_device) { if (egl->gbm_device) {
@ -535,29 +538,19 @@ bool wlr_egl_destroy_image(struct wlr_egl *egl, EGLImage image) {
if (!image) { if (!image) {
return true; return true;
} }
return egl->procs.eglDestroyImageKHR(egl->display, image); return egl->procs.eglDestroyImageKHR(egl->ctx.display, image);
} }
bool wlr_egl_make_current(struct wlr_egl *egl) { bool wlr_egl_make_current(struct wlr_egl *egl) {
if (!eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, return wlr_egl_context_set_current(&egl->ctx);
egl->context)) {
wlr_log(WLR_ERROR, "eglMakeCurrent failed");
return false;
}
return true;
} }
bool wlr_egl_unset_current(struct wlr_egl *egl) { bool wlr_egl_unset_current(struct wlr_egl *egl) {
if (!eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, return wlr_egl_context_unset_current(&egl->ctx);
EGL_NO_CONTEXT)) {
wlr_log(WLR_ERROR, "eglMakeCurrent failed");
return false;
}
return true;
} }
bool wlr_egl_is_current(struct wlr_egl *egl) { bool wlr_egl_is_current(struct wlr_egl *egl) {
return eglGetCurrentContext() == egl->context; return wlr_egl_context_is_current(&egl->ctx);
} }
bool wlr_egl_context_set_current(struct wlr_egl_context *ctx) { bool wlr_egl_context_set_current(struct wlr_egl_context *ctx) {
@ -694,8 +687,8 @@ EGLImageKHR wlr_egl_create_image_from_dmabuf(struct wlr_egl *egl,
attribs[atti++] = EGL_NONE; attribs[atti++] = EGL_NONE;
assert(atti < sizeof(attribs)/sizeof(attribs[0])); assert(atti < sizeof(attribs)/sizeof(attribs[0]));
EGLImageKHR image = egl->procs.eglCreateImageKHR(egl->display, EGL_NO_CONTEXT, EGLImageKHR image = egl->procs.eglCreateImageKHR(egl->ctx.display,
EGL_LINUX_DMA_BUF_EXT, NULL, attribs); EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs);
if (image == EGL_NO_IMAGE_KHR) { if (image == EGL_NO_IMAGE_KHR) {
wlr_log(WLR_ERROR, "eglCreateImageKHR failed"); wlr_log(WLR_ERROR, "eglCreateImageKHR failed");
return EGL_NO_IMAGE_KHR; return EGL_NO_IMAGE_KHR;
@ -736,7 +729,7 @@ static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) {
} }
EGLint num; EGLint num;
if (!egl->procs.eglQueryDmaBufFormatsEXT(egl->display, 0, NULL, &num)) { if (!egl->procs.eglQueryDmaBufFormatsEXT(egl->ctx.display, 0, NULL, &num)) {
wlr_log(WLR_ERROR, "Failed to query number of dmabuf formats"); wlr_log(WLR_ERROR, "Failed to query number of dmabuf formats");
return -1; return -1;
} }
@ -747,7 +740,8 @@ static int get_egl_dmabuf_formats(struct wlr_egl *egl, int **formats) {
return -1; return -1;
} }
if (!egl->procs.eglQueryDmaBufFormatsEXT(egl->display, num, *formats, &num)) { if (!egl->procs.eglQueryDmaBufFormatsEXT(egl->ctx.display, num, *formats,
&num)) {
wlr_log(WLR_ERROR, "Failed to query dmabuf format"); wlr_log(WLR_ERROR, "Failed to query dmabuf format");
free(*formats); free(*formats);
return -1; return -1;
@ -769,7 +763,7 @@ static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
} }
EGLint num; EGLint num;
if (!egl->procs.eglQueryDmaBufModifiersEXT(egl->display, format, 0, if (!egl->procs.eglQueryDmaBufModifiersEXT(egl->ctx.display, format, 0,
NULL, NULL, &num)) { NULL, NULL, &num)) {
wlr_log(WLR_ERROR, "Failed to query dmabuf number of modifiers"); wlr_log(WLR_ERROR, "Failed to query dmabuf number of modifiers");
return -1; return -1;
@ -791,7 +785,7 @@ static int get_egl_dmabuf_modifiers(struct wlr_egl *egl, int format,
return -1; return -1;
} }
if (!egl->procs.eglQueryDmaBufModifiersEXT(egl->display, format, num, if (!egl->procs.eglQueryDmaBufModifiersEXT(egl->ctx.display, format, num,
*modifiers, *external_only, &num)) { *modifiers, *external_only, &num)) {
wlr_log(WLR_ERROR, "Failed to query dmabuf modifiers"); wlr_log(WLR_ERROR, "Failed to query dmabuf modifiers");
free(*modifiers); free(*modifiers);
@ -892,8 +886,8 @@ int wlr_egl_dup_drm_fd(struct wlr_egl *egl) {
#endif #endif
if (render_name == NULL) { if (render_name == NULL) {
const char *primary_name = egl->procs.eglQueryDeviceStringEXT(egl->device, const char *primary_name = egl->procs.eglQueryDeviceStringEXT(
EGL_DRM_DEVICE_FILE_EXT); egl->device, EGL_DRM_DEVICE_FILE_EXT);
if (primary_name == NULL) { if (primary_name == NULL) {
wlr_log(WLR_ERROR, wlr_log(WLR_ERROR,
"eglQueryDeviceStringEXT(EGL_DRM_DEVICE_FILE_EXT) failed"); "eglQueryDeviceStringEXT(EGL_DRM_DEVICE_FILE_EXT) failed");