Bug 515402 - Loading an .icc shifts gamma to 2.2
Summary: Loading an .icc shifts gamma to 2.2
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: colour-management (other bugs)
Version First Reported In: 6.5.5
Platform: CachyOS Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2026-02-01 20:57 UTC by Rynn
Modified: 2026-02-02 01:46 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed/Implemented In:
Sentry Crash Report:


Attachments
icc profile (1.93 MB, application/vnd.iccprofile)
2026-02-01 20:57 UTC, Rynn
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Rynn 2026-02-01 20:57:26 UTC
Created attachment 189146 [details]
icc profile

SUMMARY

I created a .icc/.icm in Windows with DisplayCAL, since on Linux, I'd always get worse results than in Windows. I then loaded that file "System Settings  > Display Configuration > Color profile > ICC Profile". There is now a noticeable uplfit in grays and Gamma has shifted to 2.2. For context, my monitor's gamma is 2.42 as measured with a Colorchecker Display Pro. After profiling, a quick measurement test reports Gamma 2.40. 

This behavior is consistent across both my ASUS OLED and my LG LCD IPS.

Displaycal's "Report on display device":

WINDOWS:
Calibrated:
22:05:58,673 Setting up the instrumentlist_iccss: xdg_bds returned 21 pathslist_iccss:      ↲
             ↳ returning 21 ccss'sProduct Name:      i1Display3Serial Number:               ↲
             ↳ C2-22.B-02.022123.08Hardware Rev.:     B-02Firmware Version:  v2.28Firmware  ↲
             ↳ Date:     29Jan14Measured display update delay of 3 msec, using delay of 104 ↲
             ↳ msec & 0 msec inst reactionNo distict refresh periodCurrent calibration      ↲
             ↳ response:Black level = 0.0000 cd/m^250%   level = 46.30 cd/m^2White level =  ↲
             ↳ 244.40 cd/m^2Aprox. gamma = 2.40Contrast ratio = inf:1White chromaticity     ↲
             ↳ coordinates 0.3128, 0.3275White    Correlated Color Temperature = 6500K, DE  ↲
             ↳ 2K to locus =  3.1White Correlated Daylight Temperature = 6557K, DE 2K to    ↲
             ↳ locus =  2.3White        Visual Color Temperature = 6405K, DE 2K to locus =  ↲
             ↳ 3.0White     Visual Daylight Temperature = 6627K, DE 2K to locus =  2.2White ↲
             ↳ drift was 0.000000 DE

Uncalibrated:

22:06:49,539 Setting up the instrumentlist_iccss: xdg_bds returned 21 pathslist_iccss:      ↲
             ↳ returning 21 ccss'sProduct Name:      i1Display3Serial Number:               ↲
             ↳ C2-22.B-02.022123.08Hardware Rev.:     B-02Firmware Version:  v2.28Firmware  ↲
             ↳ Date:     29Jan14Measured display update delay of 0 msec, using delay of 100 ↲
             ↳ msec & 0 msec inst reactionNo distict refresh periodUncalibrated             ↲
             ↳ response:Black level = 0.0000 cd/m^250%   level = 45.85 cd/m^2White level =  ↲
             ↳ 244.67 cd/m^2Aprox. gamma = 2.42Contrast ratio = inf:1White chromaticity     ↲
             ↳ coordinates 0.3135, 0.3274White    Correlated Color Temperature = 6466K, DE  ↲
             ↳ 2K to locus =  2.6White Correlated Daylight Temperature = 6523K, DE 2K to    ↲
             ↳ locus =  2.8White        Visual Color Temperature = 6389K, DE 2K to locus =  ↲
             ↳ 2.5White     Visual Daylight Temperature = 6611K, DE 2K to locus =           ↲
             ↳ 2.7Effective Video LUT entry depth seems to be 10 bitsWhite drift was        ↲
             ↳ 0.000000 DE

Linux:
21:59:09,495 Setting up the instrumentlist_iccss: xdg_bds returned 18 pathslist_iccss:      ↲
             ↳ returning 18 ccss'sProduct Name:      i1Display3Serial Number:               ↲
             ↳ C2-22.B-02.022123.08Hardware Rev.:     B-02Firmware Version:  v2.28Firmware  ↲
             ↳ Date:     29Jan14Measured display update delay of 13 msec, using delay of    ↲
             ↳ 117 msec & 0 msec inst reactionNo distict refresh periodUncalibrated         ↲
             ↳ response:Black level = 0.0000 cd/m^250%   level = 53.34 cd/m^2White level =  ↲
             ↳ 242.62 cd/m^2Aprox. gamma = 2.19Contrast ratio = inf:1White chromaticity     ↲
             ↳ coordinates 0.3132, 0.3274White    Correlated Color Temperature = 6481K, DE  ↲
             ↳ 2K to locus =  2.8White Correlated Daylight Temperature = 6539K, DE 2K to    ↲
             ↳ locus =  2.6White        Visual Color Temperature = 6397K, DE 2K to locus =  ↲
             ↳ 2.7White     Visual Daylight Temperature = 6619K, DE 2K to locus =           ↲
             ↳ 2.5Effective Video LUT entry depth seems to be 8 bitsWhite drift was         ↲
             ↳ 0.000000 DE


