mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-01 14:07:34 -06:00
Issue #136: app.gpu {wait:false} still says why the GPU is off; Settings shows "GPU: starting…" while the device is created
Review follow-up: with GPU rendering off (preference, environment, earlier failure) the no-wait reply now reports available=false and the reason at once, without creating the device. The Performance tab no longer calls gpu::available() while the device is still being created, which could block the UI thread. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6376b1cebf
commit
32e55afee8
@@ -404,7 +404,12 @@ fn snapshot_defaults_to_cpu_without_gpu_environment_overrides() {
|
||||
let script = tmp("default-cpu.jsonl");
|
||||
std::fs::write(
|
||||
&script,
|
||||
format!("{}\n{}\n", json!({"method": "engine.execute", "params": {"command": "app.gpu"}}), json!({"method": "ui.screenshot"})),
|
||||
format!(
|
||||
"{}\n{}\n{}\n",
|
||||
json!({"method": "engine.execute", "params": {"command": "app.gpu", "params": {"wait": false}}}),
|
||||
json!({"method": "engine.execute", "params": {"command": "app.gpu"}}),
|
||||
json!({"method": "ui.screenshot"})
|
||||
),
|
||||
)
|
||||
.unwrap();
|
||||
let image = tmp("default-cpu.png");
|
||||
@@ -418,11 +423,13 @@ fn snapshot_defaults_to_cpu_without_gpu_environment_overrides() {
|
||||
assert!(output.status.success(), "status {}: {}", output.status, String::from_utf8_lossy(&output.stderr));
|
||||
let replies: Vec<Value> = String::from_utf8_lossy(&output.stdout).lines().map(|line| serde_json::from_str(line).unwrap()).collect();
|
||||
assert!(replies.iter().all(|reply| reply["ok"] == true), "{replies:?}");
|
||||
let gpu = &replies[0]["result"];
|
||||
assert_eq!(gpu["enabled"], false, "{gpu}");
|
||||
assert_eq!(gpu["available"], false, "{gpu}");
|
||||
assert_eq!(gpu["adapter"], Value::Null, "no device is created: {gpu}");
|
||||
assert!(gpu["reason"].as_str().is_some_and(|reason| reason.contains("preference")), "{gpu}");
|
||||
// `wait: false` (what the UI sends) still says why the GPU is off: no device is being created
|
||||
for gpu in [&replies[0]["result"], &replies[1]["result"]] {
|
||||
assert_eq!(gpu["enabled"], false, "{gpu}");
|
||||
assert_eq!(gpu["available"], false, "{gpu}");
|
||||
assert_eq!(gpu["adapter"], Value::Null, "no device is created: {gpu}");
|
||||
assert!(gpu["reason"].as_str().is_some_and(|reason| reason.contains("preference")), "{gpu}");
|
||||
}
|
||||
let decoded = lightcraft_codecs::decode(&std::fs::read(image).unwrap(), Default::default()).unwrap();
|
||||
assert_eq!((decoded.width, decoded.height), (480, 320));
|
||||
}
|
||||
|
||||
@@ -226,18 +226,21 @@ pub fn specs() -> Vec<CommandSpec> {
|
||||
"versions": ph.versions.iter().map(|v| json!({"name": v.name, "created": v.created})).collect::<Vec<_>>(),
|
||||
}))
|
||||
}),
|
||||
cmd!(query "app.gpu", "GPU Rendering", [], None, "{enabled?: bool, wait?: bool} — allow/forbid GPU rendering (CPU fallback; LIGHTCRAFT_GPU=0 forbids it for the process); returns {enabled, available, adapter, reason (why the GPU is off), lastFallback (latest render redone on the CPU, and why)}. wait: false never waits for a device still being created (available, adapter and reason are then null)", always, |_, p| {
|
||||
cmd!(query "app.gpu", "GPU Rendering", [], None, "{enabled?: bool, wait?: bool} — allow/forbid GPU rendering (CPU fallback; LIGHTCRAFT_GPU=0 forbids it for the process); returns {enabled, available, adapter, reason (why the GPU is off), lastFallback (latest render redone on the CPU, and why)}. wait: false never waits for a device still being created (available, adapter and reason are then null; with GPU rendering off they say so at once)", always, |_, p| {
|
||||
if let Some(on) = p.get("enabled").and_then(Value::as_bool) {
|
||||
lightcraft_gpu::set_enabled(on);
|
||||
}
|
||||
// the UI applies the setting on its first frame: it must not wait seconds for the
|
||||
// device there (issue #136; `warm_up` creates it off the UI thread)
|
||||
if p.get("wait").and_then(Value::as_bool) == Some(false) && !lightcraft_gpu::ready() {
|
||||
// off (preference, environment): known at once, and asking the adapter would
|
||||
// create the device; on: still being created, so nothing is known yet
|
||||
let on = lightcraft_gpu::enabled();
|
||||
return Ok(json!({
|
||||
"enabled": lightcraft_gpu::enabled(),
|
||||
"available": null,
|
||||
"enabled": on,
|
||||
"available": if on { Value::Null } else { Value::Bool(false) },
|
||||
"adapter": null,
|
||||
"reason": null,
|
||||
"reason": if on { None } else { lightcraft_gpu::unavailable_reason() },
|
||||
"lastFallback": lightcraft_gpu::last_fallback(),
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -417,7 +417,10 @@ fn performance_tab(app: &mut LightcraftApp, ui: &mut egui::Ui, t: &Tokens) {
|
||||
use lightcraft_engine::gpu;
|
||||
heading(ui, t, crate::i18n::tr("Rendering"));
|
||||
check(ui, "settings.gpu", &mut app.ui.settings.gpu, "Use the GPU for rendering");
|
||||
let status = if !gpu::available() {
|
||||
// `available` would wait for a device still being created (issue #136)
|
||||
let status = if gpu::enabled() && !gpu::ready() {
|
||||
"GPU: starting…".to_string()
|
||||
} else if !gpu::available() {
|
||||
match gpu::unavailable_reason() {
|
||||
Some(why) => crate::i18n::tr_format!("Rendering on the CPU: {why}", why = why),
|
||||
None => "No usable GPU found: rendering on the CPU".to_string(),
|
||||
|
||||
Reference in New Issue
Block a user