mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
shm: track busy buffers’ age, and add compile-time option to force double buffering
By default, age all matching buffers that are busy (i.e. in use by the compositor). This allows us to detect whether we can apply the current frame’s damage directly, or if we need to prepare the buffer first (e.g. copy old buffer, or re-apply last frame’s damage etc).
This commit is contained in:
parent
1501d36470
commit
c8b342ae51
3 changed files with 34 additions and 11 deletions
6
render.c
6
render.c
|
|
@ -2048,6 +2048,11 @@ grid_render(struct terminal *term)
|
|||
term->is_searching != term->render.was_searching ||
|
||||
term->render.margins)
|
||||
{
|
||||
if (buf->age > 0) {
|
||||
LOG_DBG("compositor double buffers (age=%d): last=%p, cur=%p",
|
||||
buf->age, (void*)term->render.last_buf, (void*)buf);
|
||||
}
|
||||
|
||||
if (term->render.last_buf != NULL &&
|
||||
term->render.last_buf->width == buf->width &&
|
||||
term->render.last_buf->height == buf->height &&
|
||||
|
|
@ -2080,6 +2085,7 @@ grid_render(struct terminal *term)
|
|||
term->render.was_searching = term->is_searching;
|
||||
}
|
||||
|
||||
buf->age = 0;
|
||||
tll_foreach(term->grid->scroll_damage, it) {
|
||||
switch (it->item.type) {
|
||||
case DAMAGE_SCROLL:
|
||||
|
|
|
|||
37
shm.c
37
shm.c
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#define TIME_SCROLL 0
|
||||
|
||||
#define FORCED_DOUBLE_BUFFERING 0
|
||||
|
||||
/*
|
||||
* Maximum memfd size allowed.
|
||||
*
|
||||
|
|
@ -222,6 +224,8 @@ shm_get_buffer(struct wl_shm *shm, int width, int height, unsigned long cookie,
|
|||
tll_remove(buffers, it);
|
||||
}
|
||||
|
||||
struct buffer *cached = NULL;
|
||||
|
||||
tll_foreach(buffers, it) {
|
||||
if (it->item.width != width)
|
||||
continue;
|
||||
|
|
@ -230,16 +234,27 @@ shm_get_buffer(struct wl_shm *shm, int width, int height, unsigned long cookie,
|
|||
if (it->item.cookie != cookie)
|
||||
continue;
|
||||
|
||||
if (!it->item.busy) {
|
||||
LOG_DBG("cookie=%lx: re-using buffer from cache (buf=%p)",
|
||||
cookie, (void *)&it->item);
|
||||
it->item.busy = true;
|
||||
it->item.purge = false;
|
||||
xassert(it->item.pix_instances == pix_instances);
|
||||
return &it->item;
|
||||
}
|
||||
if (it->item.busy)
|
||||
it->item.age++;
|
||||
else
|
||||
#if FORCED_DOUBLE_BUFFERING
|
||||
if (it->item.age == 0)
|
||||
it->item.age++;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
LOG_DBG("cookie=%lx: re-using buffer from cache (buf=%p)",
|
||||
cookie, (void *)&it->item);
|
||||
it->item.busy = true;
|
||||
it->item.purge = false;
|
||||
xassert(it->item.pix_instances == pix_instances);
|
||||
cached = &it->item;
|
||||
}
|
||||
}
|
||||
|
||||
if (cached != NULL)
|
||||
return cached;
|
||||
|
||||
/* Purge old buffers associated with this cookie */
|
||||
tll_foreach(buffers, it) {
|
||||
if (it->item.cookie != cookie)
|
||||
|
|
@ -376,9 +391,9 @@ shm_get_buffer(struct wl_shm *shm, int width, int height, unsigned long cookie,
|
|||
.scrollable = scrollable,
|
||||
.real_mmapped = real_mmapped,
|
||||
.mmap_size = memfd_size,
|
||||
.offset = 0}
|
||||
)
|
||||
);
|
||||
.offset = 0,
|
||||
.age = 0,
|
||||
}));
|
||||
|
||||
struct buffer *ret = &tll_back(buffers);
|
||||
if (!instantiate_offset(shm, ret, initial_offset))
|
||||
|
|
|
|||
2
shm.h
2
shm.h
|
|
@ -32,6 +32,8 @@ struct buffer {
|
|||
|
||||
bool scrollable;
|
||||
bool purge; /* True if this buffer should be destroyed */
|
||||
|
||||
int age;
|
||||
};
|
||||
|
||||
struct buffer *shm_get_buffer(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue