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