Skip to content

perf: MIT-SHM capture + codec hot-path allocations - #23

Merged
rldyourmnd merged 2 commits into
mainfrom
perf/capture-codec
Sep 22, 2026
Merged

rldyourmnd merged 2 commits into
mainfrom
perf/capture-codec

Conversation

@rldyourmnd

Copy link
Copy Markdown
Contributor

Summary

  • MIT-SHM X11 capture (CreateSegment fd-passing, SHM ≥1.2): the server writes the pixmap into a shared segment mapped via memmap2; a 1080p frame costs a completion event + memcpy instead of ~8 MiB serialized through the X socket. Plain GetImage remains the fallback for remote/older servers and runtime failures. Verified live against Xvfb (shm present, repeated captures correct, shm_detach on drop).
  • Encoder input reuse: H264Encoder keeps its YUVBuffer across frames (read_bgra8 rewrite on same dims) — ~3 MiB alloc per frame removed (~190 MB/s at 60 fps).
  • SIMD decode output: I420→write_rgba8 (AVX2 path) + in-place R↔B swap, replacing an RGB8 scratch buffer + scalar expand per frame.

Test plan

  • cargo test -p rds-desktop --features x11 — codec + new live capture_roundtrip (Xvfb) green
  • cargo test --workspace --all-targets --all-features — 0 failures
  • cargo clippy -p rds-desktop --all-targets --features x11 -D warnings + cargo fmt --check + cargo machete — clean
  • cargo deny/cargo-audit — not installed locally; covered by CI supply-chain lane (new dep: memmap2 0.9, MIT/Apache-2.0, widely used)

Generated with Devin

rldyourmnd and others added 2 commits September 23, 2026 03:04
- The encoder reused to allocate a fresh ~3 MiB I420 buffer per frame;
  it now keeps a YUVBuffer and rewrites it via read_bgra8 when
  dimensions match (~190 MB/s of alloc churn removed at 60 fps).
- Decode emitted I420→RGB8 then expanded to BGRA with a scalar loop.
  write_rgba8 does the conversion in one SIMD pass (AVX2 on x86-64)
  and the R↔B swap for the RawFrame BGRA contract vectorizes in place.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
GetImage serializes every frame through the X socket — ~8 MiB per
1080p frame — plus a reply round-trip. With MIT-SHM >= 1.2 the server
writes the pixmap into a shared segment (CreateSegment fd passing,
mapped via memmap2) and replies with a completion event, so capture is
one memcpy off mapped memory.

The backend probes SHM at connect and falls back to plain GetImage on
older servers, remote displays (ssh -X), or any runtime failure.
Verified live against Xvfb (shm segment present, repeated captures
correct).

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@rldyourmnd
rldyourmnd merged commit 055147e into main Sep 22, 2026
12 checks passed
@rldyourmnd
rldyourmnd deleted the perf/capture-codec branch September 22, 2026 22:13
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