shm: refactor: move away from a single, global, buffer list

Up until now, *all* buffers have been tracked in a single, global
buffer list. We've used 'cookies' to separate buffers from different
contexts (so that shm_get_buffer() doesn't try to re-use e.g. a
search-box buffer for the main grid).

This patch refactors this, and completely removes the global
list.

Instead of cookies, we now use 'chains'. A chain tracks both the
properties to apply to newly created buffers (scrollable, number of
pixman instances to instantiate etc), as well as the instantiated
buffers themselves.

This means there's strictly speaking not much use for shm_fini()
anymore, since its up to the chain owner to call shm_chain_free(),
which will also purge all buffers.

However, since purging a buffer may be deferred, if the buffer is
owned by the compositor at the time of the call to shm_purge() or
shm_chain_free(), we still keep a global 'deferred' list, on to which
deferred buffers are pushed. shm_fini() iterates this list and
destroys the buffers _even_ if they are still owned by the
compositor. This only happens at program termination, and not when
destroying a terminal instance. I.e. closing a window in a “foot
--server” does *not* trigger this.

Each terminal instatiates a number of chains, and these chains are
destroyed when the terminal instance is destroyed. Note that some
buffers may be put on the deferred list, as mentioned above.
This commit is contained in:
Daniel Eklöf 2021-07-16 16:48:49 +02:00
parent 4efb34927e
commit 53851e13ec
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
6 changed files with 190 additions and 164 deletions

View file

@ -1144,6 +1144,23 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
.tab_stops = tll_init(),
.wl = wayl,
.render = {
.chains = {
.grid = shm_chain_new(wayl->shm, true, 1 + conf->render_worker_count),
.search = shm_chain_new(wayl->shm, false, 1),
.scrollback_indicator = shm_chain_new(wayl->shm, false, 1),
.render_timer = shm_chain_new(wayl->shm, false, 1),
.url = shm_chain_new(wayl->shm, false, 1),
.csd = {
[CSD_SURF_TITLE] = shm_chain_new(wayl->shm, false, 1),
[CSD_SURF_LEFT] = shm_chain_new(wayl->shm, false, 1),
[CSD_SURF_RIGHT] = shm_chain_new(wayl->shm, false, 1),
[CSD_SURF_TOP] = shm_chain_new(wayl->shm, false, 1),
[CSD_SURF_BOTTOM] = shm_chain_new(wayl->shm, false, 1),
[CSD_SURF_MINIMIZE] = shm_chain_new(wayl->shm, false, 1),
[CSD_SURF_MAXIMIZE] = shm_chain_new(wayl->shm, false, 1),
[CSD_SURF_CLOSE] = shm_chain_new(wayl->shm, false, 1),
},
},
.scrollback_lines = conf->scrollback.lines,
.app_sync_updates.timer_fd = app_sync_updates_fd,
.title = {
@ -1458,7 +1475,15 @@ term_destroy(struct terminal *term)
sem_destroy(&term->render.workers.done);
xassert(tll_length(term->render.workers.queue) == 0);
tll_free(term->render.workers.queue);
shm_unref(term->render.last_buf);
shm_chain_free(term->render.chains.grid);
shm_chain_free(term->render.chains.search);
shm_chain_free(term->render.chains.scrollback_indicator);
shm_chain_free(term->render.chains.render_timer);
shm_chain_free(term->render.chains.url);
for (size_t i = 0; i < CSD_SURF_COUNT; i++)
shm_chain_free(term->render.chains.csd[i]);
tll_free(term->tab_stops);