From 7d86807a5f71989e944269fa430f36f2f32b1d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Wed, 8 Nov 2023 22:49:17 -0600 Subject: [PATCH] vo: don't sleep 1ms always when requested time is in the past Fixes a899e14b which changed clamp from 0 to 1 ms which effectivelly introduced 1ms sleep always, even if requested until_time_ns is in the past and should request 0 timeout. While at it also fix mp_poll wrapper to respect negative timeout which should mean infinite wait. Also keep the 37d6604 behaviour for very short timeouts, but round only the ones > 100us, anything else is 0. Fixes: a899e14b --- osdep/poll_wrapper.c | 11 +++++++++-- video/out/drm_common.c | 2 +- video/out/vo_sdl.c | 5 ++++- video/out/wayland_common.c | 2 +- video/out/x11_common.c | 2 +- 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/osdep/poll_wrapper.c b/osdep/poll_wrapper.c index 9f8885fd1c..3fe039b4c1 100644 --- a/osdep/poll_wrapper.c +++ b/osdep/poll_wrapper.c @@ -20,6 +20,7 @@ #include #include +#include "common/common.h" #include "config.h" #include "poll_wrapper.h" #include "timer.h" @@ -31,9 +32,15 @@ int mp_poll(struct pollfd *fds, int nfds, int64_t timeout_ns) struct timespec ts; ts.tv_sec = timeout_ns / MP_TIME_S_TO_NS(1); ts.tv_nsec = timeout_ns % MP_TIME_S_TO_NS(1); - return ppoll(fds, nfds, &ts, NULL); + struct timespec *tsp = timeout_ns >= 0 ? &ts : NULL; + return ppoll(fds, nfds, tsp, NULL); #endif - return poll(fds, nfds, timeout_ns / 1e6); + // Round-up to 1ms for short timeouts (100us, 1000us] + if (timeout_ns > MP_TIME_US_TO_NS(100)) + timeout_ns = MPMAX(timeout_ns, MP_TIME_MS_TO_NS(1)); + if (timeout_ns > 0) + timeout_ns /= MP_TIME_MS_TO_NS(1); + return poll(fds, nfds, timeout_ns); } // poll shim that supports device files on macOS. diff --git a/video/out/drm_common.c b/video/out/drm_common.c index aeb0bbde52..da45ca27a3 100644 --- a/video/out/drm_common.c +++ b/video/out/drm_common.c @@ -1257,7 +1257,7 @@ void vo_drm_wait_events(struct vo *vo, int64_t until_time_ns) struct vo_drm_state *drm = vo->drm; if (drm->vt_switcher_active) { int64_t wait_ns = until_time_ns - mp_time_ns(); - int64_t timeout_ns = MPCLAMP(wait_ns, 1e6, 1e10); + int64_t timeout_ns = MPCLAMP(wait_ns, 0, MP_TIME_S_TO_NS(10)); vt_switcher_poll(&drm->vt_switcher, timeout_ns); } else { vo_wait_default(vo, until_time_ns); diff --git a/video/out/vo_sdl.c b/video/out/vo_sdl.c index e101f8d620..b6069c7ecc 100644 --- a/video/out/vo_sdl.c +++ b/video/out/vo_sdl.c @@ -523,7 +523,10 @@ static void wakeup(struct vo *vo) static void wait_events(struct vo *vo, int64_t until_time_ns) { int64_t wait_ns = until_time_ns - mp_time_ns(); - int timeout_ms = MPCLAMP(wait_ns / 1e6, 1, 10000); + // Round-up to 1ms for short timeouts (100us, 1000us] + if (wait_ns > MP_TIME_US_TO_NS(100)) + wait_ns = MPMAX(wait_ns, MP_TIME_MS_TO_NS(1)); + int timeout_ms = MPCLAMP(wait_ns / MP_TIME_MS_TO_NS(1), 0, 10000); SDL_Event ev; while (SDL_WaitEventTimeout(&ev, timeout_ms)) { diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 0ee49541ed..ca1d17bb2d 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -2611,7 +2611,7 @@ void vo_wayland_wait_events(struct vo *vo, int64_t until_time_ns) struct vo_wayland_state *wl = vo->wl; int64_t wait_ns = until_time_ns - mp_time_ns(); - int64_t timeout_ns = MPCLAMP(wait_ns, 1e6, 1e10); + int64_t timeout_ns = MPCLAMP(wait_ns, 0, MP_TIME_S_TO_NS(10)); wayland_dispatch_events(wl, 2, timeout_ns); } diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 9be2e9b93d..b4605bfd0b 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -2178,7 +2178,7 @@ void vo_x11_wait_events(struct vo *vo, int64_t until_time_ns) { .fd = x11->wakeup_pipe[0], .events = POLLIN }, }; int64_t wait_ns = until_time_ns - mp_time_ns(); - int64_t timeout_ns = MPCLAMP(wait_ns, 1e6, 1e10); + int64_t timeout_ns = MPCLAMP(wait_ns, 0, MP_TIME_S_TO_NS(10)); mp_poll(fds, 2, timeout_ns);