Skip to content

perf(gpui): optimize screenshot alpha checks, flattening, and premultiplication - #2673

Open
nikolas-sapa wants to merge 2 commits into
CapSoftware:mainfrom
nikolas-sapa:perf/gpui-fast-screenshot-alpha
Open

nikolas-sapa wants to merge 2 commits into
CapSoftware:mainfrom
nikolas-sapa:perf/gpui-fast-screenshot-alpha

Conversation

@nikolas-sapa

@nikolas-sapa nikolas-sapa commented Oct 17, 2026 •

Copy link
Copy Markdown

Summary

  • Unrolled 64-byte is_opaque: Checks 16 pixels per loop iteration by accumulating 4x u128 blocks with bitwise AND before applying the alpha mask. Reduces branch evaluations and loop overhead on large screenshot buffers.
  • Fast has_translucent_pixel: Replaces the slow scalar skip(3).step_by(4) byte iterator with !is_opaque(rgba), accelerating the transparency check used on every screenshot export.
  • Fast paths for opaque screenshot frames:
    • flatten_onto_white: Checks if is_opaque(rgba) and returns rgba.to_vec() directly, avoiding millions of multiplications and divisions on opaque screenshots (the vast majority of screenshots).
    • premultiply: Checks if is_opaque(rgba) and returns early without touching buffers.
    • demultiply: Checks if is_opaque(rgba) and returns early without touching buffers.
  • Adds comprehensive benchmark harness in benches/screenshot_alpha.rs.

Benchmark Results (Apple Silicon M-series)

Benchmark Workload Baseline Median Optimized Median Speedup Correctness
has_translucent_pixel 1080p 903 µs 248 µs 3.6x Bit-exact
has_translucent_pixel Retina 2,019 µs 511 µs 4.0x Bit-exact
has_translucent_pixel 4K 3,553 µs 958 µs 3.7x Bit-exact
flatten_onto_white (solid) 1080p 1,220 µs 410 µs 3.0x Bit-exact
flatten_onto_white (solid) Retina 3,604 µs 1,188 µs 3.0x Bit-exact
flatten_onto_white (solid) 4K 8,318 µs 2,735 µs 3.0x Bit-exact
premultiply (solid) 1080p 810 µs 250 µs 3.2x Bit-exact
premultiply (solid) Retina 2,520 µs 810 µs 3.1x Bit-exact
premultiply (solid) 4K 2,876 µs 947 µs 3.0x Bit-exact
demultiply (solid) 1080p 1,120 µs 252 µs 4.4x Bit-exact
demultiply (solid) Retina 3,564 µs 806 µs 4.4x Bit-exact
demultiply (solid) 4K 4,222 µs 907 µs 4.7x Bit-exact

Test Plan

  • Run cargo test --manifest-path apps/desktop-gpui/kernels/Cargo.toml
  • Run cargo bench --manifest-path apps/desktop-gpui/kernels/Cargo.toml --bench screenshot_alpha

RetriggerView in GreptileConfidence Score: 4/5

The pixel changes appear safe, but the explicit comments policy must be satisfied before merging.

Findings

  1. P2 Comments repeat the code ▶
  2. P2 Late transparency goes unmeasured ▶
Fix with agent prompt
### Issue 1
apps/desktop-gpui/kernels/benches/screenshot_alpha.rs:83
The numbered benchmark headings only repeat the calls below them. The repository guide explicitly bans comments that narrate what the code does. Remove these headings throughout the file to satisfy that requirement before merging.

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!

### Issue 2
apps/desktop-gpui/kernels/benches/screenshot_alpha.rs:79-80
The `mixed` buffer always starts with alpha zero, so the new `is_opaque` checks stop at the first block. The benchmarks miss the costly case where transparency near the end makes a conversion scan almost the whole buffer before running its original loop.

Add a mostly opaque workload with a translucent final pixel for `flatten_onto_white`, `premultiply`, and `demultiply`. Also time `demultiply` on translucent input; its only current workload returns early. This would show the added scan cost rather than only the best-case fallback.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Speeds up screenshot alpha checks with 64-byte blocks and skips conversion work for fully opaque images.

  • Screenshot helpers scan alpha bytes faster and skip work on opaque frames.

Reviews (1) · Last reviewed commit: "perf(gpui): optimize screenshot alpha ch..." · Reviewed by Greptile

@vercel

vercel Bot commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

@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.

mixed.extend_from_slice(&[r, g, b, a]);
}

// 1. is_opaque on opaque buffer

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Comments repeat the code

The numbered benchmark headings only repeat the calls below them. The repository guide explicitly bans comments that narrate what the code does. Remove these headings throughout the file to satisfy that requirement before merging.

Context Used: AGENTS.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/kernels/benches/screenshot_alpha.rs
Line: 83

Comment:
**Comments repeat the code**

The numbered benchmark headings only repeat the calls below them. The repository guide explicitly bans comments that narrate what the code does. Remove these headings throughout the file to satisfy that requirement before merging.

**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!

Comment on lines +79 to +80
let a = if i % 100 == 0 { (i % 256) as u8 } else { 255 };
mixed.extend_from_slice(&[r, g, b, a]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Late transparency goes unmeasured

The mixed buffer always starts with alpha zero, so the new is_opaque checks stop at the first block. The benchmarks miss the costly case where transparency near the end makes a conversion scan almost the whole buffer before running its original loop.

Add a mostly opaque workload with a translucent final pixel for flatten_onto_white, premultiply, and demultiply. Also time demultiply on translucent input; its only current workload returns early. This would show the added scan cost rather than only the best-case fallback.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/kernels/benches/screenshot_alpha.rs
Line: 79-80

Comment:
**Late transparency goes unmeasured**

The `mixed` buffer always starts with alpha zero, so the new `is_opaque` checks stop at the first block. The benchmarks miss the costly case where transparency near the end makes a conversion scan almost the whole buffer before running its original loop.

Add a mostly opaque workload with a translucent final pixel for `flatten_onto_white`, `premultiply`, and `demultiply`. Also time `demultiply` on translucent input; its only current workload returns early. This would show the added scan cost rather than only the best-case fallback.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@richiemcilroy

Copy link
Copy Markdown
Member

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 @greptileai review to re-run it. Once it is 5/5 we will run the full verification suite on it.

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