[PATCH 3/7] compositor: Let renderers create and destroy surface state on their own
Kristian Høgsberg
hoegsberg at gmail.com
Fri Oct 25 21:38:18 CEST 2013
On Fri, Oct 25, 2013 at 10:27:08AM -0500, Jason Ekstrand wrote:
> Ander,
> When I was working on views, I really wanted to get rid of the
> create_surface functions too... Thanks. That said, you should probably
> also get rid of create_view (It's only used by rpi).
> --Jason Ekstrand
Yeah, I agree, this patch is a nice simplification in itself. Maybe
Tomeu could take a look at the rpi renderer and see if we can drop
create_view patch?
Kristian
> On Fri, Oct 25, 2013 at 8:26 AM, Ander Conselvan de Oliveira <
> ander.conselvan.de.oliveira at intel.com> 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;
> > +
> > 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