From c8b342ae51cba357f21a3f6c77f6a527981101b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Fri, 7 May 2021 18:18:35 +0200 Subject: [PATCH] =?UTF-8?q?shm:=20track=20busy=20buffers=E2=80=99=20age,?= =?UTF-8?q?=20and=20add=20compile-time=20option=20to=20force=20double=20bu?= =?UTF-8?q?ffering?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). --- render.c | 6 ++++++ shm.c | 37 ++++++++++++++++++++++++++----------- shm.h | 2 ++ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/render.c b/render.c index 9bcd11ba..43b6ee6f 100644 --- a/render.c +++ b/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: diff --git a/shm.c b/shm.c index 2ec581c4..a39c7c34 100644 --- a/shm.c +++ b/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)) diff --git a/shm.h b/shm.h index 2e819369..d0d79435 100644 --- a/shm.h +++ b/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(