Skip to content

Conversation

@njdom24
Copy link
Contributor

@njdom24 njdom24 commented Oct 22, 2025

Describe your PR, what does it fix/add?

Instead of the piecewise sRGB EOTF, allow the user to choose Gamma 2.2 for untagged, and/or all sRGB EOTF surfaces.
Makes SDR content with cm = hdr look more like how it does with cm = srgb on an average monitor in SDR, as SDR media content typically assumes a gamma 2.2 curve.

Should help #10950, #11341 or anyone who felt the existing gamma curve felt too "washed-out" compared to what they're used to.

Adds render:cm_sdr_eotf for specifying the transfer function for sRGB content in general for both SDR and HDR.
0: Piecewise sRGB (Existing behavior)
1: Treat untagged surfaces as Gamma 2.2
2: Treat untagged surfaces and all sRGB EOTF surfaces as Gamma 2.2

I added 2 because a lot of desktop content seems to have been developed in an environment that is encoded for sRGB on the PC side, with the expectation of being decoded by a Gamma 2.2 monitor/TV. KWin seems to behave with this in mind, and this tweak gets me the appearance I expect after spending some time with KDE.

1 was my initial plan, but I noticed a fair few apps did get tagged for sRGB transfer that I wasn't expecting (Gamescope, Proton Wayland)

On the monitorv2 side, we also have a sdr_eotf var with values of:
0: Follow the default SDR EOTF from render:sdr_eotf. This will be sRGB for cm_sdr_eotf = 0, and Gamma 2.2 for 1, 2
1: sRGB piecewise function
2: Gamma 2.2

Many (most?) monitors with an sRGB clamp also enforce a Gamma of 2.2 because it's become a standard (I don't think you'll find the piecewise sRGB EOTF on much beyond color professional displays). This allows us to acknowledge that for displays configured that way.

I left the defaults as sRGB on both ends to avoid breaking anyone's setups. Personally, I'm having a good time setting render:cm_srgb_eotf = 2 and monitorv2[*]:cm_srgb_eotf" 1 to keep a consistent image in SDR and HDR.

This also allows you to set render:cm_sdr_eotf = 0 and monitorv2[*]:sdr_eotf" 1 to get the piecewise sRGB curve on a Gamma 2.2 display, making SDR mode consistent with the default SDR-on-HDR image, if you want.

Is there anything you want to mention? (unchecked code, possible bugs, found problems, breaking compatibility, etc.)

This is the default behavior in KWin, wlroots(-git), and I believe Mutter.
I believe macOS allows the user to choose the EOTF.

Works so far on my machine. With my monitor's SDR settings set to sRGB w/ Gamma 2.2, toggling HDR on and off in Elden Ring keeps a consistent image (but with different dynamic range). This is with setting render:cm_sdr_eotf = 2 and monitorv2[*]:sdr_eotf" 0 (or 2).

Editing CM.glsl to over-brighten CM_TRANSFER_FUNCTION_GAMMA22 as a sanity check, cm = srgb is entirely unaffected by default as expected, and with cm = hdr, and render:cm_sdr_eotf = 1, most of my windows follow the expected new gamma curve, except for kitty, which is color-managed and explicitly requests sRGB.

Is it ready for merging, or does it need work?

Ready

@vaxerski
Copy link
Member

@UjinT34

@UjinT34
Copy link
Contributor

UjinT34 commented Oct 22, 2025

sRGB is the standard and the default for most content, no need to change that globally.

By default, a surface does not have an associated image description nor a rendering intent. The handling of color on such surfaces is compositor implementation defined. Compositors should handle such surfaces as sRGB, but may handle them differently if they have specific requirements.

Shouldn't break the proto if we decide to change it though. And shouldn't be much of a difference, 2.2 is a close enough approximation of sRGB.

No need to touch the shaders. If gamma 2.2 works better for SDR -> HDR then sdr surfaces without CM (!surface->m_colorManagement.valid()) should default to some other image description with gamma 2.2 in HDR mode instead of SImageDescription{}. This value is passed to passCMUniforms and the CM shader will use gamma 2.2 for SDR -> HDR. The default branch in the CM shader shouldn't be hit with the current set of supported TFs, it's a fallback for incorrect values and potential new TFs.

I don't use cm, hdr and don't like SDR -> HDR the way it is now. So any improvements to SDR -> HDR that don't affect anything else are welcome.

