Implements the wl_surface.set_release request which just causes the
buffer release events to be sent with wl_resource_post_event instead
of wl_resource_queue_event. The release mode is part of the
double-buffered surface state and gets reset to the default as soon as
a commit is performed on the surface.
---
 src/compositor.c | 53 +++++++++++++++++++++++++++++++++++++++++++++--------
 src/compositor.h |  4 ++++
 2 files changed, 49 insertions(+), 8 deletions(-)

diff --git a/src/compositor.c b/src/compositor.c
index 7e2a394..0a48f39 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -376,6 +376,7 @@ weston_surface_create(struct weston_compositor *compositor)
        surface->buffer_scale = 1;
        surface->pending.buffer_transform = surface->buffer_transform;
        surface->pending.buffer_scale = surface->buffer_scale;
+       surface->pending.release_mode = WL_SURFACE_RELEASE_DELAYED;
        surface->output = NULL;
        surface->plane = &compositor->primary_plane;
        surface->pending.newly_attached = 0;
@@ -1167,6 +1168,7 @@ weston_buffer_from_resource(struct wl_resource *resource)
        wl_signal_init(&buffer->destroy_signal);
        buffer->destroy_listener.notify = weston_buffer_destroy_handler;
        buffer->y_inverted = 1;
+       buffer->release_mode = WL_SURFACE_RELEASE_DELAYED;
        wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
        
        return buffer;
@@ -1184,17 +1186,30 @@ weston_buffer_reference_handle_destroy(struct 
wl_listener *listener,
        ref->buffer = NULL;
 }
 
+static void
+weston_buffer_send_release(struct weston_buffer *buffer)
+{
+       assert(wl_resource_get_client(buffer->resource));
+
+       if (buffer->release_mode == WL_SURFACE_RELEASE_DELAYED) {
+               wl_resource_queue_event(buffer->resource, WL_BUFFER_RELEASE);
+       } else {
+               /* The release mode state should only effect a single
+                * attach so we'll reset it back to the default after
+                * posting the event */
+               buffer->release_mode = WL_SURFACE_RELEASE_DELAYED;
+               wl_resource_post_event(buffer->resource, WL_BUFFER_RELEASE);
+       }
+}
+
 WL_EXPORT void
 weston_buffer_reference(struct weston_buffer_reference *ref,
                        struct weston_buffer *buffer)
 {
        if (ref->buffer && buffer != ref->buffer) {
                ref->buffer->busy_count--;
-               if (ref->buffer->busy_count == 0) {
-                       assert(wl_resource_get_client(ref->buffer->resource));
-                       wl_resource_queue_event(ref->buffer->resource,
-                                               WL_BUFFER_RELEASE);
-               }
+               if (ref->buffer->busy_count == 0)
+                       weston_buffer_send_release(ref->buffer);
                wl_list_remove(&ref->destroy_listener.link);
        }
 
@@ -1655,6 +1670,17 @@ weston_surface_commit(struct weston_surface *surface)
        /* wl_surface.set_buffer_scale */
        surface->buffer_scale = surface->pending.buffer_scale;
 
+       /* wl_surface.set_release */
+       if (surface->pending.release_mode == WL_SURFACE_RELEASE_IMMEDIATE) {
+               if (surface->pending.buffer)
+                       surface->pending.buffer->release_mode =
+                               WL_SURFACE_RELEASE_IMMEDIATE;
+               /* The release mode state should only effect a single
+                * attach so we'll reset it back to the default after
+                * setting it on the buffer */
+               surface->pending.release_mode = WL_SURFACE_RELEASE_DELAYED;
+       }
+
        /* wl_surface.attach */
        if (surface->pending.buffer || surface->pending.newly_attached)
                weston_surface_attach(surface, surface->pending.buffer);
@@ -1762,6 +1788,16 @@ surface_set_buffer_scale(struct wl_client *client,
        surface->pending.buffer_scale = scale;
 }
 
+static void
+surface_set_release(struct wl_client *client,
+                   struct wl_resource *resource,
+                   uint32_t value)
+{
+       struct weston_surface *surface = wl_resource_get_user_data(resource);
+
+       surface->pending.release_mode = value;
+}
+
 static const struct wl_surface_interface surface_interface = {
        surface_destroy,
        surface_attach,
@@ -1771,7 +1807,8 @@ static const struct wl_surface_interface 
surface_interface = {
        surface_set_input_region,
        surface_commit,
        surface_set_buffer_transform,
-       surface_set_buffer_scale
+       surface_set_buffer_scale,
+       surface_set_release
 };
 
 static void
@@ -2928,7 +2965,7 @@ compositor_bind(struct wl_client *client,
        struct wl_resource *resource;
 
        resource = wl_resource_create(client, &wl_compositor_interface,
-                                     MIN(version, 3), id);
+                                     MIN(version, 4), id);
        if (resource == NULL) {
                wl_client_post_no_memory(client);
                return;
@@ -3000,7 +3037,7 @@ weston_compositor_init(struct weston_compositor *ec,
 
        ec->output_id_pool = 0;
 
-       if (!wl_global_create(display, &wl_compositor_interface, 3,
+       if (!wl_global_create(display, &wl_compositor_interface, 4,
                              ec, compositor_bind))
                return -1;
 
diff --git a/src/compositor.h b/src/compositor.h
index 5ed348b..7422160 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -627,6 +627,7 @@ struct weston_buffer {
        int32_t width, height;
        uint32_t busy_count;
        int y_inverted;
+       enum wl_surface_release release_mode;
 };
 
 struct weston_buffer_reference {
@@ -818,6 +819,9 @@ struct weston_surface {
 
                /* wl_surface.set_scaling_factor */
                int32_t buffer_scale;
+
+               /* wl_surface.set_release */
+               enum wl_surface_release release_mode;
        } pending;
 
        /*
-- 
1.8.3.1

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to