STEPS TO REPRODUCE
1. Use a .icc with 2.4 Gamma
2. Load it

OBSERVED RESULT

Gamma shifts to 2.2

EXPECTED RESULT

The .icc is loaded correctly and does not apply a 2.2 Gamma.

Operating System: CachyOS Linux 
KDE Plasma Version: 6.5.5
KDE Frameworks Version: 6.22.0
Qt Version: 6.10.2
Kernel Version: 6.18.8-1-cachymod-lto (64-bit)
Graphics Platform: Wayland
Processors: 16 × AMD Ryzen 7 5800X3D 8-Core Processor
Memory: 32 GiB of RAM (31.2 GiB usable)
Graphics Processor 1: NVIDIA GeForce RTX 3070
Graphics Processor 2: NVIDIA GeForce RTX 5070 Ti
Comment 1 Zamundaaa 2026-02-01 21:57:38 UTC
Unlike with Windows, everything is color managed in KWin. The profiling / verification window of DisplayCAL doesn't support Wayland yet, so it's assumed to be sRGB - and sRGB content is meant to be displayed as gamma 2.2, so that's the expected result.
Comment 2 Rynn 2026-02-01 22:17:50 UTC
(In reply to Zamundaaa from comment #1)
> Unlike with Windows, everything is color managed in KWin. The profiling /
> verification window of DisplayCAL doesn't support Wayland yet, so it's
> assumed to be sRGB - and sRGB content is meant to be displayed as gamma 2.2,
> so that's the expected result.

Whether DisplayCAL 'supports' Wayland yet is irrelevant, it creates a standard ICC file. And the file was created in Windows.

Saying 'sRGB is meant to be displayed as gamma 2.2 is an oversimplification that ignores why we use ICC profiles in the first place.
You said it's assumed to be sRGB and displayed as gamma 2.2, but wayland-info for my session lists "bt1886" as supported transfer functions.

interface: 'wp_color_manager_v1',                        version:  1, name: 46
	supported rendering intents:
		perceptual
		relative
		absolute
		relative_bpc
	supported features:
		parametric
		extended_target_volume
		set_mastering_display_primaries
		set_primaries
		set_luminances
		windows_scrgb
	supported named transfer functions:
		gamma22
		st2084_pq
		ext_linear
		bt1886
	supported named primaries:
		srgb
		pal_m
		pal
		ntsc
		generic_film
		bt2020
		cie1931_xyz
		dci_p3
		display_p3
		adobe_rgb

If KWin supports bt1886, why is it defaulting to gamma22 for an ICC profile that is explicitly calibrated to a 2.4/BT.1886 curve? My monitor is physically 2.4; if KWin 'assumes' 2.2, it is creating a mismatch that results in washed-out colors.

Also, a point of contention in online forums for sure, but for the record: 'sRGB' is not a flat Gamma 2.2 curve. It's a piecewise function with a 2.4 exponent (IEC 61966-2-1). If KWin is just forcing a generic 2.2 power law on everything, it isn't even following the "true sRGB standard". A color-managed compositor should be reading the TRC tags in the ICC to decide which of those 'supported' transfer functions to use, rather than just hard-coding everything to 2.2.

The whole point of a color-managed compositor is to map the content to the actual display. If I have a display that is physically calibrated to 2.4 (BT.1886) and I give KWin a profile that says 'this display is 2.4', then KWin shouldn't just shrug and say "I'm assuming it's 2.2.

If KWin ignores the calibration data in the profile and just does a 1:1 passthrough because it 'assumes' the monitor matches the content, then the ICC support in Plasma is currently broken for anyone who doesn't own a generic office monitor. Calibration isn't about 'sRGB content' but correcting the hardware output, which KWin does not currently do.


I also have to ask: what happens if I calibrate my monitor to its native DCI-P3 or Wide Color Gamut (WCG) color spaces, which it supports?
If KWin 'assumes sRGB' for everything, does that mean Wide Color Gamut support is also broken? Is KWin's color management currently limited strictly to sRGB office monitors?
Comment 3 Rynn 2026-02-01 22:30:05 UTC
Just to make it clear, the observed 2.2 gamma is as visible as it can be after loading the profile, in a browser, in Dolphin, not just in DisplayCAL. I just wanted hardware confirmation, in order not to get told that my eyes are the issue; and I had DisplayCAL installed also on Linux.

If you load an .icc, the whole point is to *correct* the output, otherwise, say this scenario: if I manually misconfigure my monitor to a dark 2.6 gamma, KWin doesn't auto-magically correct it to 2.2 on its own, it needs an ICC profile.

But when I provide that profile, KWin ignores the 2.4/2.6 curve inside it and just 'assumes' 2.2 anyway. You're essentially saying KWin only supports profiles that don't actually change anything. If a profile's job is to correct the output to a target, and KWin refuses to apply that correction, then the implementation is broken by design.
Comment 4 Zamundaaa 2026-02-01 23:27:53 UTC
> Whether DisplayCAL 'supports' Wayland yet is irrelevant, it creates a
> standard ICC file. And the file was created in Windows.
You're measuring the ICC profile result with DisplayCAL. How could it not be relevant?

> You said it's assumed to be sRGB and displayed as gamma 2.2, but
> wayland-info for my session lists "bt1886" as supported transfer functions.
Yes, apps can display content tagged as BT1886. That's unrelated to how sRGB is treated.

> Also, a point of contention in online forums for sure, but for the record:
> 'sRGB' is not a flat Gamma 2.2 curve. It's a piecewise function with a 2.4
> exponent (IEC 61966-2-1). If KWin is just forcing a generic 2.2 power law on
> everything, it isn't even following the "true sRGB standard".
That's a pretty common myth, but it's completely wrong. The specification very clearly states that sRGB displays are gamma 2.2.

> I also have to ask: what happens if I calibrate my monitor to its native
> DCI-P3 or Wide Color Gamut (WCG) color spaces, which it supports?
> If KWin 'assumes sRGB' for everything, does that mean Wide Color Gamut
> support is also broken? Is KWin's color management currently limited
> strictly to sRGB office monitors?
Applications are assumed to be sRGB, not screens.

(In reply to Rynn from comment #3)
> If a profile's job is to correct the output to a target
It is not. A display class ICC profile is a description of how a screen responds to RGB inputs, plus some optional metadata about it. Its main purpose is to let applications display their image as intended, even if the screen doesn't match the one the image was created for (like sRGB).

The "calibration" towards some transfer function is a hack for non-color managed applications on X11 and Windows, nothing more.
It is not something that affects actual color management workflows, and it does not work on any fully color managed system, like KWin, MacOS, or even Windows with their opt-in ACM system.
Comment 5 Rynn 2026-02-02 01:46:21 UTC
I understand that technically ICC profiles describe a display’s response and that calibration for a specific gamma/TRC became a "workaround", but it has also become 'standard practice'.

Even in a fully color-managed workflow, a profile should act as a correction layer for the actual hardware. A BT.1886 (Gamma 2.4) calibration still displays sRGB content correctly, but it ensures the display shows the intended tone response for a controlled environment. The color management system should translate between the source profile (sRGB) and the display profile (BT.1886 calibrated). By forcing everything to 2.2, the compositor overrides the calibration, effectively saying 'I know better than your profile', which defeats the purpose of providing a display ICC in the first place.

> That's a pretty common myth, but it's completely wrong. The specification very clearly states that sRGB displays are gamma 2.2.

The sRGB = gamma 2.2 is a bit oversimplified:
C′ = 12.92 × C for C ≤ 0.0031308
C′ = 1.055 × C^(1/2.4) − 0.055 for C > 0.0031308

Unless I misunderstand, that is not a pure 2.2 power law, it is *overall* 2.2 or extremely close, but this is not the core of the problem.

This current logic feels backwards:
When no profile is loaded: KWin stays out of the way, and I get my hardware's native "wrong" 2.15/2.2/2.4/whatever factory response (and full gamut for example, unless clamped in the hardware OSD).
When a profile is loaded: I am giving more accurate data, but what I get is a less desirable visual result than intended.

I don't own a reference-grade display; I use an ICC profile as a correction layer to reach a specific target. If I calibrated for 2.4, I expect to see that, not a "fixed" 2.2/sRGB version of it.

I believe many users, photographers, video editors, and designers, want this level of control. If the intended use case for loading a profile is only for fixing primaries while ignoring the TRC/Gamma, then it is missing the 'Management' part of Color Management. Why does giving KWin more information result in a more restricted output?


>Applications are assumed to be sRGB, not screens. 
Let me try again: I switch my monitor to DCI-P3. I load a DCI-P3-calibrated profile because I want to work in that color space. Then KWin assumes my applications are sRGB and clamps the gamut?  I haven't tried it yet.

Tl;dr the current implementation views ICC profiles as a map, whereas I, from a user's 'let me fix my hardware' perspective, view it as an instruction.