diff --git a/CHANGELOG.md b/CHANGELOG.md index 24bd8a86..152c7d15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -88,6 +88,8 @@ * Ctrl+wheel up/down bound to `font-increase` and `font-decrease` respectively (in addition to the already existing default key bindings `ctrl-+` and `ctrl+-`). +* Use XRGB pixel format (instead of ARGB) when there is no + transparency. [1526]: https://codeberg.org/dnkl/foot/issues/1526 [1528]: https://codeberg.org/dnkl/foot/issues/1528 diff --git a/render.c b/render.c index c6fedfbe..4f0d2348 100644 --- a/render.c +++ b/render.c @@ -1583,7 +1583,7 @@ render_overlay(struct terminal *term) } 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); @@ -2454,7 +2454,7 @@ render_csd(struct terminal *term) } 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++) 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 *buf = shm_get_buffer(chain, width, height); + struct buffer *buf = shm_get_buffer(chain, width, height, false); wl_subsurface_set_position( 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)); 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( win->render_timer.sub, @@ -2817,7 +2817,10 @@ grid_render(struct terminal *term) xassert(term->height > 0); 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_cursor(term); @@ -3208,7 +3211,7 @@ render_search_box(struct terminal *term) size_t glyph_offset = term->render.search_glyph_offset; 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_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 *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 ? term->conf->colors.jump_label.fg diff --git a/shm.c b/shm.c index 7959a84b..fb868382 100644 --- a/shm.c +++ b/shm.c @@ -82,6 +82,7 @@ struct buffer_private { struct buffer_pool *pool; off_t offset; /* Offset into memfd where data begins */ size_t size; + bool with_alpha; bool scrollable; }; @@ -261,7 +262,7 @@ instantiate_offset(struct buffer_private *buf, off_t new_offset) wl_buf = wl_shm_pool_create_buffer( pool->wl_pool, new_offset, 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) { 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?) */ for (size_t i = 0; i < buf->public.pix_instances; i++) { 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); if (pix[i] == NULL) { LOG_ERR("failed to create pixman image"); @@ -304,7 +306,8 @@ err: static void NOINLINE get_new_buffers(struct buffer_chain *chain, size_t 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); /* @@ -322,7 +325,8 @@ get_new_buffers(struct buffer_chain *chain, size_t count, size_t total_size = 0; 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]; total_size += sizes[i]; } @@ -473,6 +477,7 @@ get_new_buffers(struct buffer_chain *chain, size_t count, .chain = chain, .ref_count = immediate_purge ? 0 : 1, .busy = true, + .with_alpha = with_alpha, .pool = pool, .offset = 0, .size = sizes[i], @@ -542,13 +547,13 @@ shm_did_not_use_buf(struct buffer *_buf) void shm_get_many(struct buffer_chain *chain, size_t 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 * -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( "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; - get_new_buffers(chain, 1, &width, &height, &ret, false); + get_new_buffers(chain, 1, &width, &height, &ret, with_alpha, false); return ret; } diff --git a/shm.h b/shm.h index 7d1796bf..b4b075ca 100644 --- a/shm.h +++ b/shm.h @@ -55,7 +55,8 @@ void shm_chain_free(struct buffer_chain *chain); * * 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 * buffer pool. @@ -73,7 +74,7 @@ struct buffer *shm_get_buffer(struct buffer_chain *chain, int width, int height) void shm_get_many( struct buffer_chain *chain, size_t 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); diff --git a/wayland.c b/wayland.c index c5feb6a1..fe3cba20 100644 --- a/wayland.c +++ b/wayland.c @@ -234,8 +234,6 @@ seat_destroy(struct seat *seat) static void shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) { - struct wayland *wayl = data; - #if defined(_DEBUG) bool have_description = false; @@ -250,9 +248,6 @@ shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) if (!have_description) LOG_DBG("shm: 0x%08x: unknown", format); #endif - - if (format == WL_SHM_FORMAT_ARGB8888) - wayl->have_argb8888 = true; } 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 */ wl_display_roundtrip(wayl->display); - if (!wayl->have_argb8888) { - LOG_ERR("compositor does not support ARGB surfaces"); - goto out; - } - tll_foreach(wayl->monitors, it) { LOG_INFO( "%s: %dx%d+%dx%d@%dHz %s %.2f\" scale=%d, DPI=%.2f/%.2f (physical/scaled)", diff --git a/wayland.h b/wayland.h index 733ebd3f..84fcbe48 100644 --- a/wayland.h +++ b/wayland.h @@ -455,7 +455,6 @@ struct wayland { struct zwp_text_input_manager_v3 *text_input_manager; #endif - bool have_argb8888; tll(struct monitor) monitors; /* All available outputs */ tll(struct seat) seats;