[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