# Conflicts:
#	crates/ui-egui/locales/pt-br.json
#	docs/whats-new.md
This commit is contained in:
bflatastic 2026-10-13 11:05:35 +07:00
commit 8ca6a835ec
15 changed files with 91 additions and 11 deletions

View File

@ -409,6 +409,9 @@ nix build github:storytold/lightcraft # → ./result/bin/{light
nix develop github:storytold/lightcraft # rust toolchain + native deps + fonts
```
On NixOS, run a `cargo` build from `nix develop`: outside it the app can't find `libvulkan.so.1`, finds no GPU and
renders on the CPU, much more slowly (it says so once at start-up). `nix run` and `nix build` set the path themselves.
In a flake configuration (NixOS, home-manager, nix-darwin):
```nix

View File

@ -857,6 +857,7 @@ fn main() -> eframe::Result {
app.notices.extend(prefs_warning);
app.notices.extend(launch_notices);
app.notices.extend(window_notice);
app.gpu_notice = true;
// what's on disk now: only changes are written
let writer = PrefsWriter {
path: if in_memory { None } else { prefs_path() },

View File

@ -2111,5 +2111,7 @@
"Adding to Apple Photos…": "Wird zu Apple Fotos hinzugefügt…",
"not added to Apple Photos (cancelled)": "nicht zu Apple Fotos hinzugefügt (abgebrochen)",
"The first time, macOS asks whether LightCraft may control Photos.": "Beim ersten Mal fragt macOS, ob LightCraft Fotos steuern darf.",
"Adding to Apple Photos": "Wird zu Apple Fotos hinzugefügt"
"Adding to Apple Photos": "Wird zu Apple Fotos hinzugefügt",
"No graphics processor found: LightCraft renders on the CPU, which is much slower. Details in Help → System Info.": "Kein Grafikprozessor gefunden: LightCraft rendert auf der CPU, was viel langsamer ist. Details unter Hilfe → Systeminformationen.",
"On NixOS, start it from `nix develop`.": "Unter NixOS starten Sie es aus `nix develop`."
}

View File

@ -1988,5 +1988,7 @@
"Adding to Apple Photos…": "Añadiendo a Fotos de Apple…",
"not added to Apple Photos (cancelled)": "no se añadieron a Fotos de Apple (cancelado)",
"The first time, macOS asks whether LightCraft may control Photos.": "La primera vez, macOS pregunta si LightCraft puede controlar Fotos.",
"Adding to Apple Photos": "Añadiendo a Fotos de Apple"
"Adding to Apple Photos": "Añadiendo a Fotos de Apple",
"No graphics processor found: LightCraft renders on the CPU, which is much slower. Details in Help → System Info.": "No se encontró ningún procesador gráfico: LightCraft renderiza en la CPU, lo que es mucho más lento. Detalles en Ayuda → Información del sistema.",
"On NixOS, start it from `nix develop`.": "En NixOS, inícielo desde `nix develop`."
}

View File

@ -1952,5 +1952,7 @@
"Adding to Apple Photos…": "Ajout à Apple Photos…",
"not added to Apple Photos (cancelled)": "non ajouté à Apple Photos (annulé)",
"The first time, macOS asks whether LightCraft may control Photos.": "La première fois, macOS demande si LightCraft peut contrôler Photos.",
"Adding to Apple Photos": "Ajout à Apple Photos"
"Adding to Apple Photos": "Ajout à Apple Photos",
"No graphics processor found: LightCraft renders on the CPU, which is much slower. Details in Help → System Info.": "Aucun processeur graphique trouvé : LightCraft effectue le rendu sur le processeur, ce qui est beaucoup plus lent. Détails dans Aide → Informations système.",
"On NixOS, start it from `nix develop`.": "Sous NixOS, lancez-le depuis `nix develop`."
}

View File

@ -1954,5 +1954,7 @@
"Adding to Apple Photos…": "Appleの写真に追加中…",
"not added to Apple Photos (cancelled)": "Appleの写真には追加されませんでした(キャンセル)",
"The first time, macOS asks whether LightCraft may control Photos.": "初回は、LightCraftに写真の操作を許可するかmacOSが確認します。",
"Adding to Apple Photos": "Appleの写真に追加中"
"Adding to Apple Photos": "Appleの写真に追加中",
"No graphics processor found: LightCraft renders on the CPU, which is much slower. Details in Help → System Info.": "グラフィックプロセッサが見つかりません。LightCraftはCPUで描画するため、かなり遅くなります。詳細は「ヘルプ → システム情報」を参照してください。",
"On NixOS, start it from `nix develop`.": "NixOSでは `nix develop` から起動してください。"
}

View File

