mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-15 03:36:48 -04:00
* Large document: a notice explains a slow CPU fallback redraw (#1015) A full refresh that falls back to the CPU compositor blocks the canvas for as long as it runs, with only a log line to say why. The first one per document that takes over a second now posts a notice: how long it took, which edits redraw the whole document, and for the GPU memory budget fallback, that raising Memory usage raises the budget (up to a quarter of RAM). * Slow-refresh notice test: check the real "Memory usage" casing; add Polish rows The last assertion looked for "Memory Usage" while the string says "Memory usage", so it passed vacuously. The budget case now asserts the hint is present too. pl.tsv gets rows for the new strings. Co-Authored-By: Claude Opus 5.5 <[email protected]> --------- Co-authored-by: Brandon Thomas <[email protected]> Co-authored-by: Claude Opus 5.5 <[email protected]>
This commit is contained in:
17 files changed
+127
-1
No files matched your search
@@ -951,6 +951,9 @@ fn ensure_gpu(app: &mut PhotocraftApp, idx: usize, visible: DRect) -> bool {
|
||||
log::info!("{e}; using the CPU compositor");
|
||||
}
|
||||
app.perf.record(r.kind, r.px, r.composite_ms, r.upload_ms);
|
||||
if r.kind == "full" {
|
||||
crate::notices::slow_cpu_refresh(app, id.0, r.composite_ms + r.upload_ms, r.fallback.as_deref());
|
||||
}
|
||||
if r.kind.starts_with("gpu") {
|
||||
app.perf.gpu_uploads = r.uploads;
|
||||
} else {
|
||||
|
||||
@@ -386,7 +386,7 @@ impl GpuCanvas {
|
||||
// compositor does it, and edits in the view (damage rects) stay on the GPU.
|
||||
if region == doc.bounds() && !comp.fits_budget(doc, region) {
|
||||
res.compositor = Some(comp);
|
||||
return Err(photocraft_gpu::Unsupported("layers exceed the GPU memory budget; full refresh on the CPU".into()));
|
||||
return Err(photocraft_gpu::Unsupported(OVER_BUDGET.into()));
|
||||
}
|
||||
if fresh {
|
||||
let tex = DocTextures::new(device, res, size, self.tile, format);
|
||||
@@ -1040,6 +1040,9 @@ fn texel_to_f32(format: wgpu::TextureFormat, b: &[u8]) -> [f32; 4] {
|
||||
/// Floor of the compositor's memory budget: enough for a viewport's pages of a dozen layers.
|
||||
pub const MIN_GPU_BUDGET: u64 = 512 << 20;
|
||||
|
||||
/// Why a full refresh whose layer pages don't fit [`memory_budget`] goes to the CPU compositor.
|
||||
pub const OVER_BUDGET: &str = "layers exceed the GPU memory budget; full refresh on the CPU";
|
||||
|
||||
/// GPU memory the wgpu compositor may hold for layer pages and effect maps: what Memory Usage
|
||||
/// (`allowance`, Preferences › Performance) leaves after the document's pixels and History
|
||||
/// (`pixels`), at most a quarter of physical memory (`ram`; 16 GB assumed when unknown), and at
|
||||
|
||||
@@ -2196,3 +2196,8 @@ cameraRaw Color Barvy
|
||||
Fuchsia Fuchsiová
|
||||
Violet Fialová
|
||||
Reset Obnovit
|
||||
Large document: redrawing on the CPU Velký dokument: překreslování na CPU
|
||||
This redraw took {seconds} s on the CPU. Toto překreslení na CPU trvalo {seconds} s.
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. Úpravy, které mění celý dokument, například režim prolnutí, krytí nebo viditelnost vrstvy, jej překreslí celý.
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. Vrstvy se nevejdou do rozpočtu paměti GPU. Zvýšením hodnoty Využití paměti v Předvolbách › Výkon se rozpočet zvětší, nejvýše na čtvrtinu paměti tohoto počítače.
|
||||
The GPU compositor wasn't used: {reason} Kompozitor GPU nebyl použit: {reason}
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2235,3 +2235,8 @@ layerLabel No Color Keine Farbe
|
||||
Indigo Indigo
|
||||
Fuchsia Fuchsia
|
||||
Violet Violett
|
||||
Large document: redrawing on the CPU Großes Dokument: Neuzeichnen auf der CPU
|
||||
This redraw took {seconds} s on the CPU. Dieses Neuzeichnen auf der CPU dauerte {seconds} s.
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. Änderungen, die das ganze Dokument betreffen, etwa Füllmethode, Deckkraft oder Sichtbarkeit einer Ebene, zeichnen es vollständig neu.
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. Die Ebenen passen nicht in das GPU-Speicherbudget. Eine höhere Speichernutzung unter Voreinstellungen › Leistung erhöht das Budget, bis zu einem Viertel des Arbeitsspeichers dieses Computers.
|
||||
The GPU compositor wasn't used: {reason} Der GPU-Compositor wurde nicht verwendet: {reason}
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2266,3 +2266,8 @@ cameraRaw Amount Cantidad
|
||||
Fuchsia Fucsia
|
||||
Violet Violeta
|
||||
Reset Restaurar
|
||||
Large document: redrawing on the CPU Documento grande: redibujando en la CPU
|
||||
This redraw took {seconds} s on the CPU. Este redibujado en la CPU tardó {seconds} s.
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. Las ediciones que cambian todo el documento, como el modo de fusión, la opacidad o la visibilidad de una capa, lo redibujan por completo.
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. Las capas no caben en el presupuesto de memoria de la GPU. Aumentar Uso de memoria en Preferencias › Rendimiento amplía el presupuesto, hasta una cuarta parte de la memoria de este equipo.
|
||||
The GPU compositor wasn't used: {reason} No se usó el compositor de GPU: {reason}
|
||||
|
Can't render this file because it contains an unexpected character in line 4 and column 47.
|
@@ -2624,3 +2624,8 @@ cameraRaw Blending Fusion
|
||||
Indigo Indigo
|
||||
Fuchsia Fuchsia
|
||||
Violet Violet
|
||||
Large document: redrawing on the CPU Document volumineux : redessin sur le CPU
|
||||
This redraw took {seconds} s on the CPU. Ce redessin sur le CPU a pris {seconds} s.
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. Les modifications qui touchent tout le document, comme le mode de fusion, l'opacité ou la visibilité d'un calque, le redessinent entièrement.
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. Les calques dépassent le budget de mémoire GPU. Augmenter Utilisation de la mémoire dans Préférences › Performances relève ce budget, jusqu'au quart de la mémoire de cet ordinateur.
|
||||
The GPU compositor wasn't used: {reason} Le compositeur GPU n'a pas été utilisé : {reason}
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2611,3 +2611,8 @@ cameraRaw Blending Pembauran
|
||||
Indigo Nila
|
||||
Fuchsia Fuksia
|
||||
Violet Ungu
|
||||
Large document: redrawing on the CPU Dokumen besar: menggambar ulang di CPU
|
||||
This redraw took {seconds} s on the CPU. Penggambaran ulang di CPU ini memakan waktu {seconds} dtk.
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. Suntingan yang mengubah seluruh dokumen, seperti mode campuran, opasitas, atau visibilitas layer, menggambar ulang semuanya.
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. Layer tidak muat dalam anggaran memori GPU. Menaikkan Pemakaian memori di Preferensi › Performa menaikkan anggaran, hingga seperempat memori komputer ini.
|
||||
The GPU compositor wasn't used: {reason} Kompositor GPU tidak digunakan: {reason}
|
||||
|
Can't render this file because it contains an unexpected character in line 4 and column 47.
|
@@ -2267,3 +2267,8 @@ cameraRaw Amount Quantità
|
||||
Indigo Indaco
|
||||
Fuchsia Fucsia
|
||||
Violet Viola
|
||||
Large document: redrawing on the CPU Documento grande: ridisegno sulla CPU
|
||||
This redraw took {seconds} s on the CPU. Questo ridisegno sulla CPU ha richiesto {seconds} s.
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. Le modifiche che cambiano tutto il documento, come metodo di fusione, opacità o visibilità di un livello, lo ridisegnano per intero.
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. I livelli non rientrano nel budget di memoria della GPU. Aumentare Uso memoria in Preferenze › Prestazioni alza il budget, fino a un quarto della memoria di questo computer.
|
||||
The GPU compositor wasn't used: {reason} Il compositore GPU non è stato usato: {reason}
|
||||
|
@@ -2179,3 +2179,8 @@ cameraRaw Color カラー
|
||||
Fuchsia フクシア
|
||||
Violet 紫
|
||||
Reset 初期化
|
||||
Large document: redrawing on the CPU 大きなドキュメント:CPUで再描画しています
|
||||
This redraw took {seconds} s on the CPU. この再描画はCPUで{seconds}秒かかりました。
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. レイヤーの描画モード、不透明度、表示/非表示など、ドキュメント全体に関わる編集では全体が再描画されます。
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. レイヤーがGPUメモリの予算に収まりません。環境設定 › パフォーマンスのメモリ使用量を増やすと、このコンピューターのメモリの4分の1まで予算が増えます。
|
||||
The GPU compositor wasn't used: {reason} GPUコンポジターは使用されませんでした:{reason}
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2779,3 +2779,8 @@ cameraRaw Color 색상
|
||||
Seafoam 바다 거품색
|
||||
Indigo 남색
|
||||
Fuchsia 자홍색
|
||||
Large document: redrawing on the CPU 큰 문서: CPU에서 다시 그리는 중
|
||||
This redraw took {seconds} s on the CPU. 이번 다시 그리기는 CPU에서 {seconds}초 걸렸습니다.
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. 레이어의 혼합 모드, 불투명도, 표시 여부처럼 문서 전체를 바꾸는 편집은 문서 전체를 다시 그립니다.
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. 레이어가 GPU 메모리 예산에 맞지 않습니다. 환경 설정 › 성능에서 메모리 사용량을 늘리면 이 컴퓨터 메모리의 4분의 1까지 예산이 늘어납니다.
|
||||
The GPU compositor wasn't used: {reason} GPU 합성기를 사용하지 않았습니다: {reason}
|
||||
|
@@ -3228,3 +3228,8 @@ cameraRaw Roughness Chropowatość
|
||||
Seafoam Morski
|
||||
Indigo Indygo
|
||||
Fuchsia Fuksja
|
||||
Large document: redrawing on the CPU Duży dokument: odświeżanie na CPU
|
||||
This redraw took {seconds} s on the CPU. To odświeżenie na CPU trwało {seconds} s.
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. Zmiany obejmujące cały dokument, takie jak tryb mieszania, krycie lub widoczność warstwy, odświeżają go w całości.
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. Warstwy nie mieszczą się w budżecie pamięci GPU. Zwiększenie wartości Użycie pamięci w Preferencje › Wydajność zwiększa budżet, maksymalnie do jednej czwartej pamięci tego komputera.
|
||||
The GPU compositor wasn't used: {reason} Kompozytor GPU nie został użyty: {reason}
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2631,3 +2631,8 @@ cameraRaw Whites Brancos
|
||||
Indigo Índigo
|
||||
Fuchsia Fúcsia
|
||||
Violet Violeta
|
||||
Large document: redrawing on the CPU Documento grande: redesenhando na CPU
|
||||
This redraw took {seconds} s on the CPU. Este redesenho na CPU levou {seconds} s.
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. Edições que mudam o documento inteiro, como modo de mesclagem, opacidade ou visibilidade de uma camada, redesenham tudo.
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. As camadas não cabem no orçamento de memória da GPU. Aumentar Uso de memória em Preferências › Desempenho eleva o orçamento, até um quarto da memória deste computador.
|
||||
The GPU compositor wasn't used: {reason} O compositor de GPU não foi usado: {reason}
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2471,3 +2471,8 @@ cameraRaw Roughness Неровность
|
||||
Indigo Индиго
|
||||
Fuchsia Фуксия
|
||||
Violet Фиолетовый
|
||||
Large document: redrawing on the CPU Большой документ: перерисовка на CPU
|
||||
This redraw took {seconds} s on the CPU. Эта перерисовка на CPU заняла {seconds} с.
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. Правки, затрагивающие весь документ, например режим наложения, непрозрачность или видимость слоя, перерисовывают его целиком.
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. Слои не помещаются в бюджет памяти GPU. Увеличение параметра «Память» в разделе Настройки › Производительность повышает бюджет, но не больше четверти памяти этого компьютера.
|
||||
The GPU compositor wasn't used: {reason} Компоновщик GPU не использовался: {reason}
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2204,3 +2204,8 @@ cameraRaw Blending 混合
|
||||
Fuchsia 紫红色
|
||||
Violet 紫罗兰色
|
||||
Reset 复位
|
||||
Large document: redrawing on the CPU 大型文档:正在用 CPU 重绘
|
||||
This redraw took {seconds} s on the CPU. 此次 CPU 重绘耗时 {seconds} 秒。
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. 更改整个文档的编辑(如图层的混合模式、不透明度或可见性)会重绘整个文档。
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. 图层超出 GPU 内存预算。在 首选项 › 性能 中提高内存使用量可增加预算,最多为本机内存的四分之一。
|
||||
The GPU compositor wasn't used: {reason} 未使用 GPU 合成器:{reason}
|
||||
|
@@ -2173,3 +2173,8 @@ cameraRaw Blending 混合
|
||||
Fuchsia 紫紅色
|
||||
Violet 紫羅蘭色
|
||||
Reset 重設
|
||||
Large document: redrawing on the CPU 大型文件:正在以 CPU 重繪
|
||||
This redraw took {seconds} s on the CPU. 此次 CPU 重繪耗時 {seconds} 秒。
|
||||
Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it. 變更整份文件的編輯(例如圖層的混合模式、不透明度或可見度)會重繪整份文件。
|
||||
Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory. 圖層超出 GPU 記憶體預算。在 偏好設定 › 效能 中提高記憶體使用量可增加預算,最多為本機記憶體的四分之一。
|
||||
The GPU compositor wasn't used: {reason} 未使用 GPU 合成器:{reason}
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -12,6 +12,8 @@ const WAYLAND_FILE_DROP_DISMISSED: &str = "ui.waylandFileDropGuidanceDismissed";
|
||||
pub const MAX_NOTICES: usize = 3;
|
||||
/// Lines shown per notice before "…and N more".
|
||||
const MAX_LINES: usize = 8;
|
||||
/// A full canvas refresh on the CPU compositor slower than this (ms) gets a notice.
|
||||
const SLOW_CPU_REFRESH_MS: f64 = 1000.0;
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Notice {
|
||||
@@ -62,6 +64,30 @@ pub fn wayland_file_drop_guidance(app: &mut PhotocraftApp) {
|
||||
);
|
||||
}
|
||||
|
||||
/// A full refresh of document `doc` fell back to the CPU compositor (`reason`, the GPU's) and took
|
||||
/// `ms`. The canvas doesn't respond while it runs, so once per document say why it was slow and
|
||||
/// which edits will do it again (#1015).
|
||||
pub fn slow_cpu_refresh(app: &mut PhotocraftApp, doc: u64, ms: f64, reason: Option<&str>) {
|
||||
if ms.is_nan() || ms < SLOW_CPU_REFRESH_MS || app.ui.slow_refresh_noticed.contains(&doc) {
|
||||
return;
|
||||
}
|
||||
app.ui.slow_refresh_noticed.push(doc);
|
||||
let seconds = format!("{:.1}", ms / 1000.0);
|
||||
let mut lines = vec![
|
||||
crate::i18n::fmt(tl!("This redraw took {seconds} s on the CPU."), &[("seconds", &seconds)]),
|
||||
tl!("Edits that change the whole document, such as a layer's blend mode, opacity or visibility, redraw all of it.").into(),
|
||||
];
|
||||
if reason == Some(crate::gpu_canvas::OVER_BUDGET) {
|
||||
lines.push(
|
||||
tl!("Its layers don't fit the GPU memory budget. Raising Memory usage in Preferences › Performance raises the budget, up to a quarter of this computer's memory.")
|
||||
.into(),
|
||||
);
|
||||
} else if let Some(r) = reason {
|
||||
lines.push(crate::i18n::fmt(tl!("The GPU compositor wasn't used: {reason}"), &[("reason", r)]));
|
||||
}
|
||||
post(app, tl!("Large document: redrawing on the CPU"), lines, false, None);
|
||||
}
|
||||
|
||||
fn dismiss(app: &mut PhotocraftApp, id: u64) {
|
||||
let dismiss_pref = app.ui.notices.iter().find(|notice| notice.id == id).and_then(|notice| notice.dismiss_pref.clone());
|
||||
app.ui.notices.retain(|notice| notice.id != id);
|
||||
@@ -206,6 +232,31 @@ mod tests {
|
||||
assert!(app.ui.notices.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_slow_cpu_refresh_is_explained_once_per_document() {
|
||||
let mut app = PhotocraftApp::new(Session::new(), Services::default());
|
||||
slow_cpu_refresh(&mut app, 1, 400.0, Some(crate::gpu_canvas::OVER_BUDGET));
|
||||
slow_cpu_refresh(&mut app, 1, f64::NAN, Some(crate::gpu_canvas::OVER_BUDGET));
|
||||
assert!(app.ui.notices.is_empty(), "a quick refresh needs no explanation");
|
||||
|
||||
slow_cpu_refresh(&mut app, 1, 55_000.0, Some(crate::gpu_canvas::OVER_BUDGET));
|
||||
assert_eq!(app.ui.notices.len(), 1);
|
||||
let text = app.ui.notices[0].lines.join(" ");
|
||||
assert!(text.contains("55.0 s"), "{text}");
|
||||
assert!(text.contains("blend mode, opacity or visibility"), "{text}");
|
||||
assert!(text.contains("Memory usage in Preferences › Performance"), "{text}");
|
||||
assert!(!app.ui.notices[0].error);
|
||||
|
||||
slow_cpu_refresh(&mut app, 1, 55_000.0, Some(crate::gpu_canvas::OVER_BUDGET));
|
||||
assert_eq!(app.ui.notices.len(), 1, "once per document");
|
||||
|
||||
slow_cpu_refresh(&mut app, 2, 3_000.0, Some("Blend If on `Overlay` (composited on the CPU)"));
|
||||
assert_eq!(app.ui.notices.len(), 2);
|
||||
let text = app.ui.notices[1].lines.join(" ");
|
||||
assert!(text.contains("Blend If on `Overlay`"), "{text}");
|
||||
assert!(!text.contains("Memory usage"), "the budget hint is only for the budget fallback: {text}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dismissing_a_notice_writes_its_own_preference_key() {
|
||||
let mut app = PhotocraftApp::new(Session::new(), Services::default());
|
||||
|
||||
@@ -873,6 +873,9 @@ pub struct UiState {
|
||||
/// Pending GPU fallback warning, visible to automation.
|
||||
#[serde(default)]
|
||||
pub gpu_fallback_notice: Option<String>,
|
||||
/// Documents (ids) whose slow full refresh on the CPU compositor has had its notice.
|
||||
#[serde(default)]
|
||||
pub slow_refresh_noticed: Vec<u64>,
|
||||
/// Status bar info field, Home screen (see `chrome_ui`).
|
||||
#[serde(default)]
|
||||
pub chrome: crate::chrome_ui::ChromeState,
|
||||
@@ -939,6 +942,7 @@ impl Default for UiState {
|
||||
status_error: false,
|
||||
notices: Vec::new(),
|
||||
gpu_fallback_notice: None,
|
||||
slow_refresh_noticed: Vec::new(),
|
||||
chrome: Default::default(),
|
||||
camera_raw_scope: Default::default(),
|
||||
camera_raw_preview: Default::default(),
|
||||
|
||||
Reference in new issue
Block a user