[PATCH weston 2/2] window: Don't free shm buffers while the compositor is using them
Kristian Høgsberg
hoegsberg at gmail.com
Tue Jun 19 09:04:12 PDT 2012
On Tue, Jun 19, 2012 at 01:45:56PM +0300, Ander Conselvan de Oliveira wrote:
> After commit 460a79bd, the compositor will only upload the contents of
> an shm buffer to a texture during repaint, but at the point the buffer
> might have been destroyed already. In that case, the surface simply
> isn't drawn.
Yeah, I think we need to change the semantics of destroying a buffer
that's attached to a surface. Currently (or used to be before my
commit broke it) you can attach a buffer and then destroy it
immediately, but the surface keeps the contents and remains visible.
The idea is that attaching has copy-semantics, or at least that the
surface references the underlying content of the buffer (gem buffer or
shm buffer for example), but not the buffer itself. That's probably a
little too subtle and under-defined. It also leads to some
awkwardness inside weston, where we can't just look at surface->buffer
to see if a buffer is attached (surface->buffer may be NULL, but we
may have a valid EGLImage, for example).
So let's just fix that and say that destroying a buffer that's
attached to a surface is equivalent to attaching NULL, ie hiding the
surface.
> The compositor sends a release event when it's done using a buffer, so
> this patch delays the destruction until then if necessary.
> ---
> clients/window.c | 35 ++++++++++++++++++++++++++++++++++-
> 1 files changed, 34 insertions(+), 1 deletions(-)
>
> diff --git a/clients/window.c b/clients/window.c
> index aaf2009..3ebbbeb 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -327,6 +327,7 @@ static const struct weston_option xkb_options[] = {
> static const cairo_user_data_key_t surface_data_key;
> struct surface_data {
> struct wl_buffer *buffer;
> + int attach_count;
> };
>
> #define MULT(_d,c,a,t) \
> @@ -402,6 +403,7 @@ display_get_buffer_for_surface(struct display *display,
> struct surface_data *data;
>
> data = cairo_surface_get_user_data (surface, &surface_data_key);
> + data->attach_count++;
>
> return data->buffer;
> }
> @@ -409,6 +411,7 @@ display_get_buffer_for_surface(struct display *display,
> struct shm_surface_data {
> struct surface_data data;
> struct shm_pool *pool;
> + int surface_gone;
> };
>
> static void
> @@ -426,6 +429,32 @@ shm_surface_data_destroy(void *p)
> free(data);
> }
>
> +static void
> +shm_buffer_destroy(void *p, struct wl_buffer *buffer)
> +{
> + struct shm_surface_data *data = p;
> +
> + data->data.attach_count = 0;
> +
> + if (data->surface_gone)
> + shm_surface_data_destroy(data);
> +}
> +
> +static const struct wl_buffer_listener shm_buffer_listener = {
> + shm_buffer_destroy
> +};
> +
> +static void
> +shm_surface_data_unref(void *p)
> +{
> + struct shm_surface_data *data = p;
> +
> + data->surface_gone = 1;
> +
> + if (data->data.attach_count == 0)
> + shm_surface_data_destroy(p);
> +}
> +
> static struct wl_shm_pool *
> make_shm_pool(struct display *display, int size, void **data)
> {
> @@ -543,8 +572,9 @@ display_create_shm_surface_from_pool(struct display *display,
> rectangle->height,
> stride);
>
> + data->surface_gone = 0;
> cairo_surface_set_user_data (surface, &surface_data_key,
> - data, shm_surface_data_destroy);
> + data, shm_surface_data_unref);
>
> if (flags & SURFACE_OPAQUE)
> format = WL_SHM_FORMAT_XRGB8888;
> @@ -556,6 +586,9 @@ display_create_shm_surface_from_pool(struct display *display,
> rectangle->height,
> stride, format);
>
> + data->data.attach_count = 0;
> + wl_buffer_add_listener(data->data.buffer, &shm_buffer_listener, data);
> +
> return surface;
> }
>
> --
> 1.7.4.1
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list