diff --git a/CHANGELOG.md b/CHANGELOG.md index 54bb5742..8d417257 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -87,9 +87,9 @@ - solarized * `regex-copy`/`show-urls-copy` will copy and paste the selected text if the hint is completed with an uppercase character ([#1975][1975]). -* `16f-bit` to `tweak.surface-bit-depth`. Makes foot use 16-bit - floating point image buffers. They provide the necessary color - precision required by `gamma-correct-blending=yes`. +* `16-bit` and `16f-bit` to `tweak.surface-bit-depth`. Makes foot use + 16-bit (integer/floating point) image buffers. They provide the + necessary color precision required by `gamma-correct-blending=yes`. [2025]: https://codeberg.org/dnkl/foot/issues/2025 [1975]: https://codeberg.org/dnkl/foot/issues/1975 diff --git a/config.c b/config.c index 2ff4c4cd..0bf846f6 100644 --- a/config.c +++ b/config.c @@ -2814,7 +2814,12 @@ parse_section_tweak(struct context *ctx) #if defined(HAVE_PIXMAN_RGBA_FLOAT16) return value_to_enum( ctx, - (const char *[]){"auto", "8-bit", "10-bit", "16f-bit", NULL}, + (const char *[]){"auto", "8-bit", "10-bit", "16-bit", "16f-bit", NULL}, + (int *)&conf->tweak.surface_bit_depth); +#elif defined(HAVE_PIXMAN_RGBA_16) + return value_to_enum( + ctx, + (const char *[]){"auto", "8-bit", "10-bit", "16-bit", NULL}, (int *)&conf->tweak.surface_bit_depth); #else return value_to_enum( diff --git a/config.h b/config.h index eb5c9651..63873edb 100644 --- a/config.h +++ b/config.h @@ -199,6 +199,7 @@ enum shm_bit_depth { SHM_BITS_AUTO, SHM_BITS_8, SHM_BITS_10, + SHM_BITS_16, SHM_BITS_16F, }; diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 502fd267..bd0d2a92 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -2024,7 +2024,7 @@ any of these options. *surface-bit-depth* Selects which RGB bit depth to use for image buffers. One of - *auto*, *8-bit*, *10-bit*, or *16f-bit*. + *auto*, *8-bit*, *10-bit*, *16-bit*, or *16f-bit*. *auto* chooses bit depth depending on other settings, and availability. @@ -2036,11 +2036,12 @@ any of these options. alpha channel. Thus, it provides higher precision color channels, but a lower precision alpha channel. - *16f-bit* uses 16 bits (floating point) for each color channel, - alpha included. If available, this is the default when - *gamma-correct-blending=yes*. + *16-bit* and *16f-bit* uses 16 bits (with *16f-bit* being floating + point) for each color channel, alpha included. If available, this + is the default when *gamma-correct-blending=yes* (with *16-bit* + being preferred over *16f-bit*). - Note that both *10-bit* and *16f-bit* are much slower than + Note that both *10-bit*, *16-bit* and *16f-bit* are much slower than *8-bit*; if you want to use gamma-correct blending, and if you prefer speed (throughput and input latency) over accurate colors, you can set *surface-bit-depth=8-bit* explicitly. diff --git a/meson.build b/meson.build index 5fe77aea..d8e300e1 100644 --- a/meson.build +++ b/meson.build @@ -150,6 +150,11 @@ if pixman.version().version_compare('>=0.44.3') add_project_arguments('-DHAVE_PIXMAN_RGBA_FLOAT16', language: 'c') endif +# TODO: 0.46.0 +if pixman.version().version_compare('>=0.44.3') + add_project_arguments('-DHAVE_PIXMAN_RGBA_16', language: 'c') +endif + tllist = dependency('tllist', version: '>=1.1.0', fallback: 'tllist') fcft = dependency('fcft', version: ['>=3.3.1', '<4.0.0'], fallback: 'fcft') diff --git a/shm.c b/shm.c index 9c227e45..afdf4b6b 100644 --- a/shm.c +++ b/shm.c @@ -986,10 +986,40 @@ shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances, static bool have_logged = false; static bool have_logged_10_fallback = false; +#if defined(HAVE_PIXMAN_RGBA_16) + static bool have_logged_16_fallback = false; + + if (desired_bit_depth == SHM_BITS_16) { + if (wayl->shm_have_abgr161616 && wayl->shm_have_xbgr161616) { + pixman_fmt_without_alpha = PIXMAN_a16b16g16r16; + shm_fmt_without_alpha = WL_SHM_FORMAT_XBGR16161616; + + pixman_fmt_without_alpha = PIXMAN_a16b16g16r16; + shm_fmt_with_alpha = WL_SHM_FORMAT_ABGR16161616; + + if (!have_logged) { + have_logged = true; + LOG_INFO("using 16-bit BGR surfaces"); + } + } else { + if (!have_logged_16_fallback) { + have_logged_16_fallback = true; + + LOG_WARN( + "16-bit surfaces requested, but compositor does not " + "implement ABGR161616+XBGR161616"); + } + } + } +#endif + #if defined(HAVE_PIXMAN_RGBA_FLOAT16) static bool have_logged_16f_fallback = false; - if (desired_bit_depth == SHM_BITS_16F) { + if (desired_bit_depth == SHM_BITS_16F || + (desired_bit_depth == SHM_BITS_16 && + pixman_fmt_with_alpha == PIXMAN_a8r8g8b8)) + { if (wayl->shm_have_abgr161616f && wayl->shm_have_xbgr161616f) { pixman_fmt_without_alpha = PIXMAN_rgba_float16; shm_fmt_without_alpha = WL_SHM_FORMAT_XBGR16161616F; @@ -1007,16 +1037,14 @@ shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances, LOG_WARN( "16f-bit surfaces requested, but compositor does not " - "implement ABGR161616F+XBGR161616F. Falling back to either " - "10- or 8-bit surfaces"); + "implement ABGR161616F+XBGR161616F"); } } } #endif - if (desired_bit_depth == SHM_BITS_10 || - (desired_bit_depth == SHM_BITS_16F && - pixman_fmt_with_alpha == PIXMAN_a8r8g8b8)) + if (desired_bit_depth >= SHM_BITS_10 && + pixman_fmt_with_alpha == PIXMAN_a8r8g8b8) { if (wayl->shm_have_argb2101010 && wayl->shm_have_xrgb2101010) { pixman_fmt_without_alpha = PIXMAN_x2r10g10b10; @@ -1051,7 +1079,7 @@ shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances, LOG_WARN( "10-bit surfaces requested, but compositor does not " "implement ARGB2101010+XRGB2101010, or " - "ABGR2101010+XBGR2101010. Falling back to 8-bit surfaces"); + "ABGR2101010+XBGR2101010"); } } } else { diff --git a/wayland.c b/wayland.c index b8003d83..a3c5e722 100644 --- a/wayland.c +++ b/wayland.c @@ -244,6 +244,8 @@ shm_format(void *data, struct wl_shm *wl_shm, uint32_t format) case WL_SHM_FORMAT_ARGB2101010: wayl->shm_have_argb2101010 = true; break; case WL_SHM_FORMAT_XBGR2101010: wayl->shm_have_xbgr2101010 = true; break; case WL_SHM_FORMAT_ABGR2101010: wayl->shm_have_abgr2101010 = true; break; + case WL_SHM_FORMAT_XBGR16161616: wayl->shm_have_xbgr161616 = true; break; + case WL_SHM_FORMAT_ABGR16161616: wayl->shm_have_abgr161616 = true; break; case WL_SHM_FORMAT_XBGR16161616F: wayl->shm_have_xbgr161616f = true; break; case WL_SHM_FORMAT_ABGR16161616F: wayl->shm_have_abgr161616f = true; break; } diff --git a/wayland.h b/wayland.h index 9e69e4a2..d693c686 100644 --- a/wayland.h +++ b/wayland.h @@ -498,6 +498,8 @@ struct wayland { bool shm_have_xbgr2101010:1; bool shm_have_abgr161616f:1; bool shm_have_xbgr161616f:1; + bool shm_have_abgr161616:1; + bool shm_have_xbgr161616:1; }; struct wayland *wayl_init(