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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1483>
This commit is contained in:
Robert Mader 2021-12-30 16:52:17 +01:00 committed by GStreamer Marge Bot
parent 6ea56e7fd3
commit e7c9960783
2 changed files with 28 additions and 12 deletions

View file

@ -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_finalize (GObject * gobject);
static void gst_wl_window_update_borders (GstWlWindow * window);
static void static void
handle_xdg_toplevel_close (void *data, struct xdg_toplevel *xdg_toplevel) 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, wl_surface_damage_buffer (window->video_surface_wrapper, 0, 0, G_MAXINT32,
G_MAXINT32); G_MAXINT32);
wl_surface_commit (window->video_surface_wrapper); 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 { } else {
/* clear both video and parent surfaces */ /* clear both video and parent surfaces */
wl_surface_attach (window->video_surface_wrapper, NULL, 0, 0); wl_surface_attach (window->video_surface_wrapper, NULL, 0, 0);
wl_surface_commit (window->video_surface_wrapper); wl_surface_commit (window->video_surface_wrapper);
wl_surface_attach (window->area_surface_wrapper, NULL, 0, 0); wl_surface_attach (window->area_surface_wrapper, NULL, 0, 0);
wl_surface_commit (window->area_surface_wrapper); wl_surface_commit (window->area_surface_wrapper);
window->is_area_surface_mapped = FALSE;
} }
if (G_UNLIKELY (info)) { if (G_UNLIKELY (info)) {
@ -486,12 +495,19 @@ gst_wl_window_update_borders (GstWlWindow * window)
GstWlBuffer *gwlbuf; GstWlBuffer *gwlbuf;
GstAllocator *alloc; GstAllocator *alloc;
if (window->no_border_update) if (window->display->viewporter) {
return; 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) { if (window->display->viewporter) {
width = height = 1; width = height = 1;
window->no_border_update = TRUE;
} else { } else {
width = window->render_rectangle.w; width = window->render_rectangle.w;
height = window->render_rectangle.h; 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); 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.x = x;
window->render_rectangle.y = y; window->render_rectangle.y = y;
window->render_rectangle.w = w; 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) if (window->area_subsurface)
wl_subsurface_set_position (window->area_subsurface, x, y); wl_subsurface_set_position (window->area_subsurface, x, y);
/* change the size of the area */ if (window->is_area_surface_mapped)
if (window->area_viewport) gst_wl_window_update_borders (window);
wp_viewport_set_destination (window->area_viewport, w, h);
gst_wl_window_update_borders (window);
if (!window->configured) if (!window->configured)
return; return;

View file

@ -68,10 +68,9 @@ struct _GstWlWindow
/* the size of the video in the buffers */ /* the size of the video in the buffers */
gint video_width, video_height; gint video_width, video_height;
/* this will be set when viewporter is available and black background has /* when this is not set both the area_surface and the video_surface are not
* already been set on the area_subsurface */ * visible and certain steps should be skipped */
gboolean no_border_update; gboolean is_area_surface_mapped;
}; };
struct _GstWlWindowClass struct _GstWlWindowClass