struct weston_surface *surface;
struct wl_listener surface_destroy_listener;
+ struct wl_listener renderer_destroy_listener;
};
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 *
}
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;
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)
gs->pitch = 1;
gs->y_inverted = 1;
+ gs->surface = surface;
+
pixman_region32_init(&gs->texture_damage);
surface->renderer_state = gs;
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;
}
{
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);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGB565);
+ wl_signal_init(&gr->destroy_signal);
+
return 0;
err_egl:
struct weston_buffer_reference buffer_ref;
struct wl_listener surface_destroy_listener;
+ struct wl_listener renderer_destroy_listener;
};
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 *
}
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;
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)
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;
}
{
struct pixman_renderer *pr = get_renderer(ec);
+ wl_signal_emit(&pr->destroy_signal, pr);
weston_binding_destroy(pr->debug_binding);
free(pr);
wl_display_add_shm_format(ec->wl_display, WL_SHM_FORMAT_RGB565);
+ wl_signal_init(&renderer->destroy_signal);
+
return 0;
}