Skip to content

Conversation

@cashmeredev
Copy link

fixes #47

the screencopy protocol can return buffers with non-aligned strides, especially with bgr888 (24-bit) formats. this breaks pixman since it expects stride in uint32_t units and aligned to 4 bytes.

for non-32bit formats or misaligned strides, we now convert directly to argb8888 by writing into pixman's buffer instead of passing the raw buffer.

tested on nixos + swayfx + nvidia rtx 3070 ti where it was failing consistently before.

fixes moverest#47

the screencopy protocol can return buffers with non-aligned strides,
especially with bgr888 (24-bit) formats. this breaks pixman since it
expects stride in uint32_t units and aligned to 4 bytes.

for non-32bit formats or misaligned strides, we now convert directly
to argb8888 by writing into pixman's buffer instead of passing the
raw buffer.

tested on nixos + swayfx + nvidia rtx 3070 ti where it was failing
consistently before.
@moverest
Copy link
Owner

Thank you for your changes and your interest in the project. I'm not really sure how to reproduce this on my machine. Does this happen with grim as well? I don't remember them having specific code for this format so I am curious to know if it also fails there.

@cashmeredev
Copy link
Author

the crash is caused by how wl-kbptr passes the screencopy buffer to pixman. the compositor can return 24‑bit bgr888 buffers where the row stride in bytes is not a multiple of 4. pixman expects any external buffer to have a 4‑byte‑aligned row stride (it stores the stride internally in uint32_t units), and if that is not true, it hits the check
rowstride_bytes % sizeof(uint32_t) == 0 and aborts.

previously, wl-kbptr just handed the screencopy buffer directly to pixman, so on setups where the compositor used bgr888 with a “weird” stride, pixman would immediately crash. with grim i don’t see this issue, presumably because it only ever gets formats/strides that already match pixman’s expectations.

on my side i can reliably reproduce and compare the behavior:

  • nvidia workstation, swayfx, started with --unsupported-gpu
    • old wl-kbptr build: crashes with the pixman assertion about rowstride_bytes % sizeof(uint32_t) == 0.
    • patched wl-kbptr (this pr): works fine, no pixman abort.
  • intel laptop (no --unsupported-gpu, integrated gpu)
    • wl-kbptr always works here; i cannot trigger the crash with either the old or the patched build.

this matches the idea that certain compositor/gpu combinations (in my case nvidia + swayfx + --unsupported-gpu) return 24‑bit bgr888 screencopy buffers with a non‑aligned stride, which pixman then rejects. this pr fixes those cases by converting such buffers into an internal argb8888 image with a proper 4‑byte‑aligned stride before passing them to pixman.

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.

Floating mode doesn't work on sway

2 participants