Perf: P78 forces the GPU budget to 512 MB, so hiding the top adjustment layer takes the CPU fallback (#7494)

This commit is contained in:
Brennan Stehling
2026-10-27 14:38:45 -07:00
parent 8cecf418e5
commit 6beffc0fb9
2 changed files with 19 additions and 11 deletions
+17 -9
View File
@@ -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
+2 -2
View File
@@ -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