diff options
author | Dudemanguy <random342@airmail.cc> | 2023-06-03 22:08:36 -0500 |
---|---|---|
committer | Dudemanguy <random342@airmail.cc> | 2023-07-12 19:19:54 +0000 |
commit | c958990833f86747ffe290950495921bf4c73218 (patch) | |
tree | 837dadc54411572a04652caaf098cf7cde10049e /video/out/wayland_common.c | |
parent | 180a3df1f1a807ee79dd97e6883d2318a6285b71 (diff) | |
download | mpv-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.c | 19 |
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); |