From e7c9960783dfac5530419b5e38ff8ba4971c345b Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Thu, 30 Dec 2021 16:52:17 +0100 Subject: [PATCH] waylandsink: Ensure correct mapping of area_surface If the `area_surface` got unmapped when changing to the `READY` or `NULL` state, we currently don't remap it when playback resumes and `wp_viewporter` is supported. Without `wp_viewporter` we do remap it, but rather unintentionally and also when not wanted. On Weston this has not been a big problem as it so far wrongly maps subsurfaces of unmapped surfaces anyway - i.e. only the black background was missing on resume. On other compositors and future Weston this prevents the `video_surface` to get remapped. Shuffle things around to ensure `area_surface` is mapped in the right situations and do some minor cleanup. See also https://gitlab.freedesktop.org/wayland/weston/-/issues/426 Part-of: --- subprojects/gst-plugins-bad/ext/wayland/wlwindow.c | 33 ++++++++++++++++------ subprojects/gst-plugins-bad/ext/wayland/wlwindow.h | 7 ++--- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/subprojects/gst-plugins-bad/ext/wayland/wlwindow.c b/subprojects/gst-plugins-bad/ext/wayland/wlwindow.c index 7abddd5..66df0fc 100644 --- a/subprojects/gst-plugins-bad/ext/wayland/wlwindow.c +++ b/subprojects/gst-plugins-bad/ext/wayland/wlwindow.c @@ -43,6 +43,8 @@ G_DEFINE_TYPE (GstWlWindow, gst_wl_window, G_TYPE_OBJECT); static void gst_wl_window_finalize (GObject * gobject); +static void gst_wl_window_update_borders (GstWlWindow * window); + static void handle_xdg_toplevel_close (void *data, struct xdg_toplevel *xdg_toplevel) { @@ -454,12 +456,19 @@ gst_wl_window_render (GstWlWindow * window, GstWlBuffer * buffer, wl_surface_damage_buffer (window->video_surface_wrapper, 0, 0, G_MAXINT32, G_MAXINT32); wl_surface_commit (window->video_surface_wrapper); + + if (!window->is_area_surface_mapped) { + gst_wl_window_update_borders (window); + wl_surface_commit (window->area_surface_wrapper); + window->is_area_surface_mapped = TRUE; + } } else { /* clear both video and parent surfaces */ wl_surface_attach (window->video_surface_wrapper, NULL, 0, 0); wl_surface_commit (window->video_surface_wrapper); wl_surface_attach (window->area_surface_wrapper, NULL, 0, 0); wl_surface_commit (window->area_surface_wrapper); + window->is_area_surface_mapped = FALSE; } if (G_UNLIKELY (info)) { @@ -486,12 +495,19 @@ gst_wl_window_update_borders (GstWlWindow * window) GstWlBuffer *gwlbuf; GstAllocator *alloc; - if (window->no_border_update) - return; + if (window->display->viewporter) { + wp_viewport_set_destination (window->area_viewport, + window->render_rectangle.w, window->render_rectangle.h); + + if (window->is_area_surface_mapped) { + /* The area_surface is already visible and only needed to get resized. + * We don't need to attach a new buffer and are done here. */ + return; + } + } if (window->display->viewporter) { width = height = 1; - window->no_border_update = TRUE; } else { width = window->render_rectangle.w; height = window->render_rectangle.h; @@ -527,6 +543,10 @@ gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, { g_return_if_fail (window != NULL); + if (window->render_rectangle.x == x && window->render_rectangle.y == y && + window->render_rectangle.w == w && window->render_rectangle.h == h) + return; + window->render_rectangle.x = x; window->render_rectangle.y = y; window->render_rectangle.w = w; @@ -536,11 +556,8 @@ gst_wl_window_set_render_rectangle (GstWlWindow * window, gint x, gint y, if (window->area_subsurface) wl_subsurface_set_position (window->area_subsurface, x, y); - /* change the size of the area */ - if (window->area_viewport) - wp_viewport_set_destination (window->area_viewport, w, h); - - gst_wl_window_update_borders (window); + if (window->is_area_surface_mapped) + gst_wl_window_update_borders (window); if (!window->configured) return; diff --git a/subprojects/gst-plugins-bad/ext/wayland/wlwindow.h b/subprojects/gst-plugins-bad/ext/wayland/wlwindow.h index c3f0172..303c336 100644 --- a/subprojects/gst-plugins-bad/ext/wayland/wlwindow.h +++ b/subprojects/gst-plugins-bad/ext/wayland/wlwindow.h @@ -68,10 +68,9 @@ struct _GstWlWindow /* the size of the video in the buffers */ gint video_width, video_height; - /* this will be set when viewporter is available and black background has - * already been set on the area_subsurface */ - gboolean no_border_update; - + /* when this is not set both the area_surface and the video_surface are not + * visible and certain steps should be skipped */ + gboolean is_area_surface_mapped; }; struct _GstWlWindowClass -- 2.7.4