Tell the user when the scene is drawn without a GPU

A day of pan/zoom that had suddenly become unusable on a 1.2M-entity
drawing turned out to be no regression at all: an unattended NVIDIA
userspace update had been applied without a reboot, the Vulkan ICD could
no longer talk to the still-loaded kernel module, and wgpu silently fell
through to Mesa's llvmpipe. Nothing in the app said so. iced picks the
adapter and names it only under RUST_LOG, so the only evidence was 32
`llvmpipe-N` threads in /proc. The same silence covers WARP on Windows,
SwiftShader in browsers, and the case where wgpu finds no adapter at all
and iced quietly draws the chrome with tiny-skia while the shader widget
is dropped, leaving a blank viewport. This commit makes all of that
visible, on every platform, without new dependencies.

Detection (src/scene/pipeline/mod.rs)
-------------------------------------
`GpuStatus` is derived from two signals:

* `record_gpu_adapter`, run from `MultiPipeline::new` (once per device,
  next to the existing uncaptured-error handler), reads
  `Device::adapter_info()`, prints one `[gpu] adapter: <name> (<backend>,
  <device type>, driver …)` line — stderr natively, `console.warn` on the
  web, which has no stderr — and keeps a copy.
* `note_scene_draw`, run from `ViewportPane::draw`, counts how often the
  viewport asked for a primitive. Every renderer makes that call; only
  wgpu goes on to `prepare` and create a device. Three draws with no
  device ever recorded therefore mean the primitive is being dropped.

