* Fix #378: draw on the GPU that drives the primary display on Windows The low-power preference picked the AMD Ryzen integrated GPU on a desktop whose monitors all hang off an NVIDIA card. Presenting from the headless iGPU to a window on another GPU took the AMD display driver down, blacking out every monitor for two minutes before PdfCraft exited. Windows now gets the display-aware adapter choice Linux already had: EnumDisplayDevices (through the safe `winsafe` crate, MIT) says which adapter drives each desktop display and which is primary; `pick_adapter` matches that to the wgpu adapters by PCI ids. The GPU driving the primary display wins, as the built-in panel does on Linux (#8). The log names the GPU chosen, the first question when a window stays black. Synthetic tests cover the Windows device-id parser and the primary-display rule; a live test checks the enumeration on the running machine. Verified on a Ryzen 7000 + RTX 3090 desktop: the app now starts on the 3090. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XBMGuLLMhs1h8orSxcJXER * 631: the winsafe feature comment says user (and kernel) --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
4.8 KiB
Developing PdfCraft
Working instructions for agents and contributors are in AGENTS.md and CLAUDE.md. This page
collects what the desktop app reads from its environment and where it writes its diagnostics.
Logs
The desktop app writes its log records to standard error and to logs/pdfcraft.log in its
settings folder, next to app.ron: Linux and FreeBSD ~/.local/share/pdfcraft/logs/ (or
$XDG_DATA_HOME/pdfcraft/logs/), macOS ~/Library/Application Support/PdfCraft/logs/, Windows
%APPDATA%\PdfCraft\data\logs\. In portable mode (a portable.txt file next to the executable, as
the Windows portable zip ships) the settings folder is PdfCraftData\ beside the executable, and
crash recovery and new digital IDs go there too. A start from a desktop menu, Finder or the Start
menu has no terminal, so this file is what to attach to a bug report: a failed autosave, a page that
would not render, a render worker that could not start and the report of an internal error all land
there.
Each launch moves the previous log to pdfcraft.1.log (and that one to pdfcraft.2.log), so the
log of a run that crashed survives the next start. The file stops growing at 16 MiB. --version
writes no file.
By default PdfCraft's own crates (pdfcraft*) log at info and everything else at warn.
RUST_LOG replaces that with env_logger-style directives, for example RUST_LOG=debug,
RUST_LOG=warn,pdfcraft_render=trace or RUST_LOG=info,wgpu_core=warn; a directive ending in *
covers every target starting with it (pdfcraft*=debug). The logger is
apps/pdfcraft/src/logging.rs. It never records the control-channel token or document passwords.
GPU surface limits
The desktop renderer enables the selected adapter's supported 2D texture extent, while keeping
egui-wgpu's other device requirements. Restored windows on mixed-DPI monitors can exceed its
default 8192-pixel extent even when the GPU supports a larger surface (#577). The enabled extent
never exceeds the adapter's capability. A window larger than even that (restored at another
monitor's scale, or stretched across monitors) gets a surface fitted within the limit and is drawn
at a correspondingly lower scale instead of panicking in Surface::configure (vendored egui-wgpu,
surface_fit; see vendor/README.md). On DX12, PdfCraft's Windows default, the surface is
stretched over the window: softer, but complete and lined up with the pointer. wgpu's GL backend
copies it unscaled into a corner of the window instead.
Renderer fallback
PdfCraft draws with wgpu, and starts again with eframe's own OpenGL renderer (glow) when wgpu fails
before the app is created: no adapter, no device, or a window surface the device can't configure.
The last of these was a panic, not an error, because wgpu's default error handler panics and
eframe configures the surface before any app code runs; a 2015 Intel GPU whose driver timed out in
Surface::configure on wgpu's GL backend closed PdfCraft at launch (#519). Vendored egui-wgpu
configures a new window's surface inside winit::catch_errors and returns a validation,
out-of-memory or internal error as WgpuError::ConfigureSurface (see vendor/README.md). Still a
panic, as upstream: an error in a later reconfigure (resizing, a lost surface); a device lost
during that first configure (wgpu reports it only to a callback, so the first frame panics, after
the app has started); and a window shown at zero size, which is first configured on resize. If
OpenGL can't start either, PdfCraft exits with both errors in the log. The fallback is logged at
error, with the wgpu error. PDFCRAFT_RENDERER skips it or chooses OpenGL from the start.
Environment variables
| Variable | Effect |
|---|---|
RUST_LOG |
Log levels for standard error and the log file (see Logs) |
RUST_BACKTRACE |
1 adds a backtrace to the report of an internal error |
XDG_DATA_HOME |
Linux/FreeBSD: base of the settings folder (pdfcraft/), the log folder and crash recovery |
WGPU_POWER_PREF |
GPU choice; by default PdfCraft draws on the GPU that drives the primary display (Windows) or the built-in panel (Linux), else the low-power (integrated) GPU. The log says which one was chosen |
WGPU_BACKEND |
Graphics backend; by default Windows uses Direct3D 12, falling back to OpenGL |
PDFCRAFT_RENDERER |
gl starts with OpenGL (glow) and never loads wgpu; wgpu reports a wgpu failure instead of retrying with OpenGL; unset, wgpu is retried with OpenGL when it can't start (see Renderer fallback) |
CRAFT_FONTS_DIR |
Build time: a craft-fonts checkout to embed (Japanese fonts) |
PDFCRAFT_SYSTEM_FONTS |
0 stops the desktop app from using an installed font for characters its embedded fonts lack (cargo xtask screenshots sets it) |