From 62c3888b76afc69f714a020957e8c5dd9d98f561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Manuel=20J=C3=A1quez=20Leal?= Date: Thu, 7 May 2015 10:36:17 +0200 Subject: [PATCH] wayland: decouple wl_buffer from frame MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch takes out the wayland's buffer from the the frame structure. The buffer is queued to wayland and destroyed in the "release" callback. The frame is freed in the surface's "done" callback. In this way a buffer may be leaked but not the whole frame structure. - surface 'done' callback is used to throttle the rendering operation and to unallocate the frame, but not the buffer. - buffer 'release' callback is used to destroy wl_buffer. Original-patch-by: Zhao Halley * code rebase * kept the the event_queue for buffer's proxy Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=749078 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 25 +++++++++------------ 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index dbbaa2fcb9..0d691ad4b2 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -55,7 +55,6 @@ struct _FrameState GstVaapiWindow *window; GstVaapiSurface *surface; GstVaapiVideoPool *surface_pool; - struct wl_buffer *buffer; struct wl_callback *callback; }; @@ -71,7 +70,6 @@ frame_state_new (GstVaapiWindow * window) frame->window = window; frame->surface = NULL; frame->surface_pool = NULL; - frame->buffer = NULL; frame->callback = NULL; return frame; } @@ -89,11 +87,6 @@ frame_state_free (FrameState * frame) } gst_vaapi_video_pool_replace (&frame->surface_pool, NULL); - if (frame->buffer) { - wl_buffer_destroy (frame->buffer); - frame->buffer = NULL; - } - if (frame->callback) { wl_callback_destroy (frame->callback); frame->callback = NULL; @@ -162,11 +155,10 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) { GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); + struct wl_display *const wl_display = + GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); while (priv->frame_pending) { - struct wl_display *const wl_display = - GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); - if (wl_display_dispatch_queue (wl_display, priv->event_queue) < 0) return FALSE; } @@ -328,8 +320,11 @@ frame_done_callback (void *data, struct wl_callback *callback, uint32_t time) GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); - if (priv->frame == frame) + if (priv->frame == frame) { priv->frame_pending = FALSE; + frame_state_free (frame); + priv->frame = NULL; + } } static const struct wl_callback_listener frame_callback_listener = { @@ -339,7 +334,7 @@ static const struct wl_callback_listener frame_callback_listener = { static void frame_release_callback (void *data, struct wl_buffer *wl_buffer) { - frame_state_free (data); + wl_buffer_destroy (wl_buffer); } static const struct wl_buffer_listener frame_buffer_listener = { @@ -500,9 +495,11 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, priv->opaque_region = NULL; } - frame->buffer = buffer; + /* @TODO: It is not OK to use internal event_queue here, since there + * may still be a WL_BUFFER_RELEASE event when we destroy the + * event_queue in gst_vaapi_window_wayland_destroy (). */ wl_proxy_set_queue ((struct wl_proxy *) buffer, priv->event_queue); - wl_buffer_add_listener (buffer, &frame_buffer_listener, frame); + wl_buffer_add_listener (buffer, &frame_buffer_listener, NULL); frame->callback = wl_surface_frame (priv->surface); wl_callback_add_listener (frame->callback, &frame_callback_listener, frame);