xwayland: Use single frame callback for Present flips and normal updates

Using a list of Present windows that need to be called back.

This prepares for the following change, there should be no change in
observed behaviour.

v2:
* Use xwl_window_create_frame_callback instead of making the
  frame_listener struct non-static (Olivier Fourdan)

Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>
(cherry picked from commit c5067feaee)
This commit is contained in:
Michel Dänzer 2019-11-27 18:04:06 +01:00 committed by Michel Dänzer
parent 915cc10776
commit 99a6d6b15e
3 changed files with 39 additions and 31 deletions

View File

@ -60,6 +60,7 @@ xwl_present_window_get_priv(WindowPtr window)
xwl_present_window->msc = 1; xwl_present_window->msc = 1;
xwl_present_window->ust = GetTimeInMicros(); xwl_present_window->ust = GetTimeInMicros();
xorg_list_init(&xwl_present_window->frame_callback_list);
xorg_list_init(&xwl_present_window->event_list); xorg_list_init(&xwl_present_window->event_list);
xorg_list_init(&xwl_present_window->release_queue); xorg_list_init(&xwl_present_window->release_queue);
@ -96,7 +97,7 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
if (xwl_present_has_events(xwl_present_window)) { if (xwl_present_has_events(xwl_present_window)) {
CARD32 timeout; CARD32 timeout;
if (xwl_present_window->frame_callback) if (!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;
@ -119,10 +120,7 @@ xwl_present_cleanup(WindowPtr window)
if (!xwl_present_window) if (!xwl_present_window)
return; return;
if (xwl_present_window->frame_callback) { xorg_list_del(&xwl_present_window->frame_callback_list);
wl_callback_destroy(xwl_present_window->frame_callback);
xwl_present_window->frame_callback = NULL;
}
if (xwl_present_window->sync_callback) { if (xwl_present_window->sync_callback) {
wl_callback_destroy(xwl_present_window->sync_callback); wl_callback_destroy(xwl_present_window->sync_callback);
@ -252,15 +250,10 @@ xwl_present_timer_callback(OsTimerPtr timer,
return 0; return 0;
} }
static void void
xwl_present_frame_callback(void *data, xwl_present_frame_callback(struct xwl_present_window *xwl_present_window)
struct wl_callback *callback,
uint32_t time)
{ {
struct xwl_present_window *xwl_present_window = data; xorg_list_del(&xwl_present_window->frame_callback_list);
wl_callback_destroy(xwl_present_window->frame_callback);
xwl_present_window->frame_callback = NULL;
if (xwl_present_window->frame_timer_firing) { if (xwl_present_window->frame_timer_firing) {
/* If the timer is firing, this frame callback is too late */ /* If the timer is firing, this frame callback is too late */
@ -275,10 +268,6 @@ xwl_present_frame_callback(void *data,
xwl_present_reset_timer(xwl_present_window); xwl_present_reset_timer(xwl_present_window);
} }
static const struct wl_callback_listener xwl_present_frame_listener = {
xwl_present_frame_callback
};
static void static void
xwl_present_sync_callback(void *data, xwl_present_sync_callback(void *data,
struct wl_callback *callback, struct wl_callback *callback,
@ -488,11 +477,12 @@ 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_present_window->frame_callback) { if (!xwl_window->frame_callback)
xwl_present_window->frame_callback = wl_surface_frame(xwl_window->surface); xwl_window_create_frame_callback(xwl_window);
wl_callback_add_listener(xwl_present_window->frame_callback,
&xwl_present_frame_listener, if (xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
xwl_present_window); xorg_list_add(&xwl_present_window->frame_callback_list,
&xwl_window->frame_callback_list);
} }
/* Realign timer */ /* Realign timer */
@ -532,14 +522,14 @@ xwl_present_unrealize_window(WindowPtr window)
{ {
struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window); struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
if (!xwl_present_window || !xwl_present_window->frame_callback) if (!xwl_present_window ||
xorg_list_is_empty(&xwl_present_window->frame_callback_list))
return; return;
/* The pending frame callback may never be called, so drop it and shorten /* The pending frame callback may never be called, so drop it and shorten
* the frame timer interval. * the frame timer interval.
*/ */
wl_callback_destroy(xwl_present_window->frame_callback); xorg_list_del(&xwl_present_window->frame_callback_list);
xwl_present_window->frame_callback = NULL;
xwl_present_reset_timer(xwl_present_window); xwl_present_reset_timer(xwl_present_window);
} }

View File

@ -600,6 +600,10 @@ ensure_surface_for_window(WindowPtr window)
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window); dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window);
xorg_list_init(&xwl_window->link_damage); xorg_list_init(&xwl_window->link_damage);
#ifdef GLAMOR_HAS_GBM
xorg_list_init(&xwl_window->frame_callback_list);
#endif
xwl_window_init_allow_commits(xwl_window); xwl_window_init_allow_commits(xwl_window);
return TRUE; return TRUE;
@ -684,11 +688,6 @@ xwl_unrealize_window(WindowPtr window)
xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
screen->UnrealizeWindow = xwl_unrealize_window; screen->UnrealizeWindow = xwl_unrealize_window;
#ifdef GLAMOR_HAS_GBM
if (xwl_screen->present)
xwl_present_unrealize_window(window);
#endif
xwl_window = xwl_window_get(window); xwl_window = xwl_window_get(window);
if (!xwl_window) if (!xwl_window)
return ret; return ret;
@ -700,6 +699,11 @@ xwl_unrealize_window(WindowPtr window)
if (xwl_window->frame_callback) if (xwl_window->frame_callback)
wl_callback_destroy(xwl_window->frame_callback); wl_callback_destroy(xwl_window->frame_callback);
#ifdef GLAMOR_HAS_GBM
if (xwl_screen->present)
xwl_present_unrealize_window(window);
#endif
free(xwl_window); free(xwl_window);
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL); dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
@ -741,6 +745,18 @@ frame_callback(void *data,
wl_callback_destroy (xwl_window->frame_callback); wl_callback_destroy (xwl_window->frame_callback);
xwl_window->frame_callback = NULL; xwl_window->frame_callback = NULL;
#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_frame_callback(xwl_present_window);
}
}
#endif
} }
static const struct wl_callback_listener frame_listener = { static const struct wl_callback_listener frame_listener = {

View File

@ -183,6 +183,7 @@ struct xwl_window {
struct wl_callback *frame_callback; struct wl_callback *frame_callback;
Bool allow_commits; Bool allow_commits;
#ifdef GLAMOR_HAS_GBM #ifdef GLAMOR_HAS_GBM
struct xorg_list frame_callback_list;
Bool present_flipped; Bool present_flipped;
#endif #endif
}; };
@ -192,7 +193,7 @@ struct xwl_present_window {
struct xwl_screen *xwl_screen; struct xwl_screen *xwl_screen;
struct xwl_present_event *sync_flip; struct xwl_present_event *sync_flip;
WindowPtr window; WindowPtr window;
struct xorg_list link; struct xorg_list frame_callback_list;
uint64_t msc; uint64_t msc;
uint64_t ust; uint64_t ust;
@ -454,6 +455,7 @@ Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen); void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
#ifdef GLAMOR_HAS_GBM #ifdef GLAMOR_HAS_GBM
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);
void xwl_present_unrealize_window(WindowPtr window); void xwl_present_unrealize_window(WindowPtr window);