@ -1991,5 +1991,7 @@
"Choose a model below (Use) to start.": "Escolha um modelo abaixo (Usar) para começar.",
"Face detector": "Detector de rostos",
"Detect Faces (Photo menu) needs it: a small one-time download.": "Detectar rostos (menu Foto) precisa dele: um pequeno download único.",
"Recognition models": "Modelos de reconhecimento"
"Recognition models": "Modelos de reconhecimento",
"No graphics processor found: LightCraft renders on the CPU, which is much slower. Details in Help → System Info.": "Nenhum processador gráfico encontrado: o LightCraft renderiza na CPU, o que é muito mais lento. Detalhes em Ajuda → Informações do sistema.",
"On NixOS, start it from `nix develop`.": "No NixOS, inicie-o a partir de `nix develop`."
}

View File

@ -2144,5 +2144,7 @@
"Adding to Apple Photos…": "Добавление в Apple Фото…",
"not added to Apple Photos (cancelled)": "не добавлено в Apple Фото (отменено)",
"The first time, macOS asks whether LightCraft may control Photos.": "В первый раз macOS спросит, может ли LightCraft управлять приложением «Фото».",
"Adding to Apple Photos": "Добавление в Apple Фото"
"Adding to Apple Photos": "Добавление в Apple Фото",
"No graphics processor found: LightCraft renders on the CPU, which is much slower. Details in Help → System Info.": "Графический процессор не найден: LightCraft выполняет рендеринг на CPU, а это намного медленнее. Подробности: Справка → Сведения о системе.",
"On NixOS, start it from `nix develop`.": "В NixOS запускайте его из `nix develop`."
}

View File

@ -2146,5 +2146,7 @@
"Adding to Apple Photos…": "Додавання до Apple Фото…",
"not added to Apple Photos (cancelled)": "не додано до Apple Фото (скасовано)",
"The first time, macOS asks whether LightCraft may control Photos.": "Першого разу macOS запитає, чи може LightCraft керувати програмою «Фото».",
"Adding to Apple Photos": "Додавання до Apple Фото"
"Adding to Apple Photos": "Додавання до Apple Фото",
"No graphics processor found: LightCraft renders on the CPU, which is much slower. Details in Help → System Info.": "Графічний процесор не знайдено: LightCraft виконує рендеринг на ЦП, а це набагато повільніше. Докладніше: Довідка → Інформація про систему.",
"On NixOS, start it from `nix develop`.": "У NixOS запускайте його з `nix develop`."
}

View File

@ -1990,5 +1990,7 @@
"Adding to Apple Photos…": "正在添加到 Apple 照片…",
"not added to Apple Photos (cancelled)": "未添加到 Apple 照片(已取消)",
"The first time, macOS asks whether LightCraft may control Photos.": "首次使用时,macOS 会询问是否允许 LightCraft 控制“照片”。",
"Adding to Apple Photos": "正在添加到 Apple 照片"
"Adding to Apple Photos": "正在添加到 Apple 照片",
"No graphics processor found: LightCraft renders on the CPU, which is much slower. Details in Help → System Info.": "未找到图形处理器:LightCraft 改用 CPU 渲染,速度会慢很多。详情见“帮助 → 系统信息”。",
"On NixOS, start it from `nix develop`.": "在 NixOS 上,请从 `nix develop` 启动。"
}

View File

@ -1952,5 +1952,7 @@
"Adding to Apple Photos…": "正在加入 Apple 照片…",
"not added to Apple Photos (cancelled)": "未加入 Apple 照片(已取消)",
"The first time, macOS asks whether LightCraft may control Photos.": "第一次使用時,macOS 會詢問是否允許 LightCraft 控制「照片」。",
"Adding to Apple Photos": "正在加入 Apple 照片"
"Adding to Apple Photos": "正在加入 Apple 照片",
"No graphics processor found: LightCraft renders on the CPU, which is much slower. Details in Help → System Info.": "找不到圖形處理器:LightCraft 改用 CPU 算繪,速度會慢很多。詳情請見「說明 → 系統資訊」。",
"On NixOS, start it from `nix develop`.": "在 NixOS 上,請從 `nix develop` 啟動。"
}

View File

