hyprwm / Hyprland

Hyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
https://hyprland.org
BSD 3-Clause "New" or "Revised" License
20.01k stars 851 forks source link

Color Management #4377

Open vifino opened 9 months ago

vifino commented 9 months ago

Description

Hey! I'd love to see color calibration/correction on Hyprland as well.

Specifically, a way to load an ICC profile per monitor to make normal SDR monitors display sRGB decently, making multi-monitor use suck less.

Plasma 6 seems to have implemented this, allowing correction for sRGB color space along with HDR/REC.2020.

While the proposed wayland protocol isn't merged, it does seem to be inching closer and closer as well.

This relates to #3423, which assumed lack of support for color management (with colord, specifically) was a bug. I don't think so, but I'd sure love to have this!

vaxerski commented 9 months ago

doubt I'll impl this before the proto gets merged because I want wlroots to impl it for a guideline on how to do it. I have no clue how icc works

Sinaaaa commented 9 months ago

Description

Hey! I'd love to see color calibration/correction on Hyprland as well.

Specifically, a way to load an ICC profile per monitor to make normal SDR monitors display sRGB decently, making multi-monitor use suck less.

Plasma 6 seems to have implemented this, allowing correction for sRGB color space along with HDR/REC.2020.

While the proposed wayland protocol isn't merged, it does seem to be inching closer and closer as well.

This relates to #3423, which assumed lack of support for color management (with colord, specifically) was a bug. I don't think so, but I'd sure love to have this!

It's possible to use Gnome's lacking implementation already & if they eventually figure this one out, then it might just continue working the same way as now. Basically you set your ICC profile in Gnome & then you log into Hyprland with GDM and the display manager will keep the profile going to the same extent it is applied in Gnome Wayland. (works in other WLR window managers as well)

vifino commented 6 months ago

wlroots seems to have a MR open that implements the simple color correction and profile loading: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4280

Seems unrelated to the protocol however.

blitzgneisserin commented 5 months ago

If you have a wide gamut screen and absolutely need color management for the colors not to look oversaturated, you can use a profile that contains only profiling data and no calibration curves. You can set the icc profile inside firefox, and some other color managed apps such as geeqie, digikam/showfoto, darktable, rawtherapee etc. You cannot set display icc profiles in other browsers than firefox though. However, if your screens color space is very similar to p3, e.g., then you can choose p3 in chromium e.g., because that's built in.

xz-dev commented 3 months ago

As a modern display system, this is absolutely indispensable.

vaxerski commented 3 months ago

if you need it so much you can write a screen shader that implements the color correction. That's what hyprland would be doing anyways once this is implemented.

blitzgneisserin commented 3 months ago

Well, implementing color management does not make sense at the moment because clients (apps), such as firefox, Gwenview etc cannot communicate with the wayland color management engine yet. Loading calibration curves and profiling data from an icc file is already implemented in sway-git, but a) it does not work properly yet b) clients cannot communicate with the protocol yet.

I think it's a bit more than just a screen shader. I will post the sway commits in a moment. Anyway, it's already implemented in wlroots.

blitzgneisserin commented 3 months ago

https://github.com/swaywm/sway/commit/40ca4150b27a5b94938b6c3d744f74bb26d347f7

blitzgneisserin commented 3 months ago

Just one more remark: well, we are waiting for the first clients to implement system wide wayland color management, afik they don't exist yet. Sebastian Wicks talk at LGM2024 was about this topic but the graphics devs still seem to be rather skeptical. Just have a closer look at it and try to understand how this works. I think most LGMers did not understand it. At the moment, what works best on wayland is profiling only and setting the profile inside the client (letting the client do color management the old x11 way). Anyway, you will have to deal with this properly if you want to support hdr screens.

vaxerski commented 3 months ago

I don't see how clients are involved here at all, the only idea I can see is an app (idk a game?) being able to send to the compositor what ICC profile to load.

