summaryrefslogtreecommitdiffstats
path: root/video/out/vo_wlshm.c
diff options
context:
space:
mode:
authorDudemanguy <random342@airmail.cc>2021-05-23 14:36:19 -0500
committerDudemanguy <random342@airmail.cc>2021-05-24 19:20:31 +0000
commitc26d83348b730d083f3be313556039fd31d32505 (patch)
tree622fe6c614615db49405d31cccde0afc3a5bc0f6 /video/out/vo_wlshm.c
parent193814497b3f72fddea17d04269759f1cf64943d (diff)
downloadmpv-c26d83348b730d083f3be313556039fd31d32505.tar.bz2
mpv-c26d83348b730d083f3be313556039fd31d32505.tar.xz
wayland: shuffle around the render loop again
Take two. f4e89dd went wrong by moving vo_wayland_wait_frame before start_frame was called. Whether or not this matters depends on the compositor, but some weird things can happen. Basically, it's a scheduling issue. vo_wayland_wait_frame queues all events and sends them to the server to process (with no blocking if presentation time is available). If mpv changes state while rendering (and this function is called before every frame is drawn), then that event also gets dispatched and sent to the compositor. This, in some cases, can cause some funny behavior because the next frame gets attached to the surface while the old buffer is getting released. It's safer to call this function after the swap already happens and well before mpv calls its next draw. There's no weird scheduling of events, and the compositor log is more normal. The second part of this is to fix some stuttering issues. This is mostly just conjecture, but probably what was happening was this thing called "composition". The easiest way to see this is to play a video on the default audio sync mode (probably easiest to see on a typical 23.976 video). Have that in a window and float it over firefox (floating windows are bloat on a tiling wm anyway). Then in firefox, do some short bursts of smooth scrolling (likely uses egl). Some stutter in video rendering could be observed, particularly in panning shots. Compositors are supposed to prevent tearing so what likely was happening was that the compositor was simply holding the buffer a wee bit longer to make sure it happened in sync with the smooth scrolling. Because the mpv code waits precisely on presentation time, the loop would timeout on occasion instead of receiving the frame callback. This would then lead to a skipped frame when rendering and thus causing stuttering. The fix is simple: just only count consecutive timeouts as not receiving frame callback. If a compositor holds the mpv buffer slightly longer to avoid tearing, then we will definitely receive frame callback on the next round of the render loop. This logic also appears to be sound for plasma (funfact: Plasma always returns frame callback even when the window is hidden. Not sure what's up with that, but luckily it doesn't matter to us.), so get rid of the goofy 1/vblank_time thing and just keep it a simple > 1 check.
Diffstat (limited to 'video/out/vo_wlshm.c')
-rw-r--r--video/out/vo_wlshm.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/video/out/vo_wlshm.c b/video/out/vo_wlshm.c
index 508da4261f..69cfdd9dcc 100644
--- a/video/out/vo_wlshm.c
+++ b/video/out/vo_wlshm.c
@@ -218,13 +218,10 @@ static void draw_image(struct vo *vo, struct mp_image *src)
struct priv *p = vo->priv;
struct vo_wayland_state *wl = vo->wl;
struct buffer *buf;
- bool callback = true;
-
- if (!wl->opts->disable_vsync)
- callback = vo_wayland_wait_frame(wl);
-
+ bool render = wl->render || wl->opts->disable_vsync;
wl->frame_wait = true;
- if (!callback)
+
+ if (!render)
return;
buf = p->free_buffers;
@@ -277,6 +274,9 @@ static void flip_page(struct vo *vo)
mp_rect_h(wl->geometry));
wl_surface_commit(wl->surface);
+ if (!wl->opts->disable_vsync)
+ vo_wayland_wait_frame(wl);
+
if (wl->presentation)
wayland_sync_swap(wl);
}