render: use a single backing SHM pool for CSD surface buffers

This commit is contained in:
Daniel Eklöf 2021-07-18 16:46:43 +02:00
parent 5b6a2b0eaf
commit 20fc80e57e
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
4 changed files with 44 additions and 56 deletions

View file

@ -1575,20 +1575,16 @@ render_csd_part(struct terminal *term,
} }
static void 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); 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; 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);
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);
uint32_t _color = term->conf->colors.fg; uint32_t _color = term->conf->colors.fg;
uint16_t alpha = 0xffff; uint16_t alpha = 0xffff;
@ -1602,30 +1598,27 @@ render_csd_title(struct terminal *term)
_color = color_dim(_color); _color = color_dim(_color);
pixman_color_t color = color_hex_to_pixman_with_alpha(_color, alpha); 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); csd_commit(term, surf, buf);
} }
static void 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(term->window->csd_mode == CSD_YES);
xassert(surf_idx >= CSD_SURF_LEFT && surf_idx <= CSD_SURF_BOTTOM); 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; 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; return;
xassert(info.width % term->scale == 0); xassert(info->width % term->scale == 0);
xassert(info.height % 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);
pixman_color_t color = color_hex_to_pixman_with_alpha(0, 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); csd_commit(term, surf, buf);
} }
@ -1792,22 +1785,19 @@ render_csd_button_close(struct terminal *term, struct buffer *buf)
} }
static void 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(term->window->csd_mode == CSD_YES);
xassert(surf_idx >= CSD_SURF_MINIMIZE && surf_idx <= CSD_SURF_CLOSE); 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; 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; return;
xassert(info.width % term->scale == 0); xassert(info->width % term->scale == 0);
xassert(info.height % 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);
uint32_t _color; uint32_t _color;
uint16_t alpha = 0xffff; uint16_t alpha = 0xffff;
@ -1856,7 +1846,7 @@ render_csd_button(struct terminal *term, enum csd_surface surf_idx)
_color = color_dim(_color); _color = color_dim(_color);
pixman_color_t color = color_hex_to_pixman_with_alpha(_color, alpha); 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) { switch (surf_idx) {
case CSD_SURF_MINIMIZE: render_csd_button_minimize(term, buf); break; 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) if (term->window->is_fullscreen)
return; 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++) { for (size_t i = 0; i < CSD_SURF_COUNT; i++) {
struct csd_data info = get_csd_data(term, i); infos[i] = get_csd_data(term, i);
const int x = info.x; const int x = infos[i].x;
const int y = info.y; const int y = infos[i].y;
const int width = info.width; const int width = infos[i].width;
const int height = info.height; const int height = infos[i].height;
struct wl_surface *surf = term->window->csd.surface[i].surf; struct wl_surface *surf = term->window->csd.surface[i].surf;
struct wl_subsurface *sub = term->window->csd.surface[i].sub; struct wl_subsurface *sub = term->window->csd.surface[i].sub;
@ -1894,20 +1888,27 @@ render_csd(struct terminal *term)
xassert(sub != NULL); xassert(sub != NULL);
if (width == 0 || height == 0) { if (width == 0 || height == 0) {
widths[i] = heights[i] = 0;
wl_subsurface_set_position(sub, 0, 0); wl_subsurface_set_position(sub, 0, 0);
wl_surface_attach(surf, NULL, 0, 0); wl_surface_attach(surf, NULL, 0, 0);
wl_surface_commit(surf); wl_surface_commit(surf);
continue; continue;
} }
widths[i] = width;
heights[i] = height;
wl_subsurface_set_position(sub, x / term->scale, y / term->scale); 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++) 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++) for (size_t i = CSD_SURF_MINIMIZE; i <= CSD_SURF_CLOSE; i++)
render_csd_button(term, i); render_csd_button(term, i, &infos[i], bufs[i]);
render_csd_title(term); render_csd_title(term, &infos[CSD_SURF_TITLE], bufs[CSD_SURF_TITLE]);
} }
static void static void

View file

@ -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), .scrollback_indicator = shm_chain_new(wayl->shm, false, 1),
.render_timer = shm_chain_new(wayl->shm, false, 1), .render_timer = shm_chain_new(wayl->shm, false, 1),
.url = shm_chain_new(wayl->shm, false, 1), .url = shm_chain_new(wayl->shm, false, 1),
.csd = { .csd = shm_chain_new(wayl->shm, false, 1),
[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, .scrollback_lines = conf->scrollback.lines,
.app_sync_updates.timer_fd = app_sync_updates_fd, .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.scrollback_indicator);
shm_chain_free(term->render.chains.render_timer); shm_chain_free(term->render.chains.render_timer);
shm_chain_free(term->render.chains.url); shm_chain_free(term->render.chains.url);
for (size_t i = 0; i < CSD_SURF_COUNT; i++) shm_chain_free(term->render.chains.csd);
shm_chain_free(term->render.chains.csd[i]);
tll_free(term->tab_stops); tll_free(term->tab_stops);

View file

@ -482,7 +482,7 @@ struct terminal {
struct buffer_chain *scrollback_indicator; struct buffer_chain *scrollback_indicator;
struct buffer_chain *render_timer; struct buffer_chain *render_timer;
struct buffer_chain *url; struct buffer_chain *url;
struct buffer_chain *csd[CSD_SURF_COUNT]; struct buffer_chain *csd;
} chains; } chains;
/* Scheduled for rendering, as soon-as-possible */ /* Scheduled for rendering, as soon-as-possible */

View file

@ -53,10 +53,9 @@ csd_destroy(struct wl_window *win)
{ {
struct terminal *term = win->term; 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]); wayl_win_subsurface_destroy(&win->csd.surface[i]);
shm_purge(term->render.chains.csd[i]); shm_purge(term->render.chains.csd);
}
} }
static void static void
@ -1470,7 +1469,6 @@ wayl_win_destroy(struct wl_window *win)
tll_foreach(win->urls, it) { tll_foreach(win->urls, it) {
wayl_win_subsurface_destroy(&it->item.surf); wayl_win_subsurface_destroy(&it->item.surf);
shm_purge(term->render.chains.url);
tll_remove(win->urls, it); 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.scrollback_indicator);
shm_purge(term->render.chains.render_timer); shm_purge(term->render.chains.render_timer);
shm_purge(term->render.chains.grid); shm_purge(term->render.chains.grid);
shm_purge(term->render.chains.url);
for (size_t i = 0; i < ALEN(win->csd.surface); i++) shm_purge(term->render.chains.csd);
shm_purge(term->render.chains.csd[i]);
#if defined(HAVE_XDG_ACTIVATION) #if defined(HAVE_XDG_ACTIVATION)
if (win->xdg_activation_token != NULL) if (win->xdg_activation_token != NULL)