Skip to content

implement proper tone mapping

Xaver Hugl requested to merge work/zamundaaa/tonemapping into master

When an image has metadata that tells us it's brighter than the max. luminance we can show, KWin will

  • convert the rgb colors to ICtCp, which very cleanly splits luminance and color
  • convert the intensity component to nits
  • apply a tone mapping curve with
    • a linear part from [0, reference], that's mapped to [0, newReference]
    • a non-linear part from [reference, max content luminance] that's mapped to [newReference, max display luminance]
  • convert nits back to intensity
  • convert ICtCp back to rgb

The results are, while not perfect (I think gamut mapping would fix the sky in the first image), imo a big improvement for playing back HDR content on an SDR display (without !6138):

Without tone mapping This MR MPV's tone mapping
Screenshot_20240814_172439 Screenshot_20240814_172901 Screenshot_20240814_173107
Screenshot_20240814_172533 Screenshot_20240814_172956 Screenshot_20240814_173122
Screenshot_20240814_172613 Screenshot_20240814_173034 Screenshot_20240814_173144

This is still draft though because

  • there's no color pipeline object for this tone mapping operation yet, so direct scanout would circumvent it
  • the shader doesn't compile in OpenGL ES?? -> apparently, dividing an integer by a float isn't a constant expression in GLES 2
  • it could use some more testing
  • we need to make sure there's not too much tone mapping going on with games, as they tend to advertise nonsensical HDR metadata and that could potentially make the image darker on some monitors -> added KWIN_DISABLE_TONEMAPPING to be able to disable it. If we get complaints / find issues before 6.2, we can just flip the default
Edited by Xaver Hugl

Merge request reports