[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