Skip to content

Conversation

@oliverbestmann
Copy link

@oliverbestmann oliverbestmann commented Dec 27, 2025

This enables hacky support for hdr output in gnome/kde.

While it works pretty well with the internal display of my macbook m1 pro. There are slight differences in color rendering of sdr content while hdr is enabled, I dont know why yet. I have not tested this with external monitors at all yet.

I've tried this on gnome 49 and kde and got to view some hdr content in firefox and play hdr video using mpv.

We need a few things for gnome/kde to realize that the output supports hdr.

  • Gnome is looking for the colorspace property on the connector and wants it to indicate support for BT2020_RGB.

  • It wants to see a HDR_OUTPUT_METADATA property on the connector.

  • Gnome reads the edid blob and checks for support of different hdr transfer functions. It requires the PQ function to be available to expose bt2020 as an available colorspace. This hacky commit will just return an edid record of a different hdr capable screen. This is a hack.

When HDR is enabled, the compositor will set the color property and the HDR_OUTPUT_METADATA property to tell the kernel about how the surface data is to be interpreted. I use this in the apple_dcp driver to switch the transfer function from sdr to hdr.

Backlight is another topic:

Since gnome 49, gnome will switch to a virtual/soft backlight control when hdr is activated (kde does that too). With an absolute transfer function like PQ that actually makes kind of sense. The actual backlight is then just set to 100%. This patch forces the backlight into max brightness when the HDR_OUTPUT_METADATA property is present (currently even more than normal sdr max brightness). When enabling hdr, you need to dial the virtual backlight all the way down, otherwise it'll crush highlights in hdr content. In KDE a sdr brightness value of around 35% looks good.

I think macOS also has an internal virtual backlight control. It is continously adjusting the bightness value of the (real) backlight when displaying hdr content while the percived brightness of sdr content on screen stays the same by varying the virtual backlight (i guess).

Knobs:

For experimenting I've exposed three parameters from apple_dcp:

  • swap_hdr_colorspace: Controls the dcp colorspace value when hdr is enabled. Defaults to DCP_COLORSPACE_NATIVE (12). I thought that using DCP_COLORSPACE_BG_BT2020 would make more sense, but that crushes everything that is not super bright.

  • swap_hdr_transferfunc: Controls the dcp transfer function when hdr is enabled. Defaults to DCP_XFER_FUNC_HDR (16).

  • swap_hdr_brightness: The backlights brightness value when hdr is enabled. I choose to use the maxiumum value observed in dcp traces when hdr content was displayed on screen: 0x98ffffc0. This is way above the maximum allowed sdr value of about 0x7fe07fc0.

This commit enables hacky support for hdr output in gnome/kde.

While it works pretty well with the internal display of my macbook m1 pro.
There are slight differences in color rendering of sdr content while hdr is enabled,
I dont know why yet. I have not tested this with external monitors at all yet.

I've tried this on gnome 49 and got to view some hdr content in firefox and
play hdr video using mpv. [2]

We need a few things for gnome/kde to realize that the output supports hdr [1].

* Gnome is looking for the colorspace property on the connector and wants it to
  indicate support for BT2020_RGB.

* It wants to see a HDR_OUTPUT_METADATA property on the connector.

* Gnome reads the edid blob and checks for support of different hdr transfer
  functions. It requires the PQ function to be available to expose bt2020 as an
  available colorspace [3]. This hacky commit will just return an edid record of
  a different hdr capable screen. This is a hack.

When HDR is enabled, the compositor will set the color property and the
HDR_OUTPUT_METADATA property to tell the kernel about how the surface data is to
be interpreted. I use this in the apple_dcp driver to switch the transfer
function from sdr to hdr.

Backlight is another topic:

Since gnome 49, gnome will switch to a virtual/soft backlight control when hdr
is activated. With an absolute transfer function like PQ that actually makes
kind of sense. The actual backlight is then just set to 100%. This patch forces
the backlight into max brightness when the HDR_OUTPUT_METADATA property is
present (currently even more than normal sdr max brightness). When enabling hdr,
you need to dial the virtual backlight all the way down, otherwise it'll crush
highlights in hdr content.

I think macOS also has an internal virtual backlight control. It is continously
adjusting the bightness value of the (real) backlight when displaying hdr
content while the percived brightness of sdr content on screen stays the same by
varying the virtual backlight (i guess).

Knobs:

For experimenting I've exposed three parameters from apple_dcp:

* swap_hdr_colorspace: Controls the dcp colorspace value when hdr is enabled.
  Defaults to DCP_COLORSPACE_NATIVE (12). I thought that using
  DCP_COLORSPACE_BG_BT2020 would make more sense, but that crushes everything
  that is not super bright.

* swap_hdr_transferfunc: Controls the dcp transfer function when hdr is enabled.
  Defaults to DCP_XFER_FUNC_HDR (16).

* swap_hdr_brightness: The backlights brightness value when hdr is enabled. I
  choose to use the maxiumum value observed in dcp traces when hdr content was
  displayed on screen: 0x98ffffc0. This is way above the maximum allowed sdr
  value of about 0x7fe07fc0.

[1] https://gitlab.gnome.org/GNOME/mutter/-/blob/31e0de8800308c87655100e1d6ffc42f58625a34/src/backends/native/meta-output-kms.c#L533
[2] https://wiki.archlinux.org/title/HDR#HDR_video_samples
[3] https://gitlab.gnome.org/GNOME/mutter/-/blob/31e0de8800308c87655100e1d6ffc42f58625a34/src/backends/meta-monitor.c#L217

Signed-off-by: Oliver Bestmann <oliver.bestmann@googlemail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant