[PATCH weston 1/2] Implement wl_surface.set_release

Neil Roberts neil at linux.intel.com
Wed Oct 23 12:05:25 PDT 2013


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



More information about the wayland-devel mailing list