From 092a20d9455ab5d2bdb4102ba5c91cd7a901bc38 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Sun, 8 Aug 2021 16:47:34 -0500 Subject: [PATCH] wayland: Avoid busy waiting for vsync --- src/video/wayland/SDL_waylandopengles.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/video/wayland/SDL_waylandopengles.c b/src/video/wayland/SDL_waylandopengles.c index 874da8ea2..f4beb8b6f 100644 --- a/src/video/wayland/SDL_waylandopengles.c +++ b/src/video/wayland/SDL_waylandopengles.c @@ -130,14 +130,28 @@ Wayland_GLES_SwapWindow(_THIS, SDL_Window *window) struct wl_display *display = ((SDL_VideoData *)_this->driverdata)->display; SDL_VideoDisplay *sdldisplay = SDL_GetDisplayForWindow(window); const Uint32 max_wait = SDL_GetTicks() + (10000 / sdldisplay->current_mode.refresh_rate); /* ~10 frames, so we'll progress even if throttled to zero. */ - while ((SDL_AtomicGet(&data->swap_interval_ready) == 0) && (!SDL_TICKS_PASSED(SDL_GetTicks(), max_wait))) { + while (SDL_AtomicGet(&data->swap_interval_ready) == 0) { + Uint32 now; + /* !!! FIXME: this is just the crucial piece of Wayland_PumpEvents */ WAYLAND_wl_display_flush(display); - if (SDL_IOReady(WAYLAND_wl_display_get_fd(display), SDL_FALSE, 0)) { - WAYLAND_wl_display_dispatch(display); - } else { - WAYLAND_wl_display_dispatch_pending(display); + if (WAYLAND_wl_display_dispatch_pending(display) > 0) { + /* We dispatched some pending events. Check if the frame callback happened. */ + continue; } + + now = SDL_GetTicks(); + if (SDL_TICKS_PASSED(now, max_wait)) { + /* Timeout expired */ + break; + } + + if (SDL_IOReady(WAYLAND_wl_display_get_fd(display), SDL_FALSE, max_wait - now) <= 0) { + /* Error or timeout expired without any events for us */ + break; + } + + WAYLAND_wl_display_dispatch(display); } SDL_AtomicSet(&data->swap_interval_ready, 0); }