From 449f06556aa9550540c37af0cae0d6902b29f204 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 26 Apr 2018 00:11:36 +0100 Subject: [PATCH] Destroy wlr_surface with wlr_renderer --- include/wlr/render/interface.h | 6 ------ include/wlr/render/wlr_renderer.h | 10 ++++++++-- include/wlr/types/wlr_surface.h | 2 ++ render/wlr_renderer.c | 5 +++++ types/wlr_region.c | 7 +++++-- types/wlr_surface.c | 15 +++++++++++++-- 6 files changed, 33 insertions(+), 12 deletions(-) diff --git a/include/wlr/render/interface.h b/include/wlr/render/interface.h index 9dbe7247..e7cdce0a 100644 --- a/include/wlr/render/interface.h +++ b/include/wlr/render/interface.h @@ -11,12 +11,6 @@ #include #include -struct wlr_renderer_impl; - -struct wlr_renderer { - const struct wlr_renderer_impl *impl; -}; - struct wlr_renderer_impl { void (*begin)(struct wlr_renderer *renderer, uint32_t width, uint32_t height); diff --git a/include/wlr/render/wlr_renderer.h b/include/wlr/render/wlr_renderer.h index eb365762..21f9c16c 100644 --- a/include/wlr/render/wlr_renderer.h +++ b/include/wlr/render/wlr_renderer.h @@ -6,9 +6,15 @@ #include #include -struct wlr_output; +struct wlr_renderer_impl; -struct wlr_renderer; +struct wlr_renderer { + const struct wlr_renderer_impl *impl; + + struct { + struct wl_signal destroy; + } events; +}; void wlr_renderer_begin(struct wlr_renderer *r, int width, int height); void wlr_renderer_end(struct wlr_renderer *r); diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h index f799b28a..5ff9996d 100644 --- a/include/wlr/types/wlr_surface.h +++ b/include/wlr/types/wlr_surface.h @@ -93,6 +93,8 @@ struct wlr_surface { // wlr_subsurface::parent_pending_link struct wl_list subsurface_pending_list; + struct wl_listener renderer_destroy; + void *data; }; diff --git a/render/wlr_renderer.c b/render/wlr_renderer.c index 700da05b..8d1bd9ce 100644 --- a/render/wlr_renderer.c +++ b/render/wlr_renderer.c @@ -5,6 +5,7 @@ #include #include #include +#include "util/signal.h" void wlr_renderer_init(struct wlr_renderer *renderer, const struct wlr_renderer_impl *impl) { @@ -18,9 +19,13 @@ void wlr_renderer_init(struct wlr_renderer *renderer, assert(impl->format_supported); assert(impl->texture_from_pixels); renderer->impl = impl; + + wl_signal_init(&renderer->events.destroy); } void wlr_renderer_destroy(struct wlr_renderer *r) { + wlr_signal_emit_safe(&r->events.destroy, r); + if (r && r->impl && r->impl->destroy) { r->impl->destroy(r); } else { diff --git a/types/wlr_region.c b/types/wlr_region.c index f452bbdf..860864c1 100644 --- a/types/wlr_region.c +++ b/types/wlr_region.c @@ -32,10 +32,13 @@ static const struct wl_region_interface region_impl = { .subtract = region_subtract, }; -static void destroy_region(struct wl_resource *resource) { +static void region_handle_resource_destroy(struct wl_resource *resource) { pixman_region32_t *reg = wlr_region_from_resource(resource); pixman_region32_fini(reg); free(reg); + + // Set by wlr_compositor + wl_list_remove(wl_resource_get_link(resource)); } struct wl_resource *wlr_region_create(struct wl_client *client, uint32_t id) { @@ -53,7 +56,7 @@ struct wl_resource *wlr_region_create(struct wl_client *client, uint32_t id) { return NULL; } wl_resource_set_implementation(region_resource, ®ion_impl, region, - destroy_region); + region_handle_resource_destroy); return region_resource; } diff --git a/types/wlr_surface.c b/types/wlr_surface.c index 578c43d3..9a2421db 100644 --- a/types/wlr_surface.c +++ b/types/wlr_surface.c @@ -622,7 +622,7 @@ void wlr_subsurface_destroy(struct wlr_subsurface *subsurface) { free(subsurface); } -static void destroy_surface(struct wl_resource *resource) { +static void surface_handle_resource_destroy(struct wl_resource *resource) { struct wlr_surface *surface = wlr_surface_from_resource(resource); wlr_signal_emit_safe(&surface->events.destroy, surface); @@ -634,6 +634,13 @@ static void destroy_surface(struct wl_resource *resource) { free(surface); } +static void surface_handle_renderer_destroy(struct wl_listener *listener, + void *data) { + struct wlr_surface *surface = + wl_container_of(listener, surface, renderer_destroy); + wl_resource_destroy(surface->resource); +} + struct wlr_surface *wlr_surface_create(struct wl_resource *res, struct wlr_renderer *renderer) { struct wlr_surface *surface = calloc(1, sizeof(struct wlr_surface)); @@ -654,7 +661,11 @@ struct wlr_surface *wlr_surface_create(struct wl_resource *res, wl_list_init(&surface->subsurfaces); wl_list_init(&surface->subsurface_pending_list); wl_resource_set_implementation(res, &surface_interface, - surface, destroy_surface); + surface, surface_handle_resource_destroy); + + wl_signal_add(&renderer->events.destroy, &surface->renderer_destroy); + surface->renderer_destroy.notify = surface_handle_renderer_destroy; + return surface; }