1
0
Fork 0
forked from wry/wry
wry/book/src/hdr.md
2026-03-21 23:04:25 +01:00

315 lines
8.8 KiB
Markdown

# HDR & Color Management
Jay supports HDR (High Dynamic Range) output and the Wayland color management
protocol. This chapter explains how HDR works in Jay and walks through
enabling it.
## Prerequisites
HDR in Jay requires:
- The **Vulkan renderer**. The OpenGL renderer does not support color
management or HDR. Vulkan is the default when available; you can verify
with `jay randr show` (look for the "Api" field under your GPU) or switch
to it in the [control center](control-center.md) GPUs pane.
- A **monitor that supports HDR**. The display must advertise PQ (Perceptual
Quantizer) support and BT.2020 colorimetry through its EDID. Run
`jay randr show` to see which color spaces and EOTFs your display supports.
## Quick start
Enable HDR10 on a specific output using the CLI:
```shell
~$ jay randr output DP-1 colors set bt2020 pq
```
Or in your configuration file:
```toml
[[outputs]]
match.serial-number = "33K03894SL0"
color-space = "bt2020"
transfer-function = "pq"
```
Enable the color management protocol so that applications can communicate
their color spaces to the compositor:
```shell
~$ jay color-management enable
```
Or in your configuration file:
```toml
[color-management]
enabled = true
```
To return to SDR:
```shell
~$ jay randr output DP-1 colors set default default
```
> [!NOTE]
> Run `jay randr` to find connector names and serial numbers for your
> displays.
## Concepts
### Color space
The color space determines the range of colors (gamut) the output uses.
`default`
: sRGB gamut. This is the standard gamut for desktop displays.
`bt2020`
: BT.2020 gamut. A much wider gamut used by HDR10 and modern cinema standards.
### Transfer function (EOTF)
The transfer function (technically the Electro-Optical Transfer Function)
controls how encoded pixel values are mapped to display luminance.
`default`
: Gamma 2.2. The traditional SDR transfer function.
`pq`
: Perceptual Quantizer (SMPTE ST 2084). The HDR10 transfer function, designed
to cover luminance levels from 0 to 10,000 cd/m^2.
Setting `color-space = "bt2020"` and `transfer-function = "pq"` together
activates HDR10 mode. Jay sends the appropriate HDR metadata infoframe to the
display, including the display's mastering luminance and primaries from its
EDID.
### Brightness
The brightness setting controls SDR content luminance in cd/m^2. This
determines how bright non-HDR content appears on an HDR display.
With the `default` (gamma 2.2) transfer function, the default brightness is
the maximum the display supports, anchored at 80 cd/m^2. Setting brightness
below 80 makes SDR content dimmer while creating HDR headroom above it.
With the `pq` transfer function, the default brightness is 203 cd/m^2 (the
ITU reference level for SDR content in an HDR signal).
```toml
[[outputs]]
match.serial-number = "33K03894SL0"
color-space = "bt2020"
transfer-function = "pq"
brightness = 250
```
```shell
~$ jay randr output DP-1 brightness 250
~$ jay randr output DP-1 brightness default
```
> [!NOTE]
> Brightness has no effect unless the Vulkan renderer is in use.
### Blend space
When Jay composites overlapping translucent surfaces, the blend space
determines in which color space the alpha blending is performed.
`srgb`
: Classic desktop blending in sRGB space. This is the default and matches the
behavior of most other compositors.
`linear`
: Blending in linear light. This is physically correct but can make
semi-transparent elements appear brighter than expected.
```toml
[[outputs]]
match.serial-number = "33K03894SL0"
blend-space = "linear"
```
```shell
~$ jay randr output DP-1 blend-space linear
```
### Native gamut
By default, Jay assumes all displays use sRGB primaries. This matches the
behavior of most other compositors, but most modern displays actually have a
wider gamut (e.g. 95% DCI-P3 coverage). Because the display interprets
sRGB-intended color values in its wider native gamut, colors appear more
saturated than they should.
Setting `use-native-gamut = true` tells Jay the display's actual primaries
from its EDID, allowing the compositor to map colors correctly. This produces
less saturated but more accurate colors, and allows color-managed applications
to address the full display gamut.
```toml
[[outputs]]
match.serial-number = "33K03894SL0"
use-native-gamut = true
```
```shell
~$ jay randr output DP-1 use-native-gamut true
```
This setting has no effect when the display is already operating in a wide
color space like BT.2020.
### Framebuffer format
The default framebuffer format (`xrgb8888`) uses 8 bits per channel, which
can cause banding in HDR content. For HDR, consider a higher-precision format:
- `xrgb2101010` or `argb2101010` -- 10 bits per channel. Good balance between
precision and performance.
- `xbgr16161616f` or `abgr16161616f` -- 16-bit floating point per channel.
Maximum precision.
```toml
[[outputs]]
match.serial-number = "33K03894SL0"
color-space = "bt2020"
transfer-function = "pq"
format = "xrgb2101010"
```
```shell
~$ jay randr output DP-1 format set xrgb2101010
```
> [!TIP]
> Run `jay randr show --formats` to see which formats your display supports.
## Color management protocol
The Wayland color management protocol (`wp_color_manager_v1`) lets
applications communicate their color space to the compositor. This enables
color-aware applications to render correctly regardless of the output's color
settings -- for example, an image viewer can tag its surfaces as sRGB and Jay
will map the colors to the output's actual gamut and transfer function.
The protocol is **disabled by default** and must be enabled explicitly:
```toml
[color-management]
enabled = true
```
Or at runtime:
```shell
~$ jay color-management enable
```
> [!NOTE]
> Changing this setting has no effect on applications that are already running.
> They must be restarted to discover the protocol.
Color management availability requires both the protocol to be enabled **and**
the Vulkan renderer to be active. Check with:
```shell
~$ jay color-management status
```
This prints one of:
`Enabled`
: The protocol is enabled and available to clients.
`Enabled (Unavailable)`
: The protocol is enabled but unavailable -- usually because the OpenGL
renderer is in use.
`Disabled`
: The protocol is disabled.
The [control center](control-center.md) **Color Management** pane shows the
same information as a toggle and a read-only availability indicator.
### Supported capabilities
Jay's color management implementation supports:
- **Parametric image descriptions** with custom primaries, luminances, and
transfer functions (including power curves).
- **Named primaries**: sRGB, BT.2020, DCI-P3, Display P3, Adobe RGB, and
others.
- **Named transfer functions**: sRGB, PQ (ST 2084), gamma 2.2, gamma 2.4,
BT.1886, linear, and others.
- **Mastering display metadata** for HDR content.
- **Windows scRGB** compatibility.
ICC profile creation is not supported.
## Checking display capabilities
Use `jay randr show` to inspect what your display supports:
```shell
~$ jay randr show
```
The output for each connector includes:
- **Color spaces** -- which color spaces the display supports (e.g. `default`,
`bt2020`), with the current setting marked.
- **EOTFs** -- which transfer functions the display supports (e.g. `default`,
`pq`), with the current setting marked.
- **Brightness range** -- minimum and maximum luminance from the EDID, in
cd/m^2.
- **Current brightness** -- displayed if a custom value is set.
- **Blend space** -- current blend space setting.
- **Native gamut** -- the display's CIE xy primaries for red, green, blue, and
white point.
## Complete example
A typical HDR configuration for a monitor that supports HDR10:
```toml
[[outputs]]
match.serial-number = "33K03894SL0"
color-space = "bt2020"
transfer-function = "pq"
brightness = 203
format = "xrgb2101010"
blend-space = "linear"
[color-management]
enabled = true
```
This sets the output to HDR10 with 10-bit color, physically correct blending,
and enables the color management protocol so applications can communicate
their color spaces.
## Control center
The Outputs pane in the [control center](control-center.md) (`alt-c` by
default) provides GUI controls for all HDR-related settings per output:
Colorimetry, EOTF, Custom Brightness, Format, Blend Space, Use Native Gamut,
and a read-only Native Gamut display. See
[Outputs (Monitors)](configuration/outputs.md) for details on each field.
The Color Management pane has a toggle to enable/disable the protocol and a
read-only indicator showing whether color management is currently available.
## See also
- [Outputs (Monitors)](configuration/outputs.md) -- per-output configuration
reference including all color and HDR fields
- [Miscellaneous](configuration/misc.md) -- the `[color-management]` config
table
- [Command-Line Interface](cli.md) -- `jay randr output` color commands and
`jay color-management`
- [GPUs](configuration/gpu.md) -- renderer selection (Vulkan is required for
HDR)