mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-05 04:06:08 -05:00
config: tweak.surface-bit-depth: add support for 16-bit surfaces
This adds supports for 16-bit surfaces, using the new PIXMAN_a16b16g16r16 buffer format. This maps to WL_SHM_FORMAT_ABGR16161616 (little-endian). Use the new 16-bit surfaces by default, when gamma-correct-blending=yes.
This commit is contained in:
parent
7354b94f73
commit
970e13db8d
10 changed files with 101 additions and 25 deletions
|
|
@ -87,6 +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]).
|
||||||
|
* `16-bit` to `tweak.surface-bit-depth`. Makes foot use 16-bit image
|
||||||
|
buffers. They provide the 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
|
||||||
|
|
@ -98,6 +101,8 @@
|
||||||
* OSC-11 without an alpha value will now restore the configured
|
* OSC-11 without an alpha value will now restore the configured
|
||||||
(i.e. from `foot.ini`) alpha, rather than keeping whatever the
|
(i.e. from `foot.ini`) alpha, rather than keeping whatever the
|
||||||
current alpha value is, unchanged.
|
current alpha value is, unchanged.
|
||||||
|
* `gamma-correct-blending=yes` now defaults to `16-bit` image buffers,
|
||||||
|
instead of `10-bit`.
|
||||||
|
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
|
||||||
9
config.c
9
config.c
|
|
@ -2809,12 +2809,19 @@ parse_section_tweak(struct context *ctx)
|
||||||
|
|
||||||
else if (streq(key, "surface-bit-depth")) {
|
else if (streq(key, "surface-bit-depth")) {
|
||||||
_Static_assert(sizeof(conf->tweak.surface_bit_depth) == sizeof(int),
|
_Static_assert(sizeof(conf->tweak.surface_bit_depth) == sizeof(int),
|
||||||
"enum is not 32-bit");
|
"enum is not 32-bit");
|
||||||
|
|
||||||
|
#if 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(
|
return value_to_enum(
|
||||||
ctx,
|
ctx,
|
||||||
(const char *[]){"auto", "8-bit", "10-bit", NULL},
|
(const char *[]){"auto", "8-bit", "10-bit", NULL},
|
||||||
(int *)&conf->tweak.surface_bit_depth);
|
(int *)&conf->tweak.surface_bit_depth);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
3
config.h
3
config.h
|
|
@ -198,7 +198,8 @@ enum which_color_theme {
|
||||||
enum shm_bit_depth {
|
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,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct config {
|
struct config {
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ empty string to be set, but it must be quoted: *KEY=""*)
|
||||||
Compared to the default (disabled), bright glyphs on a dark
|
Compared to the default (disabled), bright glyphs on a dark
|
||||||
background will appear thicker, and dark glyphs on a light
|
background will appear thicker, and dark glyphs on a light
|
||||||
background will appear thinner.
|
background will appear thinner.
|
||||||
|
|
||||||
FreeType can limit the effect of the latter, with a technique
|
FreeType can limit the effect of the latter, with a technique
|
||||||
called stem darkening. It is only available for CFF fonts
|
called stem darkening. It is only available for CFF fonts
|
||||||
(OpenType, .otf) and disabled by default (in FreeType). You can
|
(OpenType, .otf) and disabled by default (in FreeType). You can
|
||||||
|
|
@ -221,12 +221,13 @@ empty string to be set, but it must be quoted: *KEY=""*)
|
||||||
font designer set the font weight based on incorrect rendering.
|
font designer set the font weight based on incorrect rendering.
|
||||||
|
|
||||||
In order to represent colors faithfully, higher precision image
|
In order to represent colors faithfully, higher precision image
|
||||||
buffers are required. By default, foot will use 10-bit color
|
buffers are required. By default, foot will use either 16-bit, or
|
||||||
channels, if available, when gamma-correct blending is
|
10-bit color channels, depending on availability, when
|
||||||
enabled. However, the high precision buffers are slow; if you want
|
gamma-correct blending is enabled. However, the high precision
|
||||||
to use gamma-correct blending, but prefer speed (throughput and
|
buffers are slow; if you want to use gamma-correct blending, but
|
||||||
input latency) over accurate colors, you can force 8-bit color
|
prefer speed (throughput and input latency) over accurate colors,
|
||||||
channels by setting *tweak.surface-bit-depth=8-bit*.
|
you can force 8-bit color channels by setting
|
||||||
|
*tweak.surface-bit-depth=8-bit*.
|
||||||
|
|
||||||
Default: _no_.
|
Default: _no_.
|
||||||
|
|
||||||
|
|
@ -2023,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*, or *10-bit*.
|
*auto*, *8-bit*, *10-bit* or *16-bit*.
|
||||||
|
|
||||||
*auto* chooses bit depth depending on other settings, and
|
*auto* chooses bit depth depending on other settings, and
|
||||||
availability.
|
availability.
|
||||||
|
|
@ -2033,12 +2034,14 @@ any of these options.
|
||||||
|
|
||||||
*10-bit* uses 10 bits for each RGB channel, and 2 bits for the
|
*10-bit* uses 10 bits for each RGB channel, and 2 bits for the
|
||||||
alpha channel. Thus, it provides higher precision color channels,
|
alpha channel. Thus, it provides higher precision color channels,
|
||||||
but a lower precision alpha channel. It is the default when
|
but a lower precision alpha channel.
|
||||||
*gamma-correct-blending=yes*, if supported by the compositor.
|
|
||||||
|
|
||||||
Note that *10-bit* is much slower than *8-bit*; if you want to use
|
*16-bit* 16 bits for each color channel, alpha included. If
|
||||||
gamma-correct blending, and if you prefer speed (throughput and
|
available, this is the default when *gamma-correct-blending=yes*.
|
||||||
input latency) over accurate colors, you can set
|
|
||||||
|
Note that both *10-bit* and *16-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.
|
*surface-bit-depth=8-bit* explicitly.
|
||||||
|
|
||||||
Default: _auto_
|
Default: _auto_
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,10 @@ if utf8proc.found()
|
||||||
add_project_arguments('-DFOOT_GRAPHEME_CLUSTERING=1', language: 'c')
|
add_project_arguments('-DFOOT_GRAPHEME_CLUSTERING=1', language: 'c')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if pixman.version().version_compare('>=0.46.0')
|
||||||
|
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')
|
||||||
|
|
||||||
|
|
|
||||||
53
shm.c
53
shm.c
|
|
@ -338,7 +338,10 @@ 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(
|
stride[i] = stride_for_format_and_width(
|
||||||
with_alpha ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8, widths[i]);
|
with_alpha
|
||||||
|
? chain->pixman_fmt_with_alpha
|
||||||
|
: chain->pixman_fmt_without_alpha,
|
||||||
|
widths[i]);
|
||||||
sizes[i] = stride[i] * heights[i];
|
sizes[i] = stride[i] * heights[i];
|
||||||
total_size += sizes[i];
|
total_size += sizes[i];
|
||||||
}
|
}
|
||||||
|
|
@ -981,8 +984,38 @@ shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances,
|
||||||
enum wl_shm_format shm_fmt_with_alpha = WL_SHM_FORMAT_ARGB8888;
|
enum wl_shm_format shm_fmt_with_alpha = WL_SHM_FORMAT_ARGB8888;
|
||||||
|
|
||||||
static bool have_logged = false;
|
static bool have_logged = false;
|
||||||
|
static bool have_logged_10_fallback = false;
|
||||||
|
|
||||||
if (desired_bit_depth == SHM_BITS_10) {
|
#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 (desired_bit_depth >= SHM_BITS_10 &&
|
||||||
|
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;
|
||||||
shm_fmt_without_alpha = WL_SHM_FORMAT_XRGB2101010;
|
shm_fmt_without_alpha = WL_SHM_FORMAT_XRGB2101010;
|
||||||
|
|
@ -1010,13 +1043,13 @@ shm_chain_new(struct wayland *wayl, bool scrollable, size_t pix_instances,
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (!have_logged) {
|
if (!have_logged_10_fallback) {
|
||||||
have_logged = true;
|
have_logged_10_fallback = true;
|
||||||
|
|
||||||
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 {
|
||||||
|
|
@ -1063,7 +1096,11 @@ shm_chain_bit_depth(const struct buffer_chain *chain)
|
||||||
{
|
{
|
||||||
const pixman_format_code_t fmt = chain->pixman_fmt_with_alpha;
|
const pixman_format_code_t fmt = chain->pixman_fmt_with_alpha;
|
||||||
|
|
||||||
return (fmt == PIXMAN_a2r10g10b10 || fmt == PIXMAN_a2b10g10r10)
|
return fmt == PIXMAN_a8r8g8b8
|
||||||
? SHM_BITS_10
|
? SHM_BITS_8
|
||||||
: SHM_BITS_8;
|
#if defined(HAVE_PIXMAN_RGBA_16)
|
||||||
|
: fmt == PIXMAN_a16b16g16r16
|
||||||
|
? SHM_BITS_16
|
||||||
|
#endif
|
||||||
|
: SHM_BITS_10;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
sixel.c
13
sixel.c
|
|
@ -113,7 +113,18 @@ sixel_init(struct terminal *term, int p1, int p2, int p3)
|
||||||
term->sixel.linear_blending = wayl_do_linear_blending(term->wl, term->conf);
|
term->sixel.linear_blending = wayl_do_linear_blending(term->wl, term->conf);
|
||||||
term->sixel.pixman_fmt = PIXMAN_a8r8g8b8;
|
term->sixel.pixman_fmt = PIXMAN_a8r8g8b8;
|
||||||
|
|
||||||
if (term->conf->tweak.surface_bit_depth == SHM_BITS_10) {
|
/*
|
||||||
|
* Use higher-precision sixel surfaces if we're using
|
||||||
|
* higher-precision window surfaces.
|
||||||
|
*
|
||||||
|
* This is to a) get more accurate colors when doing gamma-correct
|
||||||
|
* blending, and b) use the same pixman format as the main
|
||||||
|
* surfaces, for (hopefully) better performance.
|
||||||
|
*
|
||||||
|
* For now, don't support 16-bit surfaces (too much sixel logic
|
||||||
|
* that assumes 32-bit pixels).
|
||||||
|
*/
|
||||||
|
if (shm_chain_bit_depth(term->render.chains.grid) >= SHM_BITS_10) {
|
||||||
if (term->wl->shm_have_argb2101010 && term->wl->shm_have_xrgb2101010) {
|
if (term->wl->shm_have_argb2101010 && term->wl->shm_have_xrgb2101010) {
|
||||||
term->sixel.use_10bit = true;
|
term->sixel.use_10bit = true;
|
||||||
term->sixel.pixman_fmt = PIXMAN_a2r10g10b10;
|
term->sixel.pixman_fmt = PIXMAN_a2r10g10b10;
|
||||||
|
|
|
||||||
|
|
@ -1082,7 +1082,11 @@ reload_fonts(struct terminal *term, bool resize_grid)
|
||||||
* an a2r10g0b10 type of surface, since we need more than 2
|
* an a2r10g0b10 type of surface, since we need more than 2
|
||||||
* bits for alpha.
|
* bits for alpha.
|
||||||
*/
|
*/
|
||||||
|
#if defined(HAVE_PIXMAN_RGBA_16)
|
||||||
|
options->color_glyphs.format = PIXMAN_a16b16g16r16;
|
||||||
|
#else
|
||||||
options->color_glyphs.format = PIXMAN_rgba_float;
|
options->color_glyphs.format = PIXMAN_rgba_float;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fcft_font *fonts[4];
|
struct fcft_font *fonts[4];
|
||||||
|
|
@ -1259,7 +1263,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
|
||||||
|
|
||||||
const enum shm_bit_depth desired_bit_depth =
|
const enum shm_bit_depth desired_bit_depth =
|
||||||
conf->tweak.surface_bit_depth == SHM_BITS_AUTO
|
conf->tweak.surface_bit_depth == SHM_BITS_AUTO
|
||||||
? wayl_do_linear_blending(wayl, conf) ? SHM_BITS_10 : SHM_BITS_8
|
? wayl_do_linear_blending(wayl, conf) ? SHM_BITS_16 : SHM_BITS_8
|
||||||
: conf->tweak.surface_bit_depth;
|
: conf->tweak.surface_bit_depth;
|
||||||
|
|
||||||
const struct color_theme *theme = NULL;
|
const struct color_theme *theme = NULL;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(_DEBUG)
|
#if defined(_DEBUG)
|
||||||
|
|
|
||||||
|
|
@ -496,6 +496,8 @@ struct wayland {
|
||||||
bool shm_have_xrgb2101010:1;
|
bool shm_have_xrgb2101010:1;
|
||||||
bool shm_have_abgr2101010:1;
|
bool shm_have_abgr2101010:1;
|
||||||
bool shm_have_xbgr2101010:1;
|
bool shm_have_xbgr2101010:1;
|
||||||
|
bool shm_have_abgr161616:1;
|
||||||
|
bool shm_have_xbgr161616:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wayland *wayl_init(
|
struct wayland *wayl_init(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue