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