The wlroots MR in question seems to me like it does exactly what I'd suspect, loads the ICC stuff and transforms the colors at the output with a shader:

https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4280/diffs#7324c2d10e1b31e3e01184df744e243ce94bb071

I do not write vulkan and I've never done ICC but it seems to me like all it is, is just transforming the final image.

Further reinforced by this: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4693

Since when you use a color transform, you have to re-render the image and can't push it straight to the gpu.

vaxerski commented 3 months ago

HDR is sent differently yes, and once #6608 is done I am planning to do some HDR stuff eventually, though no immediate plans.

After the full migration (and some bugfix period) I want to push HW plane support into aquamarine and get Hyprland to use hw planes as much as possible. They have a huge performance/battery life potential and more people would benefit from it than ICC or HDR, IMHO.

letting the client do color management the old x11 way

IMO it's the better approach. For many apps, 100% color accuracy is redundant and useless. (idk a file manager) and the disadvantage of having to do an extra pass where you could use direct scanout is a major con.

blitzgneisserin commented 3 months ago

Well clients are involved since they need to tell the compositor in which color space the image they show is. Also applies for e.g. a web browser. The compositor/wayland does the actual color management. The sutuation is as follows at the moment: everything is displayed as srgb. If wayland does not know in which color space the image is, in thinks it is in srgb. Colors outside of srgb cannot be displayed. Many displays nowadays have a larger color space than srgb, mostly something like adobergb or p3, especially smartphones and tablets. They can show more and more saturated colors. If the compositor thinks the screen is srgb, the colors look oversaturated. On x11, if you are using a wide gamut screen, and apps such as browser and image viewer are doing color management, everything outside those color managed programs looks oversaturated, e.g. desktop background, (desktop) icons, colored text etc. Images usually have a color space embedded, e.g. srgb or adobergb. System wide color management is functional since a long time on macos. How could I explain this better? Wayland knows the image is in srgb and the screen is in adobergb, it desatures the image, wayland knows image and screen are in srgb, it does nothing, wayland knows image in one window is in rec2020, and in the other is is srgb, the screen is adobergb, it makes window 1 more satureted and window 2 less saturated. Afaik there is also the possibility that wayland lets a certain window do the color management. The most annoying thing about this is at the moment probably the desktop background, if there is no system wide color management, the wallpaper needs to be converted to the displays color space every time At the moment hyprland assumes that everything is in srgb, but that's not good in the long run. Making it assume that everything is p3 or any other larger color space is not good either. Screens and images/ videos/games can be/have many other color spaces. Assuming srgb will not work with hdr screens, everything that is not color managed will look terrible. If hyprland has an hdr mode, non hdr content will look bad when hyprland is in hdr mode, basically there will be very little satuation and contrast.

blitzgneisserin commented 3 months ago

the only idea I can see is an app (idk a game?) being able to send to the compositor what ICC profile to load.

Exactly, that's it.

blitzgneisserin commented 3 months ago

Ok, sorry for writing so much, but you need to understand two different things: the icc profile contains profiling data=info about the size of the screen 's color space, and it can also contain calibration curves. Calibration curves are necessary if it is not possible to calibrate a screen with its osd (buttons). E.g. if a laptop screen or a mac has a color cast (usuallyit's blue), calibration curves are necessary, because only the brightness of the screen can be regulated.

I tested sway-git and unfortunately, what it did was this: for some reason it gave my screen a dark blue cast even though my screen profile does not contain calibration curves. But the saturation was ok. So basically, hyprland should do those two things: load the calibration curves, if there are any, and adjust satuation/contrast according to the displays and images color spaces.

vaxerski commented 3 months ago

You seem way more knowledgeable in this than me so I invite you to write the implementation yourself in hl and make a MR once I am done with the migration to aquamarine. You also seem to have way more of a need than me, or most other people, for it.

As I've said before, plane stuff and explicit sync will probably be on the table before color management if I am to do it, because it will benefit more people.

blitzgneisserin commented 3 months ago

