Skip to content

perf(gpui): precompute preset preview geometry, filter matrices, and column tables - #2671

Open
nikolas-sapa wants to merge 2 commits into
CapSoftware:mainfrom
nikolas-sapa:perf/gpui-preset-preview-math
Open

nikolas-sapa wants to merge 2 commits into
CapSoftware:mainfrom
nikolas-sapa:perf/gpui-preset-preview-math

Conversation

@nikolas-sapa

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

Copy link
Copy Markdown

Summary

Optimizes preset tile rasterization in cap_gpui_kernels::texture::preset_preview_bgra (apps/desktop-gpui/kernels/src/texture.rs), used by GPUI's color grading sidebar (editor_color.rs) to render 216x122 preset thumbnails.

Optimizations

  1. Gradient Trigonometry Hoisting (GradientPlan): Hoists angle-to-radians conversion, sin(), cos(), reciprocal length, and center offsets outside per-pixel loops for both scene and overlay gradients. Evaluates (dx * sin) - (dy * cos) with row-invariant dy * cos and column-invariant dx * sin.
  2. Prepared Filter Matrices (PreparedFilter): Precalculates 3x3 transformation matrices for HueRotate, Sepia, Saturate, and Grayscale, avoiding repeated sin, cos, and lerp computations for every pixel.
  3. Vignette Hoisting (VignettePlan): Short-circuits when vignette <= 0., precalculates rx, ry, and peak once, and precomputes column dx^2 and row dy^2 tables to replace per-pixel divisions and multiplications with a single addition before .sqrt().
  4. Noise Row Plan: Hoists row invariants (y0, fy, sy, and wrapping seeds) across octaves for grain noise synthesis.
  5. Direct Row Output Writes: Writes directly into 4-byte BGRA pixel slices, avoiding enumerate_pixels_mut() 2D index overhead.

Benchmarks (Apple Silicon, 216x122, cargo bench --bench preset_preview)

Bit-for-bit exact matching against baseline across all 210,816 evaluated pixels:

Preset Workload Filters / Features Baseline Optimized Speedup
teal-orange Contrast + Saturate + Overlay + Vignette + Grain 758 µs 605 µs 1.25x
noir Grayscale + Contrast + Brightness + Vignette + Grain 606 µs 522 µs 1.16x
vintage Sepia + Contrast + Saturate + Brightness + Overlay + Vignette + Grain 850 µs 750 µs 1.13x
cinematic Saturate + Contrast + HueRotate + Overlay + Vignette 634 µs 458 µs 1.38x
warm-glow Sepia + Saturate + Contrast + Brightness + Overlay + Vignette 625 µs 537 µs 1.16x
moody Brightness + Contrast + Saturate + Overlay + Vignette + Grain 825 µs 692 µs 1.19x
vibrant Saturate + Contrast 285 µs 232 µs 1.23x
clean Identity base 144 µs 116 µs 1.24x

Correctness

All 31 kernel unit tests pass with zero warnings, including bit-exact matching across presets.

RetriggerView in GreptileConfidence Score: 4/5

The PR appears safe to merge, with non-blocking improvements needed in test coverage and benchmark inputs.

Findings

  1. P2 Wrong colors pass this test ▶
  2. P2 Benchmark presets differ from sidebar ▶
Fix with agent prompt
### Issue 1
apps/desktop-gpui/kernels/src/texture.rs:616-619
The new test checks only dimensions and alpha. It passes even if the rewritten filters, gradients, vignette, or grain produce wrong RGB values. The full byte comparison lives only in the benchmark, while CI runs `cargo test -p cap-gpui-kernels`. Add a normal test that compares the rendered bytes against the old calculation or saved expected bytes.

### Issue 2
apps/desktop-gpui/kernels/benches/preset_preview.rs:59-65
The benchmark uses different inputs from the sidebar presets it is meant to measure. For example, `vintage` adds an overlay and uses a vignette of `0.3`, but the sidebar uses no overlay and a vignette of `0.14`. It also omits `dreamy`. Mirror `COLOR_CORRECTION_PRESETS` so the timings and byte comparisons cover the thumbnails users actually see.

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!

---

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

Summary

This PR moves repeated calculations out of the pixel loop in preset_preview_bgra and adds a benchmark against the old implementation.

  • Preset tiles render faster without changing their pixels.

Reviews (1) · Last reviewed commit: "perf(gpui): precompute preset preview ge..." · 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.

Comment on lines +616 to +619
let preview = preset_preview_bgra(&filters, Some(overlay), 0.25, 0.15, 32, 18);
assert_eq!(preview.dimensions(), (32, 18));
for pixel in preview.pixels() {
assert_eq!(pixel.0[3], 255);

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 Wrong colors pass this test

The new test checks only dimensions and alpha. It passes even if the rewritten filters, gradients, vignette, or grain produce wrong RGB values. The full byte comparison lives only in the benchmark, while CI runs cargo test -p cap-gpui-kernels. Add a normal test that compares the rendered bytes against the old calculation or saved expected bytes.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop-gpui/kernels/src/texture.rs
Line: 616-619

Comment:
**Wrong colors pass this test**

The new test checks only dimensions and alpha. It passes even if the rewritten filters, gradients, vignette, or grain produce wrong RGB values. The full byte comparison lives only in the benchmark, while CI runs `cargo test -p cap-gpui-kernels`. Add a normal test that compares the rendered bytes against the old calculation or saved expected bytes.

---

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

Comment on lines +59 to +65
overlay: Some(candidate::Overlay {
angle: 45.,
from: [1., 0.9, 0.7, 0.1],
to: [0.8, 0.4, 0.1, 0.1],
}),
vignette: 0.3,
grain: 0.28,

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 Benchmark presets differ from sidebar

The benchmark uses different inputs from the sidebar presets it is meant to measure. For example, vintage adds an overlay and uses a vignette of 0.3, but the sidebar uses no overlay and a vignette of 0.14. It also omits dreamy. Mirror COLOR_CORRECTION_PRESETS so the timings and byte comparisons cover the thumbnails users actually see.

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

Comment:
**Benchmark presets differ from sidebar**

The benchmark uses different inputs from the sidebar presets it is meant to measure. For example, `vintage` adds an overlay and uses a vignette of `0.3`, but the sidebar uses no overlay and a vignette of `0.14`. It also omits `dreamy`. Mirror `COLOR_CORRECTION_PRESETS` so the timings and byte comparisons cover the thumbnails users actually see.

---

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!

@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