Can be tested as is to verify that 2.2 looks better. Might not be good enough for OLED monitors because 2.2 is a bit brighter overall and may cause "crushed" blacks. Probably should end up as a config option.

@njdom24
Copy link
Contributor Author

njdom24 commented Oct 22, 2025

@UjinT34 I think that quote referring to sRGB was specifically about primaries. Looking into the spec w.r.t. transfer functions:

srgb:

Note: This is not appropriate for describing sRGB material. sRGB material is intended to be viewed on an sRGB display, and that is described by gamma22.

gamma22:

Note: an sRGB display (IEC 61966-2-1) uses this transfer function.

Thank you so much for the feedback! I'll get going on those changes tonight

@njdom24 njdom24 marked this pull request as draft October 22, 2025 12:20
@UjinT34
Copy link
Contributor

UjinT34 commented Oct 22, 2025

I'm a bit confused here.

sRGB is a colorspace which uses the same primaries as BT709 and an sRGB TF. BT709 itself uses a piece-wise TF. Different gammas are approximations which can't handle blacks well enough.

It's not clear which TF should be considered the default for the source content and which TF should be used as a default for an output. sRGB seems to be the correct one and gamma 2.2 is used when performance is more important than colors.

Makes SDR content with cm = hdr look more like how it does with cm = srgb.

Doesn't mean that this is the correct looks. With cm = srgb there is no CM transformations for most clients and it might be displayed incorrectly if the monitor isn't set to use srgb.
By default SDR -> HDR on a good HDR monitor should look the same as SDR on a regular SDR monitor if you put both side by side (meaning "look bad") which is not what most users expect or desire. This is just considered to be correct and intended.

@njdom24 njdom24 force-pushed the itm-default-gamma-2.2 branch from 61045aa to 8cfd896 Compare October 23, 2025 03:20
@njdom24 njdom24 changed the title Default to Gamma 2.2 TF for SDR -> HDR renderer/cm: allow defaulting to gamma 2.2 for SDR -> HDR Oct 23, 2025
@njdom24 njdom24 force-pushed the itm-default-gamma-2.2 branch 2 times, most recently from 819be13 to 6f406f2 Compare October 23, 2025 03:44
@njdom24 njdom24 marked this pull request as ready for review October 23, 2025 04:14
@njdom24
Copy link
Contributor Author

njdom24 commented Oct 23, 2025

@UjinT34 Looking at this has made me wonder if it makes sense for a follow-up PR to add cm = gamma22 for SDR too, for users (like me) whose displays use that gamma curve in sRGB mode. As-is, wouldn't any color-managed surface be transformed incorrectly on SDR in that case?

Edit: This PR only targets the HDR case, but maybe it should be reworked to add two new cm options (gamma22, hdrgamma22) to cover both cases.

@UjinT34
Copy link
Contributor

UjinT34 commented Oct 23, 2025

@UjinT34 Looking at this has made me wonder if it makes sense for a follow-up PR to add cm = gamma22 for SDR too, for users (like me) whose displays use that gamma curve in sRGB mode. As-is, wouldn't any color-managed surface be transformed incorrectly on SDR in that case?

Makes sense. Might need to split this option to allow setting primaries and TF independently. Will be tricky to do it backwards-compatible way though.

@njdom24 njdom24 marked this pull request as draft October 23, 2025 11:29
@njdom24
Copy link
Contributor Author

njdom24 commented Oct 23, 2025

I'm thinking just a cm_sdr_tf that defaults to srgb, but allows the gamma22 option? It could set the untagged default and target TF in SDR, and just the default in HDR.

It wouldn't cover the case of users with gamma22 displays who want their untagged SDR content considered srgb by default, but it shouldn't break current behavior. Maybe it can be split in two (cm_sdr_default_tf...?)

@njdom24 njdom24 force-pushed the itm-default-gamma-2.2 branch 2 times, most recently from 7757962 to 51eb53b Compare October 24, 2025 03:47
@njdom24

This comment was marked as outdated.

@njdom24 njdom24 marked this pull request as ready for review October 24, 2025 04:37
@njdom24 njdom24 changed the title renderer/cm: allow defaulting to gamma 2.2 for SDR -> HDR renderer/cm: allow gamma 2.2 instead of sRGB EOTF Oct 24, 2025
@njdom24
Copy link
Contributor Author

njdom24 commented Oct 24, 2025

