mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-09 04:48:04 +02:00
pixman-renderer, gl-renderer: Destroy surface state with the renderer
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.
This commit is contained in:
parent
aa398ae1f3
commit
adda00e72f
2 changed files with 83 additions and 12 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue