diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build index b76d205b2..8b3d7595a 100644 --- a/hw/xwayland/meson.build +++ b/hw/xwayland/meson.build @@ -48,6 +48,7 @@ xdg_shell_xml = join_paths(protodir, 'stable', 'xdg-shell', 'xdg-shell.xml') drm_lease_xml = join_paths(protodir, 'staging', 'drm-lease', 'drm-lease-v1.xml') shortcuts_inhibit_xml = join_paths(protodir, 'unstable', 'keyboard-shortcuts-inhibit', 'keyboard-shortcuts-inhibit-unstable-v1.xml') xwayland_shell_xml = join_paths(protodir, 'staging', 'xwayland-shell', 'xwayland-shell-v1.xml') +tearing_xml = join_paths(protodir, 'staging', 'tearing-control', 'tearing-control-v1.xml') client_header = generator(scanner, output : '@BASENAME@-client-protocol.h', @@ -76,6 +77,7 @@ srcs += client_header.process(xdg_shell_xml) srcs += client_header.process(drm_lease_xml) srcs += client_header.process(shortcuts_inhibit_xml) srcs += client_header.process(xwayland_shell_xml) +srcs += client_header.process(tearing_xml) srcs += code.process(relative_xml) srcs += code.process(pointer_xml) srcs += code.process(gestures_xml) @@ -88,6 +90,7 @@ srcs += code.process(xdg_shell_xml) srcs += code.process(drm_lease_xml) srcs += code.process(shortcuts_inhibit_xml) srcs += code.process(xwayland_shell_xml) +srcs += code.process(tearing_xml) xwayland_glamor = [] eglstream_srcs = [] diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c index 66d8b4200..42fd0067a 100644 --- a/hw/xwayland/xwayland-present.c +++ b/hw/xwayland/xwayland-present.c @@ -34,8 +34,9 @@ #include "xwayland-pixmap.h" #include "glamor.h" +#include "tearing-control-v1-client-protocol.h" -#define XWL_PRESENT_CAPS PresentCapabilityAsync +#define XWL_PRESENT_CAPS PresentCapabilityAsync | PresentCapabilityAsyncMayTear /* @@ -794,6 +795,16 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage) damage_box->x2 - damage_box->x1, damage_box->y2 - damage_box->y1); + if (xwl_window->tearing_control) { + uint32_t hint; + if (event->async_may_tear) + hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_ASYNC; + else + hint = WP_TEARING_CONTROL_V1_PRESENTATION_HINT_VSYNC; + + wp_tearing_control_v1_set_presentation_hint(xwl_window->tearing_control, hint); + } + wl_surface_commit(xwl_window->surface); if (!vblank->sync_flip) { @@ -997,11 +1008,15 @@ xwl_present_pixmap(WindowPtr window, } vblank->event_id = ++xwl_present_event_id; + event->async_may_tear = options & PresentOptionAsyncMayTear; - /* Xwayland presentations always complete (at least) one frame after they + /* Synchronous Xwayland presentations always complete (at least) one frame after they * are executed */ - vblank->exec_msc = vblank->target_msc - 1; + if (event->async_may_tear) + vblank->exec_msc = vblank->target_msc; + else + vblank->exec_msc = vblank->target_msc - 1; vblank->queued = TRUE; if (crtc_msc < vblank->exec_msc) { diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h index 806272089..4fd1e579f 100644 --- a/hw/xwayland/xwayland-present.h +++ b/hw/xwayland/xwayland-present.h @@ -59,6 +59,7 @@ struct xwl_present_event { present_vblank_rec vblank; PixmapPtr pixmap; + Bool async_may_tear; }; Bool xwl_present_entered_for_each_frame_callback(void); diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c index ac7238b96..41e7393eb 100644 --- a/hw/xwayland/xwayland-screen.c +++ b/hw/xwayland/xwayland-screen.c @@ -60,6 +60,7 @@ #include "viewporter-client-protocol.h" #include "xdg-shell-client-protocol.h" #include "xwayland-shell-v1-client-protocol.h" +#include "tearing-control-v1-client-protocol.h" static DevPrivateKeyRec xwl_screen_private_key; static DevPrivateKeyRec xwl_client_private_key; @@ -458,6 +459,10 @@ registry_global(void *data, struct wl_registry *registry, uint32_t id, xwl_screen->xwayland_shell = wl_registry_bind(registry, id, &xwayland_shell_v1_interface, 1); } + else if (strcmp(interface, "wp_tearing_control_manager_v1") == 0) { + xwl_screen->tearing_control_manager = + wl_registry_bind(registry, id, &wp_tearing_control_manager_v1_interface, 1); + } #ifdef XWL_HAS_GLAMOR else if (xwl_screen->glamor) { xwl_glamor_init_wl_registry(xwl_screen, registry, id, interface, diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h index fadd0526e..da97d7f1d 100644 --- a/hw/xwayland/xwayland-screen.h +++ b/hw/xwayland/xwayland-screen.h @@ -107,6 +107,7 @@ struct xwl_screen { struct zxdg_output_manager_v1 *xdg_output_manager; struct wp_viewporter *viewporter; struct xwayland_shell_v1 *xwayland_shell; + struct wp_tearing_control_manager_v1 *tearing_control_manager; struct xorg_list drm_lease_devices; struct xorg_list queued_drm_lease_devices; struct xorg_list drm_leases; diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c index 67485d1d3..ecf18761d 100644 --- a/hw/xwayland/xwayland-window.c +++ b/hw/xwayland/xwayland-window.c @@ -46,6 +46,7 @@ #include "xwayland-shm.h" #include "linux-dmabuf-unstable-v1-client-protocol.h" +#include "tearing-control-v1-client-protocol.h" #include "viewporter-client-protocol.h" #include "xdg-shell-client-protocol.h" #include "xwayland-shell-v1-client-protocol.h" @@ -896,6 +897,11 @@ ensure_surface_for_window(WindowPtr window) xwl_window_check_resolution_change_emulation(xwl_window); } + if (xwl_screen->tearing_control_manager) { + xwl_window->tearing_control = wp_tearing_control_manager_v1_get_tearing_control( + xwl_screen->tearing_control_manager, xwl_window->surface); + } + return TRUE; err: @@ -1106,6 +1112,9 @@ xwl_unrealize_window(WindowPtr window) xwl_present_for_each_frame_callback(xwl_window, xwl_present_unrealize_window); #endif + if (xwl_window->tearing_control) + wp_tearing_control_v1_destroy(xwl_window->tearing_control); + release_wl_surface_for_window(xwl_window); xorg_list_del(&xwl_window->link_damage); xorg_list_del(&xwl_window->link_window); diff --git a/hw/xwayland/xwayland-window.h b/hw/xwayland/xwayland-window.h index 92c700e41..45ae16da0 100644 --- a/hw/xwayland/xwayland-window.h +++ b/hw/xwayland/xwayland-window.h @@ -121,6 +121,7 @@ struct xwl_window { struct xwl_dmabuf_feedback feedback; /* If TRUE, the window buffer format supports scanout with implicit modifier */ Bool has_implicit_scanout_support; + struct wp_tearing_control_v1 *tearing_control; }; struct xwl_window *xwl_window_get(WindowPtr window);