The verdict is one of `Unknown`, `Hardware`, `Software(adapter)` or
`NoRenderer`. `Software` is `DeviceType::Cpu` — what Vulkan reports for
llvmpipe, DX12 for WARP and GL for a renderer string that gives it away —
plus a name match on the fallbacks browsers expose (SwiftShader, llvmpipe,
lavapipe, "Microsoft Basic Render"), because the WebGPU backend reports
every adapter as `Other` (gfx-rs/wgpu#8819). Metal has no software device,
so on macOS only `NoRenderer` can occur (a VM without a GPU); it is caught
by the draw count like everywhere else.

`gpu_status_if_changed` costs one atomic load per app message: a
generation counter moves only when a device is recorded or the draw count
crosses its threshold, so the app re-derives the verdict a handful of
times per session.

Notification (src/app/startup.rs, view/modal.rs, ui/statusbar)
-------------------------------------------------------------
`refresh_gpu_status` runs after every message. On a degraded verdict it
speaks through three channels, because many users never read the command
line:

* A popup, `ModalKind::GpuWarning`, queued once per verdict through the
  startup-modal queue so it waits its turn behind the file open. It names
  the adapter, states the consequence (slow navigation, unstable or
  missing rendering) and gives the remedy that usually applies on the
  running platform: a driver update not yet followed by a reboot on
  Linux, a missing driver or a Remote Desktop / VM session on Windows, a
  VM without a Metal device on macOS, hardware acceleration switched off
  in the browser. "Don't show again for this device" stores
  `GpuStatus::identity()` in `settings.gpu_warning_silenced`; keying it by
  verdict means silencing "software rendering on llvmpipe" does not
  silence a later, different failure.
* A status-bar pill in the theme's warning colours, `⚠ Software rendering`
  or `⚠ No GPU renderer`. It is not a `StatusPill`, so it cannot be hidden,
  and it stays for the session; clicking it reopens the popup, silenced or
  not.
* A command-line entry through the new `CommandLine::push_warning`, which
  is styled like an error but deliberately does not touch `last_error` /
  `error_revision`: automation reads those to decide whether the command it
  just ran failed, and a graphics warning is not a failed command.

`subscription()` requests frames only while the verdict is `Unknown` on a
document tab (the Start page draws no viewport), so the probe costs one
frame on a working GPU, three on none, then stops.

Verification
------------
* Live on the machine that had the incident, with the Vulkan loader
  restricted to Mesa (`VK_DRIVER_FILES=…/lvp_icd.json WGPU_BACKEND=vulkan`):
  popup → OK → pill → click reopens; "Don't show again" → restart → pill
  only, no popup.
* `gpu_tests::the_adapter_is_reported_once_per_device` (ignored, needs an
  adapter) asserts the classification on a real device; it was run on both
  llvmpipe (`Cpu`) and an NVIDIA GT 1030 (`DiscreteGpu`).
* Unit tests cover the name heuristic, the verdict function, the identity
  rule, the warning text with an adapter name that itself contains
  parentheses and commas, the settings round trip and the command-line
  semantics. New strings are in all 21 locales as the `gpu` Fluent group.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
PanosandClaude Opus 5 committed 2026-09-12 16:19:41 +03:00
1 parent 5f161bb037
commit 02b0f4c7d9
34 files changed
+875

No files matched your search

+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = جارٍ إعداد التخطيط…
gpu =
.title = تحذير الرسومات
.software-headline = لم يُعثر على برنامج تشغيل GPU يعمل، لذا يتم رسم المخطط برمجيًا على المعالج CPU ({ $adapter }).
.software-consequences = سيكون التنقل في الرسومات الكبيرة بطيئًا، وقد يكون الرسم غير مكتمل أو غير مستقر.
.no-renderer-headline = لا يتوفر أي معالج رسم GPU على هذا النظام، لذا لا يمكن عرض منطقة الرسم. تستمر بقية الواجهة في العمل.
.hint-linux = تحقق من برنامج تشغيل الرسومات — السبب المعتاد هو تحديث لبرنامج التشغيل لم تتبعه إعادة تشغيل بعد.
.hint-windows = حدّث برنامج تشغيل الرسومات أو أعد تثبيته. قد لا توفر جلسات سطح المكتب البعيد والأجهزة الافتراضية تسريع GPU.
.hint-macos = لا يوفر هذا الجهاز Mac أي GPU قابلة للاستخدام للتطبيق؛ والأجهزة الافتراضية عادةً لا توفرها.
.hint-web = فعّل تسريع الأجهزة من إعدادات المتصفح أو حدّث برنامج تشغيل الرسومات، ثم أعد تحميل الصفحة.
.pill-software = ⚠ رسم برمجي
.pill-no-renderer = ⚠ لا يوجد معالج رسم GPU
.pill-tip = انقر لعرض التفاصيل
.silence = عدم الإظهار مرة أخرى لهذا الجهاز
.command-line-no-renderer = لا يتوفر معالج رسم GPU — لا يمكن عرض منطقة الرسم. تحقق من برنامج تشغيل الرسومات.
recovery =
.opened-with-repairs = فُتح الرسم مع تقرير استرداد
.open-failed = تعذر فتح الرسم
@@ -1177,6 +1192,7 @@ common =
.start-a-new-editor-process = بدء عملية محرر جديدة.
.open-read-only-saving-is-disabled = جلسة للقراءة فقط (--read-only): الحفظ معطّل.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = واجهة GPU الخلفية (dx12, vulkan, gl, metal). تضبط WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = وحدة GPU غير متاحة — يتم الرسم برمجيًا على المعالج CPU (__ocs_fmt_0__). سيكون التنقل في الرسومات الكبيرة بطيئًا؛ تحقق من برنامج تشغيل الرسومات (السبب المعتاد هو تحديث برنامج التشغيل دون إعادة التشغيل).
.safe-mode-use-the-gl-backend = الوضع الآمن: استخدام واجهة GL الخلفية.
.use-the-renderer-for-gpus-without-shader-storage-buffers = استخدام العارض لوحدات GPU التي لا تدعم مخازن تظليل التخزين.
.run-the-headless-json-automation-server-stdin-stdout-or-port = تشغيل خادم أتمتة JSON دون واجهة (stdin/stdout أو --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Подготовка на оформлението…
gpu =
.title = Предупреждение за графиката
.software-headline = Не е намерен работещ драйвер за GPU, затова чертежът се изчертава софтуерно на CPU ({ $adapter }).
.software-consequences = Навигацията в големи чертежи ще бъде бавна, а изчертаването може да е непълно или нестабилно.
.no-renderer-headline = В тази система няма наличен GPU рендерер, затова областта на чертежа не може да бъде показана. Останалата част от интерфейса продължава да работи.
.hint-linux = Проверете графичния драйвер — обичайната причина е актуализация на драйвера, след която още не е направено рестартиране.
.hint-windows = Актуализирайте или преинсталирайте графичния драйвер. Сесиите на отдалечен работен плот и виртуалните машини може да не предоставят GPU ускорение.
.hint-macos = Този Mac не предоставя използваем GPU на приложението; виртуалните машини обикновено не го правят.
.hint-web = Включете хардуерното ускорение в настройките на браузъра или актуализирайте графичния драйвер, след което презаредете страницата.
.pill-software = ⚠ Софтуерно изчертаване
.pill-no-renderer = ⚠ Без GPU рендерер
.pill-tip = Щракнете за подробности
.silence = Да не се показва повече за това устройство
.command-line-no-renderer = Няма наличен GPU рендерер — областта на чертежа не може да бъде показана. Проверете графичния драйвер.
recovery =
.opened-with-repairs = Чертежът е отворен с отчет за възстановяване
.open-failed = Чертежът не можа да бъде отворен
@@ -1164,6 +1179,7 @@ common =
.start-a-new-editor-process = Стартиране на нов процес на редактора.
.open-read-only-saving-is-disabled = Сесия само за четене (--read-only): запазването е изключено.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = Графичен бекенд (dx12, vulkan, gl, metal). Задава WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU не е наличен — изчертаването се извършва софтуерно на CPU (__ocs_fmt_0__). Навигацията в големи чертежи ще бъде бавна; проверете графичния драйвер (обичайната причина е актуализация на драйвера без рестартиране).
.safe-mode-use-the-gl-backend = Безопасен режим: използване на GL бекенд.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Използване на рендерера за GPU без буфери за съхранение на шейдъри.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Стартиране на JSON сървъра за автоматизация без интерфейс (stdin/stdout или --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Příprava rozvržení…
gpu =
.title = Upozornění na grafiku
.software-headline = Nebyl nalezen funkční ovladač GPU, výkres se proto vykresluje softwarově na CPU ({ $adapter }).
.software-consequences = Navigace ve velkých výkresech bude pomalá a vykreslování může být neúplné nebo nestabilní.
.no-renderer-headline = V tomto systému není k dispozici žádný GPU renderer, oblast výkresu proto nelze zobrazit. Zbytek rozhraní dál funguje.
.hint-linux = Zkontrolujte grafický ovladač — obvyklou příčinou je aktualizace ovladače, po které ještě nenásledoval restart.
.hint-windows = Aktualizujte nebo přeinstalujte grafický ovladač. Relace Vzdálené plochy a virtuální počítače nemusí GPU akceleraci poskytovat.
.hint-macos = Tento Mac aplikaci nenabízí žádné použitelné GPU; virtuální počítače je obvykle nenabízejí.
.hint-web = Zapněte hardwarovou akceleraci v nastavení prohlížeče nebo aktualizujte grafický ovladač a poté stránku znovu načtěte.
.pill-software = ⚠ Softwarové vykreslování
.pill-no-renderer = ⚠ Bez GPU rendereru
.pill-tip = Kliknutím zobrazíte podrobnosti
.silence = Pro toto zařízení už nezobrazovat
.command-line-no-renderer = Není k dispozici žádný GPU renderer — oblast výkresu nelze zobrazit. Zkontrolujte grafický ovladač.
recovery =
.opened-with-repairs = Výkres byl otevřen se zprávou o obnovení
.open-failed = Výkres se nepodařilo otevřít
@@ -1164,6 +1179,7 @@ common =
.start-a-new-editor-process = Spustit nový proces editoru.
.open-read-only-saving-is-disabled = Relace pouze pro čtení (--read-only): ukládání je zakázáno.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = Backend GPU (dx12, vulkan, gl, metal). Nastaví WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU není k dispozici — vykresluje se softwarově na CPU (__ocs_fmt_0__). Navigace ve velkých výkresech bude pomalá; zkontrolujte grafický ovladač (obvyklou příčinou je aktualizace ovladače bez restartu).
.safe-mode-use-the-gl-backend = Nouzový režim: použít backend GL.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Použít vykreslovač pro GPU bez úložných bufferů shaderů.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Spustit automatizační server JSON bez rozhraní (stdin/stdout nebo --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Layout wird vorbereitet…
gpu =
.title = Grafikwarnung
.software-headline = Es wurde kein funktionierender GPU-Treiber gefunden, daher wird die Zeichnung per Software auf der CPU gerendert ({ $adapter }).
.software-consequences = Große Zeichnungen lassen sich nur langsam navigieren, und die Darstellung kann unvollständig oder instabil sein.
.no-renderer-headline = Auf diesem System ist kein GPU-Renderer verfügbar, daher kann der Zeichenbereich nicht angezeigt werden. Der Rest der Oberfläche funktioniert weiterhin.
.hint-linux = Prüfen Sie den Grafiktreiber — die häufigste Ursache ist eine Treiberaktualisierung, auf die noch kein Neustart gefolgt ist.
.hint-windows = Aktualisieren oder installieren Sie den Grafiktreiber neu. Remotedesktop-Sitzungen und virtuelle Maschinen bieten möglicherweise keine GPU-Beschleunigung.
.hint-macos = Dieser Mac stellt der Anwendung keine nutzbare GPU zur Verfügung; virtuelle Maschinen tun das in der Regel nicht.
.hint-web = Aktivieren Sie die Hardwarebeschleunigung in den Browsereinstellungen oder aktualisieren Sie den Grafiktreiber, und laden Sie die Seite neu.
.pill-software = ⚠ Software-Rendering
.pill-no-renderer = ⚠ Kein GPU-Renderer
.pill-tip = Für Details klicken
.silence = Für dieses Gerät nicht mehr anzeigen
.command-line-no-renderer = Kein GPU-Renderer verfügbar — der Zeichenbereich kann nicht angezeigt werden. Prüfen Sie den Grafiktreiber.
recovery =
.opened-with-repairs = Zeichnung mit einem Wiederherstellungsbericht geöffnet
.open-failed = Zeichnung konnte nicht geöffnet werden
@@ -1165,6 +1180,7 @@ common =
.start-a-new-editor-process = Einen neuen Editorprozess starten.
.open-read-only-saving-is-disabled = Schreibgeschütze Sitzung (--read-only): Speichern ist deaktiviert.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = GPU-Backend (dx12, vulkan, gl, metal). Setzt WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU nicht verfügbar — es wird per Software auf der CPU gerendert (__ocs_fmt_0__). Große Zeichnungen lassen sich nur langsam navigieren; prüfen Sie den Grafiktreiber (eine Treiberaktualisierung ohne Neustart ist die häufigste Ursache).
.safe-mode-use-the-gl-backend = Abgesicherter Modus: GL-Backend verwenden.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Renderer für GPUs ohne Shader-Speicherpuffer verwenden.
.run-the-headless-json-automation-server-stdin-stdout-or-port = JSON-Automatisierungsserver ohne Oberfläche starten (stdin/stdout oder --port).
+16
View File
@@ -180,6 +180,21 @@ viewport =
.move = Μετακίνηση θύρας προβολής
.close = Κλείσιμο θύρας προβολής
gpu =
.title = Προειδοποίηση γραφικών
.software-headline = Δεν βρέθηκε λειτουργικός οδηγός GPU, οπότε το σχέδιο αποδίδεται με λογισμικό στη CPU ({ $adapter }).
.software-consequences = Τα μεγάλα σχέδια θα πλοηγούνται αργά και η απόδοση μπορεί να είναι ελλιπής ή ασταθής.
.no-renderer-headline = Δεν υπάρχει διαθέσιμος renderer GPU σε αυτό το σύστημα, οπότε η περιοχή σχεδίασης δεν μπορεί να εμφανιστεί. Το υπόλοιπο περιβάλλον συνεχίζει να λειτουργεί.
.hint-linux = Ελέγξτε τον οδηγό γραφικών — η συνήθης αιτία είναι ενημέρωση οδηγού που δεν έχει ακολουθηθεί ακόμη από επανεκκίνηση.
.hint-windows = Ενημερώστε ή επανεγκαταστήστε τον οδηγό γραφικών. Οι συνεδρίες Remote Desktop και οι εικονικές μηχανές ενδέχεται να μην παρέχουν επιτάχυνση GPU.
.hint-macos = Αυτό το Mac δεν εκθέτει χρησιμοποιήσιμη GPU στην εφαρμογή· οι εικονικές μηχανές συνήθως δεν το κάνουν.
.hint-web = Ενεργοποιήστε την επιτάχυνση υλικού στις ρυθμίσεις του browser ή ενημερώστε τον οδηγό γραφικών και φορτώστε ξανά τη σελίδα.
.pill-software = ⚠ Απόδοση με λογισμικό
.pill-no-renderer = ⚠ Χωρίς renderer GPU
.pill-tip = Κάντε κλικ για λεπτομέρειες
.silence = Να μην εμφανιστεί ξανά για αυτή τη συσκευή
.command-line-no-renderer = Δεν υπάρχει διαθέσιμος renderer GPU — η περιοχή σχεδίασης δεν μπορεί να εμφανιστεί. Ελέγξτε τον οδηγό γραφικών.
recovery =
.opened-with-repairs = Το σχέδιο άνοιξε με αναφορά ανάκτησης
.open-failed = Δεν ήταν δυνατό το άνοιγμα του σχεδίου
@@ -1166,6 +1181,7 @@ common =
.start-a-new-editor-process = Εκκίνηση νέας διεργασίας επεξεργαστή.
.open-read-only-saving-is-disabled = Συνεδρία μόνο για ανάγνωση (--read-only): η αποθήκευση είναι απενεργοποιημένη.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = Σύστημα GPU (dx12, vulkan, gl, metal). Ορίζει το WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = Η GPU δεν είναι διαθέσιμη — η σχεδίαση γίνεται με λογισμικό στη CPU (__ocs_fmt_0__). Τα μεγάλα σχέδια θα πλοηγούνται αργά· ελέγξτε τον οδηγό γραφικών (συνήθης αιτία είναι ενημέρωση οδηγού χωρίς επανεκκίνηση).
.safe-mode-use-the-gl-backend = Ασφαλής λειτουργία: χρήση του συστήματος GL.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Χρήση του μηχανισμού απόδοσης για GPU χωρίς προσωρινές μνήμες αποθήκευσης σκιαστών.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Εκτέλεση του διακομιστή αυτοματισμού JSON χωρίς διεπαφή (stdin/stdout ή --port).
+16
View File
@@ -180,6 +180,21 @@ viewport =
.move = Move Viewport
.close = Close Viewport
gpu =
.title = Graphics Warning
.software-headline = No working GPU driver was found, so the drawing is rendered in software on the CPU ({ $adapter }).
.software-consequences = Large drawings will navigate slowly, and rendering may be incomplete or unstable.
.no-renderer-headline = No GPU renderer is available on this system, so the drawing area cannot be displayed. The rest of the interface keeps working.
.hint-linux = Check the graphics driver — a driver update that has not yet been followed by a reboot is the usual cause.
.hint-windows = Update or reinstall the graphics driver. Remote Desktop sessions and virtual machines may not provide GPU acceleration.
.hint-macos = This Mac exposes no usable GPU to the application; virtual machines usually do not.
.hint-web = Enable hardware acceleration in the browser settings or update the graphics driver, then reload the page.
.pill-software = ⚠ Software rendering
.pill-no-renderer = ⚠ No GPU renderer
.pill-tip = Click for details
.silence = Don't show again for this device
.command-line-no-renderer = No GPU renderer is available — the drawing area cannot be displayed. Check the graphics driver.
recovery =
.opened-with-repairs = Drawing opened with a recovery report
.open-failed = Drawing could not be opened
@@ -1166,6 +1181,7 @@ common =
.start-a-new-editor-process = Start a new editor process.
.open-read-only-saving-is-disabled = Open read-only: saving is disabled.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = GPU backend (dx12, vulkan, gl, metal). Sets WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU unavailable — rendering in software on the CPU (__ocs_fmt_0__). Large drawings will navigate slowly; check the graphics driver (a driver update without a reboot is the usual cause).
.safe-mode-use-the-gl-backend = Safe mode: use the GL backend.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Use the renderer for GPUs without shader storage buffers.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Run the headless JSON automation server (stdin/stdout, or --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Preparando presentación…
gpu =
.title = Aviso de gráficos
.software-headline = No se encontró ningún controlador de GPU operativo, por lo que el dibujo se renderiza por software en la CPU ({ $adapter }).
.software-consequences = Los dibujos grandes se navegarán con lentitud y el renderizado puede ser incompleto o inestable.
.no-renderer-headline = No hay ningún renderizador de GPU disponible en este sistema, por lo que el área de dibujo no se puede mostrar. El resto de la interfaz sigue funcionando.
.hint-linux = Compruebe el controlador gráfico: la causa habitual es una actualización del controlador a la que todavía no ha seguido un reinicio.
.hint-windows = Actualice o reinstale el controlador gráfico. Las sesiones de Escritorio remoto y las máquinas virtuales pueden no ofrecer aceleración por GPU.
.hint-macos = Este Mac no expone ninguna GPU utilizable a la aplicación; las máquinas virtuales normalmente no lo hacen.
.hint-web = Active la aceleración por hardware en la configuración del navegador o actualice el controlador gráfico y, después, recargue la página.
.pill-software = ⚠ Renderizado por software
.pill-no-renderer = ⚠ Sin renderizador de GPU
.pill-tip = Haga clic para ver detalles
.silence = No volver a mostrar para este dispositivo
.command-line-no-renderer = No hay ningún renderizador de GPU disponible: el área de dibujo no se puede mostrar. Compruebe el controlador gráfico.
recovery =
.opened-with-repairs = Dibujo abierto con un informe de recuperación
.open-failed = No se pudo abrir el dibujo
@@ -1165,6 +1180,7 @@ common =
.start-a-new-editor-process = Iniciar un nuevo proceso del editor.
.open-read-only-saving-is-disabled = Sesión de solo lectura (--read-only): el guardado está deshabilitado.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = Motor de GPU (dx12, vulkan, gl, metal). Establece WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU no disponible — se renderiza por software en la CPU (__ocs_fmt_0__). Los dibujos grandes se navegarán con lentitud; compruebe el controlador gráfico (la causa habitual es una actualización del controlador sin reiniciar).
.safe-mode-use-the-gl-backend = Modo seguro: usar el motor GL.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Usar el renderizador para GPU sin búferes de almacenamiento de sombreadores.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Ejecutar el servidor de automatización JSON sin interfaz (stdin/stdout o --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Asettelua valmistellaan…
gpu =
.title = Grafiikkavaroitus
.software-headline = Toimivaa GPU-ajuria ei löytynyt, joten piirustus piirretään ohjelmallisesti suorittimella ({ $adapter }).
.software-consequences = Suurten piirustusten selaaminen on hidasta, ja piirto voi olla puutteellista tai epävakaata.
.no-renderer-headline = Tässä järjestelmässä ei ole käytettävissä GPU-piirtäjää, joten piirustusaluetta ei voida näyttää. Muu käyttöliittymä toimii edelleen.
.hint-linux = Tarkista näytönohjaimen ajuri — tavallinen syy on ajuripäivitys, jonka jälkeen konetta ei ole vielä käynnistetty uudelleen.
.hint-windows = Päivitä tai asenna näytönohjaimen ajuri uudelleen. Etätyöpöytäistunnot ja virtuaalikoneet eivät välttämättä tarjoa GPU-kiihdytystä.
.hint-macos = Tämä Mac ei tarjoa sovellukselle käyttökelpoista GPU:ta; virtuaalikoneet eivät yleensä tarjoa.
.hint-web = Ota laitteistokiihdytys käyttöön selaimen asetuksissa tai päivitä näytönohjaimen ajuri ja lataa sivu uudelleen.
.pill-software = ⚠ Ohjelmallinen piirto
.pill-no-renderer = ⚠ Ei GPU-piirtäjää
.pill-tip = Napsauta nähdäksesi tiedot
.silence = Älä näytä uudelleen tälle laitteelle
.command-line-no-renderer = GPU-piirtäjää ei ole käytettävissä — piirustusaluetta ei voida näyttää. Tarkista näytönohjaimen ajuri.
recovery =
.opened-with-repairs = Piirustus avattiin palautusraportin kanssa
.open-failed = Piirustusta ei voitu avata
@@ -1164,6 +1179,7 @@ common =
.start-a-new-editor-process = Käynnistä uusi editoriprosessi.
.open-read-only-saving-is-disabled = Vain luku -istunto (--vain luku): tallennus ei ole käytössä.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = GPU-taustajärjestelmä (dx12, vulkan, gl, metal). Asettaa WGPU_BACKEND-arvon.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU ei ole käytettävissä — piirto tehdään ohjelmallisesti suorittimella (__ocs_fmt_0__). Suurten piirustusten selaaminen on hidasta; tarkista näytönohjaimen ajuri (tavallinen syy on ajuripäivitys ilman uudelleenkäynnistystä).
.safe-mode-use-the-gl-backend = Vikasietotila: käytä GL-taustajärjestelmää.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Käytä piirtäjää GPU:ille, joissa ei ole varjostimien tallennuspuskureita.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Käynnistä JSON-automaatiopalvelin ilman käyttöliittymää (stdin/stdout tai --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Préparation de la présentation…
gpu =
.title = Avertissement graphique
.software-headline = Aucun pilote GPU fonctionnel n’a été trouvé : le dessin est rendu par logiciel sur le CPU ({ $adapter }).
.software-consequences = La navigation dans les grands dessins sera lente et le rendu peut être incomplet ou instable.
.no-renderer-headline = Aucun moteur de rendu GPU n’est disponible sur ce système : la zone de dessin ne peut pas être affichée. Le reste de l’interface continue de fonctionner.
.hint-linux = Vérifiez le pilote graphique — la cause habituelle est une mise à jour du pilote qui n’a pas encore été suivie d’un redémarrage.
.hint-windows = Mettez à jour ou réinstallez le pilote graphique. Les sessions Bureau à distance et les machines virtuelles peuvent ne pas offrir d’accélération GPU.
.hint-macos = Ce Mac n’expose aucun GPU utilisable à l’application ; les machines virtuelles n’en proposent généralement pas.
.hint-web = Activez l’accélération matérielle dans les paramètres du navigateur ou mettez à jour le pilote graphique, puis rechargez la page.
.pill-software = ⚠ Rendu logiciel
.pill-no-renderer = ⚠ Pas de rendu GPU
.pill-tip = Cliquer pour les détails
.silence = Ne plus afficher pour cet appareil
.command-line-no-renderer = Aucun moteur de rendu GPU n’est disponible — la zone de dessin ne peut pas être affichée. Vérifiez le pilote graphique.
recovery =
.opened-with-repairs = Dessin ouvert avec un rapport de récupération
.open-failed = Impossible d'ouvrir le dessin
@@ -1165,6 +1180,7 @@ common =
.start-a-new-editor-process = Démarrer un nouveau processus d’édition.
.open-read-only-saving-is-disabled = Session en lecture seule (--lecture seule) : l'enregistrement est désactivé.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = Moteur GPU (dx12, vulkan, gl, metal). Définit WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU indisponible — rendu logiciel sur le CPU (__ocs_fmt_0__). La navigation dans les grands dessins sera lente ; vérifiez le pilote graphique (une mise à jour du pilote sans redémarrage en est la cause habituelle).
.safe-mode-use-the-gl-backend = Mode sans échec : utiliser le moteur GL.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Utiliser le moteur de rendu pour les GPU sans tampons de stockage de shaders.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Exécuter le serveur d’automatisation JSON sans interface (stdin/stdout ou --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = लेआउट तैयार हो रहा है…
gpu =
.title = ग्राफ़िक्स चेतावनी
.software-headline = कोई कार्यशील GPU ड्राइवर नहीं मिला, इसलिए आरेखण CPU पर सॉफ़्टवेयर से रेंडर किया जा रहा है ({ $adapter })।
.software-consequences = बड़े आरेखणों में नेविगेशन धीमा होगा और रेंडरिंग अधूरी या अस्थिर हो सकती है।
.no-renderer-headline = इस सिस्टम पर कोई GPU रेंडरर उपलब्ध नहीं है, इसलिए आरेखण क्षेत्र प्रदर्शित नहीं किया जा सकता। शेष इंटरफ़ेस काम करता रहता है।
.hint-linux = ग्राफ़िक्स ड्राइवर की जाँच करें — सामान्य कारण ऐसा ड्राइवर अपडेट है जिसके बाद अभी तक रीबूट नहीं किया गया।
.hint-windows = ग्राफ़िक्स ड्राइवर को अपडेट या पुनः इंस्टॉल करें। रिमोट डेस्कटॉप सत्र और वर्चुअल मशीनें GPU त्वरण प्रदान नहीं कर सकती हैं।
.hint-macos = यह Mac एप्लिकेशन को कोई उपयोगी GPU उपलब्ध नहीं कराता; वर्चुअल मशीनें आमतौर पर नहीं करातीं।
.hint-web = ब्राउज़र सेटिंग्स में हार्डवेयर त्वरण सक्षम करें या ग्राफ़िक्स ड्राइवर अपडेट करें, फिर पेज को पुनः लोड करें।
.pill-software = ⚠ सॉफ़्टवेयर रेंडरिंग
.pill-no-renderer = ⚠ कोई GPU रेंडरर नहीं
.pill-tip = विवरण के लिए क्लिक करें
.silence = इस डिवाइस के लिए फिर से न दिखाएँ
.command-line-no-renderer = कोई GPU रेंडरर उपलब्ध नहीं है — आरेखण क्षेत्र प्रदर्शित नहीं किया जा सकता। ग्राफ़िक्स ड्राइवर की जाँच करें।
recovery =
.opened-with-repairs = ड्रॉइंग पुनर्प्राप्ति रिपोर्ट के साथ खोली गई
.open-failed = ड्रॉइंग खोली नहीं जा सकी
@@ -1153,6 +1168,7 @@ common =
.start-a-new-editor-process = संपादक की नई प्रक्रिया शुरू करें।
.open-read-only-saving-is-disabled = केवल-पढ़ने योग्य सत्र: सहेजना अक्षम है।
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = GPU बैकएंड (dx12, vulkan, gl, metal)। WGPU_BACKEND सेट करता है।
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU उपलब्ध नहीं है — CPU पर सॉफ़्टवेयर से रेंडर किया जा रहा है (__ocs_fmt_0__)। बड़े आरेखणों में नेविगेशन धीमा होगा; ग्राफ़िक्स ड्राइवर की जाँच करें (सामान्य कारण बिना रीबूट किए ड्राइवर अपडेट करना है)।
.safe-mode-use-the-gl-backend = सुरक्षित मोड: GL बैकएंड का उपयोग करें।
.use-the-renderer-for-gpus-without-shader-storage-buffers = शेडर स्टोरेज बफ़र रहित GPU के लिए रेंडरर का उपयोग करें।
.run-the-headless-json-automation-server-stdin-stdout-or-port = बिना इंटरफ़ेस वाला JSON स्वचालन सर्वर चलाएँ (stdin/stdout या --port)।
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Elrendezés előkészítése…
gpu =
.title = Grafikai figyelmeztetés
.software-headline = Nem található működő GPU-illesztőprogram, ezért a rajz szoftveresen, a CPU-n jelenik meg ({ $adapter }).
.software-consequences = A nagy rajzokban a navigáció lassú lesz, a megjelenítés pedig hiányos vagy instabil lehet.
.no-renderer-headline = Ezen a rendszeren nem érhető el GPU-renderelő, ezért a rajzterület nem jeleníthető meg. A felület többi része tovább működik.
.hint-linux = Ellenőrizze a grafikus illesztőprogramot — a szokásos ok egy olyan illesztőprogram-frissítés, amelyet még nem követett újraindítás.
.hint-windows = Frissítse vagy telepítse újra a grafikus illesztőprogramot. A Távoli asztal munkamenetei és a virtuális gépek nem feltétlenül nyújtanak GPU-gyorsítást.
.hint-macos = Ez a Mac nem biztosít használható GPU-t az alkalmazásnak; a virtuális gépek általában nem biztosítanak.
.hint-web = Kapcsolja be a hardveres gyorsítást a böngésző beállításaiban, vagy frissítse a grafikus illesztőprogramot, majd töltse újra az oldalt.
.pill-software = ⚠ Szoftveres megjelenítés
.pill-no-renderer = ⚠ Nincs GPU-renderelő
.pill-tip = Kattintson a részletekért
.silence = Ne jelenjen meg többé ennél az eszköznél
.command-line-no-renderer = Nem érhető el GPU-renderelő — a rajzterület nem jeleníthető meg. Ellenőrizze a grafikus illesztőprogramot.
recovery =
.opened-with-repairs = A rajz helyreállítási jelentéssel nyílt meg
.open-failed = A rajz nem nyitható meg
@@ -1164,6 +1179,7 @@ common =
.start-a-new-editor-process = Új szerkesztőfolyamat indítása.
.open-read-only-saving-is-disabled = Csak olvasható munkamenet (--csak olvasható): a mentés le van tiltva.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = GPU-háttérrendszer (dx12, vulkan, gl, metal). Beállítja a WGPU_BACKEND értékét.
.gpu-unavailable-rendering-in-software-on-the-cpu = A GPU nem érhető el — a megjelenítés szoftveresen, a CPU-n történik (__ocs_fmt_0__). A nagy rajzokban a navigáció lassú lesz; ellenőrizze a grafikus illesztőprogramot (a szokásos ok egy újraindítás nélküli illesztőprogram-frissítés).
.safe-mode-use-the-gl-backend = Csökkentett mód: a GL-háttérrendszer használata.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Árnyalótároló puffer nélküli GPU-khoz való megjelenítő használata.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Felület nélküli JSON-automatizálási kiszolgáló indítása (stdin/stdout vagy --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Preparazione layout…
gpu =
.title = Avviso grafica
.software-headline = Non è stato trovato alcun driver GPU funzionante, quindi il disegno viene renderizzato via software sulla CPU ({ $adapter }).
.software-consequences = I disegni grandi saranno lenti da navigare e il rendering potrebbe risultare incompleto o instabile.
.no-renderer-headline = Su questo sistema non è disponibile alcun renderer GPU, quindi l’area di disegno non può essere visualizzata. Il resto dell’interfaccia continua a funzionare.
.hint-linux = Controllare il driver grafico: la causa più comune è un aggiornamento del driver non ancora seguito da un riavvio.
.hint-windows = Aggiornare o reinstallare il driver grafico. Le sessioni Desktop remoto e le macchine virtuali potrebbero non offrire l’accelerazione GPU.
.hint-macos = Questo Mac non espone alcuna GPU utilizzabile all’applicazione; le macchine virtuali di solito non lo fanno.
.hint-web = Attivare l’accelerazione hardware nelle impostazioni del browser o aggiornare il driver grafico, quindi ricaricare la pagina.
.pill-software = ⚠ Rendering software
.pill-no-renderer = ⚠ Nessun renderer GPU
.pill-tip = Fare clic per i dettagli
.silence = Non mostrare più per questo dispositivo
.command-line-no-renderer = Nessun renderer GPU disponibile — l’area di disegno non può essere visualizzata. Controllare il driver grafico.
recovery =
.opened-with-repairs = Disegno aperto con un rapporto di recupero
.open-failed = Impossibile aprire il disegno
@@ -1164,6 +1179,7 @@ common =
.start-a-new-editor-process = Avvia un nuovo processo dell’editor.
.open-read-only-saving-is-disabled = Sessione di sola lettura (--read-only): il salvataggio è disabilitato.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = Backend GPU (dx12, vulkan, gl, metal). Imposta WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU non disponibile — rendering software sulla CPU (__ocs_fmt_0__). I disegni grandi saranno lenti da navigare; controllare il driver grafico (la causa più comune è un aggiornamento del driver senza riavvio).
.safe-mode-use-the-gl-backend = Modalità sicura: usa il backend GL.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Usa il renderer per GPU senza buffer di archiviazione degli shader.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Avvia il server di automazione JSON senza interfaccia (stdin/stdout o --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = レイアウトを準備中…
gpu =
.title = グラフィックスの警告
.software-headline = 動作する GPU ドライバーが見つからないため、図面は CPU 上でソフトウェア描画されています ({ $adapter })。
.software-consequences = 大きな図面では操作が遅くなり、描画が不完全または不安定になることがあります。
.no-renderer-headline = このシステムでは GPU レンダラーを利用できないため、図面領域を表示できません。その他のインターフェースは引き続き動作します。
.hint-linux = グラフィックスドライバーを確認してください。ドライバー更新後にまだ再起動していないことが主な原因です。
.hint-windows = グラフィックスドライバーを更新または再インストールしてください。リモートデスクトップセッションや仮想マシンでは GPU アクセラレーションを利用できない場合があります。
.hint-macos = この Mac はアプリケーションに利用可能な GPU を提供していません。仮想マシンでは通常提供されません。
.hint-web = ブラウザーの設定でハードウェアアクセラレーションを有効にするか、グラフィックスドライバーを更新してから、ページを再読み込みしてください。
.pill-software = ⚠ ソフトウェア描画
.pill-no-renderer = ⚠ GPU レンダラーなし
.pill-tip = クリックして詳細を表示
.silence = このデバイスでは今後表示しない
.command-line-no-renderer = GPU レンダラーを利用できません — 図面領域を表示できません。グラフィックスドライバーを確認してください。
recovery =
.opened-with-repairs = 修復レポートとともに図面を開きました
.open-failed = 図面を開けませんでした
@@ -1155,6 +1170,7 @@ common =
.start-a-new-editor-process = エディターの新しいプロセスを起動します。
.open-read-only-saving-is-disabled = 読み取り専用セッション (--read-only): 保存は無効です。
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = GPUバックエンド(dx12, vulkan, gl, metal)。WGPU_BACKENDを設定します。
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU が利用できません — CPU 上でソフトウェア描画しています (__ocs_fmt_0__)。大きな図面では操作が遅くなります。グラフィックドライバーを確認してください (再起動せずにドライバーを更新したことが主な原因です)。
.safe-mode-use-the-gl-backend = セーフモード: GLバックエンドを使用します。
.use-the-renderer-for-gpus-without-shader-storage-buffers = シェーダーストレージバッファー非対応GPU用のレンダラーを使用します。
.run-the-headless-json-automation-server-stdin-stdout-or-port = 画面なしでJSON自動化サーバーを起動します(stdin/stdoutまたは--port)。
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = 배치 준비 중…
gpu =
.title = 그래픽 경고
.software-headline = 작동하는 GPU 드라이버를 찾을 수 없어 도면을 CPU에서 소프트웨어로 렌더링하고 있습니다 ({ $adapter }).
.software-consequences = 큰 도면은 탐색이 느려지고 렌더링이 불완전하거나 불안정할 수 있습니다.
.no-renderer-headline = 이 시스템에서는 사용할 수 있는 GPU 렌더러가 없어 도면 영역을 표시할 수 없습니다. 나머지 인터페이스는 계속 작동합니다.
.hint-linux = 그래픽 드라이버를 확인하세요. 드라이버를 업데이트한 뒤 아직 재부팅하지 않은 것이 일반적인 원인입니다.
.hint-windows = 그래픽 드라이버를 업데이트하거나 다시 설치하세요. 원격 데스크톱 세션과 가상 머신에서는 GPU 가속을 제공하지 않을 수 있습니다.
.hint-macos = 이 Mac은 애플리케이션에 사용 가능한 GPU를 제공하지 않습니다. 가상 머신은 보통 제공하지 않습니다.
.hint-web = 브라우저 설정에서 하드웨어 가속을 켜거나 그래픽 드라이버를 업데이트한 다음 페이지를 새로 고치세요.
.pill-software = ⚠ 소프트웨어 렌더링
.pill-no-renderer = ⚠ GPU 렌더러 없음
.pill-tip = 자세한 내용을 보려면 클릭
.silence = 이 장치에서는 다시 표시하지 않음
.command-line-no-renderer = 사용할 수 있는 GPU 렌더러가 없습니다 — 도면 영역을 표시할 수 없습니다. 그래픽 드라이버를 확인하세요.
recovery =
.opened-with-repairs = 복구 보고서와 함께 도면을 열었습니다
.open-failed = 도면을 열 수 없습니다
@@ -1164,6 +1179,7 @@ common =
.start-a-new-editor-process = 새 편집기 프로세스를 시작합니다.
.open-read-only-saving-is-disabled = 읽기 전용 세션(--read-only): 저장이 비활성화됩니다.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = GPU 백엔드(dx12, vulkan, gl, metal). WGPU_BACKEND를 설정합니다.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU를 사용할 수 없음 — CPU에서 소프트웨어로 렌더링 중입니다 (__ocs_fmt_0__). 큰 도면은 탐색이 느려집니다. 그래픽 드라이버를 확인하세요 (재부팅 없이 드라이버를 업데이트한 것이 일반적인 원인입니다).
.safe-mode-use-the-gl-backend = 안전 모드: GL 백엔드를 사용합니다.
.use-the-renderer-for-gpus-without-shader-storage-buffers = 셰이더 저장 버퍼가 없는 GPU용 렌더러를 사용합니다.
.run-the-headless-json-automation-server-stdin-stdout-or-port = 화면 없이 JSON 자동화 서버를 실행합니다(stdin/stdout 또는 --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Lay-out voorbereiden…
gpu =
.title = Grafische waarschuwing
.software-headline = Er is geen werkend GPU-stuurprogramma gevonden, dus de tekening wordt in software op de CPU gerenderd ({ $adapter }).
.software-consequences = Grote tekeningen navigeren traag en de weergave kan onvolledig of instabiel zijn.
.no-renderer-headline = Op dit systeem is geen GPU-renderer beschikbaar, dus het tekengebied kan niet worden weergegeven. De rest van de interface blijft werken.
.hint-linux = Controleer het grafische stuurprogramma — de gebruikelijke oorzaak is een stuurprogramma-update waarop nog geen herstart is gevolgd.
.hint-windows = Werk het grafische stuurprogramma bij of installeer het opnieuw. Extern bureaublad-sessies en virtuele machines bieden mogelijk geen GPU-versnelling.
.hint-macos = Deze Mac stelt geen bruikbare GPU beschikbaar aan de toepassing; virtuele machines doen dat meestal niet.
.hint-web = Schakel hardwareversnelling in bij de browserinstellingen of werk het grafische stuurprogramma bij, en laad de pagina opnieuw.
.pill-software = ⚠ Softwarerendering
.pill-no-renderer = ⚠ Geen GPU-renderer
.pill-tip = Klik voor details
.silence = Niet meer tonen voor dit apparaat
.command-line-no-renderer = Geen GPU-renderer beschikbaar — het tekengebied kan niet worden weergegeven. Controleer het grafische stuurprogramma.
recovery =
.opened-with-repairs = Tekening geopend met een herstelrapport
.open-failed = Tekening kon niet worden geopend
@@ -1163,6 +1178,7 @@ common =
.start-a-new-editor-process = Een nieuw editorproces starten.
.open-read-only-saving-is-disabled = Alleen-lezen sessie (---lezen-alleen): opslaan is uitgeschakeld.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = GPU-backend (dx12, vulkan, gl, metal). Stelt WGPU_BACKEND in.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU niet beschikbaar — er wordt in software op de CPU gerenderd (__ocs_fmt_0__). Grote tekeningen navigeren traag; controleer het grafische stuurprogramma (een stuurprogramma-update zonder herstart is de gebruikelijke oorzaak).
.safe-mode-use-the-gl-backend = Veilige modus: gebruik de GL-backend.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Gebruik de renderer voor GPU’s zonder shaderopslagbuffers.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Start de JSON-automatiseringsserver zonder interface (stdin/stdout of --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Przygotowywanie układu…
gpu =
.title = Ostrzeżenie graficzne
.software-headline = Nie znaleziono działającego sterownika GPU, więc rysunek jest renderowany programowo na CPU ({ $adapter }).
.software-consequences = Nawigacja w dużych rysunkach będzie powolna, a renderowanie może być niekompletne lub niestabilne.
.no-renderer-headline = W tym systemie nie jest dostępny żaden renderer GPU, więc obszar rysunku nie może zostać wyświetlony. Reszta interfejsu nadal działa.
.hint-linux = Sprawdź sterownik graficzny — zwykłą przyczyną jest aktualizacja sterownika, po której nie nastąpiło jeszcze ponowne uruchomienie.
.hint-windows = Zaktualizuj lub zainstaluj ponownie sterownik graficzny. Sesje Pulpitu zdalnego i maszyny wirtualne mogą nie zapewniać akceleracji GPU.
.hint-macos = Ten Mac nie udostępnia aplikacji żadnego użytecznego GPU; maszyny wirtualne zwykle tego nie robią.
.hint-web = Włącz akcelerację sprzętową w ustawieniach przeglądarki lub zaktualizuj sterownik graficzny, a następnie odśwież stronę.
.pill-software = ⚠ Renderowanie programowe
.pill-no-renderer = ⚠ Brak renderera GPU
.pill-tip = Kliknij, aby zobaczyć szczegóły
.silence = Nie pokazuj ponownie dla tego urządzenia
.command-line-no-renderer = Brak dostępnego renderera GPU — obszar rysunku nie może zostać wyświetlony. Sprawdź sterownik graficzny.
recovery =
.opened-with-repairs = Rysunek otwarto z raportem odzyskiwania
.open-failed = Nie można otworzyć rysunku
@@ -1164,6 +1179,7 @@ common =
.start-a-new-editor-process = Uruchom nowy proces edytora.
.open-read-only-saving-is-disabled = Sesja tylko do odczytu (--tylko do odczytu): zapisywanie jest wyłączone.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = Zaplecze GPU (dx12, vulkan, gl, metal). Ustawia WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU niedostępny — renderowanie programowe na CPU (__ocs_fmt_0__). Nawigacja w dużych rysunkach będzie powolna; sprawdź sterownik graficzny (zwykłą przyczyną jest aktualizacja sterownika bez ponownego uruchomienia).
.safe-mode-use-the-gl-backend = Tryb bezpieczny: użyj zaplecza GL.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Użyj renderera dla GPU bez buforów pamięci shaderów.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Uruchom serwer automatyzacji JSON bez interfejsu (stdin/stdout lub --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Preparando layout…
gpu =
.title = Aviso de gráficos
.software-headline = Nenhum driver de GPU funcional foi encontrado, então o desenho está sendo renderizado por software na CPU ({ $adapter }).
.software-consequences = Desenhos grandes terão navegação lenta, e a renderização pode ficar incompleta ou instável.
.no-renderer-headline = Nenhum renderizador de GPU está disponível neste sistema, então a área de desenho não pode ser exibida. O restante da interface continua funcionando.
.hint-linux = Verifique o driver gráfico — a causa habitual é uma atualização do driver ainda não seguida de uma reinicialização.
.hint-windows = Atualize ou reinstale o driver gráfico. Sessões de Área de Trabalho Remota e máquinas virtuais podem não oferecer aceleração por GPU.
.hint-macos = Este Mac não expõe nenhuma GPU utilizável ao aplicativo; máquinas virtuais normalmente não expõem.
.hint-web = Ative a aceleração de hardware nas configurações do navegador ou atualize o driver gráfico e recarregue a página.
.pill-software = ⚠ Renderização por software
.pill-no-renderer = ⚠ Sem renderizador de GPU
.pill-tip = Clique para ver detalhes
.silence = Não mostrar novamente para este dispositivo
.command-line-no-renderer = Nenhum renderizador de GPU disponível — a área de desenho não pode ser exibida. Verifique o driver gráfico.
recovery =
.opened-with-repairs = Desenho aberto com um relatório de recuperação
.open-failed = Não foi possível abrir o desenho
@@ -1165,6 +1180,7 @@ common =
.start-a-new-editor-process = Iniciar um novo processo do editor.
.open-read-only-saving-is-disabled = Sessão somente leitura (--read-only): o salvamento está desativado.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = Backend da GPU (dx12, vulkan, gl, metal). Define WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU indisponível — renderizando por software na CPU (__ocs_fmt_0__). Desenhos grandes terão navegação lenta; verifique o driver gráfico (a causa habitual é uma atualização do driver sem reinicialização).
.safe-mode-use-the-gl-backend = Modo seguro: usar o backend GL.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Usar o renderizador para GPUs sem buffers de armazenamento de shaders.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Executar o servidor de automação JSON sem interface (stdin/stdout ou --port).
+16
View File
@@ -181,6 +181,21 @@ viewport =
.preparing-layout = Подготовка листа…
gpu =
.title = Предупреждение о графике
.software-headline = Рабочий драйвер GPU не найден, поэтому чертёж отрисовывается программно на CPU ({ $adapter }).
.software-consequences = Навигация по большим чертежам будет медленной, а отрисовка может быть неполной или нестабильной.
.no-renderer-headline = В этой системе нет доступного GPU-рендерера, поэтому область чертежа не может быть показана. Остальной интерфейс продолжает работать.
.hint-linux = Проверьте графический драйвер — обычная причина: обновление драйвера, после которого ещё не было перезагрузки.
.hint-windows = Обновите или переустановите графический драйвер. Сеансы удалённого рабочего стола и виртуальные машины могут не предоставлять ускорение GPU.
.hint-macos = Этот Mac не предоставляет приложению пригодный GPU; виртуальные машины обычно этого не делают.
.hint-web = Включите аппаратное ускорение в настройках браузера или обновите графический драйвер, затем перезагрузите страницу.
.pill-software = ⚠ Программная отрисовка
.pill-no-renderer = ⚠ Нет GPU-рендерера
.pill-tip = Нажмите для подробностей
.silence = Больше не показывать для этого устройства
.command-line-no-renderer = GPU-рендерер недоступен — область чертежа не может быть показана. Проверьте графический драйвер.
recovery =
.opened-with-repairs = Чертёж открыт с отчётом о восстановлении
.open-failed = Не удалось открыть чертёж
@@ -1168,6 +1183,7 @@ common =
.start-a-new-editor-process = Запустить новый процесс редактора.
.open-read-only-saving-is-disabled = Сеанс только для чтения (только для чтения): экономия отключена.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = Графический бэкенд (dx12, vulkan, gl, metal). Задаёт WGPU_BACKEND.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU недоступен — отрисовка выполняется программно на CPU (__ocs_fmt_0__). Навигация по большим чертежам будет медленной; проверьте графический драйвер (обычная причина — обновление драйвера без перезагрузки).
.safe-mode-use-the-gl-backend = Безопасный режим: использовать бэкенд GL.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Использовать рендерер для GPU без буферов хранения шейдеров.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Запустить сервер автоматизации JSON без интерфейса (stdin/stdout или --port).
+16
View File
@@ -178,6 +178,21 @@ viewport =
.move = Görünüm Penceresini Taşı
.close = Görünüm Penceresini Kapat
gpu =
.title = Grafik Uyarısı
.software-headline = Çalışan bir GPU sürücüsü bulunamadı; bu nedenle çizim, CPU üzerinde yazılımla işleniyor ({ $adapter }).
.software-consequences = Büyük çizimlerde gezinme yavaş olacaktır ve işleme eksik ya da kararsız olabilir.
.no-renderer-headline = Bu sistemde kullanılabilir bir GPU işleyici yok; bu nedenle çizim alanı görüntülenemiyor. Arayüzün geri kalanı çalışmaya devam eder.
.hint-linux = Grafik sürücüsünü denetleyin — olağan neden, henüz yeniden başlatma yapılmamış bir sürücü güncellemesidir.
.hint-windows = Grafik sürücüsünü güncelleyin veya yeniden yükleyin. Uzak Masaüstü oturumları ve sanal makineler GPU hızlandırması sunmayabilir.
.hint-macos = Bu Mac, uygulamaya kullanılabilir bir GPU sunmuyor; sanal makineler genellikle sunmaz.
.hint-web = Tarayıcı ayarlarından donanım hızlandırmayı etkinleştirin veya grafik sürücüsünü güncelleyin, ardından sayfayı yeniden yükleyin.
.pill-software = ⚠ Yazılımla işleme
.pill-no-renderer = ⚠ GPU işleyici yok
.pill-tip = Ayrıntılar için tıklayın
.silence = Bu aygıt için bir daha gösterme
.command-line-no-renderer = Kullanılabilir GPU işleyici yok — çizim alanı görüntülenemiyor. Grafik sürücüsünü denetleyin.
recovery =
.opened-with-repairs = Çizim kurtarma raporuyla açıldı
.open-failed = Çizim açılamadı
@@ -1151,6 +1166,7 @@ common =
.start-a-new-editor-process = Yeni bir düzenleyici işlemi başlat.
.open-read-only-saving-is-disabled = Salt okunur oturum (--read-only): Kaydetme devre dışı.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = GPU arka ucu (dx12, vulkan, gl, metal). WGPU_BACKEND değerini ayarlar.
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU kullanılamıyor — CPU üzerinde yazılımla işleniyor (__ocs_fmt_0__). Büyük çizimlerde gezinme yavaş olacaktır; grafik sürücüsünü denetleyin (olağan neden, yeniden başlatma yapılmadan uygulanan bir sürücü güncellemesidir).
.safe-mode-use-the-gl-backend = Güvenli mod: GL arka ucunu kullan.
.use-the-renderer-for-gpus-without-shader-storage-buffers = Gölgelendirici depolama arabelleği olmayan GPU’lar için işleyiciyi kullan.
.run-the-headless-json-automation-server-stdin-stdout-or-port = Arayüzsüz JSON otomasyon sunucusunu çalıştır (stdin/stdout veya --port).
+16
View File
@@ -180,6 +180,21 @@ viewport =
.preparing-layout = 正在准备布局…
gpu =
.title = 图形警告
.software-headline = 未找到可用的 GPU 驱动程序,因此图形正在 CPU 上以软件方式渲染 ({ $adapter })。
.software-consequences = 大型图形的浏览会很慢,渲染也可能不完整或不稳定。
.no-renderer-headline = 此系统没有可用的 GPU 渲染器,因此无法显示绘图区域。界面的其余部分仍可正常使用。
.hint-linux = 请检查显卡驱动程序——通常原因是更新驱动后尚未重启。
.hint-windows = 请更新或重新安装显卡驱动程序。远程桌面会话和虚拟机可能不提供 GPU 加速。
.hint-macos = 这台 Mac 没有向应用程序提供可用的 GPU;虚拟机通常不会提供。
.hint-web = 请在浏览器设置中启用硬件加速或更新显卡驱动程序,然后重新加载页面。
.pill-software = ⚠ 软件渲染
.pill-no-renderer = ⚠ 无 GPU 渲染器
.pill-tip = 点击查看详情
.silence = 此设备不再显示
.command-line-no-renderer = 没有可用的 GPU 渲染器——无法显示绘图区域。请检查显卡驱动程序。
recovery =
.opened-with-repairs = 图形已打开,并生成修复报告
.open-failed = 无法打开图形
@@ -1152,6 +1167,7 @@ common =
.start-a-new-editor-process = 启动新的编辑器进程。
.open-read-only-saving-is-disabled = 只读会话(-只读-只读):保存是禁用.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = GPU 后端(dx12, vulkan, gl, metal)。设置 WGPU_BACKEND。
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU 不可用 — 正在 CPU 上以软件方式渲染 (__ocs_fmt_0__)。大型图形的浏览会很慢;请检查显卡驱动程序(通常原因是更新驱动后未重启)。
.safe-mode-use-the-gl-backend = 安全模式:使用 GL 后端。
.use-the-renderer-for-gpus-without-shader-storage-buffers = 使用适用于不支持着色器存储缓冲区的 GPU 的渲染器。
.run-the-headless-json-automation-server-stdin-stdout-or-port = 运行无界面的 JSON 自动化服务器(stdin/stdout 或 --port)。
+16
View File
@@ -180,6 +180,21 @@ viewport =
.preparing-layout = 正在準備配置…
gpu =
.title = 圖形警告
.software-headline = 找不到可用的 GPU 驅動程式,因此圖面正在 CPU 上以軟體方式算繪 ({ $adapter })。
.software-consequences = 大型圖面的瀏覽會很慢,算繪也可能不完整或不穩定。
.no-renderer-headline = 此系統沒有可用的 GPU 算繪器,因此無法顯示繪圖區域。介面的其餘部分仍可正常運作。
.hint-linux = 請檢查顯示卡驅動程式——通常原因是更新驅動程式後尚未重新啟動。
.hint-windows = 請更新或重新安裝顯示卡驅動程式。遠端桌面工作階段與虛擬機器可能不提供 GPU 加速。
.hint-macos = 這台 Mac 沒有向應用程式提供可用的 GPU;虛擬機器通常不會提供。
.hint-web = 請在瀏覽器設定中啟用硬體加速或更新顯示卡驅動程式,然後重新載入頁面。
.pill-software = ⚠ 軟體算繪
.pill-no-renderer = ⚠ 無 GPU 算繪器
.pill-tip = 按一下查看詳細資料
.silence = 此裝置不再顯示
.command-line-no-renderer = 沒有可用的 GPU 算繪器——無法顯示繪圖區域。請檢查顯示卡驅動程式。
recovery =
.opened-with-repairs = 圖形已開啟,並產生修復報告
.open-failed = 無法開啟圖形
@@ -1164,6 +1179,7 @@ common =
.start-a-new-editor-process = 啟動新的編輯器程序。
.open-read-only-saving-is-disabled = 只讀會話(-只讀-只讀):儲存是禁用.
.gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend = GPU 後端(dx12, vulkan, gl, metal)。設定 WGPU_BACKEND。
.gpu-unavailable-rendering-in-software-on-the-cpu = GPU 無法使用 — 正在 CPU 上以軟體方式算繪 (__ocs_fmt_0__)。大型圖面的瀏覽會很慢;請檢查顯示卡驅動程式(通常原因是更新驅動程式後未重新啟動)。
.safe-mode-use-the-gl-backend = 安全模式:使用 GL 後端。
.use-the-renderer-for-gpus-without-shader-storage-buffers = 使用適用於不支援著色器儲存緩衝區的 GPU 的算繪器。
.run-the-headless-json-automation-server-stdin-stdout-or-port = 執行無介面的 JSON 自動化伺服器(stdin/stdout 或 --port)。
+21
View File
@@ -727,6 +727,14 @@ pub(super) struct OpenCADStudio {
/// of OS windows).
active_modal: Option<ModalKind>,
pending_startup_modals: std::collections::VecDeque<ModalKind>,
/// What is drawing the scene, once the first frame has told us. Drives
/// the graphics warning (popup, status-bar pill, command line).
gpu_status: crate::scene::pipeline::GpuStatus,
/// The pipeline's status generation this app has already looked at.
gpu_status_generation: u64,
/// `GpuStatus::identity()` of the verdict whose popup the user silenced
/// with "Don't show again for this device". Persisted in the settings.
gpu_warning_silenced: String,
/// Plot modal geometry preserved while the Plot Style editor is open as
/// a child dialog. None means Plotstyle was opened directly (e.g. command).
plotstyle_parent_plot_geometry: Option<(iced::Vector, iced::Vector)>,
@@ -1739,6 +1747,10 @@ pub enum ModalKind {
/// Add / remove the annotation scales a single selected object has a
/// per-object representation for.
AnnoObjectScale,
/// The scene is drawn by a software rasterizer, or not at all: what that
/// means and what usually fixes it. Queued once per verdict; the status
/// bar's ⚠ pill reopens it.
GpuWarning,
}
/// A property group controlled by a layer state's restore mask.
@@ -2861,6 +2873,12 @@ pub enum Message {
PropConstraintLinkClick(Vec<acadrust::Handle>),
// ── About window ────────────────────────────────────────────────────
AboutOpen,
// ── Graphics warning ────────────────────────────────────────────────
/// The status bar's ⚠ pill: reopen the graphics warning.
GpuWarningOpen,
/// "Don't show again for this device": close the warning and remember
/// the verdict it described, so only a different one prompts again.
GpuWarningSilence,
/// Close whatever in-canvas modal dialog is open (Plan B).
CloseModal,
// ── Attribute editor dialog ───────────────────────────────────────────
@@ -3613,6 +3631,9 @@ impl OpenCADStudio {
recent_colors: Vec::new(),
active_modal: None,
pending_startup_modals: std::collections::VecDeque::new(),
gpu_status: crate::scene::pipeline::GpuStatus::Unknown,
gpu_status_generation: 0,
gpu_warning_silenced: String::new(),
plotstyle_parent_plot_geometry: None,
find_replace: FindReplaceState::default(),
aec_drop_acknowledged: false,
+6
View File
@@ -238,6 +238,11 @@ pub struct UserSettings {
pub default_assoc_prompted: bool,
/// App version whose donation prompt has been displayed.
pub donation_prompt_version: String,
/// The graphics verdict (`GpuStatus::identity()`) whose warning popup the
/// user chose not to see again. Empty = always show. Keyed by verdict so
/// silencing "software rendering on llvmpipe" does not silence a later,
/// different failure.
pub gpu_warning_silenced: String,
/// Ids of plugins the user turned off in the Plugin Manager. Disabled
/// plugins keep their manifest listed but drop their ribbon tab and command
/// dispatch.
@@ -398,6 +403,7 @@ impl Default for UserSettings {
otrack: false,
default_assoc_prompted: false,
donation_prompt_version: String::new(),
gpu_warning_silenced: String::new(),
disabled_plugins: Vec::new(),
plugin_repos: Vec::new(),
literal_spaces: false,
+113
View File
@@ -1,4 +1,5 @@
use super::{ModalKind, OpenCADStudio};
use crate::scene::pipeline::{GpuAdapter, GpuStatus};
impl OpenCADStudio {
pub(super) fn queue_startup_prompts(&mut self) {
@@ -23,6 +24,51 @@ impl OpenCADStudio {
}
}
/// Notice when the scene is drawn by a software rasterizer, or not at
/// all, and say so everywhere the user might look: the command line,
/// the log, a one-time popup, and a status-bar pill that stays.
///
/// Runs after every message; the pipeline records the adapter when iced
/// first builds a device and counts the viewport's draws in the meantime,
/// so the verdict lands on the first message after the first frame
/// (`subscription` keeps frames ticking until it does). A working GPU
/// gets no word here — the `[gpu] adapter:` log line already names it.
pub(super) fn refresh_gpu_status(&mut self) {
let Some(status) =
crate::scene::pipeline::gpu_status_if_changed(&mut self.gpu_status_generation)
else {
return;
};
if status == self.gpu_status {
return;
}
self.gpu_status = status;
let Some(identity) = self.gpu_status.identity() else {
return;
};
match &self.gpu_status {
GpuStatus::Software(adapter) => {
self.command_line.push_warning(&software_rasterizer_warning(adapter));
}
GpuStatus::NoRenderer => {
crate::scene::pipeline::report_gpu_line(
"[gpu] no adapter: wgpu found nothing to draw with; the interface is on \
iced's software renderer and the scene is not drawn at all",
);
self.command_line
.push_warning(&crate::tr!("gpu", "command-line-no-renderer"));
}
GpuStatus::Unknown | GpuStatus::Hardware(_) => {}
}
// The popup: once per verdict, unless the user silenced this one.
let already_queued = self.active_modal == Some(ModalKind::GpuWarning)
|| self.pending_startup_modals.contains(&ModalKind::GpuWarning);
if self.gpu_warning_silenced != identity && !already_queued {
self.pending_startup_modals.push_back(ModalKind::GpuWarning);
self.show_next_startup_modal();
}
}
pub(super) fn mark_startup_modal_shown(&mut self) {
if self.active_modal.is_some()
&& self.active_modal.as_ref() == self.pending_startup_modals.front()
@@ -38,10 +84,77 @@ impl OpenCADStudio {
}
}
/// The command-line warning for a software rasterizer, naming the adapter so
/// the user can tell llvmpipe from SwiftShader from WARP.
pub(super) fn software_rasterizer_warning(adapter: &GpuAdapter) -> String {
let adapter = &adapter.name;
crate::tf!("GPU unavailable — rendering in software on the CPU ({adapter}). Large drawings will navigate slowly; check the graphics driver (a driver update without a reboot is the usual cause).")
.into_owned()
}
/// What usually puts a machine in this state, per platform. The cause is
/// almost always outside the app, and it differs: on Linux it is a driver
/// updated under a running kernel module, on Windows a driver that is
/// missing or a session (Remote Desktop, a VM) that has no GPU to offer, on
/// macOS a VM without a Metal device, in a browser hardware acceleration
/// switched off.
pub(crate) fn gpu_platform_hint() -> String {
if cfg!(target_arch = "wasm32") {
crate::tr!("gpu", "hint-web")
} else if cfg!(target_os = "windows") {
crate::tr!("gpu", "hint-windows")
} else if cfg!(target_os = "macos") {
crate::tr!("gpu", "hint-macos")
} else {
crate::tr!("gpu", "hint-linux")
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::app::{config::AppConfig, Message};
use iced::wgpu;
#[test]
fn the_software_warning_names_the_adapter_and_every_platform_has_a_hint() {
let cpu = GpuAdapter {
name: "llvmpipe (LLVM 20.1.8, 256 bits)".to_string(),
backend: wgpu::Backend::Vulkan,
device_type: wgpu::DeviceType::Cpu,
};
let warning = software_rasterizer_warning(&cpu);
// The name carries parentheses and commas of its own; the localized
// template must still place it whole. The loader follows the system
// locale here, so the assertions stay language-neutral.
assert!(warning.contains("(llvmpipe (LLVM 20.1.8, 256 bits))"), "{warning}");
assert!(warning.contains("GPU"), "{warning}");
assert!(!warning.contains("{adapter}") && !warning.contains("__ocs_"), "{warning}");
// Every platform has a hint, and it is a sentence, not a missing key.
let hint = gpu_platform_hint();
assert!(hint.len() > 20 && !hint.contains("hint-"), "{hint}");
}
#[test]
fn silencing_the_popup_is_per_verdict_and_survives_a_settings_round_trip() {
let mut app = OpenCADStudio::new_for_test();
app.gpu_status = GpuStatus::NoRenderer;
let _ = app.update(Message::GpuWarningSilence);
assert_eq!(app.gpu_warning_silenced, "no-renderer");
assert!(app.active_modal.is_none());
let saved = serde_json::to_string(&app.current_config()).unwrap();
let mut restarted = OpenCADStudio::new_for_test();
restarted.apply_config(serde_json::from_str(&saved).unwrap());
assert_eq!(restarted.gpu_warning_silenced, "no-renderer");
// A different verdict is not covered by that choice.
let software = GpuStatus::Software(GpuAdapter {
name: "llvmpipe".to_string(),
backend: wgpu::Backend::Vulkan,
device_type: wgpu::DeviceType::Cpu,
});
assert_ne!(software.identity().unwrap(), restarted.gpu_warning_silenced);
}
#[test]
fn donation_prompt_persists_once_per_version() {
+2
View File
@@ -414,6 +414,7 @@ impl OpenCADStudio {
otrack: self.snapper.otrack_enabled,
default_assoc_prompted: self.default_assoc_prompted,
donation_prompt_version: self.donation_prompt_version.clone(),
gpu_warning_silenced: self.gpu_warning_silenced.clone(),
disabled_plugins: {
let mut v: Vec<String> = self.disabled_plugins.iter().cloned().collect();
v.sort();
@@ -493,6 +494,7 @@ impl OpenCADStudio {
self.snapper.otrack_enabled = s.otrack;
self.default_assoc_prompted = s.default_assoc_prompted;
self.donation_prompt_version = s.donation_prompt_version.clone();
self.gpu_warning_silenced = s.gpu_warning_silenced.clone();
self.disabled_plugins = s.disabled_plugins.iter().cloned().collect();
self.plugin_repos = s.plugin_repos.clone();
self.command_line.literal_spaces = s.literal_spaces;
+11
View File
@@ -288,6 +288,7 @@ impl OpenCADStudio {
}
}
let task = self.update_inner(msg);
self.refresh_gpu_status();
self.show_next_startup_modal();
self.sync_open_command_history();
// Close the document-level first-touch transaction started by
@@ -6577,6 +6578,16 @@ impl OpenCADStudio {
Task::none()
}
Message::GpuWarningOpen => {
self.active_modal = Some(super::ModalKind::GpuWarning);
Task::none()
}
Message::GpuWarningSilence => {
self.gpu_warning_silenced = self.gpu_status.identity().unwrap_or_default();
self.close_active_modal();
Task::none()
}
Message::CloseModal => {
if self.active_modal == Some(super::ModalKind::RecoveryPrompt) {
return self.update(Message::RecoveryDecline);
+14
View File
@@ -2225,6 +2225,7 @@ bg={bg_ms:.1}ms n={view_count}"
status_menu_data,
tab.scene.sketch_constraint_set(tab.current_sketch_scope()).and_then(|s| s.dof),
tab.scene.sketch_constraint_set(tab.current_sketch_scope()).map(|s| s.conflicts.len()).unwrap_or(0),
&self.gpu_status,
)
})
.width(Fill)
@@ -2479,6 +2480,18 @@ impl OpenCADStudio {
} else {
Subscription::none()
};
// Graphics verdict: a device appears inside the first frame and a
// dropped scene shows up as draws without one, but neither arrives
// as a message. Tick until the verdict is in — one frame on a
// working GPU, three on none — then stop. The Start page draws no
// viewport, so there is nothing to learn there.
let gpu_probe = if matches!(self.gpu_status, crate::scene::pipeline::GpuStatus::Unknown)
&& !self.tabs[self.active_tab].is_start
{
window::frames().map(Message::Tick)
} else {
Subscription::none()
};
let thumbnail_capture = if self.thumbnail_capture_clean {
window::frames().map(|_| Message::ThumbnailCaptureFrame)
} else {
@@ -2685,6 +2698,7 @@ impl OpenCADStudio {
grip_dwell,
hover_dwell,
nav_settle,
gpu_probe,
thumbnail_capture,
caret_blink,
web_fonts,
+55
View File
@@ -50,6 +50,7 @@ impl OpenCADStudio {
Some(K::SaveDialog) => crate::tr!("modal", "save-drawing-as"),
Some(K::Recovery) => crate::tr!("modal", "recovery-report"),
Some(K::RecoveryPrompt) => crate::tr!("modal", "recovery-prompt"),
Some(K::GpuWarning) => crate::tr!("gpu", "title"),
None => String::new(),
}
}
@@ -1378,6 +1379,9 @@ impl OpenCADStudio {
super::super::ModalKind::DonationPrompt => {
sized_flow(ex, 540, 360, donation_dialog_window)
}
super::super::ModalKind::GpuWarning => {
sized_flow(ex, 520, 400, |flow| gpu_warning_window(&self.gpu_status, flow))
}
super::super::ModalKind::AecDropWarning => {
let src_label = self
.tabs
@@ -1921,6 +1925,57 @@ fn layer_delete_warning_window(
.into()
}
/// What the graphics verdict means and what usually fixes it. Two
/// situations share the dialog — a software rasterizer (slow, but drawing)
/// and no renderer at all (a blank viewport) — and the remedy hint is per
/// platform. "OK" closes it for this session; the status-bar pill brings it
/// back. "Don't show again" silences this verdict only, so a different
/// failure on the same machine still prompts.
fn gpu_warning_window(
status: &crate::scene::pipeline::GpuStatus,
sizing: crate::ui::modal::ModalSizing,
) -> Element<'static, Message> {
use crate::scene::pipeline::GpuStatus;
let (headline, consequences) = match status {
GpuStatus::Software(adapter) => (
crate::tr!("gpu", "software-headline", adapter = adapter.name.clone()),
Some(crate::tr!("gpu", "software-consequences")),
),
_ => (crate::tr!("gpu", "no-renderer-headline"), None),
};
let mut body = column![text(headline).size(13)].spacing(8);
if let Some(consequences) = consequences {
body = body.push(text(consequences).size(13));
}
body = body.push(
text(crate::app::startup::gpu_platform_hint())
.size(13)
.style(dialog_muted_text_style),
);
container(
column![
body,
Space::new().height(20),
row![
dialog_button(t!("OK"), Message::CloseModal, button::primary),
Space::new().width(8),
dialog_button(
crate::tr!("gpu", "silence"),
Message::GpuWarningSilence,
button::secondary
),
],
]
.spacing(0),
)
.style(dialog_body_style)
.center_x(sizing.width)
.center_y(sizing.height)
.padding([24, 28])
.into()
}
fn donation_dialog_window(sizing: crate::ui::modal::ModalSizing) -> Element<'static, Message> {
container(
column![
+1
View File
@@ -3576,6 +3576,7 @@ pub(super) fn message_attribute(source: &str) -> Option<(&'static str, &'static
"Start a new editor process." => Some(("common", "start-a-new-editor-process")),
"Open read-only: saving is disabled." => Some(("common", "open-read-only-saving-is-disabled")),
"GPU backend (dx12, vulkan, gl, metal). Sets WGPU_BACKEND." => Some(("common", "gpu-backend-dx12-vulkan-gl-metal-sets-wgpu-backend")),
"GPU unavailable — rendering in software on the CPU ({adapter}). Large drawings will navigate slowly; check the graphics driver (a driver update without a reboot is the usual cause)." => Some(("common", "gpu-unavailable-rendering-in-software-on-the-cpu")),
"Safe mode: use the GL backend." => Some(("common", "safe-mode-use-the-gl-backend")),
"Use the renderer for GPUs without shader storage buffers." => Some(("common", "use-the-renderer-for-gpus-without-shader-storage-buffers")),
"Run the headless JSON automation server (stdin/stdout, or --port)." => Some(("common", "run-the-headless-json-automation-server-stdin-stdout-or-port")),
+37
View File
@@ -3,6 +3,43 @@ use crate::scene::model::{mesh_model::MeshLodSet, mesh_model::MeshModel, wire_mo
use acadrust::{types::Transform, Handle};
use iced::futures::executor::block_on;
#[test]
#[ignore = "requires a GPU adapter"]
fn the_adapter_is_reported_once_per_device() {
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor::new_without_display_handle());
let adapter = block_on(instance.request_adapter(&wgpu::RequestAdapterOptions::default()))
.expect("GPU adapter");
let (device, _queue) = block_on(adapter.request_device(&wgpu::DeviceDescriptor {
required_limits: adapter.limits(),
..Default::default()
}))
.expect("GPU device");
let mut seen = 0;
// Drain whatever an earlier test on this process recorded.
let _ = gpu_status_if_changed(&mut seen);
record_gpu_adapter(&device);
let info = adapter.get_info();
let status = gpu_status_if_changed(&mut seen).expect("a new device moves the verdict");
let reported = match &status {
GpuStatus::Hardware(reported) | GpuStatus::Software(reported) => reported,
other => panic!("a device must yield an adapter verdict, got {other:?}"),
};
assert_eq!(reported.name, info.name);
assert_eq!(reported.backend, info.backend);
assert_eq!(reported.device_type, info.device_type);
assert_eq!(
matches!(status, GpuStatus::Software(_)),
info.device_type == wgpu::DeviceType::Cpu,
"{status:?}"
);
assert!(
gpu_status_if_changed(&mut seen).is_none(),
"nothing changed, so the per-message check must stay silent"
);
assert_eq!(gpu_status(), status);
}
#[test]
#[ignore = "requires a GPU adapter"]
fn block_edits_preserve_cache_coordinates_and_arena_partition() {
+219
View File
@@ -5650,9 +5650,228 @@ fn install_gpu_error_handler(device: &wgpu::Device) {
}));
}
/// The adapter wgpu ended up drawing on.
///
/// iced chooses it and names it only under `RUST_LOG`, so a fallback to a
/// software rasterizer used to be invisible: an NVIDIA userspace update
/// applied without a reboot left the Vulkan ICD unable to talk to the loaded
/// kernel module, wgpu quietly took Mesa's `llvmpipe`, and a day of pan/zoom
/// on the CPU read as a regression in the drawing code. `record_gpu_adapter`
/// now reports one `[gpu] adapter:` line per device and keeps a copy for the
/// app, which turns it into a [`GpuStatus`] the user can see.
#[derive(Debug, Clone, PartialEq)]
pub struct GpuAdapter {
pub name: String,
pub backend: wgpu::Backend,
pub device_type: wgpu::DeviceType,
}
impl GpuAdapter {
/// A software rasterizer: every frame is drawn by the CPU, which on a
/// large drawing is the difference between interactive and unusable.
///
/// `DeviceType::Cpu` is what Vulkan says for llvmpipe, DX12 for WARP and
/// GL for anything whose renderer string gives it away. WebGPU never says
/// it — wgpu reports every browser adapter as `Other` (gfx-rs/wgpu#8819)
/// — so the names browsers give their fallbacks are matched as well, the
/// same way wgpu's own GL backend classifies them.
pub fn is_software(&self) -> bool {
if self.device_type == wgpu::DeviceType::Cpu {
return true;
}
let name = self.name.to_ascii_lowercase();
SOFTWARE_RASTERIZER_NAMES
.iter()
.any(|marker| name.contains(marker))
}
}
/// Renderer names that mean "no GPU", lower-cased: Mesa's llvmpipe (also
/// exposed as lavapipe under Vulkan), Google's SwiftShader (Chrome's WebGL /
/// WebGPU fallback), and Microsoft's WARP, which DXGI names as a driver.
const SOFTWARE_RASTERIZER_NAMES: [&str; 5] = [
"llvmpipe",
"lavapipe",
"softpipe",
"swiftshader",
"microsoft basic render",
];
/// What is drawing the scene, as far as the app can tell.
#[derive(Debug, Clone, PartialEq)]
pub enum GpuStatus {
/// No scene frame has completed yet, so nothing is known.
Unknown,
/// A GPU, through wgpu. The normal case; nothing to say.
Hardware(GpuAdapter),
/// A CPU rasterizer, through wgpu — llvmpipe, WARP, SwiftShader. Every
/// frame works, slowly, and the driver that should be here is not.
Software(GpuAdapter),
/// wgpu found no adapter at all. iced then draws the interface with
/// tiny-skia and drops the scene primitive with a `log::warn!` nobody
/// sees, so the viewport stays blank while everything else works.
NoRenderer,
}
impl GpuStatus {
/// True when the user should be told: the scene is slow or missing.
pub fn is_degraded(&self) -> bool {
matches!(self, Self::Software(_) | Self::NoRenderer)
}
/// A stable name for "this situation", so the popup can be silenced for
/// one adapter without silencing the next one.
pub fn identity(&self) -> Option<String> {
match self {
Self::Software(adapter) => Some(format!("software:{}", adapter.name)),
Self::NoRenderer => Some("no-renderer".to_string()),
Self::Unknown | Self::Hardware(_) => None,
}
}
}
/// The adapter of the most recently created device.
static GPU_ADAPTER: std::sync::Mutex<Option<GpuAdapter>> = std::sync::Mutex::new(None);
/// How many times the viewport has asked the scene for a primitive. Counted
/// in `ViewportPane::draw`, which every renderer calls; only wgpu goes on to
/// `prepare` and build a device. Draws without a device are therefore the
/// evidence that the scene is being dropped.
static SCENE_DRAWS: std::sync::atomic::AtomicU32 = std::sync::atomic::AtomicU32::new(0);
/// Draws the viewport may request before a still-missing device counts as
/// `NoRenderer`. Under wgpu the device exists before the first draw's frame
/// ends, so one would do; the margin covers a frame that was drawn but never
/// presented (an outdated surface, an occluded window).
const SCENE_DRAWS_BEFORE_NO_RENDERER: u32 = 3;
/// Bumped whenever the verdict of [`gpu_status`] can have changed: a device
/// was created, or the draw count reached its threshold. The app compares it
/// against what it last saw, so the per-message check is one atomic load.
static GPU_STATUS_GENERATION: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(0);
/// Called by the viewport's `shader::Program::draw`, whichever renderer runs it.
pub(crate) fn note_scene_draw() {
use std::sync::atomic::Ordering;
if SCENE_DRAWS.fetch_add(1, Ordering::Relaxed) + 1 == SCENE_DRAWS_BEFORE_NO_RENDERER {
GPU_STATUS_GENERATION.fetch_add(1, Ordering::Relaxed);
}
}
/// One line for whoever reads logs: stderr natively, the browser console on
/// the web, where wasm has no stderr to write to.
pub(crate) fn report_gpu_line(line: &str) {
#[cfg(target_arch = "wasm32")]
web_sys::console::warn_1(&wasm_bindgen::JsValue::from_str(line));
#[cfg(not(target_arch = "wasm32"))]
eprintln!("{line}");
}
fn record_gpu_adapter(device: &wgpu::Device) {
let info = device.adapter_info();
report_gpu_line(&format!(
"[gpu] adapter: {} ({:?}, {:?}, driver: {} {})",
info.name, info.backend, info.device_type, info.driver, info.driver_info
));
let adapter = GpuAdapter {
name: info.name,
backend: info.backend,
device_type: info.device_type,
};
if let Ok(mut slot) = GPU_ADAPTER.lock() {
*slot = Some(adapter);
}
GPU_STATUS_GENERATION.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
}
/// The verdict from what has been recorded so far. Pure, so it can be tested
/// without a device: `adapter` is the last device's adapter, `scene_draws`
/// how often the viewport asked to be drawn.
fn gpu_status_from(adapter: Option<GpuAdapter>, scene_draws: u32) -> GpuStatus {
match adapter {
Some(adapter) if adapter.is_software() => GpuStatus::Software(adapter),
Some(adapter) => GpuStatus::Hardware(adapter),
None if scene_draws >= SCENE_DRAWS_BEFORE_NO_RENDERER => GpuStatus::NoRenderer,
None => GpuStatus::Unknown,
}
}
/// The current verdict.
pub(crate) fn gpu_status() -> GpuStatus {
let adapter = GPU_ADAPTER.lock().ok().and_then(|slot| slot.clone());
gpu_status_from(adapter, SCENE_DRAWS.load(std::sync::atomic::Ordering::Relaxed))
}
/// The verdict, but only when it may have moved since `seen` — the app calls
/// this after every message, and almost every call is one atomic load.
pub(crate) fn gpu_status_if_changed(seen: &mut u64) -> Option<GpuStatus> {
let generation = GPU_STATUS_GENERATION.load(std::sync::atomic::Ordering::Relaxed);
if generation == *seen {
return None;
}
*seen = generation;
Some(gpu_status())
}
#[cfg(test)]
mod gpu_status_tests {
use super::*;
fn adapter(name: &str, device_type: wgpu::DeviceType) -> GpuAdapter {
GpuAdapter {
name: name.to_string(),
backend: wgpu::Backend::Vulkan,
device_type,
}
}
#[test]
fn software_is_the_device_type_or_a_known_fallback_name() {
assert!(adapter("llvmpipe (LLVM 21.1.8, 256 bits)", wgpu::DeviceType::Cpu).is_software());
// WebGPU reports every adapter as Other, so the name has to carry it.
assert!(adapter(
"ANGLE (Google, Vulkan 1.3.0 (SwiftShader Device (Subzero)), SwiftShader driver)",
wgpu::DeviceType::Other
)
.is_software());
assert!(adapter("Microsoft Basic Render Driver", wgpu::DeviceType::Other).is_software());
assert!(!adapter("NVIDIA GeForce GT 1030", wgpu::DeviceType::DiscreteGpu).is_software());
assert!(!adapter("Apple M2", wgpu::DeviceType::IntegratedGpu).is_software());
assert!(!adapter("", wgpu::DeviceType::Other).is_software());
}
#[test]
fn the_verdict_needs_either_a_device_or_enough_dropped_draws() {
assert_eq!(gpu_status_from(None, 0), GpuStatus::Unknown);
assert_eq!(
gpu_status_from(None, SCENE_DRAWS_BEFORE_NO_RENDERER - 1),
GpuStatus::Unknown
);
assert_eq!(
gpu_status_from(None, SCENE_DRAWS_BEFORE_NO_RENDERER),
GpuStatus::NoRenderer
);
let gpu = adapter("NVIDIA GeForce GT 1030", wgpu::DeviceType::DiscreteGpu);
assert_eq!(gpu_status_from(Some(gpu.clone()), 100), GpuStatus::Hardware(gpu));
let cpu = adapter("llvmpipe", wgpu::DeviceType::Cpu);
assert_eq!(gpu_status_from(Some(cpu.clone()), 0), GpuStatus::Software(cpu));
}
#[test]
fn only_degraded_verdicts_carry_an_identity() {
assert!(GpuStatus::Unknown.identity().is_none());
assert!(GpuStatus::Hardware(adapter("x", wgpu::DeviceType::DiscreteGpu)).identity().is_none());
assert_eq!(GpuStatus::NoRenderer.identity().as_deref(), Some("no-renderer"));
let software = GpuStatus::Software(adapter("llvmpipe", wgpu::DeviceType::Cpu));
assert!(software.is_degraded());
assert_eq!(software.identity().as_deref(), Some("software:llvmpipe"));
}
}
impl iced::widget::shader::Pipeline for MultiPipeline {
fn new(device: &wgpu::Device, queue: &wgpu::Queue, format: wgpu::TextureFormat) -> Self {
install_gpu_error_handler(device);
record_gpu_adapter(device);
Self {
block_geometry: Default::default(),
inners: vec![Pipeline::new(device, queue, format)],
+3
View File
@@ -81,6 +81,9 @@ impl<'a, Msg: std::fmt::Debug + Clone> shader::Program<Msg> for ViewportPane<'a>
_cursor: mouse::Cursor,
bounds: Rectangle,
) -> Self::Primitive {
// Every renderer calls this; only wgpu goes on to `prepare` the
// primitive. The count is how the app notices when nobody does.
crate::scene::pipeline::note_scene_draw();
match self.pane {
Some(idx) => self.scene.build_viewport_for_pane(
bounds,
+20
View File
@@ -363,6 +363,14 @@ impl CommandLine {
}
self.push(EntryKind::Error, text);
}
/// Append a warning about the session that no command caused (the
/// renderer fell back to the CPU, say). Styled like an error so it is
/// seen, but it must not touch `last_error` / `error_revision`:
/// automation reads those to decide whether the command it just ran
/// failed, and a warning is not a failed command.
pub fn push_warning(&mut self, msg: &str) {
self.push(EntryKind::Error, format!("*{}* {msg}", t!("Warning")));
}
pub fn push_info(&mut self, msg: &str) {
let text = if msg.starts_with("i ") {
msg.to_string()
@@ -1050,6 +1058,18 @@ mod tests {
.collect()
}
#[test]
fn a_warning_is_shown_without_counting_as_a_failed_command() {
let mut line = CommandLine::new();
let revision = line.error_revision;
line.push_warning("GPU unavailable");
let last = line.history.last().expect("warning must be appended");
assert_eq!(last.kind, super::EntryKind::Error);
assert!(last.text.ends_with("GPU unavailable"), "{}", last.text);
assert_eq!(line.error_revision, revision);
assert!(line.last_error.is_none());
}
#[test]
fn mcp_status_distinguishes_off_ready_and_busy() {
assert_eq!(mcp_status(false, false).0, "MCP control is off");
+37
View File
@@ -135,6 +135,8 @@ impl StatusBar {
// the pill entirely, so an ordinarily/fully-constrained drawing sees
// no new clutter.
sketch_conflicts: usize,
// What is drawing the scene. Only a degraded verdict shows anything.
gpu_status: &'a crate::scene::pipeline::GpuStatus,
) -> Element<'a, Message> {
let StatusMenuData {
layout_names,
@@ -243,6 +245,20 @@ impl StatusBar {
// when the width can't hold them all on one line.
let vis = |p: StatusPill| config.is_visible(p);
let mut pills: Vec<Element<'_, Message>> = Vec::new();
// Not a `StatusPill` and not hideable: the scene is on a software
// rasterizer or not drawn at all, and the popup that said so has been
// dismissed. This stays for the session and reopens it. Many people
// never read the command line, so this is the one place the fact
// remains visible.
if let Some(label) = gpu_pill_label(gpu_status) {
let detail = match gpu_status {
crate::scene::pipeline::GpuStatus::Software(adapter) => {
format!("{}\n{}", adapter.name, crate::tr!("gpu", "pill-tip"))
}
_ => crate::tr!("gpu", "pill-tip"),
};
pills.push(tip(warning_pill(label, Message::GpuWarningOpen), detail.into()).into());
}
if vis(StatusPill::Coords) {
let coords_label = format_coords(cursor_world, last_point, coords_mode, picking);
pills.push(
@@ -1079,6 +1095,27 @@ fn status_pill(label: impl Into<String>) -> Element<'static, Message> {
}
/// A success-colored status pill used when no degrees of freedom remain.
/// The status-bar text for a degraded graphics verdict; `None` when there is
/// nothing to say, which is the case the bar must not clutter.
fn gpu_pill_label(status: &crate::scene::pipeline::GpuStatus) -> Option<String> {
use crate::scene::pipeline::GpuStatus;
match status {
GpuStatus::Software(_) => Some(crate::tr!("gpu", "pill-software")),
GpuStatus::NoRenderer => Some(crate::tr!("gpu", "pill-no-renderer")),
GpuStatus::Unknown | GpuStatus::Hardware(_) => None,
}
}
/// A pill in the theme's warning colours: the only status-bar item that
/// means "something is wrong", so it must not look like a toggle.
fn warning_pill(label: impl Into<String>, msg: Message) -> Element<'static, Message> {
button(text(label.into()).size(12))
.on_press(msg)
.style(button::warning)
.padding([4, 8])
.into()
}
fn success_pill(label: impl Into<String>) -> Element<'static, Message> {
container(text(label.into()).size(12))
.style(|theme: &Theme| {