[PATCH 3/7] compositor: Let renderers create and destroy surface state on their own
Ander Conselvan de Oliveira
conselvan2 at gmail.com
Mon Oct 28 09:43:57 CET 2013
On 10/25/2013 10:30 PM, Kristian Høgsberg wrote:
> On Fri, Oct 25, 2013 at 04:26:33PM +0300, Ander Conselvan de Oliveira wrote:
>> Remove create_surface() and destroy_surface() from the renderer
>> interface and change the renderers to create surface state on demand
>> and destroy it using the weston_surface's destroy signal.
>>
>> Also make sure the surfaces' renderer state is reset to NULL on
>> destruction.
>>
>> This is a step towards runtime switchable renderers.
>>
>> (rpi-renderer changes are only compile-tested)
>> ---
>> src/compositor.c | 8 -------
>> src/compositor.h | 2 --
>> src/gl-renderer.c | 61 ++++++++++++++++++++++++++++++++++---------------
>> src/noop-renderer.c | 13 -----------
>> src/pixman-renderer.c | 50 ++++++++++++++++++++++++++++------------
>> src/rpi-renderer.c | 54 ++++++++++++++++++++++++++++---------------
>> 6 files changed, 112 insertions(+), 76 deletions(-)
>>
>> diff --git a/src/compositor.c b/src/compositor.c
>> index 2ed6b1e..563bade 100644
>> --- a/src/compositor.c
>> +++ b/src/compositor.c
>> @@ -407,11 +407,6 @@ weston_surface_create(struct weston_compositor *compositor)
>> surface->compositor = compositor;
>> surface->ref_count = 1;
>>
>> - if (compositor->renderer->create_surface(surface) < 0) {
>> - free(surface);
>> - return NULL;
>> - }
>> -
>> surface->buffer_transform = WL_OUTPUT_TRANSFORM_NORMAL;
>> surface->buffer_scale = 1;
>> surface->pending.buffer_transform = surface->buffer_transform;
>> @@ -1220,7 +1215,6 @@ weston_view_destroy(struct weston_view *view)
>> WL_EXPORT void
>> weston_surface_destroy(struct weston_surface *surface)
>> {
>> - struct weston_compositor *compositor = surface->compositor;
>> struct weston_frame_callback *cb, *next;
>> struct weston_view *ev, *nv;
>>
>> @@ -1248,8 +1242,6 @@ weston_surface_destroy(struct weston_surface *surface)
>>
>> weston_buffer_reference(&surface->buffer_ref, NULL);
>>
>> - compositor->renderer->destroy_surface(surface);
>> -
>> pixman_region32_fini(&surface->damage);
>> pixman_region32_fini(&surface->opaque);
>> pixman_region32_fini(&surface->input);
>> diff --git a/src/compositor.h b/src/compositor.h
>> index 73722b5..e60a512 100644
>> --- a/src/compositor.h
>> +++ b/src/compositor.h
>> @@ -521,12 +521,10 @@ struct weston_renderer {
>> pixman_region32_t *output_damage);
>> void (*flush_damage)(struct weston_surface *surface);
>> void (*attach)(struct weston_surface *es, struct weston_buffer *buffer);
>> - int (*create_surface)(struct weston_surface *surface);
>> int (*create_view)(struct weston_view *view);
>> void (*surface_set_color)(struct weston_surface *surface,
>> float red, float green,
>> float blue, float alpha);
>> - void (*destroy_surface)(struct weston_surface *surface);
>> void (*destroy_view)(struct weston_view *view);
>> void (*destroy)(struct weston_compositor *ec);
>> };
>> diff --git a/src/gl-renderer.c b/src/gl-renderer.c
>> index 0f0b5f7..d792530 100644
>> --- a/src/gl-renderer.c
>> +++ b/src/gl-renderer.c
>> @@ -79,6 +79,10 @@ struct gl_surface_state {
>> int pitch; /* in pixels */
>> int height; /* in pixels */
>> int y_inverted;
>> +
>> + struct weston_surface *surface;
>> +
>> + struct wl_listener surface_destroy_listener;
>> };
>>
>> struct gl_renderer {
>> @@ -134,9 +138,15 @@ get_output_state(struct weston_output *output)
>> return (struct gl_output_state *)output->renderer_state;
>> }
>>
>> +static int
>> +gl_renderer_create_surface(struct weston_surface *surface);
>> +
>> static inline struct gl_surface_state *
>> get_surface_state(struct weston_surface *surface)
>> {
>> + if (!surface->renderer_state)
>> + gl_renderer_create_surface(surface);
>> +
>> return (struct gl_surface_state *)surface->renderer_state;
>> }
>>
>> @@ -997,6 +1007,8 @@ gl_renderer_attach_shm(struct weston_surface *es, struct weston_buffer *buffer,
>> gs->needs_full_upload = 1;
>> gs->y_inverted = 1;
>>
>> + gs->surface = surface;
>> +
>
> I had to change this to gs->surface = es to make it compile, but other
> than that it looks good.
I had a last minute rebase error I thought I could get away without
testing it for the nth time. Apparentely I was wrong.
Ander
>
>> ensure_textures(gs, 1);
>> glBindTexture(GL_TEXTURE_2D, gs->textures[0]);
>> glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,
>> @@ -1136,6 +1148,31 @@ gl_renderer_surface_set_color(struct weston_surface *surface,
>> gs->shader = &gr->solid_shader;
>> }
>>
>> +static void
>> +surface_state_handle_surface_destroy(struct wl_listener *listener, void *data)
>> +{
>> + 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);
>> +
>> + gs->surface->renderer_state = NULL;
>> +
>> + glDeleteTextures(gs->num_textures, gs->textures);
>> +
>> + for (i = 0; i < gs->num_images; i++)
>> + gr->destroy_image(gr->egl_display, gs->images[i]);
>> +
>> + weston_buffer_reference(&gs->buffer_ref, NULL);
>> + pixman_region32_fini(&gs->texture_damage);
>> + free(gs);
>> +}
>> +
>> static int
>> gl_renderer_create_surface(struct weston_surface *surface)
>> {
>> @@ -1155,24 +1192,12 @@ gl_renderer_create_surface(struct weston_surface *surface)
>> pixman_region32_init(&gs->texture_damage);
>> surface->renderer_state = gs;
>>
>> - return 0;
>> -}
>> + gs->surface_destroy_listener.notify =
>> + surface_state_handle_surface_destroy;
>> + wl_signal_add(&surface->destroy_signal,
>> + &gs->surface_destroy_listener);
>>
>> -static void
>> -gl_renderer_destroy_surface(struct weston_surface *surface)
>> -{
>> - struct gl_surface_state *gs = get_surface_state(surface);
>> - struct gl_renderer *gr = get_renderer(surface->compositor);
>> - int i;
>> -
>> - glDeleteTextures(gs->num_textures, gs->textures);
>> -
>> - for (i = 0; i < gs->num_images; i++)
>> - gr->destroy_image(gr->egl_display, gs->images[i]);
>> -
>> - weston_buffer_reference(&gs->buffer_ref, NULL);
>> - pixman_region32_fini(&gs->texture_damage);
>> - free(gs);
>> + return 0;
>> }
>>
>> static const char vertex_shader[] =
>> @@ -1655,9 +1680,7 @@ gl_renderer_create(struct weston_compositor *ec, EGLNativeDisplayType display,
>> gr->base.repaint_output = gl_renderer_repaint_output;
>> gr->base.flush_damage = gl_renderer_flush_damage;
>> gr->base.attach = gl_renderer_attach;
>> - gr->base.create_surface = gl_renderer_create_surface;
>> gr->base.surface_set_color = gl_renderer_surface_set_color;
>> - gr->base.destroy_surface = gl_renderer_destroy_surface;
>> gr->base.destroy = gl_renderer_destroy;
>>
>> gr->egl_display = eglGetDisplay(display);
>> diff --git a/src/noop-renderer.c b/src/noop-renderer.c
>> index 91659f5..ad750b5 100644
>> --- a/src/noop-renderer.c
>> +++ b/src/noop-renderer.c
>> @@ -51,12 +51,6 @@ noop_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
>> {
>> }
>>
>> -static int
>> -noop_renderer_create_surface(struct weston_surface *surface)
>> -{
>> - return 0;
>> -}
>> -
>> static void
>> noop_renderer_surface_set_color(struct weston_surface *surface,
>> float red, float green, float blue, float alpha)
>> @@ -64,11 +58,6 @@ noop_renderer_surface_set_color(struct weston_surface *surface,
>> }
>>
>> static void
>> -noop_renderer_destroy_surface(struct weston_surface *surface)
>> -{
>> -}
>> -
>> -static void
>> noop_renderer_destroy(struct weston_compositor *ec)
>> {
>> free(ec->renderer);
>> @@ -88,9 +77,7 @@ noop_renderer_init(struct weston_compositor *ec)
>> renderer->repaint_output = noop_renderer_repaint_output;
>> renderer->flush_damage = noop_renderer_flush_damage;
>> renderer->attach = noop_renderer_attach;
>> - renderer->create_surface = noop_renderer_create_surface;
>> renderer->surface_set_color = noop_renderer_surface_set_color;
>> - renderer->destroy_surface = noop_renderer_destroy_surface;
>> renderer->destroy = noop_renderer_destroy;
>> ec->renderer = renderer;
>>
>> diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
>> index 0d85e07..98a910c 100644
>> --- a/src/pixman-renderer.c
>> +++ b/src/pixman-renderer.c
>> @@ -37,8 +37,12 @@ struct pixman_output_state {
>> };
>>
>> struct pixman_surface_state {
>> + struct weston_surface *surface;
>> +
>> pixman_image_t *image;
>> struct weston_buffer_reference buffer_ref;
>> +
>> + struct wl_listener surface_destroy_listener;
>> };
>>
>> struct pixman_renderer {
>> @@ -55,9 +59,15 @@ get_output_state(struct weston_output *output)
>> return (struct pixman_output_state *)output->renderer_state;
>> }
>>
>> +static int
>> +pixman_renderer_create_surface(struct weston_surface *surface);
>> +
>> static inline struct pixman_surface_state *
>> get_surface_state(struct weston_surface *surface)
>> {
>> + if (!surface->renderer_state)
>> + pixman_renderer_create_surface(surface);
>> +
>> return (struct pixman_surface_state *)surface->renderer_state;
>> }
>>
>> @@ -582,6 +592,24 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
>> wl_shm_buffer_get_stride(shm_buffer));
>> }
>>
>> +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);
>> +
>> + ps->surface->renderer_state = NULL;
>> +
>> + if (ps->image) {
>> + pixman_image_unref(ps->image);
>> + ps->image = NULL;
>> + }
>> + weston_buffer_reference(&ps->buffer_ref, NULL);
>> + free(ps);
>> +}
>> +
>> static int
>> pixman_renderer_create_surface(struct weston_surface *surface)
>> {
>> @@ -593,6 +621,13 @@ pixman_renderer_create_surface(struct weston_surface *surface)
>>
>> surface->renderer_state = ps;
>>
>> + ps->surface = surface;
>> +
>> + ps->surface_destroy_listener.notify =
>> + surface_state_handle_surface_destroy;
>> + wl_signal_add(&surface->destroy_signal,
>> + &ps->surface_destroy_listener);
>> +
>> return 0;
>> }
>>
>> @@ -617,19 +652,6 @@ pixman_renderer_surface_set_color(struct weston_surface *es,
>> }
>>
>> static void
>> -pixman_renderer_destroy_surface(struct weston_surface *surface)
>> -{
>> - struct pixman_surface_state *ps = get_surface_state(surface);
>> -
>> - if (ps->image) {
>> - pixman_image_unref(ps->image);
>> - ps->image = NULL;
>> - }
>> - weston_buffer_reference(&ps->buffer_ref, NULL);
>> - free(ps);
>> -}
>> -
>> -static void
>> pixman_renderer_destroy(struct weston_compositor *ec)
>> {
>> struct pixman_renderer *pr = get_renderer(ec);
>> @@ -676,9 +698,7 @@ pixman_renderer_init(struct weston_compositor *ec)
>> renderer->base.repaint_output = pixman_renderer_repaint_output;
>> renderer->base.flush_damage = pixman_renderer_flush_damage;
>> renderer->base.attach = pixman_renderer_attach;
>> - renderer->base.create_surface = pixman_renderer_create_surface;
>> renderer->base.surface_set_color = pixman_renderer_surface_set_color;
>> - renderer->base.destroy_surface = pixman_renderer_destroy_surface;
>> renderer->base.destroy = pixman_renderer_destroy;
>> ec->renderer = &renderer->base;
>> ec->capabilities |= WESTON_CAP_ROTATION_ANY;
>> diff --git a/src/rpi-renderer.c b/src/rpi-renderer.c
>> index ea48b08..5de4d43 100644
>> --- a/src/rpi-renderer.c
>> +++ b/src/rpi-renderer.c
>> @@ -120,6 +120,8 @@ struct rpir_surface {
>>
>> struct weston_buffer_reference buffer_ref;
>> enum buffer_type buffer_type;
>> +
>> + struct wl_listener surface_destroy_listener;
>> };
>>
>> struct rpir_view {
>> @@ -167,9 +169,15 @@ struct rpi_renderer {
>> int has_bind_display;
>> };
>>
>> +static int
>> +rpi_renderer_create_surface(struct weston_surface *base);
>> +
>> static inline struct rpir_surface *
>> to_rpir_surface(struct weston_surface *surface)
>> {
>> + if (!surface->renderer_state)
>> + rpi_renderer_create_surface(surface);
>> +
>> return surface->renderer_state;
>> }
>>
>> @@ -1395,6 +1403,27 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer)
>> }
>> }
>>
>> +static void
>> +rpir_surface_handle_surface_destroy(struct wl_listener *listener, void *data)
>> +{
>> + struct rpir_surface *surface;
>> + struct weston_surface *base = data;
>> +
>> + surface = container_of(listener, struct rpir_surface,
>> + surface_destroy_listener);
>> +
>> + assert(surface);
>> + assert(surface->surface == base);
>> + if (!surface)
>> + return;
>> +
>> + surface->surface = NULL;
>> + base->renderer_state = NULL;
>> +
>> + if (wl_list_empty(&surface->views))
>> + rpir_surface_destroy(surface);
>> +}
>> +
>> static int
>> rpi_renderer_create_surface(struct weston_surface *base)
>> {
>> @@ -1409,6 +1438,12 @@ rpi_renderer_create_surface(struct weston_surface *base)
>>
>> surface->surface = base;
>> base->renderer_state = surface;
>> +
>> + surface->surface_destroy_listener.notify =
>> + rpir_surface_handle_surface_destroy;
>> + wl_signal_add(&base->destroy_signal,
>> + &surface->surface_destroy_listener);
>> +
>> return 0;
>> }
>>
>> @@ -1471,23 +1506,6 @@ rpi_renderer_surface_set_color(struct weston_surface *base,
>> }
>>
>> static void
>> -rpi_renderer_destroy_surface(struct weston_surface *base)
>> -{
>> - struct rpir_surface *surface = to_rpir_surface(base);
>> -
>> - assert(surface);
>> - assert(surface->surface == base);
>> - if (!surface)
>> - return;
>> -
>> - surface->surface = NULL;
>> - base->renderer_state = NULL;
>> -
>> - if (wl_list_empty(&surface->views))
>> - rpir_surface_destroy(surface);
>> -}
>> -
>> -static void
>> rpi_renderer_destroy_view(struct weston_view *base)
>> {
>> struct rpir_view *view = to_rpir_view(base);
>> @@ -1546,10 +1564,8 @@ rpi_renderer_create(struct weston_compositor *compositor,
>> renderer->base.repaint_output = rpi_renderer_repaint_output;
>> renderer->base.flush_damage = rpi_renderer_flush_damage;
>> renderer->base.attach = rpi_renderer_attach;
>> - renderer->base.create_surface = rpi_renderer_create_surface;
>> renderer->base.create_view = rpi_renderer_create_view;
>> renderer->base.surface_set_color = rpi_renderer_surface_set_color;
>> - renderer->base.destroy_surface = rpi_renderer_destroy_surface;
>> renderer->base.destroy_view = rpi_renderer_destroy_view;
>> renderer->base.destroy = rpi_renderer_destroy;
>>
>> --
>> 1.7.9.5
>>
>> _______________________________________________
>> wayland-devel mailing list
>> wayland-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> _______________________________________________
> 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