mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-04-16 08:21:20 -04:00
config: tweak.surface-bit-depth: add support for 16f surfaces
This adds supports for 16F surfaces (i.e. 16-bit floating point). We haven't been able to support this until now, since there were no corresponding pixman image type. Now there is. Use the new 16f surfaces by default, when gamma-correct-blending=yes.
This commit is contained in:
parent
7354b94f73
commit
8faea42d9e
9 changed files with 88 additions and 25 deletions
11
config.c
11
config.c
|
|
@ -2809,12 +2809,21 @@ 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");
|
||||||
|
|
||||||
|
/* TODO: check which version PIXMAN_rgba_float16 ended up in;
|
||||||
|
guessing 0.47.0, but PR is currently stuck at 0.44.3 */
|
||||||
|
#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0, 44, 3)
|
||||||
|
return value_to_enum(
|
||||||
|
ctx,
|
||||||
|
(const char *[]){"auto", "8-bit", "10-bit", "16f-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_16F,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct config {
|
struct config {
|
||||||
|
|
|
||||||
|
|
@ -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 *16f-bit*.
|
||||||
|
|
||||||
*auto* chooses bit depth depending on other settings, and
|
*auto* chooses bit depth depending on other settings, and
|
||||||
availability.
|
availability.
|
||||||
|
|
@ -2033,13 +2034,16 @@ 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
|
*16f-bit* uses 16 bits (floating point) for each color channel,
|
||||||
gamma-correct blending, and if you prefer speed (throughput and
|
alpha included. If available, this is the default when
|
||||||
input latency) over accurate colors, you can set
|
*gamma-correct-blending=yes*.
|
||||||
*surface-bit-depth=8-bit* explicitly.
|
|
||||||
|
Note that both *10-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.
|
||||||
|
|
||||||
Default: _auto_
|
Default: _auto_
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,7 @@ endif
|
||||||
math = cc.find_library('m')
|
math = cc.find_library('m')
|
||||||
threads = [dependency('threads'), cc.find_library('stdthreads', required: false)]
|
threads = [dependency('threads'), cc.find_library('stdthreads', required: false)]
|
||||||
libepoll = dependency('epoll-shim', required: false)
|
libepoll = dependency('epoll-shim', required: false)
|
||||||
pixman = dependency('pixman-1')
|
pixman = dependency('pixman-1', fallback: 'pixman')
|
||||||
wayland_protocols = dependency('wayland-protocols', version: '>=1.41',
|
wayland_protocols = dependency('wayland-protocols', version: '>=1.41',
|
||||||
fallback: 'wayland-protocols',
|
fallback: 'wayland-protocols',
|
||||||
default_options: ['tests=false'])
|
default_options: ['tests=false'])
|
||||||
|
|
|
||||||
48
shm.c
48
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,37 @@ 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_16f_fallback = false;
|
||||||
|
static bool have_logged_10_fallback = false;
|
||||||
|
|
||||||
if (desired_bit_depth == SHM_BITS_10) {
|
if (desired_bit_depth == SHM_BITS_16F) {
|
||||||
|
if (wayl->shm_have_abgr161616f && wayl->shm_have_xbgr161616f) {
|
||||||
|
pixman_fmt_without_alpha = PIXMAN_rgba_float16;
|
||||||
|
shm_fmt_without_alpha = WL_SHM_FORMAT_XBGR16161616F;
|
||||||
|
|
||||||
|
pixman_fmt_with_alpha = PIXMAN_rgba_float16;
|
||||||
|
shm_fmt_with_alpha = WL_SHM_FORMAT_ABGR16161616F;
|
||||||
|
|
||||||
|
if (!have_logged) {
|
||||||
|
have_logged = true;
|
||||||
|
LOG_INFO("using 16-bit (float) BGR surfaces");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!have_logged_16f_fallback) {
|
||||||
|
have_logged_16f_fallback = true;
|
||||||
|
|
||||||
|
LOG_WARN(
|
||||||
|
"16f-bit surfaces requested, but compositor does not "
|
||||||
|
"implement ABGR161616F+XBGR161616F. Falling back to either "
|
||||||
|
"10- or 8-bit surfaces");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desired_bit_depth == SHM_BITS_10 ||
|
||||||
|
(desired_bit_depth == SHM_BITS_16F &&
|
||||||
|
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,8 +1042,8 @@ 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 "
|
||||||
|
|
@ -1063,7 +1095,9 @@ 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;
|
: fmt == PIXMAN_rgba_float16
|
||||||
|
? SHM_BITS_16F
|
||||||
|
: 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 16f 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;
|
||||||
|
|
|
||||||
|
|
@ -1259,7 +1259,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_16F : 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_XBGR16161616F: wayl->shm_have_xbgr161616f = true; break;
|
||||||
|
case WL_SHM_FORMAT_ABGR16161616F: wayl->shm_have_abgr161616f = 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_abgr161616f:1;
|
||||||
|
bool shm_have_xbgr161616f:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wayland *wayl_init(
|
struct wayland *wayl_init(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue