shm: revert part of 299186a654

299186a654 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
299186a654, 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 299186a654 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.
This commit is contained in:
Daniel Eklöf 2025-12-16 14:56:42 +01:00
parent 15ebc433ba
commit 4e96780eef
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 6 additions and 5 deletions

View file

@ -101,6 +101,7 @@
character in the last column. character in the last column.
* Crash when reverse-scrolling (terminfo capability `rin`) such that * Crash when reverse-scrolling (terminfo capability `rin`) such that
the current viewport ends up outside the scrollback ([#2232][2232]). the current viewport ends up outside the scrollback ([#2232][2232]).
* Regression: visual glitches in rare circumstances.
[2232]: https://codeberg.org/dnkl/foot/issues/2232 [2232]: https://codeberg.org/dnkl/foot/issues/2232

10
shm.c
View file

@ -628,14 +628,14 @@ shm_get_buffer(struct buffer_chain *chain, int width, int height, bool with_alph
else else
#endif #endif
{ {
if (cached == NULL) if (cached == NULL) {
cached = buf; cached = buf;
else { } else {
/* We have multiple buffers eligible for /* We have multiple buffers eligible for
* reuse. Pick the "youngest" one, and mark the * reuse. Pick the "youngest" one, and mark the
* other one for purging */ * other one for purging */
if (buf->public.age < cached->public.age) { if (buf->public.age < cached->public.age) {
//shm_unref(&cached->public); shm_unref(&cached->public);
cached = buf; cached = buf;
} else { } 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 * should be safe; "our" tll_foreach() already
* holds the next pointer. * holds the next pointer.
*/ */
//if (buffer_unref_no_remove_from_chain(buf)) if (buffer_unref_no_remove_from_chain(buf))
// tll_remove(chain->bufs, it); tll_remove(chain->bufs, it);
} }
} }
} }