Yea, I already thought about that, and my biggest wish is to do it, but unfortunately so far I can only fix tiny little bugs with the help of AI. As you can see on my website, I am mainly a photographer, a tester (I am really good at that!) and an IT journalist. As I said, there is no hurry. Nobody knows when the first clients will be available that can talk to the color management engine. Until then the best thing is to set the profile inside the client. Probably it'll take a few years until everyone has hdr screens. Maybe just keep in mind that the sway devs are already on it, although I have the feeling that they don't entirely understand how color management works. Thanks for the invitation though. Well, maybe I can try and have a look at it.

aruhier commented 2 months ago

To help moving on with this feature, Sway and wlroots did it in the vulkan renderer this way: https://github.com/swaywm/sway/pull/7681 and https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4280.

It's apparently doable in GLES3 too: https://github.com/swaywm/sway/issues/1486#issuecomment-2261238722

vaxerski commented 2 months ago

the proper way to do color management is what is WIP at https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/14 (and has been for literal fuckin years)

The way sway does color management atm is wasteful and IMHO dumb.

It's definitely doable in gl (I don't see why even gl3 would be needed) but I have no plans atm of implementing it due to many drawbacks

aruhier commented 2 months ago

I have no plans atm of implementing it due to many drawbacks

That makes sense, no worries

The way sway does color management atm is wasteful and IMHO dumb.

For my curiosity (and maybe to avoid someone spending time on it until the wayland protocol is ready maybe one day), what are the drawbacks and why do you find it dumb?

vaxerski commented 2 months ago

color management should be done by the application. The app should get info about preferred color modifications and implement the management itself.

Right now, sway will instead do it itself, meaning after rendering your scene, it will texture it again and re-render it applying a color profile.

aruhier commented 2 months ago

color management should be done by the application. The app should get info about preferred color modifications and implement the management itself.

Right now, sway will instead do it itself, meaning after rendering your scene, it will texture it again and re-render it applying a color profile.

Got it, thanks! I thought that compositor side color mapping was a preferred option, to avoid falling in the case of Windows for example, when the color profile is rarely applied as it often depends on the apps to make use of it or not.

BBaoVanC commented 1 month ago

Got it, thanks! I thought that compositor side color mapping was a preferred option, to avoid falling in the case of Windows for example, when the color profile is rarely applied as it often depends on the apps to make use of it or not.

I'm not very familiar with color management, but my understanding was that ideally you let programs provide and use the ICC profile themselves, and if they don't then just assume the program is sRGB. Which would work fine if you have the monitor profile set right since it'll know how to transform from sRGB to your monitor.

It sounds like what sway is doing is to assume all programs are sRGB (since no color management protocol yet), but also allow transforming everything after the fact to the profile you provide?

Someone tell me if I am getting all of that right.

vaxerski commented 1 month ago

sounds about right

kainz commented 1 month ago

Id say you actually want both options, but with some degree of customizability. Ideally, all of this list is true:

The latter point is what I think compositors should do, as it fits neatly in the concept that a compositor or display driver or WM can, and should, when not contraindicated, provide a normalized color space for all applications.

YMMV, but for me personally, having the latter makes running multi-display systems immensely nicer. The concerns about speed, latency, and the wastefulness of multiple roundtrips through the pipeline are a real concern, but id think theres got to be a sane way somewhere to make CM work without incurring that much cost. To me, its been a real regression in the wayland era in general.

As far as direct scanout goes, what happened to graphics drivers being able to load a 2d or 3d LUT to provide color profiling along with direct scanout?

Edit:.... theres also monitors that provide display side LUT functionality, but those are even less consistently implemented...

vaxerski commented 1 month ago

As far as direct scanout goes, what happened to graphics drivers being able to load a 2d or 3d LUT to provide color profiling along with direct scanout?

that's there, but DRM/KMS doesn't support it yet on Linux

gnusenpai commented 1 month ago