@ -381,6 +381,9 @@ pub struct LightcraftApp {
pub window_is_fullscreen: bool,
/// The GPU preference last applied (`app.gpu`), to apply Settings changes once.
gpu_applied: Option<bool>,
/// Say once, when the GPU device has been tried, that no graphics processor was found
/// ([`panels::notices::gpu_notice`]). The desktop app sets it; headless sessions and tests don't.
pub gpu_notice: bool,
/// The memory budget setting last applied (MB, 0 = automatic).
memory_applied: Option<u32>,
/// The display profile setting last applied (`app.displayProfile`).
@ -463,6 +466,7 @@ impl LightcraftApp {
hover_preview: None,
window_is_fullscreen: false,
gpu_applied: None,
gpu_notice: false,
memory_applied: None,
display_applied: None,
display_error: None,

View File

@ -8,10 +8,36 @@ use crate::theme::Tokens;
use crate::widgets::register;
use crate::{LightcraftApp, QuitPrompt};
/// Collect the library's settings-file warnings (each is shown once).
/// Collect the library's settings-file warnings (each is shown once), and the no-GPU notice once the GPU device has
/// been tried.
pub fn logic(app: &mut LightcraftApp) {
let new = app.session.take_library_warnings();
app.notices.extend(new);
use lightcraft_engine::gpu;
if app.gpu_notice && app.gpu_applied == Some(true) && gpu::ready() {
app.gpu_notice = false;
if !gpu::available() {
app.notices.extend(gpu_notice(gpu::unavailable_reason().as_deref(), app.ui.settings.gpu));
}
}
}
/// What to tell the user when GPU rendering is on (`enabled`) but the GPU could not be used for `reason`: only when no
/// graphics adapter was found at all ("no GPU adapter among …", e.g. no Vulkan loader on Linux), which makes every
/// render much slower without saying so. Nothing when it was turned off (preference, `LIGHTCRAFT_GPU`), a software
/// adapter was skipped, or it failed later; Settings ▸ Performance and Help ▸ System Info show those.
pub fn gpu_notice(reason: Option<&str>, enabled: bool) -> Option<String> {
if !enabled || !reason?.starts_with("no GPU adapter") {
return None;
}
let mut text =
crate::i18n::tr("No graphics processor found: LightCraft renders on the CPU, which is much slower. Details in Help → System Info.")
.to_string();
if cfg!(target_os = "linux") {
text.push(' ');
text.push_str(crate::i18n::tr("On NixOS, start it from `nix develop`."));
}
Some(text)
}
/// The window may close now (`true`), or the quit prompt is shown (`false`). Running tasks that
@ -143,3 +169,27 @@ pub fn show(app: &mut LightcraftApp, ctx: &egui::Context) {
}
}
}
#[cfg(test)]
mod tests {
use super::gpu_notice;
#[test]
fn the_gpu_notice_is_only_for_a_missing_adapter() {
let none = "no GPU adapter among Backends(VULKAN | GL) (No suitable graphics adapter found)";
let text = gpu_notice(Some(none), true).expect("no adapter: say so");
assert!(text.starts_with("No graphics processor found") && text.contains("System Info"), "{text}");
assert_eq!(text.contains("nix develop"), cfg!(target_os = "linux"), "{text}");
assert_eq!(gpu_notice(Some(none), false), None, "the preference is off");
for reason in [
"disabled by LIGHTCRAFT_GPU=0",
"disabled by LIGHTCRAFT_GPU_BACKEND=off",
"disabled by the GPU rendering preference (app.gpu)",
"software adapter (llvmpipe (LLVM 19.1.7, 256 bits)) skipped: the CPU pipeline is faster",
"stopped after a GPU failure: device lost",
] {
assert_eq!(gpu_notice(Some(reason), true), None, "{reason}");
}
assert_eq!(gpu_notice(None, true), None, "the GPU is in use");
}
}

View File

