shm: use XRGB surfaces when we know we wont be using transparency

This commit is contained in:
Daniel Eklöf 2024-02-21 16:29:10 +01:00
parent 09d856f2ff
commit 67f97cbca1
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
6 changed files with 28 additions and 28 deletions

View file

@ -88,6 +88,8 @@
* Ctrl+wheel up/down bound to `font-increase` and `font-decrease` * Ctrl+wheel up/down bound to `font-increase` and `font-decrease`
respectively (in addition to the already existing default key respectively (in addition to the already existing default key
bindings `ctrl-+` and `ctrl+-`). bindings `ctrl-+` and `ctrl+-`).
* Use XRGB pixel format (instead of ARGB) when there is no
transparency.
[1526]: https://codeberg.org/dnkl/foot/issues/1526 [1526]: https://codeberg.org/dnkl/foot/issues/1526
[1528]: https://codeberg.org/dnkl/foot/issues/1528 [1528]: https://codeberg.org/dnkl/foot/issues/1528

View file

@ -1583,7 +1583,7 @@ render_overlay(struct terminal *term)
} }
struct buffer *buf = shm_get_buffer( struct buffer *buf = shm_get_buffer(
term->render.chains.overlay, term->width, term->height); term->render.chains.overlay, term->width, term->height, true);
pixman_image_set_clip_region32(buf->pix[0], NULL); pixman_image_set_clip_region32(buf->pix[0], NULL);
@ -2454,7 +2454,7 @@ render_csd(struct terminal *term)
} }
struct buffer *bufs[CSD_SURF_COUNT]; struct buffer *bufs[CSD_SURF_COUNT];
shm_get_many(term->render.chains.csd, CSD_SURF_COUNT, widths, heights, bufs); shm_get_many(term->render.chains.csd, CSD_SURF_COUNT, widths, heights, bufs, true);
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, &infos[i], bufs[i]); render_csd_border(term, i, &infos[i], bufs[i]);
@ -2599,7 +2599,7 @@ render_scrollback_position(struct terminal *term)
} }
struct buffer_chain *chain = term->render.chains.scrollback_indicator; struct buffer_chain *chain = term->render.chains.scrollback_indicator;
struct buffer *buf = shm_get_buffer(chain, width, height); struct buffer *buf = shm_get_buffer(chain, width, height, false);
wl_subsurface_set_position( wl_subsurface_set_position(
win->scrollback_indicator.sub, roundf(x / scale), roundf(y / scale)); win->scrollback_indicator.sub, roundf(x / scale), roundf(y / scale));
@ -2642,7 +2642,7 @@ render_render_timer(struct terminal *term, struct timespec render_time)
height = roundf(scale * ceilf(height / scale)); height = roundf(scale * ceilf(height / scale));
struct buffer_chain *chain = term->render.chains.render_timer; struct buffer_chain *chain = term->render.chains.render_timer;
struct buffer *buf = shm_get_buffer(chain, width, height); struct buffer *buf = shm_get_buffer(chain, width, height, false);
wl_subsurface_set_position( wl_subsurface_set_position(
win->render_timer.sub, win->render_timer.sub,
@ -2817,7 +2817,10 @@ grid_render(struct terminal *term)
xassert(term->height > 0); xassert(term->height > 0);
struct buffer_chain *chain = term->render.chains.grid; struct buffer_chain *chain = term->render.chains.grid;
struct buffer *buf = shm_get_buffer(chain, term->width, term->height); bool use_alpha = !term->window->is_fullscreen &&
term->colors.alpha != 0xffff;
struct buffer *buf = shm_get_buffer(
chain, term->width, term->height, use_alpha);
/* Dirty old and current cursor cell, to ensure they're repainted */ /* Dirty old and current cursor cell, to ensure they're repainted */
dirty_old_cursor(term); dirty_old_cursor(term);
@ -3208,7 +3211,7 @@ render_search_box(struct terminal *term)
size_t glyph_offset = term->render.search_glyph_offset; size_t glyph_offset = term->render.search_glyph_offset;
struct buffer_chain *chain = term->render.chains.search; struct buffer_chain *chain = term->render.chains.search;
struct buffer *buf = shm_get_buffer(chain, width, height); struct buffer *buf = shm_get_buffer(chain, width, height, true);
pixman_region32_t clip; pixman_region32_t clip;
pixman_region32_init_rect(&clip, 0, 0, width, height); pixman_region32_init_rect(&clip, 0, 0, width, height);
@ -3670,7 +3673,7 @@ render_urls(struct terminal *term)
struct buffer_chain *chain = term->render.chains.url; struct buffer_chain *chain = term->render.chains.url;
struct buffer *bufs[render_count]; struct buffer *bufs[render_count];
shm_get_many(chain, render_count, widths, heights, bufs); shm_get_many(chain, render_count, widths, heights, bufs, false);
uint32_t fg = term->conf->colors.use_custom.jump_label uint32_t fg = term->conf->colors.use_custom.jump_label
? term->conf->colors.jump_label.fg ? term->conf->colors.jump_label.fg

21
shm.c
View file

@ -82,6 +82,7 @@ struct buffer_private {
struct buffer_pool *pool; struct buffer_pool *pool;
off_t offset; /* Offset into memfd where data begins */ off_t offset; /* Offset into memfd where data begins */
size_t size; size_t size;
bool with_alpha;
bool scrollable; bool scrollable;
}; };
@ -261,7 +262,7 @@ instantiate_offset(struct buffer_private *buf, off_t new_offset)
wl_buf = wl_shm_pool_create_buffer( wl_buf = wl_shm_pool_create_buffer(
pool->wl_pool, new_offset, pool->wl_pool, new_offset,
buf->public.width, buf->public.height, buf->public.stride, buf->public.width, buf->public.height, buf->public.stride,
WL_SHM_FORMAT_ARGB8888); buf->with_alpha ? WL_SHM_FORMAT_ARGB8888 : WL_SHM_FORMAT_XRGB8888);
if (wl_buf == NULL) { if (wl_buf == NULL) {
LOG_ERR("failed to create SHM buffer"); LOG_ERR("failed to create SHM buffer");
@ -271,7 +272,8 @@ instantiate_offset(struct buffer_private *buf, off_t new_offset)
/* One pixman image for each worker thread (do we really need multiple?) */ /* One pixman image for each worker thread (do we really need multiple?) */
for (size_t i = 0; i < buf->public.pix_instances; i++) { for (size_t i = 0; i < buf->public.pix_instances; i++) {
pix[i] = pixman_image_create_bits_no_clear( pix[i] = pixman_image_create_bits_no_clear(
PIXMAN_a8r8g8b8, buf->public.width, buf->public.height, buf->with_alpha ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
buf->public.width, buf->public.height,
(uint32_t *)mmapped, buf->public.stride); (uint32_t *)mmapped, buf->public.stride);
if (pix[i] == NULL) { if (pix[i] == NULL) {
LOG_ERR("failed to create pixman image"); LOG_ERR("failed to create pixman image");
@ -304,7 +306,8 @@ err:
static void NOINLINE static void NOINLINE
get_new_buffers(struct buffer_chain *chain, size_t count, get_new_buffers(struct buffer_chain *chain, size_t count,
int widths[static count], int heights[static count], int widths[static count], int heights[static count],
struct buffer *bufs[static count], bool immediate_purge) struct buffer *bufs[static count], bool with_alpha,
bool immediate_purge)
{ {
xassert(count == 1 || !chain->scrollable); xassert(count == 1 || !chain->scrollable);
/* /*
@ -322,7 +325,8 @@ get_new_buffers(struct buffer_chain *chain, size_t count,
size_t total_size = 0; size_t total_size = 0;
for (size_t i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
stride[i] = stride_for_format_and_width(PIXMAN_a8r8g8b8, widths[i]); stride[i] = stride_for_format_and_width(
with_alpha ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8, widths[i]);
sizes[i] = stride[i] * heights[i]; sizes[i] = stride[i] * heights[i];
total_size += sizes[i]; total_size += sizes[i];
} }
@ -473,6 +477,7 @@ get_new_buffers(struct buffer_chain *chain, size_t count,
.chain = chain, .chain = chain,
.ref_count = immediate_purge ? 0 : 1, .ref_count = immediate_purge ? 0 : 1,
.busy = true, .busy = true,
.with_alpha = with_alpha,
.pool = pool, .pool = pool,
.offset = 0, .offset = 0,
.size = sizes[i], .size = sizes[i],
@ -542,13 +547,13 @@ shm_did_not_use_buf(struct buffer *_buf)
void void
shm_get_many(struct buffer_chain *chain, size_t count, shm_get_many(struct buffer_chain *chain, size_t count,
int widths[static count], int heights[static count], int widths[static count], int heights[static count],
struct buffer *bufs[static count]) struct buffer *bufs[static count], bool with_alpha)
{ {
get_new_buffers(chain, count, widths, heights, bufs, true); get_new_buffers(chain, count, widths, heights, bufs, with_alpha, true);
} }
struct buffer * struct buffer *
shm_get_buffer(struct buffer_chain *chain, int width, int height) shm_get_buffer(struct buffer_chain *chain, int width, int height, bool with_alpha)
{ {
LOG_DBG( LOG_DBG(
"chain=%p: looking for a reusable %dx%d buffer " "chain=%p: looking for a reusable %dx%d buffer "
@ -610,7 +615,7 @@ shm_get_buffer(struct buffer_chain *chain, int width, int height)
} }
struct buffer *ret; struct buffer *ret;
get_new_buffers(chain, 1, &width, &height, &ret, false); get_new_buffers(chain, 1, &width, &height, &ret, with_alpha, false);
return ret; return ret;
} }

5
shm.h
View file

@ -55,7 +55,8 @@ void shm_chain_free(struct buffer_chain *chain);
* *
* A newly allocated buffer has an age of 1234. * A newly allocated buffer has an age of 1234.
*/ */
struct buffer *shm_get_buffer(struct buffer_chain *chain, int width, int height); struct buffer *shm_get_buffer(
struct buffer_chain *chain, int width, int height, bool with_alpha);
/* /*
* Returns many buffers, described by 'info', all sharing the same SHM * Returns many buffers, described by 'info', all sharing the same SHM
* buffer pool. * buffer pool.
@ -73,7 +74,7 @@ struct buffer *shm_get_buffer(struct buffer_chain *chain, int width, int height)
void shm_get_many( void shm_get_many(
struct buffer_chain *chain, size_t count, struct buffer_chain *chain, size_t count,
int widths[static count], int heights[static count], int widths[static count], int heights[static count],
struct buffer *bufs[static count]); struct buffer *bufs[static count], bool with_alpha);
void shm_did_not_use_buf(struct buffer *buf); void shm_did_not_use_buf(struct buffer *buf);

View file

@ -234,8 +234,6 @@ seat_destroy(struct seat *seat)
static void static void
shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
{ {
struct wayland *wayl = data;
#if defined(_DEBUG) #if defined(_DEBUG)
bool have_description = false; bool have_description = false;
@ -250,9 +248,6 @@ shm_format(void *data, struct wl_shm *wl_shm, uint32_t format)
if (!have_description) if (!have_description)
LOG_DBG("shm: 0x%08x: unknown", format); LOG_DBG("shm: 0x%08x: unknown", format);
#endif #endif
if (format == WL_SHM_FORMAT_ARGB8888)
wayl->have_argb8888 = true;
} }
static const struct wl_shm_listener shm_listener = { static const struct wl_shm_listener shm_listener = {
@ -1576,11 +1571,6 @@ wayl_init(struct fdm *fdm, struct key_binding_manager *key_binding_manager,
/* Trigger listeners registered when handling globals */ /* Trigger listeners registered when handling globals */
wl_display_roundtrip(wayl->display); wl_display_roundtrip(wayl->display);
if (!wayl->have_argb8888) {
LOG_ERR("compositor does not support ARGB surfaces");
goto out;
}
tll_foreach(wayl->monitors, it) { tll_foreach(wayl->monitors, it) {
LOG_INFO( LOG_INFO(
"%s: %dx%d+%dx%d@%dHz %s %.2f\" scale=%d, DPI=%.2f/%.2f (physical/scaled)", "%s: %dx%d+%dx%d@%dHz %s %.2f\" scale=%d, DPI=%.2f/%.2f (physical/scaled)",

View file

@ -455,7 +455,6 @@ struct wayland {
struct zwp_text_input_manager_v3 *text_input_manager; struct zwp_text_input_manager_v3 *text_input_manager;
#endif #endif
bool have_argb8888;
tll(struct monitor) monitors; /* All available outputs */ tll(struct monitor) monitors; /* All available outputs */
tll(struct seat) seats; tll(struct seat) seats;