From 7548c72a7d7db3e1d1d2bb2965a08d028907565a Mon Sep 17 00:00:00 2001 From: Michael Olbrich Date: Tue, 3 Feb 2015 16:52:06 +0100 Subject: [PATCH] wayland: free frame in buffer release callback MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The Wayland compositor may still use the buffer when the frame done callback is called. This patch destroys the frame (which contains the buffer) until the release callback is called. The draw termination callback only controls the display queue dispatching. Signed-off-by: Víctor Manuel Jáquez Leal https://bugzilla.gnome.org/show_bug.cgi?id=747492 --- gst-libs/gst/vaapi/gstvaapiwindow_wayland.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c index e28d06e..4194317 100644 --- a/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c +++ b/gst-libs/gst/vaapi/gstvaapiwindow_wayland.c @@ -114,6 +114,7 @@ struct _GstVaapiWindowWaylandPrivate guint is_shown:1; guint fullscreen_on_show:1; guint use_vpp:1; + guint frame_pending:1; }; /** @@ -162,14 +163,14 @@ gst_vaapi_window_wayland_sync (GstVaapiWindow * window) GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window); - if (priv->frame) { + if (priv->frame_pending) { struct wl_display *const wl_display = GST_VAAPI_OBJECT_NATIVE_DISPLAY (window); do { if (wl_display_dispatch_queue (wl_display, priv->event_queue) < 0) return FALSE; - } while (priv->frame); + } while (priv->frame_pending); } return TRUE; } @@ -329,15 +330,24 @@ frame_redraw_callback (void *data, struct wl_callback *callback, uint32_t time) GstVaapiWindowWaylandPrivate *const priv = GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (frame->window); - frame_state_free (frame); if (priv->frame == frame) - priv->frame = NULL; + priv->frame_pending = FALSE; } static const struct wl_callback_listener frame_callback_listener = { frame_redraw_callback }; +static void +frame_release_callback (void *data, struct wl_buffer *wl_buffer) +{ + frame_state_free (data); +} + +static const struct wl_buffer_listener frame_buffer_listener = { + frame_release_callback +}; + static GstVaapiSurface * vpp_convert (GstVaapiWindow * window, GstVaapiSurface * surface, @@ -474,6 +484,7 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, if (!frame) return FALSE; priv->frame = frame; + priv->frame_pending = TRUE; if (need_vpp && priv->use_vpp) { frame->surface = surface; @@ -492,6 +503,9 @@ gst_vaapi_window_wayland_render (GstVaapiWindow * window, } frame->buffer = buffer; + wl_proxy_set_queue ((struct wl_proxy *) buffer, priv->event_queue); + wl_buffer_add_listener (buffer, &frame_buffer_listener, frame); + frame->callback = wl_surface_frame (priv->surface); wl_callback_add_listener (frame->callback, &frame_callback_listener, frame); -- 2.7.4