[PATCH 4/7] pixman-renderer, gl-renderer: Destroy surface state with the renderer
Ander Conselvan de Oliveira
ander.conselvan.de.oliveira at intel.com
Fri Oct 25 15:26:34 CEST 2013
Previously the renderers destroy function assumed they are only called
when the compositor is shutting down and that the compositor had
already destroyed all the surfaces. However, if a runtime renderer
switch would be done, the surface state would be leaked.
This patch adds a destroy_signal to the pixman and gl renderers. The
surface state objects will listen for that signal and destroy
themselves if needed.
This is a step towards runtime switchable renderers.
---
src/gl-renderer.c | 54 +++++++++++++++++++++++++++++++++++++++++--------
src/pixman-renderer.c | 41 +++++++++++++++++++++++++++++++++----
2 files changed, 83 insertions(+), 12 deletions(-)
diff --git a/src/gl-renderer.c b/src/gl-renderer.c
index d792530..c3c6ae9 100644
--- a/src/gl-renderer.c
+++ b/src/gl-renderer.c
@@ -83,6 +83,7 @@ struct gl_surface_state {
struct weston_surface *surface;
struct wl_listener surface_destroy_listener;
+ struct wl_listener renderer_destroy_listener;
};
struct gl_renderer {
@@ -130,6 +131,8 @@ struct gl_renderer {
struct gl_shader invert_color_shader;
struct gl_shader solid_shader;
struct gl_shader *current_shader;
+
+ struct wl_signal destroy_signal;
};
static inline struct gl_output_state *
@@ -1149,17 +1152,12 @@ gl_renderer_surface_set_color(struct weston_surface *surface,
}
static void
-surface_state_handle_surface_destroy(struct wl_listener *listener, void *data)
+surface_state_destroy(struct gl_surface_state *gs, struct gl_renderer *gr)
{
- struct gl_surface_state *gs;
- struct gl_renderer *gr;
- struct weston_surface *surface = data;
int i;
- gr = get_renderer(surface->compositor);
-
- gs = container_of(listener, struct gl_surface_state,
- surface_destroy_listener);
+ wl_list_remove(&gs->surface_destroy_listener.link);
+ wl_list_remove(&gs->renderer_destroy_listener.link);
gs->surface->renderer_state = NULL;
@@ -1173,10 +1171,39 @@ surface_state_handle_surface_destroy(struct wl_listener *listener, void *data)
free(gs);
}
+static void
+surface_state_handle_surface_destroy(struct wl_listener *listener, void *data)
+{
+ struct gl_surface_state *gs;
+ struct gl_renderer *gr;
+
+ gs = container_of(listener, struct gl_surface_state,
+ surface_destroy_listener);
+
+ gr = get_renderer(gs->surface->compositor);
+
+ surface_state_destroy(gs, gr);
+}
+
+static void
+surface_state_handle_renderer_destroy(struct wl_listener *listener, void *data)
+{
+ struct gl_surface_state *gs;
+ struct gl_renderer *gr;
+
+ gr = data;
+
+ gs = container_of(listener, struct gl_surface_state,
+ renderer_destroy_listener);
+
+ surface_state_destroy(gs, gr);
+}
+
static int
gl_renderer_create_surface(struct weston_surface *surface)
{
struct gl_surface_state *gs;
+ struct gl_renderer *gr = get_renderer(surface->compositor);
gs = calloc(1, sizeof *gs);
if (!gs)
@@ -1189,6 +1216,8 @@ gl_renderer_create_surface(struct weston_surface *surface)
gs->pitch = 1;
gs->y_inverted = 1;
+ gs->surface = surface;
+
pixman_region32_init(&gs->texture_damage);
surface->renderer_state = gs;
@@ -1197,6 +1226,11 @@ gl_renderer_create_surface(struct weston_surface *surface)
wl_signal_add(&surface->destroy_signal,
&gs->surface_destroy_listener);
+ gs->renderer_destroy_listener.notify =
+ surface_state_handle_renderer_destroy;
+ wl_signal_add(&gr->destroy_signal,
+ &gs->renderer_destroy_listener);
+
return 0;
}
@@ -1579,6 +1613,8 @@ gl_renderer_destroy(struct weston_compositor *ec)
{
struct gl_renderer *gr = get_renderer(ec);
+ wl_signal_emit(&gr->destroy_signal, gr);
+
if (gr->has_bind_display)
gr->unbind_display(gr->egl_display, ec->wl_display);
@@ -1705,6 +1741,8 @@ gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGB565);
+ wl_signal_init(&gr->destroy_signal);
+
return 0;
err_egl:
diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
index 98a910c..79c1d5b 100644
--- a/src/pixman-renderer.c
+++ b/src/pixman-renderer.c
@@ -43,6 +43,7 @@ struct pixman_surface_state {
struct weston_buffer_reference buffer_ref;
struct wl_listener surface_destroy_listener;
+ struct wl_listener renderer_destroy_listener;
};
struct pixman_renderer {
@@ -51,6 +52,8 @@ struct pixman_renderer {
int repaint_debug;
pixman_image_t *debug_color;
struct weston_binding *debug_binding;
+
+ struct wl_signal destroy_signal;
};
static inline struct pixman_output_state *
@@ -593,12 +596,11 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
}
static void
-surface_state_handle_surface_destroy(struct wl_listener *listener, void *data)
+pixman_renderer_surface_state_destroy(struct pixman_surface_state *ps)
{
- struct pixman_surface_state *ps;
+ wl_list_remove(&ps->surface_destroy_listener.link);
+ wl_list_remove(&ps->renderer_destroy_listener.link);
- ps = container_of(listener, struct pixman_surface_state,
- surface_destroy_listener);
ps->surface->renderer_state = NULL;
@@ -610,10 +612,33 @@ surface_state_handle_surface_destroy(struct wl_listener *listener, void *data)
free(ps);
}
+static void
+surface_state_handle_surface_destroy(struct wl_listener *listener, void *data)
+{
+ struct pixman_surface_state *ps;
+
+ ps = container_of(listener, struct pixman_surface_state,
+ surface_destroy_listener);
+
+ pixman_renderer_surface_state_destroy(ps);
+}
+
+static void
+surface_state_handle_renderer_destroy(struct wl_listener *listener, void *data)
+{
+ struct pixman_surface_state *ps;
+
+ ps = container_of(listener, struct pixman_surface_state,
+ renderer_destroy_listener);
+
+ pixman_renderer_surface_state_destroy(ps);
+}
+
static int
pixman_renderer_create_surface(struct weston_surface *surface)
{
struct pixman_surface_state *ps;
+ struct pixman_renderer *pr = get_renderer(surface->compositor);
ps = calloc(1, sizeof *ps);
if (!ps)
@@ -628,6 +653,11 @@ pixman_renderer_create_surface(struct weston_surface *surface)
wl_signal_add(&surface->destroy_signal,
&ps->surface_destroy_listener);
+ ps->renderer_destroy_listener.notify =
+ surface_state_handle_renderer_destroy;
+ wl_signal_add(&pr->destroy_signal,
+ &ps->renderer_destroy_listener);
+
return 0;
}
@@ -656,6 +686,7 @@ pixman_renderer_destroy(struct weston_compositor *ec)
{
struct pixman_renderer *pr = get_renderer(ec);
+ wl_signal_emit(&pr->destroy_signal, pr);
weston_binding_destroy(pr->debug_binding);
free(pr);
@@ -710,6 +741,8 @@ pixman_renderer_init(struct weston_compositor *ec)
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGB565);
+ wl_signal_init(&renderer->destroy_signal);
+
return 0;
}
--
1.7.9.5
More information about the wayland-devel
mailing list