diff options
author | Aaron Boxer <boxerab@protonmail.com> | 2022-05-18 10:35:53 -0400 |
---|---|---|
committer | Dudemanguy <random342@airmail.cc> | 2022-05-24 21:39:34 +0000 |
commit | defb02daa461200f4de972c57c4ac8dc108feb5f (patch) | |
tree | 0f6725f695b3d8be240c71bc1c5e35aacc3fdb8c /video/out/wayland_common.c | |
parent | 9022b1b51dc1204760f9d495e7b3b5550f501bf3 (diff) | |
download | mpv-defb02daa461200f4de972c57c4ac8dc108feb5f.tar.bz2 mpv-defb02daa461200f4de972c57c4ac8dc108feb5f.tar.xz |
vo: add new vaapi-wayland driver
This driver makes use of dmabuffer and viewporter interfaces
to enable efficient display of vaapi surfaces, avoiding
any unnecessary colour space conversion, and avoiding scaling
or colour conversion using GPU shader resources.
Diffstat (limited to 'video/out/wayland_common.c')
-rw-r--r-- | video/out/wayland_common.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index cd97c77bf6..93a44fde7a 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -32,17 +32,21 @@ #include "osdep/timer.h" #include "wayland_common.h" #include "win_state.h" +#include "drm_common.h" // Generated from wayland-protocols #include "generated/wayland/idle-inhibit-unstable-v1.h" #include "generated/wayland/presentation-time.h" #include "generated/wayland/xdg-decoration-unstable-v1.h" #include "generated/wayland/xdg-shell.h" +#include "generated/wayland/linux-dmabuf-unstable-v1.h" +#include "generated/wayland/viewporter.h" #if WAYLAND_VERSION_MAJOR > 1 || WAYLAND_VERSION_MINOR >= 20 #define HAVE_WAYLAND_1_20 #endif + static const struct mp_keymap keymap[] = { /* Special keys */ {XKB_KEY_Pause, MP_KEY_PAUSE}, {XKB_KEY_Escape, MP_KEY_ESC}, @@ -1039,6 +1043,41 @@ static const struct wl_callback_listener frame_listener = { frame_callback, }; +static void dmabuf_format(void *data, + struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format) { + struct vo_wayland_state *wl = data; + + if (wl->drm_format_ct == wl->drm_format_ct_max) { + wl->drm_format_ct_max *= 2; + wl->drm_formats = talloc_realloc(NULL,wl->drm_formats,uint, wl->drm_format_ct_max); + } + wl->drm_formats[wl->drm_format_ct++] = format; + MP_VERBOSE(wl, "%s available\n", drm_format_string(format)); +} + +bool vo_wayland_supported_format(struct vo *vo, uint drm_format) { + struct vo_wayland_state *wl = vo->wl; + + for (uint i = 0; i < wl->drm_format_ct; ++i) { + if (drm_format == wl->drm_formats[i]) + return true; + } + + return false; +} + +/* currently unused */ +static void dmabuf_modifier(void *data, + struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format, + uint32_t modifier_hi, uint32_t modifier_lo) { + +} + +static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = { + dmabuf_format, + dmabuf_modifier +}; + static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id, const char *interface, uint32_t ver) { @@ -1048,10 +1087,34 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id if (!strcmp(interface, wl_compositor_interface.name) && (ver >= 4) && found++) { wl->compositor = wl_registry_bind(reg, id, &wl_compositor_interface, 4); 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 */ + struct wl_region *region = wl_compositor_create_region (wl->compositor); + 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); } + if (!strcmp(interface, wl_subcompositor_interface.name) && (ver >= 1) && found++) { + wl->subcompositor = wl_registry_bind(reg, id, &wl_subcompositor_interface, 1); + wl->video_subsurface = wl_subcompositor_get_subsurface(wl->subcompositor, wl->video_surface, wl->surface); + wl_subsurface_set_desync (wl->video_subsurface); + } + + if (!strcmp (interface, zwp_linux_dmabuf_v1_interface.name) && (ver >= 2) && found++) { + wl->dmabuf = wl_registry_bind (reg, id, &zwp_linux_dmabuf_v1_interface, 2); + zwp_linux_dmabuf_v1_add_listener (wl->dmabuf, &dmabuf_listener, wl); + wl->drm_format_ct_max = 64; + wl->drm_formats = talloc_array(NULL,uint,wl->drm_format_ct_max); + } + + if (!strcmp (interface, wp_viewporter_interface.name) && (ver >= 1) && found++) { + wl->viewporter = wl_registry_bind (reg, id, &wp_viewporter_interface, 1); + wl->viewport = wp_viewporter_get_viewport (wl->viewporter, wl->surface); + wl->video_viewport = wp_viewporter_get_viewport (wl->viewporter,wl->video_surface); + } + if (!strcmp(interface, wl_data_device_manager_interface.name) && (ver >= 3) && found++) { wl->dnd_devman = wl_registry_bind(reg, id, &wl_data_device_manager_interface, 3); } @@ -1938,6 +2001,9 @@ void vo_wayland_uninit(struct vo *vo) if (wl->compositor) wl_compositor_destroy(wl->compositor); + if (wl->subcompositor) + wl_subcompositor_destroy(wl->subcompositor); + if (wl->current_output && wl->current_output->output) wl_output_destroy(wl->current_output->output); @@ -1980,6 +2046,18 @@ void vo_wayland_uninit(struct vo *vo) if (wl->registry) wl_registry_destroy(wl->registry); + if (wl->viewporter) + wp_viewporter_destroy (wl->viewporter); + + if (wl->viewport) + wp_viewport_destroy (wl->viewport); + + if (wl->video_viewport) + wp_viewport_destroy (wl->video_viewport); + + if (wl->dmabuf) + zwp_linux_dmabuf_v1_destroy (wl->dmabuf); + if (wl->seat) wl_seat_destroy(wl->seat); @@ -1989,6 +2067,12 @@ void vo_wayland_uninit(struct vo *vo) if (wl->surface) wl_surface_destroy(wl->surface); + if (wl->video_surface) + wl_surface_destroy(wl->video_surface); + + if (wl->video_subsurface) + wl_subsurface_destroy(wl->video_subsurface); + if (wl->wm_base) xdg_wm_base_destroy(wl->wm_base); @@ -2022,6 +2106,8 @@ void vo_wayland_uninit(struct vo *vo) wl_list_for_each_safe(output, tmp, &wl->output_list, link) remove_output(output); + talloc_free(wl->drm_formats); + talloc_free(wl->dnd_mime_type); for (int n = 0; n < 2; n++) |