A possible compositor abstract color pipeline
This write-up was inspired by an IRC discussion attempting to determine whether and which client content color properties ("input description" below) should be attached to the wl_buffer
vs. wl_surface
. Importing a dmabuf in a compositor is a two-step process: importing, and preparing the texture/sampler. Different APIs determine different color properties at different steps. E.g. EGL may use the YUV-RGB conversion information at the import step and decode input transfer function (if it happens to be the sRGB piece-wise) at OpenGL texture preparation step.
Whether each piece of information is attached to wl_buffer
vs. wl_surface
affects whether a compositor need to be able to maintain a texture per surface, per buffer, or per the combination of surface and buffer. Another important aspect is whether clients will be able to attach the necessary information to a wl_buffer
if a Wayland extension is designed to attach to wl_buffer
. Attaching information to wl_surface
is not a problem in clients, because application code always has access to the wl_surface
, unlike to wl_buffer
. This is a property of the glue APIs: EGL, Vulkan WSI.
The following is one possible compositor color pipeline design. The compositor designer has chosen to use the linearized output color space as the blending space. The advantage is that one only needs to do gamut and tone mapping once, straight from input to output color space. The designer has also chosen to use full range, unclipped (values not limited to the unit range [0.0, 1.0]) pipeline.
The table starts from an YUV input image, describes the stages the pixels will go through, and denotes where the information comes from that is needed at each stage.
Gamut mapping is at stage 4 because I believe that is where a CMM (e.g. LittleCMS) will insert it by default. Gamut mapping and tone mapping could also be combined and done in stages 4 or 8, assuming an unclipped color pipeline
Note: LUTs by definition must clip their input and usually have clipped output. OTOH, analytically defined operators (matrices, parametric curves) can often extrapolate just fine.
# | Stage | input description | preferences | output description |
---|---|---|---|---|
1 | YUV-RGB conversion (YUV decoding matrix coefficients, chroma siting / undo sub-sampling, quantization range) | X | ||
2 | Decode with input transfer (characteristic) function (input profile, e.g. 3x 1D LUT) | X | ||
3 | Color conversion to PCS (input profile, e.g. 3x3 matrix) | X | ||
4 | Gamut mapping, white point compensation | X | X | X |
5 | Color conversion to output color space (output profile, e.g. 3x3 matrix) | X | ||
6 | Encode with output transfer (characteristic) function (output profile, e.g. 3x 1D LUT) | X | ||
7 | Linearization (undo step 6) | X | ||
8 | Dynamic range / tone mapping | X | X | X |
9 | Blending (compositing) | |||
10 | Encoding for display (redo step 6) | X |
- Input description must be provided by the Wayland client.
- Output description is part of the compositor configuration.
- Preferences include all of compositor designer opinions, end user preferences (compositor configuration), and potentially rendering intent from the Wayland client.
- If input profile is an ICC file, it provides stages 2 and 3 together and is generally indivisible.
- If output profile is an ICC file, it provides stages 5 and 6 together and is generally indivisible. However, it is possible to infer at least an approximate transfer characteristic for use in stages 7 and 10.
- Stage 10 must be the exact numerical inverse of stage 7 in order to guarantee that opaque top-most pixels go through blending without unintended errors added. Stage 10 is inherently vulnerable to numerical errors.
- If the compositor were to use KMS off-loading: everything before blending must be implemented through KMS plane properties, and everything after blending must be done through KMS CRTC properties.
- Some KMS connector properties affect the output description.