[RFC weston] Add a release_type argument to weston_buffer_reference
Tomeu Vizoso
tomeu at tomeuvizoso.net
Tue Dec 3 03:46:17 PST 2013
Kristian,
what do you think of this one?
The current state of affairs is that clients have to choose between
holding more than 2 buffers, or constantly syncing with the compositor
until a release comes.
Thanks,
Tomeu
On 31 October 2013 02:59, Jason Ekstrand <jason at jlekstrand.net> wrote:
> This allows the caller to specify whether the wl_buffer.release event (if
> one is generated) should be sent immediately or queued for later. This
> only makes a difference if this weston_buffer_reference call will release
> the buffer. If there are other references to the buffer remaining, the
> argument is simply ignored.
> ---
> src/compositor-drm.c | 9 ++++++---
> src/compositor.c | 28 +++++++++++++++++++---------
> src/compositor.h | 8 +++++++-
> src/gl-renderer.c | 12 ++++++++----
> src/pixman-renderer.c | 13 +++++++++----
> src/rpi-renderer.c | 21 ++++++++++++++-------
> 6 files changed, 63 insertions(+), 28 deletions(-)
>
> diff --git a/src/compositor-drm.c b/src/compositor-drm.c
> index b929728..ad57415 100644
> --- a/src/compositor-drm.c
> +++ b/src/compositor-drm.c
> @@ -237,7 +237,8 @@ drm_fb_destroy_callback(struct gbm_bo *bo, void *data)
> if (fb->fb_id)
> drmModeRmFB(gbm_device_get_fd(gbm), fb->fb_id);
>
> - weston_buffer_reference(&fb->buffer_ref, NULL);
> + weston_buffer_reference(&fb->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
>
> free(data);
> }
> @@ -310,7 +311,8 @@ drm_fb_destroy_dumb(struct drm_fb *fb)
> if (fb->fb_id)
> drmModeRmFB(fb->fd, fb->fb_id);
>
> - weston_buffer_reference(&fb->buffer_ref, NULL);
> + weston_buffer_reference(&fb->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
>
> munmap(fb->map, fb->size);
>
> @@ -395,7 +397,8 @@ drm_fb_set_buffer(struct drm_fb *fb, struct weston_buffer *buffer)
>
> fb->is_client_buffer = 1;
>
> - weston_buffer_reference(&fb->buffer_ref, buffer);
> + weston_buffer_reference(&fb->buffer_ref, buffer,
> + WESTON_BUFFER_RELEASE_DELAYED);
> }
>
> static void
> diff --git a/src/compositor.c b/src/compositor.c
> index 563bade..f67bc49 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -1240,7 +1240,8 @@ weston_surface_destroy(struct weston_surface *surface)
> if (surface->pending.buffer)
> wl_list_remove(&surface->pending.buffer_destroy_listener.link);
>
> - weston_buffer_reference(&surface->buffer_ref, NULL);
> + weston_buffer_reference(&surface->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
>
> pixman_region32_fini(&surface->damage);
> pixman_region32_fini(&surface->opaque);
> @@ -1310,14 +1311,18 @@ weston_buffer_reference_handle_destroy(struct wl_listener *listener,
>
> WL_EXPORT void
> weston_buffer_reference(struct weston_buffer_reference *ref,
> - struct weston_buffer *buffer)
> + struct weston_buffer *buffer,
> + enum weston_buffer_release_type release_type)
> {
> 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 (release_type == WESTON_BUFFER_RELEASE_DELAYED)
> + wl_resource_queue_event(ref->buffer->resource,
> + WL_BUFFER_RELEASE);
> + else
> + wl_buffer_send_release(ref->buffer->resource);
> }
> wl_list_remove(&ref->destroy_listener.link);
> }
> @@ -1336,7 +1341,8 @@ static void
> weston_surface_attach(struct weston_surface *surface,
> struct weston_buffer *buffer)
> {
> - weston_buffer_reference(&surface->buffer_ref, buffer);
> + weston_buffer_reference(&surface->buffer_ref, buffer,
> + WESTON_BUFFER_RELEASE_DELAYED);
>
> if (!buffer) {
> if (weston_surface_is_mapped(surface))
> @@ -1464,7 +1470,8 @@ compositor_accumulate_damage(struct weston_compositor *ec)
> * clients to use single-buffering.
> */
> if (!ev->surface->keep_buffer)
> - weston_buffer_reference(&ev->surface->buffer_ref, NULL);
> + weston_buffer_reference(&ev->surface->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_IMMEDIATE);
> }
> }
>
> @@ -2107,7 +2114,8 @@ weston_subsurface_commit_from_cache(struct weston_subsurface *sub)
> /* wl_surface.attach */
> if (sub->cached.buffer_ref.buffer || sub->cached.newly_attached)
> weston_surface_attach(surface, sub->cached.buffer_ref.buffer);
> - weston_buffer_reference(&sub->cached.buffer_ref, NULL);
> + weston_buffer_reference(&sub->cached.buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
>
> surface->width = 0;
> surface->height = 0;
> @@ -2187,7 +2195,8 @@ weston_subsurface_commit_to_cache(struct weston_subsurface *sub)
> if (surface->pending.newly_attached) {
> sub->cached.newly_attached = 1;
> weston_buffer_reference(&sub->cached.buffer_ref,
> - surface->pending.buffer);
> + surface->pending.buffer,
> + WESTON_BUFFER_RELEASE_DELAYED);
> }
> sub->cached.sx += surface->pending.sx;
> sub->cached.sy += surface->pending.sy;
> @@ -2487,7 +2496,8 @@ weston_subsurface_cache_fini(struct weston_subsurface *sub)
> wl_list_for_each_safe(cb, tmp, &sub->cached.frame_callback_list, link)
> wl_resource_destroy(cb->resource);
>
> - weston_buffer_reference(&sub->cached.buffer_ref, NULL);
> + weston_buffer_reference(&sub->cached.buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
> pixman_region32_fini(&sub->cached.damage);
> pixman_region32_fini(&sub->cached.opaque);
> pixman_region32_fini(&sub->cached.input);
> diff --git a/src/compositor.h b/src/compositor.h
> index e60a512..689c542 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -624,6 +624,11 @@ struct weston_buffer {
> int y_inverted;
> };
>
> +enum weston_buffer_release_type {
> + WESTON_BUFFER_RELEASE_IMMEDIATE = 0,
> + WESTON_BUFFER_RELEASE_DELAYED = 1
> +};
> +
> struct weston_buffer_reference {
> struct weston_buffer *buffer;
> struct wl_listener destroy_listener;
> @@ -1136,7 +1141,8 @@ weston_buffer_from_resource(struct wl_resource *resource);
>
> void
> weston_buffer_reference(struct weston_buffer_reference *ref,
> - struct weston_buffer *buffer);
> + struct weston_buffer *buffer,
> + enum weston_buffer_release_type release_type);
>
> uint32_t
> weston_compositor_get_time(void);
> diff --git a/src/gl-renderer.c b/src/gl-renderer.c
> index d181c07..72ca2ce 100644
> --- a/src/gl-renderer.c
> +++ b/src/gl-renderer.c
> @@ -942,7 +942,8 @@ done:
> pixman_region32_init(&gs->texture_damage);
> gs->needs_full_upload = 0;
>
> - weston_buffer_reference(&gs->buffer_ref, NULL);
> + weston_buffer_reference(&gs->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
> }
>
> static void
> @@ -1106,7 +1107,8 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
> EGLint format;
> int i;
>
> - weston_buffer_reference(&gs->buffer_ref, buffer);
> + weston_buffer_reference(&gs->buffer_ref, buffer,
> + WESTON_BUFFER_RELEASE_DELAYED);
>
> if (!buffer) {
> for (i = 0; i < gs->num_images; i++) {
> @@ -1130,7 +1132,8 @@ gl_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
> gl_renderer_attach_egl(es, buffer, format);
> else {
> weston_log("unhandled buffer type!\n");
> - weston_buffer_reference(&gs->buffer_ref, NULL);
> + weston_buffer_reference(&gs->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
> gs->buffer_type = BUFFER_TYPE_NULL;
> gs->y_inverted = 1;
> }
> @@ -1166,7 +1169,8 @@ surface_state_destroy(struct gl_surface_state *gs, struct gl_renderer *gr)
> for (i = 0; i < gs->num_images; i++)
> gr->destroy_image(gr->egl_display, gs->images[i]);
>
> - weston_buffer_reference(&gs->buffer_ref, NULL);
> + weston_buffer_reference(&gs->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
> pixman_region32_fini(&gs->texture_damage);
> free(gs);
> }
> diff --git a/src/pixman-renderer.c b/src/pixman-renderer.c
> index 79c1d5b..f16c049 100644
> --- a/src/pixman-renderer.c
> +++ b/src/pixman-renderer.c
> @@ -550,7 +550,8 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
> struct wl_shm_buffer *shm_buffer;
> pixman_format_code_t pixman_format;
>
> - weston_buffer_reference(&ps->buffer_ref, buffer);
> + weston_buffer_reference(&ps->buffer_ref, buffer,
> + WESTON_BUFFER_RELEASE_DELAYED);
>
> if (ps->image) {
> pixman_image_unref(ps->image);
> @@ -564,7 +565,8 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
>
> if (! shm_buffer) {
> weston_log("Pixman renderer supports only SHM buffers\n");
> - weston_buffer_reference(&ps->buffer_ref, NULL);
> + weston_buffer_reference(&ps->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
> return;
> }
>
> @@ -580,7 +582,9 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
> break;
> default:
> weston_log("Unsupported SHM buffer format\n");
> - weston_buffer_reference(&ps->buffer_ref, NULL);
> + weston_buffer_reference(&ps->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
> +
> return;
> break;
> }
> @@ -608,7 +612,8 @@ pixman_renderer_surface_state_destroy(struct pixman_surface_state *ps)
> pixman_image_unref(ps->image);
> ps->image = NULL;
> }
> - weston_buffer_reference(&ps->buffer_ref, NULL);
> + weston_buffer_reference(&ps->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
> free(ps);
> }
>
> diff --git a/src/rpi-renderer.c b/src/rpi-renderer.c
> index b7e9487..b41bcf8 100644
> --- a/src/rpi-renderer.c
> +++ b/src/rpi-renderer.c
> @@ -386,7 +386,8 @@ rpir_egl_buffer_destroy(struct rpir_egl_buffer *egl_buffer)
> vc_dispmanx_resource_delete(egl_buffer->resource_handle);
> } else {
> vc_dispmanx_set_wl_buffer_in_use(buffer->resource, 0);
> - weston_buffer_reference(&egl_buffer->buffer_ref, NULL);
> + weston_buffer_reference(&egl_buffer->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_IMMEDIATE);
> }
>
> free(egl_buffer);
> @@ -1345,7 +1346,8 @@ rpi_renderer_flush_damage(struct weston_surface *base)
> weston_log("%s error: updating Dispmanx resource failed.\n",
> __func__);
>
> - weston_buffer_reference(&surface->buffer_ref, NULL);
> + weston_buffer_reference(&surface->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
> }
>
> static void
> @@ -1367,7 +1369,8 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer)
> /* XXX: cannot do this, if middle of an update */
> rpi_resource_release(surface->front);
>
> - weston_buffer_reference(&surface->buffer_ref, NULL);
> + weston_buffer_reference(&surface->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
> }
>
> /* If buffer is NULL, Weston core unmaps the surface, the surface
> @@ -1384,7 +1387,8 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer)
> buffer->width = wl_shm_buffer_get_width(buffer->shm_buffer);
> buffer->height = wl_shm_buffer_get_height(buffer->shm_buffer);
>
> - weston_buffer_reference(&surface->buffer_ref, buffer);
> + weston_buffer_reference(&surface->buffer_ref, buffer,
> + WESTON_BUFFER_RELEASE_DELAYED);
> } else {
> #if ENABLE_EGL
> struct rpi_renderer *renderer = to_rpi_renderer(base->compositor);
> @@ -1395,7 +1399,8 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer)
> wl_resource,
> EGL_WIDTH, &buffer->width)) {
> weston_log("unhandled buffer type!\n");
> - weston_buffer_reference(&surface->buffer_ref, NULL);
> + weston_buffer_reference(&surface->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
> surface->buffer_type = BUFFER_TYPE_NULL;
> }
>
> @@ -1408,12 +1413,14 @@ rpi_renderer_attach(struct weston_surface *base, struct weston_buffer *buffer)
> if(surface->egl_back == NULL)
> surface->egl_back = calloc(1, sizeof *surface->egl_back);
>
> - weston_buffer_reference(&surface->egl_back->buffer_ref, buffer);
> + weston_buffer_reference(&surface->egl_back->buffer_ref, buffer,
> + WESTON_BUFFER_RELEASE_DELAYED);
> surface->egl_back->resource_handle =
> vc_dispmanx_get_handle_from_wl_buffer(wl_resource);
> #else
> weston_log("unhandled buffer type!\n");
> - weston_buffer_reference(&surface->buffer_ref, NULL);
> + weston_buffer_reference(&surface->buffer_ref, NULL,
> + WESTON_BUFFER_RELEASE_DELAYED);
> surface->buffer_type = BUFFER_TYPE_NULL;
> #endif
> }
> --
> 1.8.3.1
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list