diff --git a/config.c b/config.c index 0de1a1be..459a1de9 100644 --- a/config.c +++ b/config.c @@ -2848,6 +2848,10 @@ parse_section_tweak(struct context *ctx) #endif } + else if (streq(key, "min-stride-alignment")) { + return value_to_uint32(ctx, 10, &conf->tweak.min_stride_alignment); + } + else { LOG_CONTEXTUAL_ERR("not a valid option: %s", key); return false; @@ -3496,6 +3500,7 @@ config_load(struct config *conf, const char *conf_path, .font_monospace_warn = true, .sixel = true, .surface_bit_depth = SHM_BITS_AUTO, + .min_stride_alignment = 256, }, .touch = { diff --git a/config.h b/config.h index 86fb2a8f..11439d3a 100644 --- a/config.h +++ b/config.h @@ -435,6 +435,7 @@ struct config { bool font_monospace_warn; bool sixel; enum shm_bit_depth surface_bit_depth; + uint32_t min_stride_alignment; } tweak; struct { diff --git a/main.c b/main.c index 1afbd16d..b6a0d825 100644 --- a/main.c +++ b/main.c @@ -597,6 +597,7 @@ main(int argc, char *const *argv) } shm_set_max_pool_size(conf.tweak.max_shm_pool_size); + shm_set_min_stride_alignment(conf.tweak.min_stride_alignment); if ((fdm = fdm_init()) == NULL) goto out; diff --git a/shm.c b/shm.c index 4680c12c..7b13db9b 100644 --- a/shm.c +++ b/shm.c @@ -13,7 +13,6 @@ #include -#include #include #define LOG_MODULE "shm" @@ -21,6 +20,7 @@ #include "log.h" #include "debug.h" #include "macros.h" +#include "stride.h" #include "xmalloc.h" #if !defined(MAP_UNINITIALIZED) @@ -61,6 +61,8 @@ static off_t max_pool_size = 512 * 1024 * 1024; static bool can_punch_hole = false; static bool can_punch_hole_initialized = false; +static size_t min_stride_alignment = 0; + struct buffer_pool { int fd; /* memfd */ struct wl_shm_pool *wl_pool; @@ -113,6 +115,12 @@ shm_set_max_pool_size(off_t _max_pool_size) max_pool_size = _max_pool_size; } +void +shm_set_min_stride_alignment(size_t _min_stride_alignment) +{ + min_stride_alignment = _min_stride_alignment; +} + static void buffer_destroy_dont_close(struct buffer *buf) { @@ -342,6 +350,13 @@ get_new_buffers(struct buffer_chain *chain, size_t count, ? chain->pixman_fmt_with_alpha : chain->pixman_fmt_without_alpha, widths[i]); + + if (min_stride_alignment > 0) { + const size_t m = min_stride_alignment; + stride[i] = (stride[i] + m - 1) / m * m; + } + + xassert(min_stride_alignment == 0 || stride[i] % min_stride_alignment == 0); sizes[i] = stride[i] * heights[i]; total_size += sizes[i]; } diff --git a/shm.h b/shm.h index 8f8c406a..6050f1c7 100644 --- a/shm.h +++ b/shm.h @@ -42,7 +42,10 @@ struct buffer { }; void shm_fini(void); + +/* TODO: combine into shm_init() */ void shm_set_max_pool_size(off_t max_pool_size); +void shm_set_min_stride_alignment(size_t min_stride_alignment); struct buffer_chain; struct buffer_chain *shm_chain_new( diff --git a/tests/test-config.c b/tests/test-config.c index 8c0805f4..64b61540 100644 --- a/tests/test-config.c +++ b/tests/test-config.c @@ -1413,6 +1413,9 @@ test_section_tweak(void) test_float(&ctx, &parse_section_tweak, "bold-text-in-bright-amount", &conf.bold_in_bright.amount); + test_uint32(&ctx, &parse_section_tweak, "min-stride-alignment", + &conf.tweak.min_stride_alignment); + #if 0 /* Must be equal to, or less than INT32_MAX */ test_uint32(&ctx, &parse_section_tweak, "max-shm-pool-size-mb", &conf.tweak.max_shm_pool_size);