summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDudemanguy <random342@airmail.cc>2020-02-06 23:54:57 -0600
committerDudemanguy <random342@airmail.cc>2020-02-07 18:33:32 +0000
commitaf021a289169ae215ab8443634ff26fd1c79ad36 (patch)
treeb07df7f7ce02c467b2d0363f8bfaf0b6c30dec83
parentc4570be3b8b3428efb7ab70ec6875032d00ed95b (diff)
downloadmpv-af021a289169ae215ab8443634ff26fd1c79ad36.tar.bz2
mpv-af021a289169ae215ab8443634ff26fd1c79ad36.tar.xz
wayland: adjust vo_wayland_wait_frame logic
Wayland uses vo_wayland_wait_frame plus some polling with a timeout for blocking on vsync. Here are a couple of changes that seem to be improvements. First, the poll time is always rounded up instead of truncated. When rendering frames longer than the standard 16.666 ms timeout, it seems that truncating the poll time slightly early may cause some vsync jitter spikes. Waiting longer, even if it's too long, appears to behave better. The second change is to use wl_display_roundtrip instead of wl_display_dispatch_pending. wl_display_dispatch_pending dispatches all events immediately. This is good to avoid blocking, but it's not guaranteed to wait long enough for all events to be processed on the display fd. The preceding wl_display_read_events routine ensures that all events on the display fd are queued. We just need a semi-blocking routine to dispatch them for the most reliable vsync. wl_display_roundtrip will dispatch any events for us, but also wait for a reply from the display server. This makes it ideal for this role. If the compositor doesn't reply to the client something else is probably horribly broken and wrong anyway. It's also not a permanently blocking call like wl_display_dispatch. If there's no frame callback (i.e. the window is hidden), then it does not dispatch any events and returns immediately.
-rw-r--r--video/out/wayland_common.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index 73949f4555..d42758a7bc 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -1609,19 +1609,19 @@ void vo_wayland_wait_frame(struct vo_wayland_state *wl)
while (wl->frame_wait && finish_time > mp_time_us()) {
- while (wl_display_prepare_read(wl->display) != 0)
- wl_display_dispatch_pending(wl->display);
- wl_display_flush(wl->display);
-
- int poll_time = (finish_time - mp_time_us()) / 1000;
+ int poll_time = ceil((double)(finish_time - mp_time_us()) / 1000);
if (poll_time < 0) {
poll_time = 0;
}
+ while (wl_display_prepare_read(wl->display) != 0)
+ wl_display_dispatch_pending(wl->display);
+ wl_display_flush(wl->display);
+
poll(fds, 1, poll_time);
wl_display_read_events(wl->display);
- wl_display_dispatch_pending(wl->display);
+ wl_display_roundtrip(wl->display);
}
if (wl->frame_wait) {