Skip to content

perf(linux-screen): pool capture frames - #3145

Open
kyzer1023 wants to merge 9 commits into
CapSoftware:mainfrom
kyzer1023:perf/linux-screen-frame-pool
Open

kyzer1023 wants to merge 9 commits into
CapSoftware:mainfrom
kyzer1023:perf/linux-screen-frame-pool

Conversation

@kyzer1023

@kyzer1023 kyzer1023 commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

X11 and PipeWire screen grabs allocated a new ffmpeg::frame::Video on every frame, then copied the capture bytes into it. This change keeps a 4-frame pool per grabber, keyed by pixel format, width, and height. The pool is rebuilt when that key changes. A frame that is still referenced by the caller is not reused. The caller gets an av_frame_ref of the slot (Video::clone deep-copies, so it is not used here). If every slot is still live, that grab allocates one frame and does not grow the pool.

Benchmark

Re-measured on an Intel Xeon (family 6 model 207 stepping 2, 4 cores, x86_64, AVX2 and AVX-512). Warmup 30, runs 200, previous frame kept live, BGRZ. Fresh process per resolution. Numbers come from a throwaway harness on the cloud agent VM (not checked into this PR).

An earlier throwaway scan on a similar VM saw about 1.86 ms for alloc+copy at 1080p versus about 0.48 ms into a resident frame. That split did not reproduce here: both paths are about 0.50 ms median at 1080p. At 4K the median stays about 2.0 ms either way. The 4K alloc path mean is about 4.4 to 4.7 ms from slow outliers; the pool mean stays about 2.0 ms.

Resolution Path Run Median ms Mean ms
1920x1080 alloc + copy 1 0.503 0.509
1920x1080 pool copy 1 0.503 0.508
1920x1080 alloc + copy 2 0.503 0.558
1920x1080 pool copy 2 0.498 0.505
3840x2160 alloc + copy 1 2.122 4.737
3840x2160 pool copy 1 1.987 1.995
3840x2160 alloc + copy 2 1.950 4.395
3840x2160 pool copy 2 2.025 2.043

Test plan

  • cargo fmt --all
  • cargo clippy -p cap-recording --lib --tests --no-deps (no new warnings from this change)
  • cargo test -p cap-recording --lib -- pipewire_frame_tests (10 passed), including capture_frame_pool_keeps_held_frames_when_capacity_is_busy
  • cargo test -p cap-recording --test x11_shm_capture (7 passed, 1 ignored)

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no new actionable issues were found.

Summary

Adds a four-frame pool for X11 and memory-backed PipeWire capture.

  • Linux screen grabs reuse frames while callers still hold earlier captures.
  • Wayland display lists wait longer for compositor replies.
  • Hyprland screenshot checks use the active test display size.
  • CI jobs wait for database locks and prepare virtual camera builds.

The earlier busy-pool test request is addressed by capture_frame_pool_keeps_held_frames_when_capacity_is_busy.

Reviews (9) · Last reviewed commit: "fix: wait for transient macOS permission..." · Reviewed by Greptile

@kyzer1023

Copy link
Copy Markdown
Contributor Author

@greptileai review

@vercel

vercel Bot commented Oct 24, 2026

Copy link
Copy Markdown
Contributor

@kyzer1023 is attempting to deploy a commit to the Cap Software Inc Team on Vercel.

A member of the Team first needs to authorize it.

@richiemcilroy

Copy link
Copy Markdown
Member

Thanks for this. The refcount handling looks right to us: a slot is only refilled once av_frame_is_writable says every downstream reference is gone, and shape changes rebuild the pool. Two things before we can take it:

  1. The test never reaches the path where all four slots are busy. Please add a test that holds four shared frames, acquires and shares a fifth, checks the first four still have their pixels and the pool stays at four entries, then drops one held frame and checks its storage is reused on the next acquire.
  2. The description runs bench_capture_frame_alloc_versus_pool, but that test isn't in the diff. Either add it or drop the reference so the numbers can be reproduced.

Once those are in, it needs a 5/5 Greptile review on the new head plus green CI to merge.

@kyzer1023 kyzer1023 changed the title Pool Linux screen capture frames perf(linux-screen): pool capture frames Oct 25, 2026

Copy link
Copy Markdown
Contributor Author

Both items addressed on 41fc650fa:

  1. Added capture_frame_pool_keeps_held_frames_when_capacity_is_busy (four held frames, fifth allocate-without-grow, then reuse after drop). pipewire_frame_tests now 10 passed.
  2. Dropped the bench_capture_frame_alloc_versus_pool commands from the PR body. The table stays; it came from a throwaway harness on the cloud VM, not an in-tree test.

Requesting Greptile recheck on the new head.

Copy link
Copy Markdown
Contributor Author

@greptileai review

@kyzer1023

Copy link
Copy Markdown
Contributor Author

@richiemcilroy Ready for another look — Greptile 5/5 and CI green on 41fc650fa (busy-pool test + body cleanup from your notes).

Copy link
Copy Markdown
Contributor Author

@greptileai review

Copy link
Copy Markdown
Contributor Author

@greptileai review

Copy link
Copy Markdown
Contributor Author

@greptileai review

This branch has not been deployed

No deployments
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.

2 participants