Repository navigation
perf(linux-screen): cache screenshot swscale context - #3231
Merged
richiemcilroy merged 2 commits intoOct 25, 2026
Merged
Conversation
Reuse one swscale context across screenshot conversions and, when the RGB24 stride is already width*3, let swscale write that plane straight into the image instead of packing a second buffer.
Contributor
Author
|
@greptileai review |
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. |
Contributor
Author
|
@greptileai review |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
convert_ffmpeg_frame_to_imagekeeps one swscale context per thread, keyed by source pixel format and size and by the RGB24 destination size.X11Grabberis still created for a single shot and dropped, so the cache lives next to the conversion rather than on the grabber (crates/recording/src/sources/screen_capture/linux.rsis already in open PR #3145).When
width * 3is a multiple of the 32-byte line alignmentVideo::allocuses, swscale writes that tight RGB24 plane straight into the image buffer. 4K (stride 11520) and 1080p (stride 5760) take this path, so the second row pack is skipped. Widths that would be padded still scale into an ffmpeg-owned frame and pack rows, which is the same layout as before.Why
Each X11 screenshot built a new swscale context, scaled into
Video::empty, then copied every row into a tight RGB buffer. A 4K BGRZ frame is about 24 MB of RGB, and that second pack moved it again. Corner rounding (#2808) and screenshot blur (#2979) run on the RGB image after this conversion. Output pixels match the previous swscale result.Measurement
Synthetic BGRZ → RGB24, release build, one thread. The baseline is the old conversion (new swscale context every call, then a row pack). The cached path is
convert_ffmpeg_frame_to_imageafter 5 warmup calls. Timed runs: 30.scaler_builds_during_timed_runs=0on both sizes, so the 30 timed calls reused the context.cargo test -p cap-recording --release --lib bench_bgrz_screenshot_conversion -- --ignored --nocapture --test-threads=1Hardware: Linux 6.12.94+ x86_64, KVM, Intel Xeon family 6 model 207 stepping 2, 4 vCPU at 2400 MHz. rustc 1.88.0. libswscale 8.3.100. Two process runs; the table is the second. The first 4K medians were 12.407 ms → 5.248 ms wall.
4K median wall time is 2.37× shorter (7.11 ms less per shot). Wall and thread CPU stay within a few microseconds, so the time is on-CPU. The timed loop did not rebuild the scaler.
Test plan
cargo test -p cap-recording --release --lib bgrx_screenshot_reuses_scaler— BGRZ and BGRA pixels match a channel swap and the old pack path; a second call with the same format and size does not build another context; a size or format change does.cargo test -p cap-recording --release --lib rounded_cornerscargo test -p cap-recording --release --lib rgb_cargo fmt -p cap-recording -- crates/recording/src/screenshot.rscargo clippy -p cap-recording --release --lib --no-deps -- -D warningsis clean.--lib --testsstill reports the existingnonminimal_boolincrates/recording/src/cursor.rs(untouched).No overlap with open PRs #3144, #3145, #3146, #2980, #2981, #2979, #2809, #3112, #3223, #3225, #3227, or other open screenshot changes. This diff is only
crates/recording/src/screenshot.rs.

Confidence Score: 5/5
The PR appears safe to merge.Summary
Caches the screenshot scaler per thread and skips the extra row copy when RGB rows meet the alignment requirement.
Reviews (2) · Last reviewed commit: "test(linux-screen): assert cached screen..." · Reviewed by Greptile