Add opt-in native Wayland support on Linux - #11821
Conversation
…d) (bambulab#2595) - Build wxWidgets dep with wxUSE_GLCANVAS_EGL=ON so wxGLCanvas works on Wayland - Stop force-overriding GDK_BACKEND; default stays x11, a user-set GDK_BACKEND=wayland is now honored - Set WEBKIT_DISABLE_DMABUF_RENDERER=1 on Wayland sessions (overridable) to avoid blank WebKitGTK views on NVIDIA/VMs - Treat GLEW_ERROR_NO_GLX_DISPLAY from glewInit as non-fatal: GLX-built GLEW reports it under native Wayland/EGL and under the CLI's OSMesa context; core GL entry points are already resolved at that point - Add libwayland-dev, wayland-protocols, libegl-dev to debian deps
…subsurfaces The fork's 3.1-era wxGLCanvasEGL mishandles the Wayland subsurface lifecycle: the subsurface is created against a not-yet-mapped parent, never repositioned after layout, and eglSwapBuffers() can stall on frame callbacks the compositor withholds for occluded surfaces. Port the wxWidgets 3.2.11 src/unix/glegl.cpp + include/wx/unix/glegl.h wholesale, adapted to the fork: - subsurface created on map-event, destroyed on unmap - geometry refreshed on size-allocate/scale change from the current GtkAllocation and widget-tree coordinates (gdk_window_get_origin can report stale positions after compositor-driven resizes) - swap interval 0 so eglSwapBuffers() never blocks the UI thread - shims for wrapgdk/backend/elfversion headers the fork predates, and wxABI version guards removed Applied via ExternalProject PATCH_COMMAND with an idempotency guard.
GCodeViewer::get_renderer() force-called OpenGLManager::init_gl() during startup, before the canvas GL context had ever been made current. On Wayland this compiles every shader program into GTK's internal EGL context; all later glUseProgram() calls in the app's render context fail with GL_INVALID_VALUE and the 3D viewport stays blank (white). On X11 the app context happens to be current by then, which masked the bug. Defer renderer creation until GL has been initialized by the render path, which is guarded by _set_current(). Adds OpenGLManager::is_gl_initialized() for that check.
1f0db03 to
74b2593
Compare
|
Status: not finished — please treat this as work in progress, and testers are very welcome. Since opening this PR I found (and partly fixed) two further problems, and one known problem remains open. Summary of where things actually stand: Fixed since the initial push
Still broken / needs work
Testers wanted. The default backend is unchanged (X11/XWayland), so a normal launch should behave exactly as before — that part needs regression testing as much as the new path does. To try native Wayland: Useful reports: your distro, compositor, GPU and driver, whether you launched with or without |
|
Sorry for this dumb question, but is there a precompiled AppImage somewhere and corresponding to this PR, or is it expected for testers to build it from source ? |
On X11 the EGL window surface can only be created when the EGLConfig's EGL_NATIVE_VISUAL_ID matches the visual of the X window. Mesa tolerates a mismatch; the NVIDIA driver rejects it with EGL_BAD_ALLOC, and because wx is built with asserts disabled the failure is silent: the GL context reports 4.6 and shaders compile, but there is no surface to draw into, so the 3D viewport stays blank. wxWidgets aligns the widget's visual with the chosen visual for the GLX path (parent_set_hook) but never does so for the EGL path. Install the equivalent hook for EGL on X11. Measured on an RTX 4090 (driver 610.43.03): window visual 0x2ec, all five offered configs report native visual 0x71, eglCreatePlatformWindow- Surface fails; after aligning the widget visual with the config the surface is created and glReadPixels returns the cleared color.
|
I can provide an appimage from the latest sources if there is interest. |
If easy enough for you to upload it somewhere, would be easier to test, indeed. |
|
After a reboot (now kernel 7.1.6-arch1-1 + NVIDIA 610.57.04), still same behavior, however the log is cleaner |
When BambuStudio starts without input files, post_init() disables canvas rendering, switches to the 3D tab and eagerly initializes OpenGL — but only if the canvas passes IsShownOnScreen() && make_current_for_postinit() at that instant. On Wayland this guard can never pass: the EGL canvas's IsShownOnScreen() requires its wl_subsurface, which is only created when the widget is mapped, and mapping cannot happen within the same event-loop turn that just switched the tab. The "postpone the init" branch then left rendering disabled with no retry anywhere, so GLCanvas3D::render() returned at the !m_enable_render guard for the rest of the session. An EGL interposer confirmed the process never issued a single eglMakeCurrent/eglSwapBuffers; the "blank viewport after loading a model" reported on PR bambulab#11821 is this dead render loop becoming visible the first time the user opens the Prepare tab. Starting with a file on the command line sets switch_to_3d and skips the block entirely, which is why that path always rendered and why the bug looked load-related. Two changes: - GUI_App::post_init(): when the eager init is postponed, re-enable rendering so the normal render path — which is fully guarded by _is_shown_on_screen(), _set_current() and init_opengl() — performs the same initialization lazily on the first paint after the canvas is actually mapped. This is exactly the sequence the (working) start-with-a-file path already uses. - GLCanvas3D::init(): if model objects were loaded while GL init was still deferred, the reload_scene() calls made during that load were no-ops (reload_scene early-returns when !m_initialized), leaving the scene empty after the deferred init. Rebuild the scene at the end of init() in that case (deferred refresh; init() runs inside render()). Verified on NVIDIA RTX 4090 / driver 610.43.03 / Hyprland, native Wayland: start without file → load model at runtime now shows plate and model (was: grey viewport); second runtime load also renders; start with file unchanged. X11 (XWayland): start with file renders identically to the unpatched build; post_init still takes the eager branch there.
|
The "viewport blank after loading a model" bug is diagnosed and fixed — commit a8beca8, new test build: wayland-test-a8beca80b (AppImage is uploading from CI and appears on the release shortly). Root causeIt was never a load-path or rendering bug — the render loop was dead from startup. When the app starts without a file argument, Starting with a file on the command line sets Fix (2 small changes)
Verified (screenshots, NVIDIA RTX 4090 / driver 610.43.03 / Hyprland)
Not yet re-verified on Intel/Mesa with this commit — covered by the earlier commits' testing, will re-check with the new AppImage. Related findWhile debugging this I found that Linux single-instance file passing (handing a file to an already-running instance) has never worked on any backend — a DBus name case mismatch makes the message vanish silently. Fixed separately in #11826. |
|
Thanks for testing this @SR-G . Works for me on both nvidia and intel/mesa. marking the PR ready to review again |
|
I just tested your latest AppImage for this, and it already runs so much smoother and less buggy than the X11 client for me! It scales properly, I see no long black screens, it loads the printer device status and video preview, and it seems like starting prints works reliably, unlike the x11 client that permanently freezes often when trying to start a print. The only 2 things I noticed in that quick test:
Recorded a short video of it: 1786379406.mp4It still has some issues, but is already much more usable, and I will start using it over the xwayland client already! 👍 |
v3 revision consolidating what we learned executing Phases 0-2: - Environment: concrete details (Fedora 44, GNOME 50, Intel Arc LNL, xe driver, Mesa 26.1.6) - Communication policy: hard rule that tooling never publishes to bambulab/*; drafts stay local, user posts manually - Category C: seven build-system / Fedora ergonomic issues discovered during Phase 1 (apt-not-dnf, missing perl-FindBin/nasm/libquadmath-devel, lib vs lib64 split, silent-failure cascade, missing +x) - Category D: two issues surfaced by Phase 2 pr/11821 testing (no SSD under GNOME Wayland, XWayland hang whose regression-status is TBD) - Build recipe: what actually works on Fedora 44 today, until Cat C fixes land - Phase 2.5 proposed: master-build comparison to determine whether the XWayland hang (D2) is a bambulab#11821 regression or pre-existing


Fixes #2595
Adds native Wayland support on Linux, opt-in for now. Three commits:
1. Enable opt-in native Wayland support
wxUSE_GLCANVAS_EGL=ONsowxGLCanvasuses EGL and works on both X11 and native Wayland.GDK_BACKENDis no longer force-overridden (replacechanged tofalse). The default remainsx11(XWayland), so nothing changes for existing users, but launching withGDK_BACKEND=waylandnow gives a native Wayland session instead of being silently reverted.glewInit()toleratesGLEW_ERROR_NO_GLX_DISPLAY: GLX-built GLEW returns it when no GLX display exists (native Wayland/EGL, and the CLI's OSMesa offscreen context used for thumbnails). Core GL entry points are already resolved at that point. GLEW intentionally stays a GLX build (GLEW_EGLwould break the CLI/OSMesa path).WEBKIT_DISABLE_DMABUF_RENDERER=1is set (non-overriding) on Wayland sessions to avoid blank/garbled WebKitGTK views on NVIDIA and VMs.linux.d/debiangainslibwayland-dev,wayland-protocols,libegl-dev.2. Port wxWidgets 3.2.11 EGL canvas into the wxWidgets dep
The fork's 3.1-era
wxGLCanvasEGLmishandles the Wayland subsurface lifecycle (subsurface created against a not-yet-mapped parent, never repositioned after layout,eglSwapBuffers()can stall on withheld frame callbacks).deps/wxWidgets/0002-fix-wayland-egl-subsurface.patchports the upstream 3.2.11 implementation, adapted to the fork: subsurface created on map-event and destroyed on unmap, geometry refreshed from the liveGtkAllocation/widget-tree coordinates on size-allocate and scale changes, swap interval 0.3. Do not initialize OpenGL without the canvas context current
GCodeViewer::get_renderer()force-calledOpenGLManager::init_gl()during startup before the canvas GL context had ever been made current. On Wayland this compiled every shader program into GTK's internal EGL context, so all laterglUseProgram()calls in the render context failed withGL_INVALID_VALUEand the 3D viewport stayed blank. On X11 the app context happened to be current by then, masking the bug. Renderer creation is now deferred until GL has been initialized by the (properly guarded) render path.Tested on Arch Linux under Hyprland (Wayland session, mixed-DPI monitors, Intel + NVIDIA): with
GDK_BACKEND=waylandthe AppImage runs as a native Wayland client (compositor reportsxwayland: false); the 3D viewport (build plate, models, toolbars, gizmos), WebKit webviews and the rest of the UI render correctly and track window resizes. Default launch (X11/XWayland) is unchanged. Built viaDockerBuild.sh(ubu24), clean deps + app build.Known follow-ups under native Wayland: window move/resize can feel slightly laggy (subsurface repositioning), and
gtk_window_resizeassertion warnings from the dropdown popup sizing code (src/slic3r/GUI/Widgets/DropDown.cpp).