add hdr support#18
Conversation
This commit introduces the `wp_color_management_v1` Wayland protocol, allowing clients to provide parametric image descriptions for surfaces. This enables the compositor to correctly interpret and display content on various display types, such as HDR or wide-gamut monitors. The implementation focuses on parametric descriptions (primaries, transfer functions, luminances) and explicitly does not support ICC profiles, aligning with the scope of GLES-based rendering pipelines.
Introduce core types for managing output color modes (SDR/HDR10) and blending spaces (sRGB/Linear BT.2020). This includes enabling 10-bit scanout formats (ABGR/ARGB2101010) and integrating a new color management protocol, laying the groundwork for full HDR support.
Introduce detailed parametric descriptions for color primaries, transfer characteristics, and luminances via `ImageDescription`. These types form the basis for `wp_color_management_v1` and DRM metadata signaling. Implement logic to dynamically resolve the `OutputColorMode` for each connector, factoring in EDID capabilities and the `SHOJI_HDR_OUTPUTS` experimental gate. Per-output state now captures a synthesized `ImageDescription` based on the resolved mode. Note that while HDR signaling is enabled, the compositor's blend space remains sRGB; full linear BT.2020 blending is a future phase.
Introduce `Chromaticity` and `PrimariesChromaticities` types to represent CIE 1931 color primary and white point data for standards like sRGB (BT.709) and BT.2020. This also includes utility methods for encoding this data into formats used by the Wayland color management protocol (`wp_image_description_info_v1`) and DRM HDR metadata (CTA-861-G).
This module introduces functionality to read HDR static metadata from a connector's EDID, determining capabilities like EOTF support and luminance ranges. It also implements the signaling mechanism for HDR10 output, configuring DRM connector properties such as `max bpc`, `Colorspace` (to BT2020_RGB), and `HDR_OUTPUT_METADATA` (SMPTE ST 2086 / CTA-861.3 blob) to inform the display about the incoming HDR signal. These properties are set using legacy `SET_PROPERTY` ioctl to ensure persistence across smithay's atomic commits. A reset function is provided for transitioning back to SDR.
This change fully implements the `wp_color_management_v1` Wayland protocol for parametric image descriptions. It allows clients to query output color capabilities, provide color descriptions for their surfaces, and request preferred descriptions from the compositor. HDR features, such as BT.2020 primaries and ST.2084 PQ transfer functions, are now dynamically advertised based on the `SHOJI_HDR_OUTPUTS` experiment gate, ensuring clients only use capabilities the compositor supports. The implementation includes comprehensive state management and error handling for all protocol objects.
This change integrates the previously introduced EDID HDR probing and DRM HDR10 signaling into the output connection process. When a connector is detected, its color pipeline is resolved, determining if HDR10 signaling is applicable based on EDID. The necessary DRM connector properties are configured to signal HDR to the display. The resolved output color state is then stored and made available to Wayland clients via the `wp_color_management_v1` protocol.
The kernel only frees DRM property blobs when the device file descriptor closes. Since the DRM device remains open across hotplug cycles, explicitly destroy HDR metadata blobs when an output disconnects to prevent resource leaks during replug cycles.
Extract the logic for destroying HDR output metadata blobs into a dedicated helper function. This centralizes the destruction process, adds error logging, and improves code organization within the color management backend.
Adjust how enum property values are retrieved from the `drm` crate's `ValueType::Enum` variant to match an API change. The values are now accessed via `values().1`.
These tests verify the correct extraction of HDR static metadata from EDID blocks. They also confirm that the Rust `HdrOutputMetadata` and `HdrMetadataInfoframe` structs match the expected kernel ABI, which is crucial to prevent silent corruption of HDR infoframe data passed to the display.
Provides Rust implementations for RGB-XYZ matrix derivation and SMPTE ST 2084 (PQ) curves. Unit tests use these to validate hardcoded color transformation constants in GLSL shaders, preventing subtle color errors.
The `ModeTypeFlags` import and its associated `_keep_mode_type_flags` function were a temporary workaround to silence dead-code warnings. They are no longer necessary.
This flag is probed once per device to indicate if the GPU can render into fp16 targets. It gates HDR10 output modes, which require fp16 intermediates.
This adds the logic to detect if the GPU supports rendering into FP16 targets and stores this capability in the backend data. This information is essential for enabling HDR10 output modes.
This applies the HDR10 encode pipeline to composite the entire frame for outputs configured in HDR10. All elements are composited into an FP16 intermediate buffer before PQ encoding. It also ensures that HDR10 mode is only enabled if the GPU supports FP16 render targets, which are required by the pipeline.
When HDR encoding is active, frame optimizations such as direct scanout or plane promotion would bypass the HDR encode pass. This could cause sRGB content to be misinterpreted as PQ (Perceptual Quantizer) by an HDR display, leading to incorrect colors.
some minor reformatting too
The`wp_image_description_v1::Request::GetInformation` response must be deferred. Sending the response from inside the dispatch handler that created the `info` object would cause wayland-backend to write through a freed pointer, as the `done` destructor event may already have occurred.
The `wp_image_description_info_v1` response must be deferred. Sending the response from inside the dispatch handler that created the `info` object would cause wayland-backend to write through a freed pointer, as the `done` destructor event may already have occurred
Previously, HDR output mode resolution relied on a generic experiment flag. This change introduces an explicit check against `runtime_output_configs` and environment variables for HDR requests, directly informing the color mode selection. This ensures user-defined HDR preferences are applied, with a re-resolution handled for config updates.
This introduces a mechanism to re-evaluate and apply requested color modes (e.g., HDR via runtime config or environment variables) to already connected TTY outputs. Outputs connect before the full runtime config is evaluated, so this allows a "live switch" into or out of HDR mode without requiring an output reconnect, by managing DRM connector state.
The HDR opt-in is determined by output configurations. This ensures the session-wide HDR advertisement and TTY output color modes are updated when output configs change, addressing timing issues where outputs connect before full config evaluation.
This option allows configuring whether a specific output should attempt to drive HDR10 (PQ/BT.2020 signaling) when its EDID advertises ST 2084 support. It is an experimental feature, and SDR content is composited in sRGB and PQ-encoded as a final pass.
Verify the correct deserialization of the `hdr` option in `RuntimeDisplayConfigUpdate`, ensuring `Some(true)` for an explicit `true` value and `None` when the key is absent to preserve SDR behavior for older configurations.
|
That’s great! Thank you. |
|
@sophietheopossum |
|
Ah, I Don't have an AMD GPU admittedly, only other GPU is an integrated intel xe. This is the test display : https://www.philips.co.uk/c-p/43PUS8505_12/8500-series-4k-uhd-led-android-tv-with-ambilight-3-sided I think it's HDR 400 iirc. |
|
Oh, actually I do, I have a steamdeck, and it has an oled HDR display..... okay i'll look into this further, but you're welcome to work on it too if i take too long |
fairly self explanatory, it took me way longer than i thought it would.... tested it on a hdr device, it looks the same as hdr on kde, so it all seems to work as expected.