summaryrefslogtreecommitdiffstats
path: root/video/out/wayland_common.c
diff options
context:
space:
mode:
authorDudemanguy <random342@airmail.cc>2023-06-03 22:08:36 -0500
committerDudemanguy <random342@airmail.cc>2023-07-12 19:19:54 +0000
commitc958990833f86747ffe290950495921bf4c73218 (patch)
tree837dadc54411572a04652caaf098cf7cde10049e /video/out/wayland_common.c
parent180a3df1f1a807ee79dd97e6883d2318a6285b71 (diff)
downloadmpv-c958990833f86747ffe290950495921bf4c73218.tar.bz2
mpv-c958990833f86747ffe290950495921bf4c73218.tar.xz
vo_dmabuf_wayland: add osd support
This adds osd support via shm buffers using a similar approach that the normal buffers do, but it differs in a few key areas. One thing to note is that sway and weston actually handle this extremely differently which required all the abstractions here. In particular, weston does not cope well with destroying the wl_buffer from shm outside of the release handler at all (i.e. it segfaults). The workaround here is to simply attach a NULL to the osd surface and do a surface commit before we destroy the buffers. This is reasonable enough and seems to work well although it's pretty weird. Sway is more straightforward although it actually releases the osd buffer when the window goes out of sight. Also, I found that it doesn't always release every buffer before you close it unlike weston seems to do which is part of the reason all this bookkeeping is required. I don't know if there's any other compositor out there that can possibly handle vo_dmabuf_wayland right now, but suffering through these two is good enough for now I think.
Diffstat (limited to 'video/out/wayland_common.c')
-rw-r--r--video/out/wayland_common.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index 9d1e8e8784..cecacf5215 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -1257,10 +1257,14 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
wl->compositor = wl_registry_bind(reg, id, &wl_compositor_interface, ver);
wl->surface = wl_compositor_create_surface(wl->compositor);
wl->video_surface = wl_compositor_create_surface(wl->compositor);
- /* never accept input events on the video surface */
+ wl->osd_surface = wl_compositor_create_surface(wl->compositor);
+
+ /* never accept input events on anything besides the main surface */
struct wl_region *region = wl_compositor_create_region(wl->compositor);
+ wl_surface_set_input_region(wl->osd_surface, region);
wl_surface_set_input_region(wl->video_surface, region);
wl_region_destroy(region);
+
wl->cursor_surface = wl_compositor_create_surface(wl->compositor);
wl_surface_add_listener(wl->surface, &surface_listener, wl);
}
@@ -1470,10 +1474,11 @@ static int create_viewports(struct vo_wayland_state *wl)
{
if (wl->viewporter) {
wl->viewport = wp_viewporter_get_viewport(wl->viewporter, wl->surface);
+ wl->osd_viewport = wp_viewporter_get_viewport(wl->viewporter, wl->osd_surface);
wl->video_viewport = wp_viewporter_get_viewport(wl->viewporter, wl->video_surface);
}
- if (wl->viewporter && (!wl->viewport || !wl->video_viewport)) {
+ if (wl->viewporter && (!wl->viewport || !wl->osd_viewport || !wl->video_viewport)) {
MP_ERR(wl, "failed to create viewport interfaces!\n");
return 1;
}
@@ -2206,6 +2211,7 @@ bool vo_wayland_init(struct vo *vo)
goto err;
if (wl->subcompositor) {
+ wl->osd_subsurface = wl_subcompositor_get_subsurface(wl->subcompositor, wl->osd_surface, wl->video_surface);
wl->video_subsurface = wl_subcompositor_get_subsurface(wl->subcompositor, wl->video_surface, wl->surface);
wl_subsurface_set_desync(wl->video_subsurface);
}
@@ -2443,6 +2449,9 @@ void vo_wayland_uninit(struct vo *vo)
if (wl->viewport)
wp_viewport_destroy(wl->viewport);
+ if (wl->osd_viewport)
+ wp_viewport_destroy(wl->osd_viewport);
+
if (wl->video_viewport)
wp_viewport_destroy(wl->video_viewport);
@@ -2466,6 +2475,12 @@ void vo_wayland_uninit(struct vo *vo)
if (wl->surface)
wl_surface_destroy(wl->surface);
+ if (wl->osd_surface)
+ wl_surface_destroy(wl->osd_surface);
+
+ if (wl->osd_subsurface)
+ wl_subsurface_destroy(wl->osd_subsurface);
+
if (wl->video_surface)
wl_surface_destroy(wl->video_surface);