diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwldisplay.c b/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwldisplay.c index 1550f11bd8..1ec9fb79ea 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwldisplay.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwldisplay.c @@ -26,6 +26,7 @@ #include "fullscreen-shell-unstable-v1-client-protocol.h" #include "linux-dmabuf-unstable-v1-client-protocol.h" +#include "single-pixel-buffer-v1-client-protocol.h" #include "viewporter-client-protocol.h" #include "xdg-shell-client-protocol.h" @@ -48,6 +49,7 @@ typedef struct _GstWlDisplayPrivate struct wl_subcompositor *subcompositor; struct xdg_wm_base *xdg_wm_base; struct zwp_fullscreen_shell_v1 *fullscreen_shell; + struct wp_single_pixel_buffer_manager_v1 *single_pixel_buffer; struct wl_shm *shm; struct wp_viewporter *viewporter; struct zwp_linux_dmabuf_v1 *dmabuf; @@ -146,6 +148,9 @@ gst_wl_display_finalize (GObject * gobject) if (priv->fullscreen_shell) zwp_fullscreen_shell_v1_release (priv->fullscreen_shell); + if (priv->single_pixel_buffer) + wp_single_pixel_buffer_manager_v1_destroy (priv->single_pixel_buffer); + if (priv->compositor) wl_compositor_destroy (priv->compositor); @@ -323,6 +328,10 @@ registry_handle_global (void *data, struct wl_registry *registry, priv->dmabuf = wl_registry_bind (registry, id, &zwp_linux_dmabuf_v1_interface, 3); zwp_linux_dmabuf_v1_add_listener (priv->dmabuf, &dmabuf_listener, self); + } else if (g_strcmp0 (interface, "wp_single_pixel_buffer_manager_v1") == 0) { + priv->single_pixel_buffer = + wl_registry_bind (registry, id, + &wp_single_pixel_buffer_manager_v1_interface, 1); } } @@ -610,6 +619,14 @@ gst_wl_display_get_dmabuf_formats (GstWlDisplay * self) return priv->dmabuf_formats; } +struct wp_single_pixel_buffer_manager_v1 * +gst_wl_display_get_single_pixel_buffer_manager_v1 (GstWlDisplay * self) +{ + GstWlDisplayPrivate *priv = gst_wl_display_get_instance_private (self); + + return priv->single_pixel_buffer; +} + gboolean gst_wl_display_has_own_display (GstWlDisplay * self) { diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwldisplay.h b/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwldisplay.h index ea35e3fcef..e9b32c65f1 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwldisplay.h +++ b/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwldisplay.h @@ -99,6 +99,9 @@ GArray *gst_wl_display_get_dmabuf_modifiers (GstWlDisplay * self); GST_WL_API struct zwp_linux_dmabuf_v1 *gst_wl_display_get_dmabuf_v1 (GstWlDisplay * self); +GST_WL_API +struct wp_single_pixel_buffer_manager_v1 * gst_wl_display_get_single_pixel_buffer_manager_v1 (GstWlDisplay * self); + GST_WL_API gboolean gst_wl_display_has_own_display (GstWlDisplay * self); diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwlwindow.c b/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwlwindow.c index da5300facd..1a129bc44f 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwlwindow.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/wayland/gstwlwindow.c @@ -27,6 +27,7 @@ #include "gstwlwindow.h" #include "fullscreen-shell-unstable-v1-client-protocol.h" +#include "single-pixel-buffer-v1-client-protocol.h" #include "viewporter-client-protocol.h" #include "xdg-shell-client-protocol.h" @@ -553,13 +554,11 @@ static void gst_wl_window_update_borders (GstWlWindow * self) { GstWlWindowPrivate *priv = gst_wl_window_get_instance_private (self); - GstVideoFormat format; - GstVideoInfo info; gint width, height; GstBuffer *buf; struct wl_buffer *wlbuf; + struct wp_single_pixel_buffer_manager_v1 *single_pixel; GstWlBuffer *gwlbuf; - GstAllocator *alloc; if (gst_wl_display_get_viewporter (priv->display)) { wp_viewport_set_destination (priv->area_viewport, @@ -579,19 +578,34 @@ gst_wl_window_update_borders (GstWlWindow * self) height = priv->render_rectangle.h; } - /* we want WL_SHM_FORMAT_XRGB8888 */ - format = GST_VIDEO_FORMAT_BGRx; - /* draw the area_subsurface */ - gst_video_info_set_format (&info, format, width, height); + single_pixel = + gst_wl_display_get_single_pixel_buffer_manager_v1 (priv->display); + if (width == 1 && height == 1 && single_pixel) { + buf = gst_buffer_new_allocate (NULL, 1, NULL); + wlbuf = + wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer (single_pixel, + 0, 0, 0, 0xffffffffU); + } else { + GstVideoFormat format; + GstVideoInfo info; + GstAllocator *alloc; - alloc = gst_shm_allocator_get (); + /* we want WL_SHM_FORMAT_XRGB8888 */ + format = GST_VIDEO_FORMAT_BGRx; + gst_video_info_set_format (&info, format, width, height); + alloc = gst_shm_allocator_get (); + + buf = gst_buffer_new_allocate (alloc, info.size, NULL); + gst_buffer_memset (buf, 0, 0, info.size); + + wlbuf = + gst_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf, 0), + priv->display, &info); + + g_object_unref (alloc); + } - buf = gst_buffer_new_allocate (alloc, info.size, NULL); - gst_buffer_memset (buf, 0, 0, info.size); - wlbuf = - gst_wl_shm_memory_construct_wl_buffer (gst_buffer_peek_memory (buf, 0), - priv->display, &info); gwlbuf = gst_buffer_add_wl_buffer (buf, wlbuf, priv->display); gst_wl_buffer_attach (gwlbuf, priv->area_surface_wrapper); wl_surface_damage_buffer (priv->area_surface_wrapper, 0, 0, G_MAXINT32, @@ -600,7 +614,6 @@ gst_wl_window_update_borders (GstWlWindow * self) /* at this point, the GstWlBuffer keeps the buffer * alive and will free it on wl_buffer::release */ gst_buffer_unref (buf); - g_object_unref (alloc); } static void diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/wayland/meson.build b/subprojects/gst-plugins-bad/gst-libs/gst/wayland/meson.build index 186a717802..88be46eba1 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/wayland/meson.build +++ b/subprojects/gst-plugins-bad/gst-libs/gst/wayland/meson.build @@ -1,6 +1,7 @@ wl_req = '>= 1.15' wl_client_dep = dependency('wayland-client', version: wl_req, required: get_option('wayland')) libdrm_dep = dependency('libdrm', version: '>= 2.4.98', required: get_option('wayland')) +wl_proto_req = '>= 1.26' wl_protocol_dep = dependency('wayland-protocols', version: wl_req, required: get_option('wayland')) wl_scanner = find_program('wayland-scanner', required: get_option('wayland')) # Also used in ext/wayland @@ -38,7 +39,8 @@ if use_wayland ['viewporter', 'stable', ], ['linux-dmabuf', 'unstable', 'v1', ], ['fullscreen-shell', 'unstable', 'v1', ], - ['xdg-shell', 'stable', ] + ['xdg-shell', 'stable', ], + ['single-pixel-buffer', 'staging', 'v1' ], ] protocols_files = [] diff --git a/subprojects/wayland-protocols.wrap b/subprojects/wayland-protocols.wrap new file mode 100644 index 0000000000..ee9ee73373 --- /dev/null +++ b/subprojects/wayland-protocols.wrap @@ -0,0 +1,10 @@ +[wrap-file] +directory = wayland-protocols-1.32 +source_url = https://gitlab.freedesktop.org/wayland/wayland-protocols/-/releases/1.32/downloads/wayland-protocols-1.32.tar.xz +source_filename = wayland-protocols-1.32.tar.xz +source_hash = 7459799d340c8296b695ef857c07ddef24c5a09b09ab6a74f7b92640d2b1ba11 +source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/wayland-protocols_1.32-1/wayland-protocols-1.32.tar.xz +wrapdb_version = 1.32-1 + +[provide] +wayland-protocols = wayland_protocols