From 4e96780eef048baa7370499c64a33210b4e0406d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 16 Dec 2025 14:56:42 +0100 Subject: [PATCH] shm: revert part of 299186a6547f6e038ee6f3822caf9a0fdfabceef 299186a6547f6e038ee6f3822caf9a0fdfabceef introduced a regression, where we don't handle SHM buffer "hiccups" correctly. If foot, for some reason is forced to render a frame "too soon", we might end up having multiple buffers "in flight" (i.e. committed to the compositor). This could happen if the compositor pushes multiple configure events rapidly, for example. Or anything else that forces foot to render something "immediately", without waiting for a frame callback. The compositor typically releases both buffers at the same time (or close to it), so the _next_ time we want to render a frame, we have *two* buffers to pick between. The problem here is that after 299186a6547f6e038ee6f3822caf9a0fdfabceef, foot no longer purges the additional buffer(s), but keeps all of them around. This messes up foot's age tracking, and the _next_ time we're forced to pull two buffers (without the compositor releasing the first one in between), we try to apply damage tracking that is no longer valid. This results in visual glitches. This never self-repairs, and we're stuck with visual glitches until the window is resized, and we're forced to allocate completely new buffers. It is unclear why 299186a6547f6e038ee6f3822caf9a0fdfabceef stopped removing the buffers. It was likely done early in the development, and is no longer needed. So far, I haven't noticed any bugs by re-introducing the buffer purging, but further testing is needed. --- CHANGELOG.md | 1 + shm.c | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85dc3762..70ab43b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -101,6 +101,7 @@ character in the last column. * Crash when reverse-scrolling (terminfo capability `rin`) such that the current viewport ends up outside the scrollback ([#2232][2232]). +* Regression: visual glitches in rare circumstances. [2232]: https://codeberg.org/dnkl/foot/issues/2232 diff --git a/shm.c b/shm.c index 72b32f16..f488d6b6 100644 --- a/shm.c +++ b/shm.c @@ -628,14 +628,14 @@ shm_get_buffer(struct buffer_chain *chain, int width, int height, bool with_alph else #endif { - if (cached == NULL) + if (cached == NULL) { cached = buf; - else { + } else { /* We have multiple buffers eligible for * reuse. Pick the "youngest" one, and mark the * other one for purging */ if (buf->public.age < cached->public.age) { - //shm_unref(&cached->public); + shm_unref(&cached->public); cached = buf; } else { /* @@ -646,8 +646,8 @@ shm_get_buffer(struct buffer_chain *chain, int width, int height, bool with_alph * should be safe; "our" tll_foreach() already * holds the next pointer. */ - //if (buffer_unref_no_remove_from_chain(buf)) - // tll_remove(chain->bufs, it); + if (buffer_unref_no_remove_from_chain(buf)) + tll_remove(chain->bufs, it); } } }