render: add color transform option for render pass output
This is an attempt to rebase and continue !4090 (closed) . I am posting this since adding support for output color profiles is a lot of work, and having a partially working design may help either myself or others design a more polished MR.
To test this, use the corresponding Sway PR, https://github.com/swaywm/sway/pull/7681 .
This PR is mainly concerned with getting the necessary infrastructure to color manage outputs. There are a few possible improvements which I probably will not have the time to do myself in the next few months.
-
Color transform precision is low -- a 33x33x33 3D LUT can't properly capture e.g. the linear segment of the linear->sRGB function. To implement the ICC lutBtoAType, would need a multistage transform ( Matrix→3x(1d LUT)→Matrix->3x(1d lut)→3d LUT->3x(1d lut) .) [This might be worth delaying to a future MR, as it would probably cost >1000 LoC to handle all the cases.]
-
That color transforms actually interpret the ICC profiles correctly, and white point correctly, etc.
-
The
wlr_color_transform
and its addons (wlr_vk_color_transform
) currently are kept alive as long as there are things that require either; it might be more efficient to delete thewlr_color_transform
as soon as there are no references to it, and then keep thewlr_vk_color_transform
alive until all rendering involving it has completed. This probably isn't critical. -
When using a non-8-bpc output buffer format, taking a (shm-type) screenshot may redraw pixels without the color transform applied. types/wlr_screencopy_v1.c#L211-216 uses the old renderer API, and in particular calling(Fixed and merged in separate MR).wlr_renderer_end()
will run the second subpass that copies the pixels from in the blend_image to the main buffer, without using a color transform. !4211 (merged) would probably fix this, as it no longer callswlr_renderer_begin()
/wlr_renderer_end()
in the screencopy code. -
Need to block direct scan-out when applying a nontrivial color transform.(Fixed on Sway impl) -
Validation errors when not using color management: need to bind a dummy lut_3d texture to the output pipeline.(done) -
Flickering -- some frames render with a garbage color transform, suggesting a race condition. Does anyone know what the issue is?(Fixed, was a buffer span offset/alignment issue) -
Requires that the blend_image is already set up; i.e., the output transforms are only enabled when non-8-bit buffer formats are in use.(Fixed, currently ugly solution) -
Creating a 3d lut texture on every frame is inefficient; typical use is unlikely to change the output ICC profile rapidly -
Should keepwlr_vk_color_transform
alive until all commands involving it complete.