From d5a1f708b22bf457681b624cdf6f26b227784196 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Wed, 20 May 2026 02:30:07 +0800 Subject: [PATCH] Fix sluggish printer Web View on Linux for AMD/Intel GPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The WebKit hardware-acceleration workaround intended for NVIDIA proprietary drivers was being applied to every Linux GPU vendor, causing slow printer Web View rendering for AMD and Intel users on Wayland — even though the same printer web UI ran fine in standalone browsers like Epiphany on the same hardware. The workaround is now gated to the cases that actually need it (true XWayland sessions, or NVIDIA on native Wayland), so AMD and Intel users regain full hardware acceleration. --- src/OrcaSlicer.cpp | 49 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index 880eaffa4b..a246bf2e91 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -1206,14 +1206,51 @@ int CLI::run(int argc, char **argv) } #endif - // WebKit2GTK compositing can fail under XWayland. Only disable it when - // both DISPLAY and WAYLAND_DISPLAY are set (i.e., XWayland is in use). - // On pure X11 or native Wayland, compositing is left enabled. + // Orca: WebKit2GTK has two distinct workarounds, depending on display server and GPU: + // - XWayland (any GPU): WebKit's compositing mode fails silently, leaving + // WebViews blank. Fix: WEBKIT_DISABLE_COMPOSITING_MODE=1. + // - Native Wayland + NVIDIA proprietary driver: WebKit's DMABUF renderer + // is broken (WebKit bug 262607, RESOLVED WONTFIX). Fix: WEBKIT_DISABLE_DMABUF_RENDERER=1. + // - Native Wayland + AMD/Intel: leave WebKit defaults; hardware accel works fine. + // We detect GPU vendor via the PCI vendor ID exposed in /sys/class/drm. + // setenv() uses replace=false so user-set values win. { - const char* display_env_wk = ::getenv("DISPLAY"); - const char* wayland_env_wk = ::getenv("WAYLAND_DISPLAY"); - if (display_env_wk && *display_env_wk && wayland_env_wk && *wayland_env_wk) { + const char* wayland_env = ::getenv("WAYLAND_DISPLAY"); + const char* gdk_backend = ::getenv("GDK_BACKEND"); + const bool has_wayland = wayland_env && *wayland_env; + // GTK uses X11 when GDK_BACKEND forces it, or when WAYLAND_DISPLAY is unset. + // Otherwise it prefers native Wayland (this matches the wxHAS_EGL fallback + // above, which sets GDK_BACKEND=x11 explicitly when EGL is unavailable). + const bool gdk_forces_x11 = gdk_backend && boost::starts_with(gdk_backend, "x11"); + const bool xwayland = gdk_forces_x11 && has_wayland; + const bool native_wayland = !gdk_forces_x11 && has_wayland; + + auto has_nvidia_gpu = []() -> bool { +#ifdef __linux__ + namespace fs = boost::filesystem; + try { + for (const auto& entry : fs::directory_iterator("/sys/class/drm")) { + const std::string name = entry.path().filename().string(); + // Match the card itself (e.g. "card0"), not connector subdirs ("card0-DP-1"). + if (!boost::starts_with(name, "card") || name.find('-') != std::string::npos) + continue; + boost::nowide::ifstream f((entry.path() / "device" / "vendor").string()); + std::string vendor_id; + // 0x10de = NVIDIA. (0x1002 = AMD, 0x8086 = Intel.) + if (std::getline(f, vendor_id) && vendor_id == "0x10de") + return true; + } + } catch (...) {} +#endif + return false; + }; + + if (xwayland) { + BOOST_LOG_TRIVIAL(info) << "XWayland detected; disabling WebKit compositing mode."; ::setenv("WEBKIT_DISABLE_COMPOSITING_MODE", "1", /* replace */ false); + } else if (native_wayland && has_nvidia_gpu()) { + BOOST_LOG_TRIVIAL(info) << "Native Wayland with NVIDIA GPU detected; disabling WebKit DMABUF renderer."; + ::setenv("WEBKIT_DISABLE_DMABUF_RENDERER", "1", /* replace */ false); } }