Skip to content

perf(rendering): convert YUV420P frames in 2x2 blocks - #2631

Merged
richiemcilroy merged 6 commits into
CapSoftware:mainfrom
The-Best-Codes:best/yuv420p-convert-blocks
Oct 18, 2026
Merged

richiemcilroy merged 6 commits into
CapSoftware:mainfrom
The-Best-Codes:best/yuv420p-convert-blocks

Conversation

@The-Best-Codes

@The-Best-Codes The-Best-Codes commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

The YUV420P to RGBA shader ran one thread per pixel. In 4:2:0 video every 2x2 block of pixels shares one U and one V sample, so each colour sample was read four times.

Each thread now converts one 2x2 block and reads its U and V once. The per-pixel math is untouched. It just moved into a helper function.

This shader handles software-decoded frames on Linux and Windows, in both editor playback and export.

Numbers from an i7-8650U with UHD 620, using a 31s 3024x1964 recording with camera:

main this PR
Conversion pass, per frame 5.0 ms 2.9 ms
Render time per frame, 1080p export ~8.4 ms ~6.6 ms
1080p export, with #2602 applied 35.2 s 33.9 s

Without #2602, export time on my machine stays the same, because decoding is the bottleneck there. The GPU work drops either way.

Testing:

  • Exported 4 projects (padding, rounding, border, motion blur, square aspect, moved camera) on main and on this branch. The MP4s are byte-identical.
  • cargo test -p cap-rendering passes.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge.

Summary

Converts YUV420P frames in 2×2 blocks to share U and V reads.

  • YUV420P conversion now reads chroma once for each 2×2 block.

Reviews (1) · Last reviewed commit: "perf(rendering): convert YUV420P frames ..." · Reviewed by Greptile

Signed-off-by: BestCodes <106822363+The-Best-Codes@users.noreply.github.com>
@vercel

vercel Bot commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

@The-Best-Codes is attempting to deploy a commit to the Cap Software Inc Team on Vercel.

A member of the Team first needs to authorize it.

Signed-off-by: BestCodes <106822363+The-Best-Codes@users.noreply.github.com>

@The-Best-Codes The-Best-Codes left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ready for review. I just did some benchmarks in editor playback too. I had Claude Opus 5.5 test with a 3024x1964 software-decoded recording (UHD 620), 3 alternating runs per build:

Mode FPS main -> branch Render p50
Full 1920x1080 22.1 -> 25.0 (+13%) 25.7 -> 21.7 ms
Half 1248x702 27.0 -> 31.2 (+16%) 20.6 -> 17.2 ms
Quarter 480x270 32.3 -> 36.7 (+14%) 17.4 -> 14.8 ms
Scrub (half) 9.7 -> 10.1 (+4%) 24.2 -> 19.8 ms

Every run on this branch beat every run on main! According to Opus, scrubbing gains less because it's mostly keyframe decoding. Export barely moves because CPU encoding hides the GPU saving there; playback has no encoder, so it shows up directly.

The speedup applies wherever frames are decoded in software (Linux, and Windows without hardware decode). macOS is unaffected.

The-Best-Codes and others added 4 commits October 16, 2026 01:04
Signed-off-by: BestCodes <106822363+The-Best-Codes@users.noreply.github.com>
…t-blocks

# Conflicts:
#	crates/rendering/src/shaders/yuv420p_to_rgba.wgsl
#	crates/rendering/src/yuv_converter.rs
@richiemcilroy
richiemcilroy merged commit b354b19 into CapSoftware:main Oct 18, 2026
45 of 47 checks passed
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