From abf527b0754cc920e5324c593b109ff4c4607471 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sat, 29 May 2021 10:25:25 +0200 Subject: [PATCH] render/gles2: fix texture cleanup on destroy When importing a DMA-BUF wlr_buffer as a wlr_texture, the GLES2 renderer caches the result, in case the buffer is used for texturing again in the future. When the wlr_texture is destroyed by the caller, the wlr_buffer is unref'ed, but the wlr_gles2_texture is kept around. This is fine because wlr_gles2_texture listens for wlr_buffer's destroy event to avoid any use-after-free. However, with this logic wlr_texture_destroy doesn't "really" destroy the wlr_gles2_texture. It just decrements the wlr_buffer ref'count. Each wlr_texture_destroy call must have a matching prior wlr_texture_create_from_buffer call or the ref'counting will go south. Wehn destroying the renderer, we don't want to decrement any wlr_buffer ref'count. Instead, we want to go through any cached wlr_gles2_texture and destroy our GL state. So instead of calling wlr_texture_destroy, we need to call our internal gles2_texture_destroy function. Closes: https://github.com/swaywm/wlroots/issues/2941 --- include/render/gles2.h | 1 + render/gles2/renderer.c | 2 +- render/gles2/texture.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/render/gles2.h b/include/render/gles2.h index 39ec1da0..0e93522f 100644 --- a/include/render/gles2.h +++ b/include/render/gles2.h @@ -128,6 +128,7 @@ struct wlr_texture *gles2_texture_from_dmabuf(struct wlr_renderer *wlr_renderer, struct wlr_dmabuf_attributes *attribs); struct wlr_texture *gles2_texture_from_buffer(struct wlr_renderer *wlr_renderer, struct wlr_buffer *buffer); +void gles2_texture_destroy(struct wlr_gles2_texture *texture); void push_gles2_debug_(struct wlr_gles2_renderer *renderer, const char *file, const char *func); diff --git a/render/gles2/renderer.c b/render/gles2/renderer.c index 707b2c49..0770993e 100644 --- a/render/gles2/renderer.c +++ b/render/gles2/renderer.c @@ -546,7 +546,7 @@ static void gles2_destroy(struct wlr_renderer *wlr_renderer) { struct wlr_gles2_texture *tex, *tex_tmp; wl_list_for_each_safe(tex, tex_tmp, &renderer->textures, link) { - wlr_texture_destroy(&tex->wlr_texture); + gles2_texture_destroy(tex); } push_gles2_debug(renderer); diff --git a/render/gles2/texture.c b/render/gles2/texture.c index 9ffabbdc..7d8ad106 100644 --- a/render/gles2/texture.c +++ b/render/gles2/texture.c @@ -125,7 +125,7 @@ static bool gles2_texture_invalidate(struct wlr_gles2_texture *texture) { return true; } -static void gles2_texture_destroy(struct wlr_gles2_texture *texture) { +void gles2_texture_destroy(struct wlr_gles2_texture *texture) { wl_list_remove(&texture->link); wl_list_remove(&texture->buffer_destroy.link);