From d3a28f12c9ced29982fc831722075bd0c73fb821 Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Sat, 29 Oct 2022 15:59:11 -0500 Subject: [PATCH] wayland: hack around presentation_feedback weirdness 964692ad4cec90888bb437064c53d8844db9f590 added some code to destroy presentation_feedback we get in the presentation_discarded event. This is the correct thing to do since the compositor could send us this instead of feedback_presented. Without that change, mutter could potentially leak memory on every frame. Unfortunately, life is not so simple and wlroots and weston act differently. These compositors only send one presentation_discarded event if the mpv window is hidden. Not on every single missed frame like mutter. Now in theory this shouldn't matter, but it also turns out that mpv attempts to free the presentation feedback twice if you quit it while it is hidden away (on weston and wlroots compositors only). The inital wp_presentation_feedback_destroy in feedback_discarded fires, but then the function goes off again in vo_wayland_uninit because wl->feedback is apparently not NULL for some reason. Possibly, this is some race condition but we can't just get rid of what's in feedback_discarded since mutter needs this line. Instead, just hack it by explicitly setting wl->feedback to NULL in feedback_discarded after we destroy the presentation feedback. Some valgrind testing in mutter, sway, and weston shows that this works correctly on all of those compositors with various combinations of mpv being visible or not while quitting. feedback_presented doesn't appear to exhibit this behavior so we just leave that as-is. --- video/out/wayland_common.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 318e8e838d..f2f3ef02f9 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -1041,8 +1041,17 @@ static void feedback_presented(void *data, struct wp_presentation_feedback *fbac static void feedback_discarded(void *data, struct wp_presentation_feedback *fback) { - if (fback) + struct vo_wayland_state *wl = data; + + // Really weird hack needed here. wlroots and weston send the discarded event + // only once (not every frame) if the window is hidden. If mpv quits in this + // state, fback will get destroyed but wl->feedback (in theory, this is supposed + // to be same as fback) will not be NULL and thus will be mistakenly tried to be + // free'd again. Hack this by just setting it to NULL explicitly. + if (fback) { wp_presentation_feedback_destroy(fback); + wl->feedback = NULL; + } } static const struct wp_presentation_feedback_listener feedback_listener = {