Repository navigation
perf(gpui): SIMD vectorize rgba_to_rgb and eliminate image conversion overhead - #2672
nikolas-sapa wants to merge 2 commits into
Conversation
|
@nikolas-sapa is attempting to deploy a commit to the Cap Software Inc Team on Vercel. A member of the Team first needs to authorize it. |
| } | ||
| } | ||
|
|
||
| // Portable 4-pixel chunk unrolled fallback |
There was a problem hiding this comment.
The new // Portable 4-pixel chunk unrolled fallback comment only describes the loop below it. The repository guide explicitly bans comments that narrate what the code does. Remove it before merging to meet that requirement.
| // Portable 4-pixel chunk unrolled fallback |
Context Used: AGENTS.md (source)
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/kernels/src/codec.rs
Line: 45
Comment:
**Comment repeats the code**
The new `// Portable 4-pixel chunk unrolled fallback` comment only describes the loop below it. The repository guide explicitly bans comments that narrate what the code does. Remove it before merging to meet that requirement.
```suggestion
```
**Context Used:** AGENTS.md ([source](https://github.com/capsoftware/cap/blob/main/AGENTS.md))
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
| let rgb = rgba_to_rgb(rgba.as_raw()); | ||
| encode_jpeg_rgb(&rgb, rgba.width(), rgba.height(), quality) |
There was a problem hiding this comment.
JPEG test compares identical paths
Routing encode_jpeg_rgba_as_rgb through encode_jpeg_rgb makes jpeg_paths_agree_on_the_same_pixels compare the same conversion and encoder calls with themselves. It no longer checks that this replacement preserves the old JPEG output. Keep an independent reference in the test using ConvertBuffer and encode_image, then compare it with the new path.
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/kernels/src/codec.rs
Line: 127-128
Comment:
**JPEG test compares identical paths**
Routing `encode_jpeg_rgba_as_rgb` through `encode_jpeg_rgb` makes `jpeg_paths_agree_on_the_same_pixels` compare the same conversion and encoder calls with themselves. It no longer checks that this replacement preserves the old JPEG output. Keep an independent reference in the test using `ConvertBuffer` and `encode_image`, then compare it with the new path.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.|
Thanks @nikolas-sapa! Greptile is at 4/5 here. We only merge once Greptile reaches 5/5, so please address its findings in the summary above (or reply to them if you think one is wrong), then comment |
53ddcbd to
ea2a513
Compare
|
Rebased onto current
That pairing is a useful cross-check rather than just coexistence — upstream's test calls On Greptile's two findings: both were already addressed in
Verification: |
|
@greptileai review |
|
@richiemcilroy addressed — details in my summary above. Quick version: rebased onto current One thing worth knowing across these PRs: Greptile's findings on #2668, #2671, #2672 and #2673 were already fixed in commits pushed shortly after it reviewed — nobody had posted
|
| fn baseline_rgba_to_rgb(rgba: &[u8]) -> Vec<u8> { | ||
| rgba.chunks_exact(4) | ||
| .flat_map(|px| [px[0], px[1], px[2]]) | ||
| .collect() | ||
| } |
There was a problem hiding this comment.
Benchmark measures the wrong baseline
baseline_rgba_to_rgb does not match the code this PR replaces. The base version already allocates the output once and fills it with chunks_exact(4).zip(...); this benchmark instead measures flat_map(...).collect(). Its before_ns column therefore cannot show the speedup over the previous production code.
Copy the base implementation into the benchmark, and keep the iterator version as a separately named comparison if useful.
| fn baseline_rgba_to_rgb(rgba: &[u8]) -> Vec<u8> { | |
| rgba.chunks_exact(4) | |
| .flat_map(|px| [px[0], px[1], px[2]]) | |
| .collect() | |
| } | |
| fn baseline_rgba_to_rgb(rgba: &[u8]) -> Vec<u8> { | |
| let len = rgba.len() / 4 * 3; | |
| let mut rgb = vec![0u8; len]; | |
| for (src, dst) in rgba.chunks_exact(4).zip(rgb.chunks_exact_mut(3)) { | |
| dst[0] = src[0]; | |
| dst[1] = src[1]; | |
| dst[2] = src[2]; | |
| } | |
| rgb | |
| } |
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/kernels/benches/rgba_to_rgb.rs
Line: 5-9
Comment:
**Benchmark measures the wrong baseline**
`baseline_rgba_to_rgb` does not match the code this PR replaces. The base version already allocates the output once and fills it with `chunks_exact(4).zip(...)`; this benchmark instead measures `flat_map(...).collect()`. Its `before_ns` column therefore cannot show the speedup over the previous production code.
Copy the base implementation into the benchmark, and keep the iterator version as a separately named comparison if useful.
```suggestion
fn baseline_rgba_to_rgb(rgba: &[u8]) -> Vec<u8> {
let len = rgba.len() / 4 * 3;
let mut rgb = vec![0u8; len];
for (src, dst) in rgba.chunks_exact(4).zip(rgb.chunks_exact_mut(3)) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
}
rgb
}
```
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.|
Thanks! The NEON |
Summary
rgba_to_rgbinapps/desktop-gpui/kernels/src/codec.rsusing aarch64 NEON SIMD (vld4q_u8+vst3q_u8), processing 16 pixels (64 bytes in -> 48 bytes out) per iteration.chunks_exact(4).flat_map(...).collect().encode_jpeg_rgba_as_rgbto callrgba_to_rgbdirectly instead ofrgba.convert(), saving memory allocation and redundant pixel traversal during JPEG thumbnail and export encoding.benches/rgba_to_rgb.rs.Benchmark Results (Apple Silicon M-series)
thumbnail-320x180preset-216x122screen-720pscreen-1080pscreen-retinascreen-4kTest Plan
cargo test --manifest-path apps/desktop-gpui/kernels/Cargo.tomlcargo bench --manifest-path apps/desktop-gpui/kernels/Cargo.toml --bench rgba_to_rgb

Confidence Score: 5/5
The PR appears safe to merge, with a non-blocking benchmark correction.Findings
Fix with agent prompt
Summary
Adds aarch64 NEON conversion, portable four-pixel loops, and direct RGB conversion before JPEG encoding.
Reviews (2) · Last reviewed commit: "test(gpui): assert JPEG output against i..." · Reviewed by Greptile