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: 9b31358c52
("xwayland: Use frame callbacks for Present vblank events")
Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
This commit is contained in:
parent
102764b683
commit
9e5a379610
|
@ -66,6 +66,7 @@ xwl_present_window_get_priv(WindowPtr window)
|
||||||
if (!xwl_present_window)
|
if (!xwl_present_window)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
xwl_present_window->window = window;
|
||||||
xwl_present_window->msc = 1;
|
xwl_present_window->msc = 1;
|
||||||
xwl_present_window->ust = GetTimeInMicros();
|
xwl_present_window->ust = GetTimeInMicros();
|
||||||
|
|
||||||
|
@ -127,14 +128,16 @@ xwl_present_has_pending_events(struct xwl_present_window *xwl_present_window)
|
||||||
!xorg_list_is_empty(&xwl_present_window->wait_list);
|
!xorg_list_is_empty(&xwl_present_window->wait_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
|
xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
|
||||||
{
|
{
|
||||||
if (xwl_present_has_pending_events(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 now = GetTimeInMillis();
|
||||||
CARD32 timeout;
|
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;
|
timeout = TIMER_LEN_FLIP;
|
||||||
else
|
else
|
||||||
timeout = TIMER_LEN_COPY;
|
timeout = TIMER_LEN_COPY;
|
||||||
|
@ -505,8 +508,8 @@ xwl_present_queue_vblank(ScreenPtr screen,
|
||||||
xorg_list_del(&event->vblank.event_queue);
|
xorg_list_del(&event->vblank.event_queue);
|
||||||
xorg_list_append(&event->vblank.event_queue, &xwl_present_window->wait_list);
|
xorg_list_append(&event->vblank.event_queue, &xwl_present_window->wait_list);
|
||||||
|
|
||||||
/* If there's a pending frame callback, use that */
|
/* Hook up to frame callback */
|
||||||
if (xwl_window && xwl_window->frame_callback &&
|
if (xwl_window &&
|
||||||
xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
|
xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
|
||||||
xorg_list_add(&xwl_present_window->frame_callback_list,
|
xorg_list_add(&xwl_present_window->frame_callback_list,
|
||||||
&xwl_window->frame_callback_list);
|
&xwl_window->frame_callback_list);
|
||||||
|
@ -700,14 +703,14 @@ xwl_present_flip(WindowPtr present_window,
|
||||||
/* We can flip directly to the main surface (full screen window without clips) */
|
/* We can flip directly to the main surface (full screen window without clips) */
|
||||||
wl_surface_attach(xwl_window->surface, buffer, 0, 0);
|
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)) {
|
if (xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
|
||||||
xorg_list_add(&xwl_present_window->frame_callback_list,
|
xorg_list_add(&xwl_present_window->frame_callback_list,
|
||||||
&xwl_window->frame_callback_list);
|
&xwl_window->frame_callback_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!xwl_window->frame_callback)
|
||||||
|
xwl_window_create_frame_callback(xwl_window);
|
||||||
|
|
||||||
xwl_surface_damage(xwl_window->xwl_screen, xwl_window->surface,
|
xwl_surface_damage(xwl_window->xwl_screen, xwl_window->surface,
|
||||||
damage_box->x1 - present_window->drawable.x,
|
damage_box->x1 - present_window->drawable.x,
|
||||||
damage_box->y1 - present_window->drawable.y,
|
damage_box->y1 - present_window->drawable.y,
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
|
|
||||||
#ifdef GLAMOR_HAS_GBM
|
#ifdef GLAMOR_HAS_GBM
|
||||||
struct xwl_present_window {
|
struct xwl_present_window {
|
||||||
|
WindowPtr window;
|
||||||
|
|
||||||
struct xorg_list frame_callback_list;
|
struct xorg_list frame_callback_list;
|
||||||
|
|
||||||
uint64_t msc;
|
uint64_t msc;
|
||||||
|
@ -59,6 +61,7 @@ struct xwl_present_event {
|
||||||
PixmapPtr pixmap;
|
PixmapPtr pixmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void xwl_present_reset_timer(struct xwl_present_window *xwl_present_window);
|
||||||
void xwl_present_frame_callback(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);
|
Bool xwl_present_init(ScreenPtr screen);
|
||||||
void xwl_present_cleanup(WindowPtr window);
|
void xwl_present_cleanup(WindowPtr window);
|
||||||
|
|
|
@ -765,6 +765,18 @@ xwl_window_create_frame_callback(struct xwl_window *xwl_window)
|
||||||
xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
|
xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
|
||||||
wl_callback_add_listener(xwl_window->frame_callback, &frame_listener,
|
wl_callback_add_listener(xwl_window->frame_callback, &frame_listener,
|
||||||
xwl_window);
|
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
|
Bool
|
||||||
|
|
Loading…
Reference in New Issue