From 6beffc0fb91d8a678bc4e6c4d9e809d530874d47 Mon Sep 17 00:00:00 2001 From: Brennan Stehling <277419+brennanMKE@users.noreply.github.com> Date: Sun, 25 Oct 2026 01:10:24 -0700 Subject: [PATCH] Perf: P78 forces the GPU budget to 512 MB, so hiding the top adjustment layer takes the CPU fallback (#7494) --- crates/ui-egui/examples/perf_scenarios.rs | 26 +++++++++++++++-------- perf/budgets.toml | 4 ++-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/crates/ui-egui/examples/perf_scenarios.rs b/crates/ui-egui/examples/perf_scenarios.rs index 02dc7700ff..1644c73728 100644 --- a/crates/ui-egui/examples/perf_scenarios.rs +++ b/crates/ui-egui/examples/perf_scenarios.rs @@ -595,7 +595,7 @@ fn layered_scenarios(b: &mut Bench, sz: &Sizes) { fn full_canvas_layer_scenarios(b: &mut Bench, sz: &Sizes) { let opacity = "opacity of a layer among many full-canvas layers + refresh"; let hide = "hide a layer among many full-canvas layers + refresh"; - let adjust = "hide an adjustment layer among many full-canvas layers + refresh"; + let adjust = "hide the top adjustment layer among many full-canvas layers, over the GPU budget + refresh"; if !b.wanted(opacity) && !b.wanted(hide) && !b.wanted(adjust) { return; } @@ -624,17 +624,14 @@ fn full_canvas_layer_scenarios(b: &mut Bench, sz: &Sizes) { return; } }; + let mut app_budget = None; if let (Some((g, _)), Some(st)) = (&b.gpu, s.active()) { // As the app counts it (`canvas::gpu_budget`). let pixels = st.memory_bytes() as u64; let allowance = u64::from(photocraft_engine::prefs::Performance::default().memory_usage_mb) << 20; - g.set_memory_budget(photocraft_ui_egui::gpu_canvas::memory_budget( - allowance, - pixels, - photocraft_ui_egui::gpu_canvas::physical_memory(), - g.video_memory(), - 0, - )); + let budget = photocraft_ui_egui::gpu_canvas::memory_budget(allowance, pixels, photocraft_ui_egui::gpu_canvas::physical_memory(), g.video_memory(), 0); + g.set_memory_budget(budget); + app_budget = Some(budget); } let _ = b.refresh(&s, true); let reps = b.reps; @@ -649,13 +646,20 @@ fn full_canvas_layer_scenarios(b: &mut Bench, sz: &Sizes) { Ok(ms(t) + b.refresh(s, false)?) }); // #6533: an adjustment among them, added after the rows above so their document is unchanged. + // It lands on top (above the active `full n-1`), #6533's "hide the top adjustment layer" case. let _ = exec(&mut s, "layer.setProps", json!({"layer": mid, "visible": true})); b.current = Some(adjust.to_string()); let adj = exec(&mut s, "layer.newAdjustmentLayer.levels", json!({"inBlack": 8, "inWhite": 245, "gamma": 1.05})).and_then(|_| active_layer(&s)); match adj { Ok(adj) => { + // As #6533's repro (`performance.gpuMemoryMb = 512`): the ~3.6 GB working set no longer + // fits, so a full refresh takes the from-scratch CPU path on every machine. + if let Some((g, _)) = &b.gpu { + g.set_memory_budget(photocraft_ui_egui::gpu_canvas::MIN_GPU_BUDGET); + } let _ = b.refresh(&s, true); - b.time(adjust, &mut s, reps, true, |b, s, i| { + // Each run is a from-scratch CPU composite of 150 full-canvas layers. + b.time(adjust, &mut s, reps.min(5), true, |b, s, i| { let t = Instant::now(); exec(s, "layer.setProps", json!({"layer": adj, "visible": i % 2 == 1}))?; Ok(ms(t) + b.refresh(s, false)?) @@ -663,6 +667,10 @@ fn full_canvas_layer_scenarios(b: &mut Bench, sz: &Sizes) { } Err(e) => b.errors.push((adjust.to_string(), e)), } + // `b.gpu` is shared with the later groups: give them back the budget they see on main. + if let (Some((g, _)), Some(budget)) = (&b.gpu, app_budget) { + g.set_memory_budget(budget); + } } /// #1015, #9330: a huge document with one painted layer, refreshed zoomed out (the reduced CPU diff --git a/perf/budgets.toml b/perf/budgets.toml index 36a3a844a6..ac5dda0205 100644 --- a/perf/budgets.toml +++ b/perf/budgets.toml @@ -722,10 +722,10 @@ enforce = false # new; as P5 [[scenario]] id = "P78" -title = "Hide an adjustment layer among 150 full-canvas layers, 6 MP (app GPU budget)" +title = "Hide the top adjustment layer among 150 full-canvas layers, 6 MP, GPU budget forced to 512 MB (CPU fallback)" issue = 6533 bench = "perf_scenarios" -row = "hide an adjustment layer among many full-canvas layers + refresh" +row = "hide the top adjustment layer among many full-canvas layers, over the GPU budget + refresh" budget_ms = 30 enforce = false # new; as P61