UI: "Preparing the GPU compositor…" stays until the compositor is attached

The status line is the toast that clears itself after 5 s, so the
preparing notice went blank while the viewer was still on the CPU for the
rest of a cold-cache build (tens of seconds), though `init_gpu` says the
status bar tells the user so. draw_toast now leaves that one status up
while `gpu_initializing()`; `finish_gpu_build` clears it when the
compositor lands, and the worker's repaint brings that frame, so the
toast doesn't tick meanwhile. A click still dismisses it; every other
status clears as before.

Test: with the build held on its gate, 30 more steps (7.5 s) leave the
status as it was; before this change it was empty by then.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jason Luker
2026-10-29 16:10:41 -07:00
co-authored by Claude Opus 5.5
parent 57adb3e3ed
commit 83bb74d21c
2 changed files with 18 additions and 0 deletions
+7
View File
@@ -461,6 +461,13 @@ impl EffectcraftApp {
self.ui.status.clear();
self.toast = None;
}
// "Preparing the GPU compositor…" stays until the compositor is attached (tens of
// seconds on a cold shader cache), not 5 s: `finish_gpu_build` clears it, and the
// worker's repaint brings that frame, so nothing needs to tick meanwhile. A click
// still dismisses it.
if self.ui.status == crate::GPU_PREPARING && self.gpu_initializing() {
return;
}
ui.ctx().request_repaint_after(std::time::Duration::from_millis(500));
if !self.ui.status.is_empty() {
let since: f64 = ui.data(|d| d.get_temp(egui::Id::unique("status-since")).unwrap_or(now));
+11
View File
@@ -47,6 +47,9 @@ fn the_interface_draws_and_composites_on_the_cpu_while_the_gpu_compositor_is_bui
let s = small_session();
let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).wgpu().build_eframe(move |_| {
let mut app = EffectcraftApp::new(s);
// The status line's 5 s expiry reads the app clock: a manual one makes the steps below
// stand for a known span of time.
app.use_manual_clock();
app.hooks.before_gpu_build = Some(Box::new(move || {
let _ = gate.recv();
}));
@@ -67,6 +70,14 @@ fn the_interface_draws_and_composites_on_the_cpu_while_the_gpu_compositor_is_bui
assert_eq!(h.state().session.accel_note.as_deref(), Some(effectcraft_ui_egui::GPU_PREPARING));
assert!(h.state().frames.last_ms.lock().map(|v| *v > 0.0).unwrap_or(false), "a frame was composited on the CPU meanwhile");
assert!(h.state_mut().viewer_pixels().is_some(), "the viewer shows that frame");
// Other statuses clear after 5 s; this one stays for as long as the build takes (each step
// is a quarter of a second).
for _ in 0..30 {
h.state_mut().clock_mut().advance(0.25);
h.step();
}
assert!(h.state().gpu_initializing());
assert_eq!(h.state().ui.status, effectcraft_ui_egui::GPU_PREPARING, "the status line still says so 7.5 s later");
release.send(()).unwrap();
settle(&mut h);
assert!(!h.state().gpu_initializing());