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.

>               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
> [email protected]
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
_______________________________________________
wayland-devel mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to