For those interested in super basic color management in Hyprland: I have a proof-of-concept branch (lut) that allows sending any texture to the built-in shader functionality primarily for the purposes of display calibration/color correction. It includes an example shader that implements a 3D LUT.

I probably will not submit a formal PR because, for this usecase, it is kind of a hack and shouldn't be the direction Hyprland goes. (But maybe there would be interest in a more generalized version for enhanced shader customization?)

vaxerski commented 1 month ago

tbh since screen shaders are a thing just writing your own LUT converter in glsl is completely reasonable (that's what sway does on vk afaik anyways)

you get output uniforms as well so it can work with multimon

Loara commented 1 week ago

Maybe we can contact the maintainer of ArgyllCMS in order to get some advice on color management.

cnschn commented 1 week ago

While I think just implementing a user screen shader for a LUT would be fine, there's one thing missing: As far as I can tell there's no way to define additional uniforms for the screen shader, in particular nothing to load additional textures. So I think for this to be a valid workaround for the color management issue, Hyprland would either have to add a generic way to load textures that are passed into the screen shader, or add a setting for a LUT specifically (sort of how @gnusenpai's branch does it).

I'm not sure what the best direction would be design-wise, but having a "decoration:lut" config for just this purpose is probably the least amount of work, compared to a completely general "add arbitrary additional inputs to screen shaders".

vaxerski commented 1 week ago

it still won't work for multiple displays with different LUTs each. Furthermore, although this is a fine temporary band-aid, what about 10bit? 256x LUTs are, well, 256. 8bit.

Don't ICC profiles encode what LUTs do using continuous functions instead? In that case they would be better.

I don't think we'll manage to get LUTs make sense without allowing arbitrary texture loads into user shaders.

cnschn commented 1 week ago

Well, at least for multiple displays we do have the monitor ID as a uniform, but yeah it's not much more than a band-aid for sure.

MCPO-Spartan-117 commented 1 week ago

Furthermore, although this is a fine temporary band-aid, what about 10bit? 256x LUTs are, well, 256. 8bit.

The PNGs can be 16-bit and the shader does work with it.

Don't ICC profiles encode what LUTs do using continuous functions instead? In that case they would be better.

Going off of Reshade's shader

Would skipping the PNG sampling be faster? probably but not really the biggest reason for wanting to drop the PNG requirement.

vaxerski commented 1 week ago

I wasn't talking about sampling time but rather accuracy

The PNGs can be 16-bit and the shader does work with it.

But they still are 256x no? which limits them to 256 pixels, 2^8.

gnusenpai commented 1 week ago

But they still are 256x no? which limits them to 256 pixels, 2^8.

I'm a bit confused about what's being discussed here. LUTs can really be any size.

1D LUTs can easily be 256x which should be small enough to be embedded in a shader directly, if you wanted. In-between values on 10-bit displays can be interpolated. 1024x is doable, but I don't think they are commonly used.

3D LUTs pretty much only go up to 65x65x65, which is basically transparent with interpolation and sufficient bit-depth.

vaxerski commented 1 week ago

alright

I am not well versed in color management, excuse my ineptness

Loara commented 1 week ago

While the proposed wayland protocol isn't merged, it does seem to be inching closer and closer as well.

Maybe we can also get a look to the respective frog protocol.

vaxerski commented 1 week ago

I'd wait for an impl from some other player (at least draft) to gain some practical insight

As I've said here:

I am not well versed in color management, excuse my ineptness

I read both fifo and color-mgmt from frog and in fifo I am unsure how it works, and in color-mgmt I don't understand half the techy terms :P

https://github.com/user-attachments/assets/73127850-d66e-4013-af1a-4a5af7329fb8

Loara commented 1 week ago

As I've said here:

I am not well versed in color management, excuse my ineptness

I read both fifo and color-mgmt from frog and in fifo I am unsure how it works, and in color-mgmt I don't understand half the techy terms :P

We may ask to mantainers of feog-protocols for some advice on how to implement their protocols in Hyprland.