@ -471,7 +471,7 @@ differences and missing bindings are in [ui-parity.md](ui-parity.md#shortcuts).
| LR-BEHAV-BG-TASKS | Background tasks | P0 | ✅ | `cmd:activity.list`, `cmd:activity.cancel`, `crates/engine/src/activity.rs`, `crates/ui-egui/src/panels/activity.rs`, `docs/background-tasks.md`, `crates/preview/src/lib.rs` (`JobPool`) | renders off the UI thread; exports run several photos of a batch side by side (`export_parallelism`, memory-gated; files, names and order as one at a time, #496); one activity stack in the top-left corner under the top bar, as in Lightroom Classic (issue #345): imports, folder scans, exports (and the contact sheet PDF), Synchronize Folder (its scan and its run), Build / Smart Previews, Lightroom catalog inspect / import, Photo Merge, model downloads (SAM 3, face, AI Denoise), the face scan, AI Denoise and Find Missing Photos each show a row (name, progress bar or a sweep while the amount isn't known, count and current item) once 0.5 s old, three rows then "+N more"; ✕ cancels the jobs that can stop ("Stopping…" until they do); quitting asks while a cancellable task runs; agents and `ui.inspect` (`activity`) see the same list. No pause (Lightroom can pause some tasks) |
| LR-BEHAV-OFFLINE | Offline editing | P1 | ✅ | | local-first: everything works offline |
| LR-BEHAV-WEB-SAFETY | Library safety in the browser build | P1 | 🟡 | `cmd:file.backupLibrary`, `cmd:file.restoreLibrary`, `apps/lightcraft-web/src/safety.rs`, `apps/lightcraft-web/src/backup.rs`, `apps/lightcraft-web/src/files.rs` | web only (experimental): Back Up Library (zip of the catalog and every stored original) and a non-destructive Restore; failed saves show as unsaved and are retried; a photo that can't be stored isn't added; one tab per library (Web Locks); notices for storage that isn't persistent and for a library that can't open; `?reset` asks first; a panic shows a message. Missing: `?safe` start, deleting originals of removed photos, zip64 (backups > 4 GB) |
| LR-BEHAV-GPU | GPU acceleration | P0 | ✅ | `crates/gpu/src/render.rs`, `cmd:app.gpu`, `docs/gpu-pipeline.md` | CPU fallback per render on device limits, out of memory, device errors / loss, incomplete or black results (`perf.gpuReason`, `perf.gpuFallback`; each render reports its own reason — `lightcraft_gpu::try_render`, `gpuFallback` per exported file — issue #675); short submissions for slow iGPUs; backend choice (DX12 only on Windows, `LIGHTCRAFT_GPU_BACKEND` / `WGPU_BACKEND`), device created after the window opens, crash sentinel (issue #136); quitting waits (up to 2 s) for renders in flight and starts no new GPU work, so none is inside the driver when the process exits (`crates/gpu/src/exit.rs`, issue #620; seen crashing only on Linux + NVIDIA, other drivers unverified); no tiling beyond the buffer limit (CPU) |
| LR-BEHAV-GPU | GPU acceleration | P0 | ✅ | `crates/gpu/src/render.rs`, `cmd:app.gpu`, `docs/gpu-pipeline.md`, `crates/ui-egui/src/panels/notices.rs` | CPU fallback per render on device limits, out of memory, device errors / loss, incomplete or black results (`perf.gpuReason`, `perf.gpuFallback`; each render reports its own reason — `lightcraft_gpu::try_render`, `gpuFallback` per exported file — issue #675); short submissions for slow iGPUs; backend choice (DX12 only on Windows, `LIGHTCRAFT_GPU_BACKEND` / `WGPU_BACKEND`), device created after the window opens, crash sentinel (issue #136); quitting waits (up to 2 s) for renders in flight and starts no new GPU work, so none is inside the driver when the process exits (`crates/gpu/src/exit.rs`, issue #620; seen crashing only on Linux + NVIDIA, other drivers unverified); with GPU rendering on and no adapter found at all (e.g. no Vulkan loader on NixOS outside `nix develop`), the desktop app says once per session that it renders on the CPU and points to Help ▸ System Info (`gpu_notice`; not when the GPU is turned off or only a software adapter exists); no tiling beyond the buffer limit (CPU) |
| LR-BEHAV-RENDER-FIDELITY | Rendering matches Lightroom | P1 | 🟡 | `crates/pipeline/src/lib.rs`, `crates/pipeline/src/tone.rs` | every slider exists and works, but the character of the result (tone curve shape, highlight recovery, texture / clarity / dehaze, noise reduction, sharpening, default look) is tuned by eye; there is no systematic side-by-side comparison against Lightroom on the same CC0 raws. Needs a fidelity suite: Lightroom reference renders kept only in the local `plan/` (never committed), compared per slider and preset with a perceptual metric. Tuning that changes how existing settings render ships as a new process version (LRC-DEV-PROCESS, `docs/process-versions.md`) |
| LR-BEHAV-DRAGDROP | Drag and drop | P1 | ✅ | `crates/ui-egui/src/lib.rs`, `crates/ui-egui/src/panels/grid.rs` (`drag_feedback`), `crates/ui-egui/src/panels/left.rs` (`drop_target`, `album_drag_over`, `top_level_drop_target`, `drag_auto_scroll`) | files → app (import); grid photos → an album row (adds the selection, with a count badge while dragging); sidebar album / folder rows → a folder (moves it; its name follows the pointer); a drag of albums or grid photos near the top or bottom edge of the sidebar scrolls it (faster nearer the edge, only while the pointer is over the sidebar) |
| LR-BEHAV-TOAST | Toast notifications | P1 | ✅ | `crates/ui-egui/src/panels/mod.rs` | |

View File

@ -54,6 +54,10 @@
### Older raw cameras
- Olympus E-10 raws open with the camera's white balance (White Balance ▸ As Shot) and without the grey haze in
the shadows: the black level recorded in the file is now subtracted.
### Told when there is no GPU
- When GPU rendering is on but no graphics processor can be found, LightCraft now says so once at start-up instead
of quietly rendering everything on the CPU, much more slowly. Help ▸ System Info says why. On NixOS this happens
when a `cargo` build runs outside `nix develop` (no Vulkan loader); start it from there.
## 2026-10-11