libs: window: wayland: wait for configure before committing the first buffer
authorMichael Olbrich <m.olbrich@pengutronix.de>
Mon, 6 Jul 2020 07:59:40 +0000 (09:59 +0200)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Mon, 27 Jul 2020 15:02:19 +0000 (15:02 +0000)
Committing the first buffer for a surface must not be done before
ack_configure() has been sent for the xdg_surface.

With weston, the commit will fail with "error 3: xdg_surface has never been
configured".

Wait in gst_vaapi_window_wayland_show() until configure is done to avoid
this.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/346>

gst-libs/gst/vaapi/gstvaapiwindow_wayland.c

index 8e09152..abf492f 100644 (file)
@@ -111,6 +111,7 @@ struct _GstVaapiWindowWaylandPrivate
   guint fullscreen_on_show:1;
   guint sync_failed:1;
   volatile guint num_frames_pending;
+  gint configure_pending;
   gboolean need_vpp;
 };
 
@@ -184,6 +185,8 @@ static const struct xdg_toplevel_listener xdg_toplevel_listener = {
   handle_xdg_toplevel_close,
 };
 
+static gboolean gst_vaapi_window_wayland_sync (GstVaapiWindow * window);
+
 static gboolean
 gst_vaapi_window_wayland_show (GstVaapiWindow * window)
 {
@@ -200,6 +203,8 @@ gst_vaapi_window_wayland_show (GstVaapiWindow * window)
     return TRUE;
   }
 
+  g_atomic_int_set (&priv->configure_pending, 1);
+  g_atomic_int_inc (&priv->num_frames_pending);
   /* Create a toplevel window out of it */
   priv->xdg_toplevel = xdg_surface_get_toplevel (priv->xdg_surface);
   g_return_val_if_fail (priv->xdg_toplevel, FALSE);
@@ -213,7 +218,7 @@ gst_vaapi_window_wayland_show (GstVaapiWindow * window)
   /* Commit the xdg_surface state as top-level window */
   wl_surface_commit (priv->surface);
 
-  return TRUE;
+  return gst_vaapi_window_wayland_sync (window);
 }
 
 static gboolean
@@ -322,7 +327,13 @@ static void
 handle_xdg_surface_configure (void *data, struct xdg_surface *xdg_surface,
     uint32_t serial)
 {
+  GstVaapiWindow *window = GST_VAAPI_WINDOW (data);
+  GstVaapiWindowWaylandPrivate *priv =
+      GST_VAAPI_WINDOW_WAYLAND_GET_PRIVATE (window);
+
   xdg_surface_ack_configure (xdg_surface, serial);
+  if (g_atomic_int_compare_and_exchange (&priv->configure_pending, 1, 0))
+    g_atomic_int_dec_and_test (&priv->num_frames_pending);
 }
 
 static const struct xdg_surface_listener xdg_surface_listener = {