cm: add ICC profile loading#12711
Conversation
|
@fufexan can we get nix |
|
can you guys let me know if this works well? I have done very limited testing. |
Do not see anything in the logs showing it is loading the ICC profile, or rather nothing icc at all. What am I doing wrong there? |
|
oh oops, I think I forgot v2 |
|
my bad should work now |
|
Yup, it does attempt to load now. Unfortunately looks like the only ICC profile for my monitor is split-trc, so I won't be able to assist much with testing here.
|
|
I've added logging of the trc to the debug output, can you post the icc data dump here? |
|
Sure, here you go! |
|
thanks, despite xmas :P |
|
This should work. I've loaded my ICC profile and it does seem to change the colors on my panel a bit, but without a colorimeter I have no way of verifying if it's correct. Please load your ICC and let me know. |
|
It does seem to change the colors. I've ordered a colorimeter to verify though, should have it within a week. |
|
talk about dedication. I do think its wrong, sway's is different. |
|
@UjinT34 would you mind checking the LUT shader changes? I'm quite sure I am doing something wrong there. Shadows are a tad too bright I think. Can't say for sure without a colorimeter but they do look a bit flat and weird. |
|
I checked KDE, colors shift a tad but not as much as we do. Something's wrong. |
|
I am not that familiar with math around icc luts. |
|
fixed, but it's again surfacing that nightmare where kitty sets the DEFAULTS and yet it changes how we render shit. I need to do something about this... |
|
nvm its not fixed it just had a bug where it wouldnt apply cm curves fuck my life |
|
in general @UjinT34 shouldn't we compose to a linear SRGB buffer internally and then do a final CM pass on the entire image? Why are we doing it per-surface? This would be desirable as ICC shifts colors and will mess up e.g. color pickers. We should screencopy un-icc'd buffers. |
|
I've pushed a completely different approach with a 3D LUT instead, which also changes how we render CM. This will need some testing. This needs an HDR-kill-switch internally (HDR should disable ICC, currently it's likely the other way round) This needs people to run this shit and report any visual glitches or bugs, feel free to drive this @Flat thanks for your testing, if you could compare how this looks vs KDE it would be great. Sway's ICC is busted on my end, but KWin's works properly. |
|
I've decided to use Gamma 2.2 for internal storage just like kwin does, this lifts up the shadows a bit and looks more accurate in my opinion. |
|
Yay! This is my use case! I have a colorimeter, good wide gamut display, its ICC profile, and the display itself has a pretty accurate sRGB clamp which I measured. I hope to have some time to test this PR this weekend. Meanwhile the only program I've found that applies ICC profile correctly (for sRGB clamp) is https://github.com/ledoge/novideo_srgb. But its for Windows. Every Linux DE implementation I tried was way off color-wise, at least the last time I checked. |
|
while working on screencopy I realized the work buffer was actually not srgb but I can't seem to get pc to work again |
|
fixed, screencopy should work now too. @wilecoyote2015 sorry for being so annoying but could you recheck the colorimeter, plus check if CM doesn't disturb screencopy? (screenshots / screen recordings) - these should be in SRGB, IOW if I open a terminal on srgb no icc and use a color picker e.g. hyprpicker to pick the background, the same #hex should be printed with icc. I ran some tests and on my end looks good |
|
if colorimerer passes this is gtg |
|
Working on updating ArgyllCMS and Displaycal to give another test as well. Hopefully have that test done in next couple hours. |
|
Still about the same for me, using the same verification options as wileycoyote2015. Same profile profiled on Hyprland used on Hyprland and KDE tests. Resultant ICC Profile: |
|
wtf happened in indigo there |
|
Million dollar question 😀. Ujin suggested it could be a float precision issue since blues were closest to 0, #12711 (comment) Or a difference in colorspaces. Here's a diff between drm_info on hyprland and kde 85c85
< │ │ ├───"EDID" (immutable): blob = 147
---
> │ │ ├───"EDID" (immutable): blob = 154
136c136
< │ │ ├───"EDID" (immutable): blob = 152
---
> │ │ ├───"EDID" (immutable): blob = 147
161c161
< │ ├───"EDID" (immutable): blob = 148
---
> │ ├───"EDID" (immutable): blob = 152
217c217
< │ │ ├───"MODE_ID" (atomic): blob = 160
---
> │ │ ├───"MODE_ID" (atomic): blob = 163
237c237
< │ │ ├───"MODE_ID" (atomic): blob = 167
---
> │ │ ├───"MODE_ID" (atomic): blob = 164
291,292c291,292
< │ │ ├───FB ID: 184
< │ │ │ ├───Object ID: 184
---
> │ │ ├───FB ID: 160
> │ │ │ ├───Object ID: 160
294c294
< │ │ │ ├───Format: XBGR2101010 (0x30334258)
---
> │ │ │ ├───Format: ABGR16161616F (0x48344241)
297c297
< │ │ │ └───Plane 0: offset = 0, pitch = 13760 bytes
---
> │ │ │ └───Plane 0: offset = 0, pitch = 27520 bytes
324,325c324,325
< │ ├───"FB_ID" (atomic): object framebuffer = 184
< │ │ ├───Object ID: 184
---
> │ ├───"FB_ID" (atomic): object framebuffer = 160
> │ │ ├───Object ID: 160
327c327
< │ │ ├───Format: XBGR2101010 (0x30334258)
---
> │ │ ├───Format: ABGR16161616F (0x48344241)
330c330
< │ │ └───Plane 0: offset = 0, pitch = 13760 bytes
---
> │ │ └───Plane 0: offset = 0, pitch = 27520 bytes
537,540c537,540
< │ ├───"CRTC_X" (atomic): srange [INT32_MIN, INT32_MAX] = 0
< │ ├───"CRTC_Y" (atomic): srange [INT32_MIN, INT32_MAX] = 0
< │ ├───"CRTC_W" (atomic): range [0, INT32_MAX] = 0
< │ ├───"CRTC_H" (atomic): range [0, INT32_MAX] = 0
---
> │ ├───"CRTC_X" (atomic): srange [INT32_MIN, INT32_MAX] = 467
> │ ├───"CRTC_Y" (atomic): srange [INT32_MIN, INT32_MAX] = 1423
> │ ├───"CRTC_W" (atomic): range [0, INT32_MAX] = 256
> │ ├───"CRTC_H" (atomic): range [0, INT32_MAX] = 256
543,544c543,544
< │ ├───"SRC_W" (atomic): range [0, UINT32_MAX] = 0
< │ ├───"SRC_H" (atomic): range [0, UINT32_MAX] = 0
---
> │ ├───"SRC_W" (atomic): range [0, UINT32_MAX] = 256
> │ ├───"SRC_H" (atomic): range [0, UINT32_MAX] = 256
778,779c778,779
< │ │ ├───FB ID: 171
< │ │ │ ├───Object ID: 171
---
> │ │ ├───FB ID: 148
> │ │ │ ├───Object ID: 148
781c781
< │ │ │ ├───Format: XBGR2101010 (0x30334258)
---
> │ │ │ ├───Format: ABGR16161616F (0x48344241)
784c784
< │ │ │ └───Plane 0: offset = 0, pitch = 13760 bytes
---
> │ │ │ └───Plane 0: offset = 0, pitch = 27520 bytes
811,812c811,812
< │ ├───"FB_ID" (atomic): object framebuffer = 171
< │ │ ├───Object ID: 171
---
> │ ├───"FB_ID" (atomic): object framebuffer = 148
> │ │ ├───Object ID: 148
814c814
< │ │ ├───Format: XBGR2101010 (0x30334258)
---
> │ │ ├───Format: ABGR16161616F (0x48344241)
817c817
< │ │ └───Plane 0: offset = 0, pitch = 13760 bytes
---
> │ │ └───Plane 0: offset = 0, pitch = 27520 bytes
1016,1017c1016,1017
< │ │ ├───FB ID: 174
< │ │ │ ├───Object ID: 174
---
> │ │ ├───FB ID: 166
> │ │ │ ├───Object ID: 166
1027,1028c1027,1028
< │ ├───"FB_ID" (atomic): object framebuffer = 174
< │ │ ├───Object ID: 174
---
> │ ├───"FB_ID" (atomic): object framebuffer = 166
> │ │ ├───Object ID: 166
1036,1037c1036,1037
< │ ├───"CRTC_X" (atomic): srange [INT32_MIN, INT32_MAX] = 1720
< │ ├───"CRTC_Y" (atomic): srange [INT32_MIN, INT32_MAX] = 720
---
> │ ├───"CRTC_X" (atomic): srange [INT32_MIN, INT32_MAX] = 799
> │ ├───"CRTC_Y" (atomic): srange [INT32_MIN, INT32_MAX] = 386 |
|
|
|
update: running main version, and setting thanks. |
This would disable the ICC profile from being applied. I checked my profile on gnome and it will not apply ICC profiles globally unless they are calibrated profiles. If in gnome it has an information icon that you mouse over it will say this profile cannot be used for whole display color correction or something to that effect. |
well mine applies globally in both cases, hyprland and gnome, i checked gnome and yeah my profile doesnt have an information icon |
|
Please correct me if I'm wrong - my info on gnome and KDE CM is a bit outdated (X11 times ..):
The latter is BTW a good reason why one might like to disable CM for some application and let the application handle the display transform entirely: different rendering intents or blackpoint correction than Hyprland does may be desired |
With this PR the ICC profile isn't a part of the CM proto and any app supporting the proto will treat the monitor as a default unprofiled gamma22 sRGB. Some internals might also ignore the ICC part unless specifically modified to handle it. |
|
I've also run the verification - but this time calibrated and verified with 10 bit and used the large verification chart. Measurement Report 3.9.17 - Web @ localhost - 2026-03-05 17-04.html |
|
that tbh could suggest a precision problem because dark colors are the most susceptible to this |
|
we could likely try pushing F16 buffers into KMS later and see if that helps but that would be after ujin's renderer refactors I don't want to cause another rebase mess xD |
|
Thinking about it. Maybe it has to do with screen capability to cover what percentage of srgb. I know my screen doesn't cover a good percentage. From what I understand using an icc forces srgb. Not sure if this makes sense. I just thought of sharing it. |
|
Hello, I don't really know where else to put this, there seems to be a github discussion from a year ago regarding icc profiles, but seems inactive, so I am deciding to write here and not opening a new issue since I believe it is related. As hyprland updated I decided to test the icc profiles, since my monitor has an awful hdr by default, so I loaded some that I found on the web for my monitor, (it is the exact same model) here is the link to the repo, I tested them all and none of them worked, not even loaded, I enabled debug on hyprland to see what was going on and the only output regarding icc was Also I checked the profiles with displaycal and iccdump, they seem to be correctly formatted. I will be checking the discussion closely, and test whatever I can, I don't have a colorimetrer so it would just be with the naked eye. |
icc not icm |
|
both icc and icm usually are the same. I don't know why the loading fails, it's done by lcms |
Adds an ICC profile pipeline, loading via config and applying via 3D LUTs.








Adds loading of icc profiles for the properties we support
ref #9064
Usage
v2:
icc = /full/pathv1:
, icc, /full/pathInfo
This also changes how we handle CM in general, where our intermediate buffer (offload) is in sRGB, and we CM at the end.
This should also make it possible to have actual, proper pixel-perfect screencopy in a follow-up MR (as we can copy the offloaded fb for screencopy purposes) - But that's for a follow-up MR
Requires: