summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordudemanguy <random342@airmail.cc>2019-12-05 13:03:16 -0600
committerDudemanguy <random342@airmail.cc>2019-12-10 17:55:43 +0000
commitc68251a3a72f8284e6cb7808a57e2e5137376c3a (patch)
tree590093e08bcbce4d6a375e023771171a4e4e85c2
parent59b0fec5089962f65aa2232d1d4aa44524a5a5cb (diff)
downloadmpv-c68251a3a72f8284e6cb7808a57e2e5137376c3a.tar.bz2
mpv-c68251a3a72f8284e6cb7808a57e2e5137376c3a.tar.xz
wayland: adjust hidden state detection
The wayland backend needs to keep track of whether or not a window is hidden for presentation time. There is no presentation feedback when a window is hidden which means we shouldn't be sending information to the vo_sync_info structure (i.e. just leave it all at -1). This seemed to work fine, but recent changes to presentation time in one notable compositor (Sway; it was probably always broken in Weston actually) changed the presentation time behavior. For reasons that aren't clear, there is a greater than 16.666ms delay between the first presentation time event and the second presentation time event (compositor latency?) when you switch back to an mpv window after it is hidden for long enough (a few seconds). When using presentation time, this causes mpv to feed in some bad values in its vsync timing mechanism thus causing the A/V desync spike as described in issue #7223. This solution is not really ideal. It would be better if the presentation time events received by the compositors did not have the aforementioned inconsistency. However since this occurs in both Sway and Weston and clients can't really fight compositors in wayland-world, here's a reasonable enough workaround. Basically, just add a slight delay before we start feeding information into the vo_sync_info again. We already do this when the window is hidden, so it's not a huge leap. The delay chosen here is arbitrary, and it basically just recycles the same parameters used to detect if a window is hidden. If vo_wayland_wait_frame times out 60 times in a row (or whatever your monitor's refresh rate is), then we assume the window is hidden. This is a pretty safe assumption; something has to be terribly wrong for you to miss 60 vblanks in a row while a window is on the screen. In this case, we basically just do the reverse of that. If mpv receives 60 frame callbacks in a row (or whatever your monitor's refresh rate is), then it assumes the window is not hidden. Previously, as soon as it received 1 frame callback it was declared not hidden. Essentially, there's just 1 second of delay after reshowing a window before the presentation time statistics are used again. This should be more than enough time to skip over the weird inconsistent behavior presentation time behavior and avoid the A/V desync spike. Fixes #7223
-rw-r--r--video/out/wayland_common.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index dd20432394..41c2d1ac22 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -1613,14 +1613,24 @@ void vo_wayland_wait_frame(struct vo_wayland_state *wl, int frame_offset)
}
if (wl->frame_wait) {
- wl->timeout_count += 1;
+ if (!wl->hidden) {
+ wl->timeout_count += 1;
+ } else {
+ wl->timeout_count = 0;
+ }
} else {
- wl->timeout_count = 0;
- wl->hidden = false;
+ if (wl->hidden) {
+ wl->timeout_count -= 1;
+ } else {
+ wl->timeout_count = 0;
+ }
}
- if (wl->timeout_count > wl->current_output->refresh_rate)
+ if (wl->timeout_count > wl->current_output->refresh_rate) {
wl->hidden = true;
+ } else if (wl->timeout_count < -1*wl->current_output->refresh_rate) {
+ wl->hidden = false;
+ }
}
void vo_wayland_wait_events(struct vo *vo, int64_t until_time_us)