From 20fc80e57e365f2e002eead7de110cb23ffa7adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Sun, 18 Jul 2021 16:46:43 +0200 Subject: [PATCH] render: use a single backing SHM pool for CSD surface buffers --- render.c | 73 +++++++++++++++++++++++++++--------------------------- terminal.c | 14 ++--------- terminal.h | 2 +- wayland.c | 11 +++----- 4 files changed, 44 insertions(+), 56 deletions(-) diff --git a/render.c b/render.c index 7bcad519..7750dd19 100644 --- a/render.c +++ b/render.c @@ -1575,20 +1575,16 @@ render_csd_part(struct terminal *term, } static void -render_csd_title(struct terminal *term) +render_csd_title(struct terminal *term, const struct csd_data *info, + struct buffer *buf) { xassert(term->window->csd_mode == CSD_YES); - struct csd_data info = get_csd_data(term, CSD_SURF_TITLE); struct wl_surface *surf = term->window->csd.surface[CSD_SURF_TITLE].surf; + xassert(info->width > 0 && info->height > 0); - xassert(info.width > 0 && info.height > 0); - - xassert(info.width % term->scale == 0); - xassert(info.height % term->scale == 0); - - struct buffer_chain *chain = term->render.chains.csd[CSD_SURF_TITLE]; - struct buffer *buf = shm_get_buffer(chain, info.width, info.height); + xassert(info->width % term->scale == 0); + xassert(info->height % term->scale == 0); uint32_t _color = term->conf->colors.fg; uint16_t alpha = 0xffff; @@ -1602,30 +1598,27 @@ render_csd_title(struct terminal *term) _color = color_dim(_color); pixman_color_t color = color_hex_to_pixman_with_alpha(_color, alpha); - render_csd_part(term, surf, buf, info.width, info.height, &color); + render_csd_part(term, surf, buf, info->width, info->height, &color); csd_commit(term, surf, buf); } static void -render_csd_border(struct terminal *term, enum csd_surface surf_idx) +render_csd_border(struct terminal *term, enum csd_surface surf_idx, + const struct csd_data *info, struct buffer *buf) { xassert(term->window->csd_mode == CSD_YES); xassert(surf_idx >= CSD_SURF_LEFT && surf_idx <= CSD_SURF_BOTTOM); - struct csd_data info = get_csd_data(term, surf_idx); struct wl_surface *surf = term->window->csd.surface[surf_idx].surf; - if (info.width == 0 || info.height == 0) + if (info->width == 0 || info->height == 0) return; - xassert(info.width % term->scale == 0); - xassert(info.height % term->scale == 0); - - struct buffer_chain *chain = term->render.chains.csd[surf_idx]; - struct buffer *buf = shm_get_buffer(chain, info.width, info.height); + xassert(info->width % term->scale == 0); + xassert(info->height % term->scale == 0); pixman_color_t color = color_hex_to_pixman_with_alpha(0, 0); - render_csd_part(term, surf, buf, info.width, info.height, &color); + render_csd_part(term, surf, buf, info->width, info->height, &color); csd_commit(term, surf, buf); } @@ -1792,22 +1785,19 @@ render_csd_button_close(struct terminal *term, struct buffer *buf) } static void -render_csd_button(struct terminal *term, enum csd_surface surf_idx) +render_csd_button(struct terminal *term, enum csd_surface surf_idx, + const struct csd_data *info, struct buffer *buf) { xassert(term->window->csd_mode == CSD_YES); xassert(surf_idx >= CSD_SURF_MINIMIZE && surf_idx <= CSD_SURF_CLOSE); - struct csd_data info = get_csd_data(term, surf_idx); struct wl_surface *surf = term->window->csd.surface[surf_idx].surf; - if (info.width == 0 || info.height == 0) + if (info->width == 0 || info->height == 0) return; - xassert(info.width % term->scale == 0); - xassert(info.height % term->scale == 0); - - struct buffer_chain *chain = term->render.chains.csd[surf_idx]; - struct buffer *buf = shm_get_buffer(chain, info.width, info.height); + xassert(info->width % term->scale == 0); + xassert(info->height % term->scale == 0); uint32_t _color; uint16_t alpha = 0xffff; @@ -1856,7 +1846,7 @@ render_csd_button(struct terminal *term, enum csd_surface surf_idx) _color = color_dim(_color); pixman_color_t color = color_hex_to_pixman_with_alpha(_color, alpha); - render_csd_part(term, surf, buf, info.width, info.height, &color); + render_csd_part(term, surf, buf, info->width, info->height, &color); switch (surf_idx) { case CSD_SURF_MINIMIZE: render_csd_button_minimize(term, buf); break; @@ -1880,12 +1870,16 @@ render_csd(struct terminal *term) if (term->window->is_fullscreen) return; + struct csd_data infos[CSD_SURF_COUNT]; + int widths[CSD_SURF_COUNT]; + int heights[CSD_SURF_COUNT]; + for (size_t i = 0; i < CSD_SURF_COUNT; i++) { - struct csd_data info = get_csd_data(term, i); - const int x = info.x; - const int y = info.y; - const int width = info.width; - const int height = info.height; + infos[i] = get_csd_data(term, i); + const int x = infos[i].x; + const int y = infos[i].y; + const int width = infos[i].width; + const int height = infos[i].height; struct wl_surface *surf = term->window->csd.surface[i].surf; struct wl_subsurface *sub = term->window->csd.surface[i].sub; @@ -1894,20 +1888,27 @@ render_csd(struct terminal *term) xassert(sub != NULL); if (width == 0 || height == 0) { + widths[i] = heights[i] = 0; wl_subsurface_set_position(sub, 0, 0); wl_surface_attach(surf, NULL, 0, 0); wl_surface_commit(surf); continue; } + widths[i] = width; + heights[i] = height; + wl_subsurface_set_position(sub, x / term->scale, y / term->scale); } + struct buffer *bufs[CSD_SURF_COUNT]; + shm_get_many(term->render.chains.csd, CSD_SURF_COUNT, widths, heights, bufs); + for (size_t i = CSD_SURF_LEFT; i <= CSD_SURF_BOTTOM; i++) - render_csd_border(term, i); + render_csd_border(term, i, &infos[i], bufs[i]); for (size_t i = CSD_SURF_MINIMIZE; i <= CSD_SURF_CLOSE; i++) - render_csd_button(term, i); - render_csd_title(term); + render_csd_button(term, i, &infos[i], bufs[i]); + render_csd_title(term, &infos[CSD_SURF_TITLE], bufs[CSD_SURF_TITLE]); } static void diff --git a/terminal.c b/terminal.c index af5172bb..46e7fc01 100644 --- a/terminal.c +++ b/terminal.c @@ -1150,16 +1150,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, .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), - }, + .csd = shm_chain_new(wayl->shm, false, 1), }, .scrollback_lines = conf->scrollback.lines, .app_sync_updates.timer_fd = app_sync_updates_fd, @@ -1482,8 +1473,7 @@ term_destroy(struct terminal *term) 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]); + shm_chain_free(term->render.chains.csd); tll_free(term->tab_stops); diff --git a/terminal.h b/terminal.h index d699d644..688e42cc 100644 --- a/terminal.h +++ b/terminal.h @@ -482,7 +482,7 @@ struct terminal { struct buffer_chain *scrollback_indicator; struct buffer_chain *render_timer; struct buffer_chain *url; - struct buffer_chain *csd[CSD_SURF_COUNT]; + struct buffer_chain *csd; } chains; /* Scheduled for rendering, as soon-as-possible */ diff --git a/wayland.c b/wayland.c index 38c80999..0679dee3 100644 --- a/wayland.c +++ b/wayland.c @@ -53,10 +53,9 @@ csd_destroy(struct wl_window *win) { struct terminal *term = win->term; - for (size_t i = 0; i < ALEN(win->csd.surface); i++) { + for (size_t i = 0; i < ALEN(win->csd.surface); i++) wayl_win_subsurface_destroy(&win->csd.surface[i]); - shm_purge(term->render.chains.csd[i]); - } + shm_purge(term->render.chains.csd); } static void @@ -1470,7 +1469,6 @@ wayl_win_destroy(struct wl_window *win) tll_foreach(win->urls, it) { wayl_win_subsurface_destroy(&it->item.surf); - shm_purge(term->render.chains.url); tll_remove(win->urls, it); } @@ -1483,9 +1481,8 @@ wayl_win_destroy(struct wl_window *win) shm_purge(term->render.chains.scrollback_indicator); shm_purge(term->render.chains.render_timer); shm_purge(term->render.chains.grid); - - for (size_t i = 0; i < ALEN(win->csd.surface); i++) - shm_purge(term->render.chains.csd[i]); + shm_purge(term->render.chains.url); + shm_purge(term->render.chains.csd); #if defined(HAVE_XDG_ACTIVATION) if (win->xdg_activation_token != NULL)