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