summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <mdaenzer@redhat.com>2022-03-15 17:47:56 +0100
committerOlivier Fourdan <fourdan@gmail.com>2022-07-20 14:41:01 +0000
commitb97c7c78c544a0cb0684a154a17c59d8c89be4a6 (patch)
treed295815901b9562ad48229916ad3940dc63f8436
parentbd134231e282d9eb126b6fdaa40bb383180fa72b (diff)
downloadxserver-b97c7c78c544a0cb0684a154a17c59d8c89be4a6.tar.gz
xwayland: Always hook up frame_callback_list in xwl_present_queue_vblank
Even if there's no pending frame callback yet. Without this, if there was no pending frame callback yet in xwl_present_queue_vblank, xwl_present_msc_bump would only get called from xwl_present_timer_callback, resulting in the MSC ticking at ~58 Hertz. Doing this requires some adjustments elsewhere: 1. xwl_present_reset_timer needs to check for a pending frame callback as well. 2. xwl_window_create_frame_callback needs to call xwl_present_reset_timer for all child windows hooked up to frame_callback_list, to make sure the timer length takes the pending frame callback into account. 3. xwl_present_flip needs to hook up the window to frame_callback_list before calling xwl_window_create_frame_callback, for 2. to work. Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1309 Fixes: 9b31358c52e9 ("xwayland: Use frame callbacks for Present vblank events") Reviewed-by: Olivier Fourdan <ofourdan@redhat.com> (cherry picked from commit 9e5a3796108e2b89212fa440f80e918d24b971c8)
-rw-r--r--hw/xwayland/xwayland-present.c16
-rw-r--r--hw/xwayland/xwayland-present.h1
-rw-r--r--hw/xwayland/xwayland-window.c12
3 files changed, 22 insertions, 7 deletions
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 1a99228a1..7ae13e649 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -98,14 +98,16 @@ xwl_present_has_pending_events(struct xwl_present_window *xwl_present_window)
!xorg_list_is_empty(&xwl_present_window->wait_list);
}
-static void
+void
xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
{
if (xwl_present_has_pending_events(xwl_present_window)) {
+ struct xwl_window *xwl_window = xwl_window_from_window(xwl_present_window->window);
CARD32 now = GetTimeInMillis();
CARD32 timeout;
- if (!xorg_list_is_empty(&xwl_present_window->frame_callback_list))
+ if (xwl_window && xwl_window->frame_callback &&
+ !xorg_list_is_empty(&xwl_present_window->frame_callback_list))
timeout = TIMER_LEN_FLIP;
else
timeout = TIMER_LEN_COPY;
@@ -359,8 +361,8 @@ xwl_present_queue_vblank(WindowPtr present_window,
xorg_list_append(&event->list, &xwl_present_window->wait_list);
- /* If there's a pending frame callback, use that */
- if (xwl_window && xwl_window->frame_callback &&
+ /* Hook up to frame callback */
+ if (xwl_window &&
xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
xorg_list_add(&xwl_present_window->frame_callback_list,
&xwl_window->frame_callback_list);
@@ -495,9 +497,6 @@ xwl_present_flip(WindowPtr present_window,
/* We can flip directly to the main surface (full screen window without clips) */
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
- if (!xwl_window->frame_callback)
- xwl_window_create_frame_callback(xwl_window);
-
if (xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
xorg_list_add(&xwl_present_window->frame_callback_list,
&xwl_window->frame_callback_list);
@@ -506,6 +505,9 @@ xwl_present_flip(WindowPtr present_window,
/* Realign timer */
xwl_present_reset_timer(xwl_present_window);
+ if (!xwl_window->frame_callback)
+ xwl_window_create_frame_callback(xwl_window);
+
xwl_surface_damage(xwl_window->xwl_screen, xwl_window->surface,
damage_box->x1 - present_window->drawable.x,
damage_box->y1 - present_window->drawable.y,
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index 40bd79459..ce91f557b 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -64,6 +64,7 @@ struct xwl_present_event {
struct xorg_list list;
};
+void xwl_present_reset_timer(struct xwl_present_window *xwl_present_window);
void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window);
Bool xwl_present_init(ScreenPtr screen);
void xwl_present_cleanup(WindowPtr window);
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 92bcae326..41061e344 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -765,6 +765,18 @@ xwl_window_create_frame_callback(struct xwl_window *xwl_window)
xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
wl_callback_add_listener(xwl_window->frame_callback, &frame_listener,
xwl_window);
+
+#ifdef GLAMOR_HAS_GBM
+ if (xwl_window->xwl_screen->present) {
+ struct xwl_present_window *xwl_present_window, *tmp;
+
+ xorg_list_for_each_entry_safe(xwl_present_window, tmp,
+ &xwl_window->frame_callback_list,
+ frame_callback_list) {
+ xwl_present_reset_timer(xwl_present_window);
+ }
+ }
+#endif
}
Bool