@UjinT34 I'd argue in favor of setting the defaults to gamma 2.2 both for monitors and for how we interpret sRGB EOTF content in general, because most users' displays wouldn't natively be decoding using a piecewise sRGB EOTF in SDR, and also wouldn't want/expect their colors to be transformed for most of their apps.

But my current implementation leaves the defaults as they are now. Otherwise, ready for review.

Edit: There's some good discussion at mpv-player/mpv#16915

@njdom24 njdom24 marked this pull request as draft October 24, 2025 23:48
@njdom24 njdom24 force-pushed the itm-default-gamma-2.2 branch 3 times, most recently from 51eb53b to fc2f631 Compare October 25, 2025 00:21
@njdom24 njdom24 marked this pull request as ready for review October 25, 2025 00:53
@njdom24 njdom24 force-pushed the itm-default-gamma-2.2 branch from fc2f631 to 876afd0 Compare October 26, 2025 02:58
@njdom24 njdom24 marked this pull request as draft October 26, 2025 15:54
@njdom24 njdom24 force-pushed the itm-default-gamma-2.2 branch from 876afd0 to a545cac Compare October 26, 2025 16:41
@njdom24 njdom24 marked this pull request as ready for review October 26, 2025 16:44
@njdom24
Copy link
Contributor Author

njdom24 commented Oct 26, 2025

@s0mebodyhelpme I flubbed a change when I pushed last night (sorry about that!). The latest version of this branch should have the SDR settings fixed, and I'm using them on my machine as I write this.

Edit: Note that screenshare brightness will be messed up again (like it is on the main branch). That's because it's tied to the reference luminance of 80 nits, and when this branch was broken, it stopped that from being updated. Rest assured, that's on my TODO list for the future :)

@s0mebodyhelpme
Copy link

s0mebodyhelpme commented Oct 26, 2025

@njdom24 thanks! appreciate the fix and your effort in general, and i'm looking forward to your further work on HDR with Hyprland so that it can get better. Also look forward to testing whatever you've got in mind for the screenshare fix.

@njdom24 njdom24 force-pushed the itm-default-gamma-2.2 branch from a545cac to e52ee50 Compare October 27, 2025 05:02
@njdom24
Copy link
Contributor Author

njdom24 commented Oct 27, 2025

Updated to change render:cm_srgb_eotf to cm_sdr_eotf, and monitorv2[*]:cm_srgb_eotf to monitorv2[*]:sdr_eotf to keep the variable names (slightly) distinct, and I feel using SDR instead of sRGB makes their purpose a little bit clearer.

It also lines up with how macOS declares it:
image

Also changed the defaults for the monitor variable. Now:
0: Follow the default SDR EOTF from render:sdr_eotf. This will be sRGB for cm_sdr_eotf = 0, and Gamma 2.2 for 1 or 2
1: sRGB piecewise function
2: Gamma 2.2

This will make it so users don't have to change settings for every monitor if they have a global preferred default.

@njdom24 njdom24 force-pushed the itm-default-gamma-2.2 branch from e52ee50 to 37d4426 Compare October 27, 2025 05:48
@njdom24
Copy link
Contributor Author

njdom24 commented Oct 27, 2025

I'm keeping an eye on some discussion of a potential v2 of the proto: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/456#note_3159579

Looks like these changes may be relevant for supporting whichever direction it ends up going

@ssareta
Copy link

ssareta commented Oct 27, 2025

Thanks a lot for your work on this! May I ask, could you also add a config option of the gamma value in the power curve? e.g. when the gamma option is selected, let the user set gamma 2.4 or 2.6 instead of 2.2, similar to macOS?

Reason being, I think for some display types (e.g. OLED) or in darker ambients higher gamma values can look/behave slightly better.

@njdom24
Copy link
Contributor Author

njdom24 commented Oct 27, 2025

@ssareta I'm not opposed to enhancing this in the future, but I want to focus this PR on just Gamma 2.2 because it's the one in the spec.

Copy link
Member

@vaxerski vaxerski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this ready to go?

@njdom24 njdom24 force-pushed the itm-default-gamma-2.2 branch from 37d4426 to cd455e4 Compare October 29, 2025 11:30
@njdom24
Copy link
Contributor Author

njdom24 commented Oct 29, 2025

@vaxerski Yeah, should be ready for review

@vaxerski vaxerski merged commit ff50dc3 into hyprwm:main Oct 29, 2025
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants