Skip to content

Conversation

@emersion
Copy link
Member

@emersion emersion commented Mar 18, 2025

No description provided.

@briancarbone
Copy link

briancarbone commented Jun 20, 2025

For me, this patch with HDR enabled adds significant delay to opening programs; even @dnkl's foot seems to take about half a second whereas without HDR the delay is imperceptible. In truth, my RX 6900 XT isn't state-of-the-art anymore, but it's certainly not a slouch.

With gamma-correct-blending enabled in foot, other open terminal windows will turn dark momentarily during the delay for a new terminal window to launch. Edit: Also occurs while resizing the terminal.

Screen recording (the colors aren't actually this pale; wf-recorder just seems to lack HDR compatibility currently):

recording.mp4

@briancarbone
Copy link

The delay on opening a program seems to have been fixed. Feels much better.

@emersion
Copy link
Member Author

Yes, it was unrelated to this PR: #8775

@Billli11
Copy link
Contributor

Getting error when compiling with clang.

ninja output
[268/347] Compiling C object sway/sway.p/commands_output_hdr.c.o
FAILED: sway/sway.p/commands_output_hdr.c.o 
clang -Isway/sway.p -Isway -I../sway -Iinclude -I../include -Iprotocols -I/usr/include/cairo -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/harfbuzz -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/sysprof-6 -I/usr/include/pixman-1 -I/usr/include/libdrm -I/usr/include/json-c -I/usr/include/libevdev-1.0 -I/usr/include/pango-1.0 -I/usr/include/libmount -I/usr/include/blkid -I/usr/include/fribidi -I/usr/include/wlroots-0.20 -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Werror -std=c11 -O0 -g -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L -Wno-unused-parameter -Wno-unused-result -Wno-missing-braces -Wno-format-zero-length -Wundef -Wvla '-DSYSCONFDIR="//usr/local/etc"' '-DSWAY_VERSION="1.12-dev-c2f08075 (" __DATE__ ", branch '"'"'master'"'"')"' -fmacro-prefix-map=../= -pthread -MD -MQ sway/sway.p/commands_output_hdr.c.o -MF sway/sway.p/commands_output_hdr.c.o.d -o sway/sway.p/commands_output_hdr.c.o -c ../sway/commands/output/hdr.c
../sway/commands/output/hdr.c:16:6: error: variable 'current' is used uninitialized whenever 'if' condition is false [-Werror,-Wsometimes-uninitialized]
   16 |         if (strcasecmp(argv[0], "toggle") == 0) {
      |             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../sway/commands/output/hdr.c:32:70: note: uninitialized use occurs here
   32 |         config->handler_context.output_config->hdr = parse_boolean(argv[0], current);
      |                                                                             ^~~~~~~
../sway/commands/output/hdr.c:16:2: note: remove the 'if' if its condition is always true
   16 |         if (strcasecmp(argv[0], "toggle") == 0) {
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../sway/commands/output/hdr.c:15:14: note: initialize the variable 'current' to silence this warning
   15 |         bool current;
      |                     ^
      |                      = false
1 error generated.
[285/347] Compiling C object sway/sway.p/tree_container.c.o
ninja: build stopped: subcommand failed.

Defaulting current to false like clang suggested fix the error.

@emersion
Copy link
Member Author

Ah yes, clang doesn't realize that the uninitialized variable is unreachable. Added a default value!

@emersion emersion force-pushed the hdr10 branch 2 times, most recently from 5445fee to ec343a0 Compare June 26, 2025 10:26
@emersion emersion marked this pull request as ready for review June 26, 2025 10:32
} else {
wlr_output_state_set_render_format(pending, DRM_FORMAT_XRGB8888);
}
enum render_bit_depth render_bit_depth = get_config_render_bit_depth(oc);
Copy link
Member

Choose a reason for hiding this comment

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

This defaults to 10-bit even if set_hdr would bail out on requesting HDR. Maybe we should flip things, setting HDR and changing the default based on whether HDR was set or not.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm, that sounds complicated to implement because get_config_render_bit_depth() is called from elsewhere too, e.g. search_render_format(). Also I think it's better to keep things simple to make the render bit depth default only depend on the config alone rather than the renderer/output capabilities.

Copy link
Member

@kennylevinsen kennylevinsen Jun 26, 2025

Choose a reason for hiding this comment

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

It does feel a little bit surprising that output * hdr on (where someone just wants to use HDR whenever available) would lead to all non-HDR displays having 10-bit render depth, especially as you cannot easily revert it (output * render_bit_depth 8 would also impact HDR-capable displays), and as 10-bit on Vulkan would activate the blending buffer which currently triples VRAM use and degrades performance a bit.

On the other hand I doubt anyone needs output * hdr on, at least right now where HDR is very much hit and miss. We can probably just ignore this for now.

get_config_render_bit_depth() is called from elsewhere too, e.g. search_render_format()

Both uses would be able to take wlr_output_state as argument if one wanted to check if hdr is enabled to select default render bit depth. search_render_format is called after queue_output_config has filled out the state, and HDR is not currently part of the output config search so it stays set until we give up.


bool hdr = oc && oc->hdr == 1;
if (hdr && oc->color_transform != NULL) {
sway_log(SWAY_ERROR, "Cannot HDR on output %s: output has an ICC profile set", wlr_output->name);
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we should log from here, queue_output_config is called all the the time and should just produce the current wlr_output_state. Same applies to set_hdr - if someone does output * hdr on, getting "PQ transfer function not supported by output" errors one or more times for every output not supporting HDR, every time any output changes is a bit noisy...

Maybe we could log something about output capabilities (HDR and VRR for example) when we create the output.

Copy link
Member Author

Choose a reason for hiding this comment

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

We already log for other errors, e.g. mode not found, invalid modeline etc.

I think it's important to log something when the user tries to enable HDR but we can't. Logging on startup isn't enough IMHO.

The current scheme only logs when the output configuration changes, which isn't too spammy and easy enough for users to fix if they want to (by only enabling HDR if the output supports it).

Copy link
Member

Choose a reason for hiding this comment

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

only logs when the output configuration changes

Multiple times on every change. I really don't like log noise. :/

I have slowly been chipping away at it (e.g., a630272), removing most bogus logging and collecting meaningful stuff in places like dump_output_state instead of just whenever we construct a wlr_output_state. The only remaining logs in queue_output_config is set_mode stating fallback to preferred mode and set_modeline failing if called on a non-drm output, which I didn't have an immediate replacement for...

The HDR case is logically similar to the adaptive sync case where the setting is best effort and can be disabled by display, link or connector restrictions, in which case not enabling is not considered an error. I do think in that case that we need to clarify what the output capabilities are in the log, as we right now only communicate what we end up doing (with debug log level).

Copy link
Member Author

Choose a reason for hiding this comment

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

I noticed the adaptive sync thing and was about to write a patch to add a log there. I find it pretty confusing that a command like output DP-1 adaptive_sync on would silently do nothing.

Copy link
Member

Choose a reason for hiding this comment

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

This was the kind of INFO-level logging I was thinking of: #8784

I feel like that's clearer than error logging. We could consider also logging the final output state as INFO though, right now that's only debug.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't think that kind of logging is very helpful to users TBH.

Copy link
Member

@kennylevinsen kennylevinsen Jun 29, 2025

Choose a reason for hiding this comment

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

I think it's far more helpful than sporadic error messages. Errors is something people try to fix as if something is wrong that has to be corrected, and there's nothing to tell if something isn't meant to work.

It's much easier to know if something is supported and to troubleshoot if the first step is: Does it say "yes"? Both for users, those providing support and those writing various FAQs/wikis for self-help.

But I won't hold up the feature for that further.

Copy link
Member Author

Choose a reason for hiding this comment

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

If the config tries to enable HDR10 and HDR10 cannot be enabled, I think it's only fair to print an error.

Anyways, it doesn't seem like we're going to come to an agreement here.

@LevitatingBusinessMan
Copy link

I get renderer doesn't support output color transforms on my monitor.

The model in question is "G272QPF E2" by MSI.

I tried manually disabling this check, but that resulted in some pretty awful colors.

@kennylevinsen
Copy link
Member

I tried manually disabling this check, but that resulted in some pretty awful colors.

That's because your renderer doesn't support color transforms as the error stated. Make sure you're using the vulkan renderer (WLR_RENDERER=vulkan).

@LevitatingBusinessMan
Copy link

I recompiled wlroots and used the vulkan renderer, now sway starts without error, but the colors are still broken. Most of this github page is just white, there's no contrast.

@briancarbone
Copy link

Something broke in a recent change (around when bool current = false was fixed); I think the color transforms were moved to wlroots and the implementation is not yet complete. Simon has a handful of branches for colors/luminance.

@emersion
Copy link
Member Author

emersion commented Jul 3, 2025

Something broke in a recent change (around when bool current = false was fixed); I think the color transforms were moved to wlroots and the implementation is not yet complete. Simon has a handful of branches for colors/luminance.

Indeed:
https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5102

@briancarbone
Copy link

Yep, that fixed it. Thanks.

@LevitatingBusinessMan
Copy link

https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5102

This worked for me. I am not sure how to actually test the HDR support but both sway and my monitor say it's enabled, and there's no obvious bugs.

@paul-ri
Copy link
Contributor

paul-ri commented Jul 5, 2025

I'm getting:

[ERROR] [sway/config/output.c:355] Cannot enable HDR on output eDP-1: BT2020 primaries not supported by output

Despite it being OK on Windows. Am I missing a setting? The laptop is an ASUS Zenbook 14 OLED (UX3405).

Currently on 35748a5 for Sway & 31b78a4f3 for wlroots

Relevant logs (hopefully):

Click to expand!

[INFO] [wlr] [backend/drm/drm.c:1836] 'eDP-1' connected
[DEBUG] [wlr] [backend/drm/drm.c:1611] Current CRTC: 82
[INFO] [wlr] [backend/drm/drm.c:1625] Detected modes:
[INFO] [wlr] [backend/drm/drm.c:1649]   2880x1800 @ 120.000 Hz (preferred)
[INFO] [wlr] [backend/drm/drm.c:1649]   2880x1800 @ 60.001 Hz (preferred)
[INFO] [wlr] [backend/drm/drm.c:1686] Physical size: 300x190
[INFO] [wlr] [backend/drm/drm.c:1811] Found connector 'DP-1'
[INFO] [wlr] [backend/drm/drm.c:1811] Found connector 'DP-2'
[INFO] [wlr] [backend/drm/drm.c:1811] Found connector 'HDMI-A-1'
[INFO] [wlr] [backend/drm/drm.c:1870] connector eDP-1: Requesting modeset
[DEBUG] [sway/desktop/output.c:541] New output 0x55df1f61c440: eDP-1 (non-desktop: 0)
[INFO] [wlr] [backend/headless/backend.c:17] Starting headless backend
[DEBUG] [sway/config/output.c:935] Committing 1 outputs
[ERROR] [sway/config/output.c:355] Cannot enable HDR on output eDP-1: BT2020 primaries not supported by output
[DEBUG] [sway/config/output.c:701] Output state for eDP-1
[DEBUG] [sway/config/output.c:703]     enabled:       yes
[DEBUG] [sway/config/output.c:707]     render_format: XR30
[DEBUG] [sway/config/output.c:715]     mode:          2880x1800@120000mHz (preferred)
[DEBUG] [sway/config/output.c:721]     adaptive_sync: enabled
[DEBUG] [sway/config/output.c:725]     scale:         2.000000
[DEBUG] [sway/config/output.c:728]     subpixel:      unknown
[DEBUG] [wlr] [types/wlr_output_swapchain_manager.c:160] Preparing test commit for 1 outputs with explicit modifiers
[DEBUG] [wlr] [render/swapchain.c:103] Allocating new swapchain buffer
[DEBUG] [wlr] [render/allocator/gbm.c:117] Allocated 2880x1800 GBM buffer with format XR30 (0x30335258), modifier 4_TILED_MTL_RC_C>
[DEBUG] [wlr] [types/wlr_output_swapchain_manager.c:181] Test commit for 1 outputs succeeded
[DEBUG] [wlr] [render/vulkan/renderer.c:887] vulkan create_render_buffer: XR30, 2880x1800
[DEBUG] [sway/config/output.c:995] Commit of 1 outputs succeeded
[DEBUG] [sway/config/output.c:1002] Finalizing config for eDP-1

Relevant env vars:

ENABLE_HDR_WSI=1
WAYLAND_DEBUG=1
WAYLAND_DISPLAY=wayland-1
WLR_RENDERER=vulkan
XDG_CURRENT_DESKTOP=sway
XDG_SESSION_TYPE=wayland
XDG_SESSION_DESKTOP=sway

Sway is started with systemd-cat --identifier=sway sway --verbose --debug. Kanshi is used to set output profiles

@emersion
Copy link
Member Author

emersion commented Jul 6, 2025

@paul-ri Can you share your EDID? You can find it in /sys/class/drm/card*-*/edid.

@paul-ri
Copy link
Contributor

paul-ri commented Jul 6, 2025

Yep: zenbook_edid_binary.txt

Output of cat /sys/class/drm/card1-eDP-1/edid | edid-decode below:

Click to expand!

edid-decode (hex):

00 ff ff ff ff ff ff 00 4c 83 9d 41 00 00 00 00
00 20 01 04 b5 1e 13 78 03 cf d1 ae 51 3e b6 23
0b 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 cb fe 40 64 b0 08 38 77 20 08
88 00 2e bd 10 00 00 1b 00 00 00 fd 00 30 78 da
da 42 01 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 fe
00 41 54 4e 41 34 30 43 55 30 36 2d 30 20 01 25

70 20 79 02 00 20 00 0c 4c 83 00 9d 41 00 00 00
00 00 20 00 21 00 1d b8 0b 6c 07 40 0b 08 07 00
ee ea 50 ec d3 b6 3d 42 0b 01 45 54 40 5e d0 60
18 10 23 78 26 00 09 07 06 03 00 00 00 50 00 00
22 00 14 e7 f3 09 85 3f 0b 63 00 1f 00 07 00 07
07 17 00 07 00 07 00 81 00 1f 73 1a 00 00 03 03
30 78 00 a0 74 02 60 02 78 00 00 00 00 8d e3 05
80 00 e6 06 05 01 74 60 02 00 00 00 00 00 91 90

----------------

Block 0, Base EDID:
  EDID Structure Version & Revision: 1.4
  Vendor & Product Identification:
    Manufacturer: SDC
    Model: 16797
    Made in: 2022
  Basic Display Parameters & Features:
    Digital display
    Bits per primary color channel: 10
    DisplayPort interface
    Maximum image size: 30 cm x 19 cm
    Gamma: 2.20
    Supported color formats: RGB 4:4:4
    First detailed timing includes the native pixel format and preferred refresh rate
    Display supports continuous frequencies
  Color Characteristics:
    Red  : 0.6826, 0.3164
    Green: 0.2451, 0.7138
    Blue : 0.1396, 0.0439
    White: 0.3125, 0.3291
  Established Timings I & II: none
  Standard Timings: none
  Detailed Timing Descriptors:
    DTD 1:  2880x1800   60.000699 Hz  16:10   218.883 kHz    652.270000 MHz (302 mm x 189 mm)
                 Hfront   32 Hsync   8 Hback   60 Hpol P
                 Vfront    8 Vsync   8 Vback 1832 Vpol N
    Display Range Limits:
      Monitor ranges (Range Limits Only): 48-120 Hz V, 218-218 kHz H, max dotclock 660 MHz
    Manufacturer-Specified Display Descriptor (0x00): 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 '................'
    Alphanumeric Data String: 'ATNA40CU06-0 '
  Extension blocks: 1
Checksum: 0x25

----------------

Block 1, DisplayID Extension Block:
  Version: 2.0
  Extension Count: 0
  Display Product Primary Use Case: None of the listed primary use cases; generic display
  Product Identification Data Block (0x20), OUI 4C-83-00:
    Product Code: 16797
    Year of Manufacture: 2032
  Display Parameters Data Block (0x21):
    Image size: 300.0 mm x 190.0 mm
    Display native pixel format: 2880x1800
    Scan Orientation: Left to Right, Top to Bottom
    Luminance Information: Minimum guaranteed value
    Color Information: CIE 1931
    Audio Speaker Information: integrated
    Native Color Chromaticity:
      Primary #1:  (0.683105, 0.315918)
      Primary #2:  (0.245117, 0.714111)
      Primary #3:  (0.139893, 0.043945)
      White Point: (0.312744, 0.329102)
    Native Maximum Luminance (Full Coverage): 400.000000 cd/m^2
    Native Maximum Luminance (10% Rectangular Coverage): 616.000000 cd/m^2
    Native Minimum Luminance: 0.000500 cd/m^2
    Native Color Depth: 12 bpc
    Display Device Technology: Organic LED
    Native Gamma EOTF: 2.20
  Display Interface Features Data Block:
    Supported bpc for RGB encoding: 6, 8, 10
    Supported bpc for YCbCr 4:4:4 encoding: 8, 10
    Supported bpc for YCbCr 4:2:2 encoding: 8, 10
    Supported color space and EOTF standard combination 1: DCI-P3, BT.2020/SMPTE ST 2084
  Video Timing Modes Type 7 - Detailed Timings Data Block:
    DTD:  2880x1800  120.000294 Hz  16:10   218.881 kHz    652.264000 MHz (aspect 16:10, no 3D stereo, preferred)
               Hfront   32 Hsync   8 Hback   60 Hpol N
               Vfront    8 Vsync   8 Vback    8 Vpol N
  CTA-861 DisplayID Data Block:
  Vendor-Specific Data Block (AMD), OUI 00-00-1A:
    Version: 3
    Feature Caps: 0x03
    Minimum Refresh Rate: 48 Hz
    Maximum Refresh Rate: 120 Hz
    Flags 1.x: 0x00
    Flags 2.x: 0xa0
    Maximum luminance: 116 (616.884 cd/m^2)
    Minimum luminance: 2 (0.000 cd/m^2)
    Unknown: 0x60 0x02
  Colorimetry Data Block:
    BT2020RGB
  HDR Static Metadata Data Block:
    Electro optical transfer functions:
      Traditional gamma - SDR luminance range
      SMPTE ST2084
    Supported static metadata descriptors:
      Static metadata type 1
    Desired content max luminance: 116 (616.884 cd/m^2)
    Desired content max frame-average luminance: 96 (400.000 cd/m^2)
    Desired content min luminance: 2 (0.000 cd/m^2)
  Checksum: 0x91
Checksum: 0x90

@emersion
Copy link
Member Author

emersion commented Jul 6, 2025

Ah, thanks! It seems like all of the interesting stuff is inside a DisplayID 2 extension block.

See this issue for DisplayID 2 support in libdisplay-info: https://gitlab.freedesktop.org/emersion/libdisplay-info/-/issues/18

@paul-ri
Copy link
Contributor

paul-ri commented Jul 6, 2025

Cheers! That'll help other folks in the same situation as me. Thanks for the amazing efforts!

@emersion emersion merged commit 94c819c into swaywm:master Jul 8, 2025
3 checks passed
@emersion emersion deleted the hdr10 branch July 8, 2025 23:25
JayceFayne pushed a commit to JayceFayne/swayipc-rs that referenced this pull request Oct 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

7 participants