Kwin HDR 10-bit screencast support (How to debug a plugin?)

I’m on a mission to get HDR 10-bit screen capture working with OBS via pipewire, so I can screen record in HDR. I’m a developer with video & HDR experience but lacking KDE / Wayland / kernel background, so I may need a little assistance figuring out how to debug & test changes to a plugin on a live system.

TLDR: OBS and pipewire are already 10-bit capable; the limitation appears to be in Kwin’s screencast plugin only listing 8-bit pixel formats, truncating the pixel data to 8-bit and losing the extended dynamic range.

I’m using CachyOS (Arch-based), KDE Plasma 6.5.5, KWin (Wayland). My display is HDR capable and displays HDR correctly, that part works fine. OBS 32.0.4 (or built from git main), pipewire 1.4.10 (latest).

After some searching, here’s what I think I know and where I think the problem occurs:

  1. HDR composited screen buffers should already be in either DRM_FORMAT_ABGR2101010 or DRM_FORMAT_XBGR2101010 (2:10:10:10 in 32bpp)
  2. pipewire already supports these for screencasting if both sides of the connection support it, and OBS already sends these in its negotiation list of formats. OBS also already supports recording to HDR 10-bit video formats with correct metadata (and I’ve verified this part works fine), but pipewire is only negotiating a BGRA 8-bit buffer because that’s all the underlying screen output device claims to support.
  3. In KWin plugins/screencast/screencaststream.cpp, the supportedFormats[] array only lists 8-bit DRM formats, no 10-bit formats.
  4. Effectively the 10-bit screen buffer is getting truncated to 8-bit in the GL texture copy, zero copied via pipewire as a BGRA 8-bit surface, then OBS is converting the 8-bit truncated data back to 10-bit which doesn’t restore the lost dynamic range.

Changes needed:

  1. In screencaststream.cpp, add mappings from the 2 DRM formats above to SPA_VIDEO_FORMAT_ABGR_210LE and SPA_VIDEO_FORMAT_xBGR_210LE respectively.
  2. Also in screencaststream.cpp, where the comment says “/* announce equivalent format without alpha */”, do the same for ABGR_210LE to xBGR_210LE.
  3. In screencastutils.h, add a case for QImage::Format_RGB30 to GL_RGB10_A2
  4. Now hopefully doGrabTexture() in screencastutils.h will do a copy instead of a format convert to an 8-bit texture.
  5. Probably a handful of other small changes but I don’t see anything major.

Hopefully it’s as simple as the above. The number of bytes per pixel is the same as RGBA, so buffer sizes won’t change.

One thing I don’t know is how to go about debugging / testing a Kwin plugin on a live running system that depends on Kwin to have a working screen. I was going to ask on the Kwin mailing list, but the link from their Github is broken; Kwin is not a valid mailing list on the KDE mailing list server. If anyone has some pointers on how to debug & test a modified plugin on a live system that would be really helpful to get me started.

Thanks.