From 1d461687d24856a15fd8c37f744f40730888c9b0 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sat, 9 Jan 2021 12:00:31 +0100 Subject: [PATCH] render/egl: replace init/finish with create/destroy This ensures wlr_gles2_renderer can properly take ownership of the wlr_egl. Closes: https://github.com/swaywm/wlroots/issues/2612 --- examples/idle-inhibit.c | 10 +++++----- examples/input-inhibitor.c | 10 +++++----- examples/keyboard-shortcuts-inhibit.c | 10 +++++----- examples/layer-shell.c | 20 ++++++++++---------- examples/pointer-constraints.c | 10 +++++----- examples/relative-pointer-unstable-v1.c | 5 ++--- examples/text-input.c | 10 +++++----- examples/toplevel-decoration.c | 10 +++++----- include/wlr/render/egl.h | 5 ++--- render/egl.c | 21 ++++++++++++++------- render/gles2/renderer.c | 4 +--- render/wlr_renderer.c | 15 +++------------ 12 files changed, 62 insertions(+), 68 deletions(-) diff --git a/examples/idle-inhibit.c b/examples/idle-inhibit.c index 44a7f5b5..7037681f 100644 --- a/examples/idle-inhibit.c +++ b/examples/idle-inhibit.c @@ -27,12 +27,12 @@ static struct xdg_wm_base *wm_base = NULL; static struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager = NULL; static struct zwp_idle_inhibitor_v1 *idle_inhibitor = NULL; -struct wlr_egl egl; +struct wlr_egl *egl; struct wl_egl_window *egl_window; struct wlr_egl_surface *egl_surface; static void draw(void) { - eglMakeCurrent(egl.display, egl_surface, egl_surface, egl.context); + eglMakeCurrent(egl->display, egl_surface, egl_surface, egl->context); float color[] = {1.0, 1.0, 0.0, 1.0}; if (idle_inhibitor) { @@ -43,7 +43,7 @@ static void draw(void) { glClearColor(color[0], color[1], color[2], 1.0); glClear(GL_COLOR_BUFFER_BIT); - eglSwapBuffers(egl.display, egl_surface); + eglSwapBuffers(egl->display, egl_surface); } static void pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, @@ -193,7 +193,7 @@ int main(int argc, char **argv) { } EGLint attribs[] = { EGL_NONE }; - wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, attribs); + egl = wlr_egl_create(EGL_PLATFORM_WAYLAND_EXT, display, attribs); struct wl_surface *surface = wl_compositor_create_surface(compositor); struct xdg_surface *xdg_surface = @@ -214,7 +214,7 @@ int main(int argc, char **argv) { wl_surface_commit(surface); egl_window = wl_egl_window_create(surface, width, height); - egl_surface = wlr_egl_create_surface(&egl, egl_window); + egl_surface = wlr_egl_create_surface(egl, egl_window); wl_display_roundtrip(display); diff --git a/examples/input-inhibitor.c b/examples/input-inhibitor.c index 80be3916..a0acebd0 100644 --- a/examples/input-inhibitor.c +++ b/examples/input-inhibitor.c @@ -18,12 +18,12 @@ static struct xdg_wm_base *wm_base = NULL; static struct zwlr_input_inhibit_manager_v1 *input_inhibit_manager = NULL; static struct zwlr_input_inhibitor_v1 *input_inhibitor = NULL; -struct wlr_egl egl; +struct wlr_egl *egl; struct wl_egl_window *egl_window; struct wlr_egl_surface *egl_surface; static void render_frame(void) { - eglMakeCurrent(egl.display, egl_surface, egl_surface, egl.context); + eglMakeCurrent(egl->display, egl_surface, egl_surface, egl->context); glViewport(0, 0, width, height); if (keys) { @@ -33,7 +33,7 @@ static void render_frame(void) { } glClear(GL_COLOR_BUFFER_BIT); - eglSwapBuffers(egl.display, egl_surface); + eglSwapBuffers(egl->display, egl_surface); } static void xdg_surface_handle_configure(void *data, @@ -158,7 +158,7 @@ int main(int argc, char **argv) { assert(input_inhibitor); EGLint attribs[] = { EGL_NONE }; - wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, attribs); + egl = wlr_egl_create(EGL_PLATFORM_WAYLAND_EXT, display, attribs); struct wl_surface *surface = wl_compositor_create_surface(compositor); assert(surface); @@ -174,7 +174,7 @@ int main(int argc, char **argv) { wl_surface_commit(surface); egl_window = wl_egl_window_create(surface, width, height); - egl_surface = wlr_egl_create_surface(&egl, egl_window); + egl_surface = wlr_egl_create_surface(egl, egl_window); wl_display_roundtrip(display); diff --git a/examples/keyboard-shortcuts-inhibit.c b/examples/keyboard-shortcuts-inhibit.c index 1b2d7aab..58684683 100644 --- a/examples/keyboard-shortcuts-inhibit.c +++ b/examples/keyboard-shortcuts-inhibit.c @@ -33,12 +33,12 @@ static struct zwp_keyboard_shortcuts_inhibitor_v1 * keyboard_shortcuts_inhibitor = NULL; static bool active = false; -struct wlr_egl egl; +struct wlr_egl *egl; struct wl_egl_window *egl_window; struct wlr_egl_surface *egl_surface; static void draw(void) { - eglMakeCurrent(egl.display, egl_surface, egl_surface, egl.context); + eglMakeCurrent(egl->display, egl_surface, egl_surface, egl->context); float color[] = {1.0, 1.0, 0.0, 1.0}; if (keyboard_shortcuts_inhibitor) { @@ -49,7 +49,7 @@ static void draw(void) { glClearColor(color[0], color[1], color[2], 1.0); glClear(GL_COLOR_BUFFER_BIT); - eglSwapBuffers(egl.display, egl_surface); + eglSwapBuffers(egl->display, egl_surface); } static void keyboard_shortcuts_inhibit_handle_active(void *data, @@ -225,7 +225,7 @@ int main(int argc, char **argv) { } EGLint attribs[] = { EGL_NONE }; - wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, attribs); + egl = wlr_egl_create(EGL_PLATFORM_WAYLAND_EXT, display, attribs); struct wl_surface *surface = wl_compositor_create_surface(compositor); struct xdg_surface *xdg_surface = @@ -241,7 +241,7 @@ int main(int argc, char **argv) { wl_surface_commit(surface); egl_window = wl_egl_window_create(surface, width, height); - egl_surface = wlr_egl_create_surface(&egl, egl_window); + egl_surface = wlr_egl_create_surface(egl, egl_window); wl_display_roundtrip(display); diff --git a/examples/layer-shell.c b/examples/layer-shell.c index 6d1cb78c..1779855a 100644 --- a/examples/layer-shell.c +++ b/examples/layer-shell.c @@ -29,7 +29,7 @@ struct zwlr_layer_surface_v1 *layer_surface; static struct wl_output *wl_output; struct wl_surface *wl_surface; -struct wlr_egl egl; +struct wlr_egl *egl; struct wl_egl_window *egl_window; struct wlr_egl_surface *egl_surface; struct wl_callback *frame_callback; @@ -93,7 +93,7 @@ static struct wl_callback_listener popup_frame_listener = { }; static void draw(void) { - eglMakeCurrent(egl.display, egl_surface, egl_surface, egl.context); + eglMakeCurrent(egl->display, egl_surface, egl_surface, egl->context); struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); @@ -142,7 +142,7 @@ static void draw(void) { frame_callback = wl_surface_frame(wl_surface); wl_callback_add_listener(frame_callback, &frame_listener, NULL); - eglSwapBuffers(egl.display, egl_surface); + eglSwapBuffers(egl->display, egl_surface); demo.last_frame = ts; } @@ -150,7 +150,7 @@ static void draw(void) { static void draw_popup(void) { static float alpha_mod = -0.01; - eglMakeCurrent(egl.display, popup_egl_surface, popup_egl_surface, egl.context); + eglMakeCurrent(egl->display, popup_egl_surface, popup_egl_surface, egl->context); glViewport(0, 0, popup_width, popup_height); glClearColor(popup_red, 0.5f, 0.5f, popup_alpha); popup_alpha += alpha_mod; @@ -162,7 +162,7 @@ static void draw_popup(void) { popup_frame_callback = wl_surface_frame(popup_wl_surface); assert(popup_frame_callback); wl_callback_add_listener(popup_frame_callback, &popup_frame_listener, NULL); - eglSwapBuffers(egl.display, popup_egl_surface); + eglSwapBuffers(egl->display, popup_egl_surface); wl_surface_commit(popup_wl_surface); } @@ -187,7 +187,7 @@ static void xdg_popup_configure(void *data, struct xdg_popup *xdg_popup, } static void popup_destroy(void) { - wlr_egl_destroy_surface(&egl, popup_egl_surface); + wlr_egl_destroy_surface(egl, popup_egl_surface); wl_egl_window_destroy(popup_egl_window); xdg_popup_destroy(popup); wl_surface_destroy(popup_wl_surface); @@ -241,7 +241,7 @@ static void create_popup(uint32_t serial) { popup_wl_surface = surface; popup_egl_window = wl_egl_window_create(surface, popup_width, popup_height); assert(popup_egl_window); - popup_egl_surface = wlr_egl_create_surface(&egl, popup_egl_window); + popup_egl_surface = wlr_egl_create_surface(egl, popup_egl_window); assert(popup_egl_surface); draw_popup(); } @@ -259,7 +259,7 @@ static void layer_surface_configure(void *data, static void layer_surface_closed(void *data, struct zwlr_layer_surface_v1 *surface) { - wlr_egl_destroy_surface(&egl, egl_surface); + wlr_egl_destroy_surface(egl, egl_surface); wl_egl_window_destroy(egl_window); zwlr_layer_surface_v1_destroy(surface); wl_surface_destroy(wl_surface); @@ -611,7 +611,7 @@ int main(int argc, char **argv) { assert(cursor_surface); EGLint attribs[] = { EGL_ALPHA_SIZE, 8, EGL_NONE }; - wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, attribs); + egl = wlr_egl_create(EGL_PLATFORM_WAYLAND_EXT, display, attribs); wl_surface = wl_compositor_create_surface(compositor); assert(wl_surface); @@ -633,7 +633,7 @@ int main(int argc, char **argv) { egl_window = wl_egl_window_create(wl_surface, width, height); assert(egl_window); - egl_surface = wlr_egl_create_surface(&egl, egl_window); + egl_surface = wlr_egl_create_surface(egl, egl_window); assert(egl_surface); wl_display_roundtrip(display); diff --git a/examples/pointer-constraints.c b/examples/pointer-constraints.c index e020c5e7..ddd91bf1 100644 --- a/examples/pointer-constraints.c +++ b/examples/pointer-constraints.c @@ -16,7 +16,7 @@ static struct wl_seat *seat = NULL; static struct xdg_wm_base *wm_base = NULL; static struct zwp_pointer_constraints_v1 *pointer_constraints = NULL; -struct wlr_egl egl; +struct wlr_egl *egl; struct wl_egl_window *egl_window; struct wlr_egl_surface *egl_surface; struct zwp_locked_pointer_v1* locked_pointer; @@ -32,7 +32,7 @@ enum { struct wl_region *regions[3]; static void draw(void) { - eglMakeCurrent(egl.display, egl_surface, egl_surface, egl.context); + eglMakeCurrent(egl->display, egl_surface, egl_surface, egl->context); float color[] = {1.0, 1.0, 0.0, 1.0}; @@ -40,7 +40,7 @@ static void draw(void) { glClearColor(color[0], color[1], color[2], 1.0); glClear(GL_COLOR_BUFFER_BIT); - eglSwapBuffers(egl.display, egl_surface); + eglSwapBuffers(egl->display, egl_surface); } static void pointer_handle_button(void *data, struct wl_pointer *pointer, @@ -212,7 +212,7 @@ int main(int argc, char **argv) { regions[REGION_TYPE_JOINT] = joint_region; EGLint attribs[] = { EGL_NONE }; - wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, attribs); + egl = wlr_egl_create(EGL_PLATFORM_WAYLAND_EXT, display, attribs); struct wl_surface *surface = wl_compositor_create_surface(compositor); struct xdg_surface *xdg_surface = @@ -241,7 +241,7 @@ int main(int argc, char **argv) { wl_surface_commit(surface); egl_window = wl_egl_window_create(surface, width, height); - egl_surface = wlr_egl_create_surface(&egl, egl_window); + egl_surface = wlr_egl_create_surface(egl, egl_window); wl_display_roundtrip(display); diff --git a/examples/relative-pointer-unstable-v1.c b/examples/relative-pointer-unstable-v1.c index de7919bd..f6b6c923 100644 --- a/examples/relative-pointer-unstable-v1.c +++ b/examples/relative-pointer-unstable-v1.c @@ -171,7 +171,7 @@ static void xdg_toplevel_handle_configure(void *data, static void xdg_toplevel_handle_close(void *data, struct xdg_toplevel *xdg_toplevel) { struct egl_info *e = data; - wlr_egl_finish(e->egl); + wlr_egl_destroy(e->egl); exit(EXIT_SUCCESS); } @@ -440,11 +440,10 @@ int main(int argc, char **argv) { /* Initialize EGL context */ struct egl_info *e = calloc(1, sizeof(struct egl_info)); - e->egl = calloc(1, sizeof(struct wlr_egl)); e->width = e->height = 512; EGLint attribs[] = { EGL_NONE }; - wlr_egl_init(e->egl, EGL_PLATFORM_WAYLAND_EXT, display, attribs); + e->egl = wlr_egl_create(EGL_PLATFORM_WAYLAND_EXT, display, attribs); /* Create the surface and xdg_toplevels, and set listeners */ diff --git a/examples/text-input.c b/examples/text-input.c index 8559810f..b8d75fee 100644 --- a/examples/text-input.c +++ b/examples/text-input.c @@ -63,12 +63,12 @@ static struct xdg_wm_base *wm_base = NULL; static struct zwp_text_input_manager_v3 *text_input_manager = NULL; static struct zwp_text_input_v3 *text_input = NULL; -struct wlr_egl egl; +struct wlr_egl *egl; struct wl_egl_window *egl_window; struct wlr_egl_surface *egl_surface; static void draw(void) { - eglMakeCurrent(egl.display, egl_surface, egl_surface, egl.context); + eglMakeCurrent(egl->display, egl_surface, egl_surface, egl->context); float color[] = {1.0, 1.0, 0.0, 1.0}; color[0] = enabled * 1.0; @@ -78,7 +78,7 @@ static void draw(void) { glClearColor(color[0], color[1], color[2], 1.0); glClear(GL_COLOR_BUFFER_BIT); - eglSwapBuffers(egl.display, egl_surface); + eglSwapBuffers(egl->display, egl_surface); } static size_t utf8_strlen(char *str) { @@ -364,7 +364,7 @@ int main(int argc, char **argv) { zwp_text_input_v3_add_listener(text_input, &text_input_listener, NULL); EGLint attribs[] = { EGL_NONE }; - wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, attribs); + egl = wlr_egl_create(EGL_PLATFORM_WAYLAND_EXT, display, attribs); struct wl_surface *surface = wl_compositor_create_surface(compositor); struct xdg_surface *xdg_surface = @@ -377,7 +377,7 @@ int main(int argc, char **argv) { wl_surface_commit(surface); egl_window = wl_egl_window_create(surface, width, height); - egl_surface = wlr_egl_create_surface(&egl, egl_window); + egl_surface = wlr_egl_create_surface(egl, egl_window); wl_display_roundtrip(display); diff --git a/examples/toplevel-decoration.c b/examples/toplevel-decoration.c index f10ac742..0369116a 100644 --- a/examples/toplevel-decoration.c +++ b/examples/toplevel-decoration.c @@ -20,7 +20,7 @@ static struct wl_compositor *compositor = NULL; static struct xdg_wm_base *wm_base = NULL; static struct zxdg_decoration_manager_v1 *decoration_manager = NULL; -struct wlr_egl egl; +struct wlr_egl *egl; struct wl_egl_window *egl_window; struct wlr_egl_surface *egl_surface; @@ -53,7 +53,7 @@ static void request_preferred_mode(void) { } static void draw(void) { - eglMakeCurrent(egl.display, egl_surface, egl_surface, egl.context); + eglMakeCurrent(egl->display, egl_surface, egl_surface, egl->context); float color[] = {1.0, 1.0, 0.0, 1.0}; if (current_mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE) { @@ -64,7 +64,7 @@ static void draw(void) { glClearColor(color[0], color[1], color[2], 1.0); glClear(GL_COLOR_BUFFER_BIT); - eglSwapBuffers(egl.display, egl_surface); + eglSwapBuffers(egl->display, egl_surface); } static void xdg_surface_handle_configure(void *data, @@ -219,7 +219,7 @@ int main(int argc, char **argv) { } EGLint attribs[] = { EGL_NONE }; - wlr_egl_init(&egl, EGL_PLATFORM_WAYLAND_EXT, display, attribs); + egl = wlr_egl_create(EGL_PLATFORM_WAYLAND_EXT, display, attribs); struct wl_surface *surface = wl_compositor_create_surface(compositor); struct xdg_surface *xdg_surface = @@ -238,7 +238,7 @@ int main(int argc, char **argv) { wl_surface_commit(surface); egl_window = wl_egl_window_create(surface, width, height); - egl_surface = wlr_egl_create_surface(&egl, egl_window); + egl_surface = wlr_egl_create_surface(egl, egl_window); wl_display_roundtrip(display); diff --git a/include/wlr/render/egl.h b/include/wlr/render/egl.h index 67f32e42..b967be8e 100644 --- a/include/wlr/render/egl.h +++ b/include/wlr/render/egl.h @@ -78,21 +78,20 @@ struct wlr_egl { struct wlr_drm_format_set dmabuf_render_formats; }; -// TODO: Allocate and return a wlr_egl /** * Initializes an EGL context for the given platform and remote display. * Will attempt to load all possibly required api functions. * * If config_attribs is NULL, the EGL config is not created. */ -bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, +struct wlr_egl *wlr_egl_create(EGLenum platform, void *remote_display, const EGLint *config_attribs); /** * Frees all related EGL resources, makes the context not-current and * unbinds a bound wayland display. */ -void wlr_egl_finish(struct wlr_egl *egl); +void wlr_egl_destroy(struct wlr_egl *egl); /** * Binds the given display to the EGL instance. diff --git a/render/egl.c b/render/egl.c index 57146a06..8cf20ece 100644 --- a/render/egl.c +++ b/render/egl.c @@ -149,8 +149,14 @@ out: free(formats); } -bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, +struct wlr_egl *wlr_egl_create(EGLenum platform, void *remote_display, const EGLint *config_attribs) { + struct wlr_egl *egl = calloc(1, sizeof(struct wlr_egl)); + if (egl == NULL) { + wlr_log_errno(WLR_ERROR, "Allocation failed"); + return NULL; + } + const char *client_exts_str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); if (client_exts_str == NULL) { if (eglGetError() == EGL_BAD_DISPLAY) { @@ -158,12 +164,12 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, } else { wlr_log(WLR_ERROR, "Failed to query EGL client extensions"); } - return false; + return NULL; } if (!check_egl_ext(client_exts_str, "EGL_EXT_platform_base")) { wlr_log(WLR_ERROR, "EGL_EXT_platform_base not supported"); - return false; + return NULL; } load_egl_proc(&egl->procs.eglGetPlatformDisplayEXT, "eglGetPlatformDisplayEXT"); @@ -205,7 +211,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, const char *display_exts_str = eglQueryString(egl->display, EGL_EXTENSIONS); if (display_exts_str == NULL) { wlr_log(WLR_ERROR, "Failed to query EGL display extensions"); - return false; + return NULL; } if (check_egl_ext(display_exts_str, "EGL_KHR_image_base")) { @@ -343,7 +349,7 @@ bool wlr_egl_init(struct wlr_egl *egl, EGLenum platform, void *remote_display, } } - return true; + return egl; error: eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); @@ -351,10 +357,10 @@ error: eglTerminate(egl->display); } eglReleaseThread(); - return false; + return NULL; } -void wlr_egl_finish(struct wlr_egl *egl) { +void wlr_egl_destroy(struct wlr_egl *egl) { if (egl == NULL) { return; } @@ -371,6 +377,7 @@ void wlr_egl_finish(struct wlr_egl *egl) { eglDestroyContext(egl->display, egl->context); eglTerminate(egl->display); eglReleaseThread(); + free(egl); } bool wlr_egl_bind_display(struct wlr_egl *egl, struct wl_display *local_display) { diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 2a78eb3e..5474e1b6 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -694,9 +694,7 @@ static void gles2_destroy(struct wlr_renderer *wlr_renderer) { } wlr_egl_unset_current(renderer->egl); - - wlr_egl_finish(renderer->egl); - free(renderer->egl); + wlr_egl_destroy(renderer->egl); if (renderer->drm_fd >= 0) { close(renderer->drm_fd); diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index b721036f..377b795e 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -249,25 +249,16 @@ bool wlr_renderer_init_wl_display(struct wlr_renderer *r, struct wlr_renderer *wlr_renderer_autocreate(EGLenum platform, void *remote_display) { - struct wlr_egl *egl = calloc(1, sizeof(*egl)); + struct wlr_egl *egl = wlr_egl_create(platform, remote_display, NULL); if (egl == NULL) { - wlr_log_errno(WLR_ERROR, "Allocation failed"); - return NULL; - } - - if (!wlr_egl_init(egl, platform, remote_display, NULL)) { wlr_log(WLR_ERROR, "Could not initialize EGL"); return NULL; } - /* - * wlr_renderer becomes the owner of the previously wlr_egl, and will - * take care of freeing the allocated memory - * TODO: move the wlr_egl logic to wlr_gles2_renderer - */ struct wlr_renderer *renderer = wlr_gles2_renderer_create(egl); if (!renderer) { - wlr_egl_finish(egl); + wlr_log(WLR_ERROR, "Failed to create GLES2 renderer"); + wlr_egl_destroy(egl); } return renderer;