config: tweak.surface-bit-depth: add 16-bit

This adds support for 16-bit (integer) surfaces. The corresponding
pixman type (PIXMAN_a16b16g16r16) was added in 0.46.0.

If the new 16-bit type is requested, but not supported by the
compositor, fallback to 16f-bit, and if that fails, 10-bit (and
finally 8-bit).
This commit is contained in:
Daniel Eklöf 2025-05-01 11:55:21 +02:00
parent 429a922723
commit 5dbf5ea89d
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
8 changed files with 60 additions and 16 deletions

View file

@ -87,9 +87,9 @@
- solarized - solarized
* `regex-copy`/`show-urls-copy` will copy and paste the selected text if the hint * `regex-copy`/`show-urls-copy` will copy and paste the selected text if the hint
is completed with an uppercase character ([#1975][1975]). is completed with an uppercase character ([#1975][1975]).
* `16f-bit` to `tweak.surface-bit-depth`. Makes foot use 16-bit * `16-bit` and `16f-bit` to `tweak.surface-bit-depth`. Makes foot use
floating point image buffers. They provide the necessary color 16-bit (integer/floating point) image buffers. They provide the
precision required by `gamma-correct-blending=yes`. necessary color precision required by `gamma-correct-blending=yes`.
[2025]: https://codeberg.org/dnkl/foot/issues/2025 [2025]: https://codeberg.org/dnkl/foot/issues/2025
[1975]: https://codeberg.org/dnkl/foot/issues/1975 [1975]: https://codeberg.org/dnkl/foot/issues/1975

View file

@ -2814,7 +2814,12 @@ parse_section_tweak(struct context *ctx)
#if defined(HAVE_PIXMAN_RGBA_FLOAT16) #if defined(HAVE_PIXMAN_RGBA_FLOAT16)
return value_to_enum( return value_to_enum(
ctx, 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); (int *)&conf->tweak.surface_bit_depth);
#else #else
return value_to_enum( return value_to_enum(

View file

@ -199,6 +199,7 @@ enum shm_bit_depth {
SHM_BITS_AUTO, SHM_BITS_AUTO,
SHM_BITS_8, SHM_BITS_8,
SHM_BITS_10, SHM_BITS_10,
SHM_BITS_16,
SHM_BITS_16F, SHM_BITS_16F,
}; };

View file

@ -2024,7 +2024,7 @@ any of these options.
*surface-bit-depth* *surface-bit-depth*
Selects which RGB bit depth to use for image buffers. One of 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 *auto* chooses bit depth depending on other settings, and
availability. availability.
@ -2036,11 +2036,12 @@ any of these options.
alpha channel. Thus, it provides higher precision color channels, alpha channel. Thus, it provides higher precision color channels,
but a lower precision alpha channel. but a lower precision alpha channel.
*16f-bit* uses 16 bits (floating point) for each color channel, *16-bit* and *16f-bit* uses 16 bits (with *16f-bit* being floating
alpha included. If available, this is the default when point) for each color channel, alpha included. If available, this
*gamma-correct-blending=yes*. 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 *8-bit*; if you want to use gamma-correct blending, and if you
prefer speed (throughput and input latency) over accurate colors, prefer speed (throughput and input latency) over accurate colors,
you can set *surface-bit-depth=8-bit* explicitly. you can set *surface-bit-depth=8-bit* explicitly.

View file

@ -150,6 +150,11 @@ if pixman.version().version_compare('>=0.44.3')
add_project_arguments('-DHAVE_PIXMAN_RGBA_FLOAT16', language: 'c') add_project_arguments('-DHAVE_PIXMAN_RGBA_FLOAT16', language: 'c')
endif 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') tllist = dependency('tllist', version: '>=1.1.0', fallback: 'tllist')
fcft = dependency('fcft', version: ['>=3.3.1', '<4.0.0'], fallback: 'fcft') fcft = dependency('fcft', version: ['>=3.3.1', '<4.0.0'], fallback: 'fcft')

42
shm.c
View file

@ -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 = false;
static bool have_logged_10_fallback = 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) #if defined(HAVE_PIXMAN_RGBA_FLOAT16)
static bool have_logged_16f_fallback = false; 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) { if (wayl->shm_have_abgr161616f && wayl->shm_have_xbgr161616f) {
pixman_fmt_without_alpha = PIXMAN_rgba_float16; pixman_fmt_without_alpha = PIXMAN_rgba_float16;
shm_fmt_without_alpha = WL_SHM_FORMAT_XBGR16161616F; 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( LOG_WARN(
"16f-bit surfaces requested, but compositor does not " "16f-bit surfaces requested, but compositor does not "
"implement ABGR161616F+XBGR161616F. Falling back to either " "implement ABGR161616F+XBGR161616F");
"10- or 8-bit surfaces");
} }
} }
} }
#endif #endif
if (desired_bit_depth == SHM_BITS_10 || if (desired_bit_depth >= SHM_BITS_10 &&
(desired_bit_depth == SHM_BITS_16F && pixman_fmt_with_alpha == PIXMAN_a8r8g8b8)
pixman_fmt_with_alpha == PIXMAN_a8r8g8b8))
{ {
if (wayl->shm_have_argb2101010 && wayl->shm_have_xrgb2101010) { if (wayl->shm_have_argb2101010 && wayl->shm_have_xrgb2101010) {
pixman_fmt_without_alpha = PIXMAN_x2r10g10b10; pixman_fmt_without_alpha = PIXMAN_x2r10g10b10;
@ -1051,7 +1079,7 @@ shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances,
LOG_WARN( LOG_WARN(
"10-bit surfaces requested, but compositor does not " "10-bit surfaces requested, but compositor does not "
"implement ARGB2101010+XRGB2101010, or " "implement ARGB2101010+XRGB2101010, or "
"ABGR2101010+XBGR2101010. Falling back to 8-bit surfaces"); "ABGR2101010+XBGR2101010");
} }
} }
} else { } else {

View file

@ -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_ARGB2101010: wayl->shm_have_argb2101010 = true; break;
case WL_SHM_FORMAT_XBGR2101010: wayl->shm_have_xbgr2101010 = 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_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_XBGR16161616F: wayl->shm_have_xbgr161616f = true; break;
case WL_SHM_FORMAT_ABGR16161616F: wayl->shm_have_abgr161616f = true; break; case WL_SHM_FORMAT_ABGR16161616F: wayl->shm_have_abgr161616f = true; break;
} }

View file

@ -498,6 +498,8 @@ struct wayland {
bool shm_have_xbgr2101010:1; bool shm_have_xbgr2101010:1;
bool shm_have_abgr161616f:1; bool shm_have_abgr161616f:1;
bool shm_have_xbgr161616f:1; bool shm_have_xbgr161616f:1;
bool shm_have_abgr161616:1;
bool shm_have_xbgr161616:1;
}; };
struct wayland *wayl_init( struct wayland *wayl_init(