mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
WgpuViewportWindow: stop using QSurface::MetalSurface on macOS
NSZombieEnabled-lldb on macOS revealed the actual cause of the
"OS_os_log displayLock" / segfault that has been chasing us:
*** -[QMetalLayer displayLock]:
message sent to deallocated instance 0xb5e234e40
Qt's QMetalLayer (its CAMetalLayer subclass installed when surfaceType
== MetalSurface) is dealloc'd while Qt's QCocoaWindow still holds an
internal reference to it. Once wgpu-native bridge-retains the layer in
its Rust surface code and re-publishes the drawable pool from
configureSurface, Qt's QMetalLayer life is implicitly handed to
wgpu-native and Qt's separate ref winds up dangling. The next Qt
expose event sends -displayLock to the dead pointer.
Earlier guesses (Qt-6.11/macOS-26 incompatibility, multi-display) were
both wrong — single-display still crashed, and the Tahoe os_log
selector-cast theory was a red herring; the real error is "deallocated
instance", revealed only by NSZombieEnabled.
# Fix
Set surfaceType to OpenGLSurface on macOS too. On macOS that still
gives us a layer-backed NSView; Qt just doesn't install QMetalLayer.
WgpuMetalSurface_mac.mm's else-branch (the one that always fires when
the existing layer isn't already a CAMetalLayer) now consistently
attaches a vanilla CAMetalLayer we fully own — wgpu-native can do
whatever it wants to the layer's lifetime without stepping on any
Qt-side bookkeeping.
We never bind a real GL context on top of OpenGLSurface — it's just
the most portable "hardware-rendering-ready surface" hint Qt has, and
it's already what Linux and Windows use.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -689,16 +689,26 @@ WgpuViewportWindow::WgpuViewportWindow(QWindow* parent)
|
||||
// wgpu doesn't need a GL context; we just need a real native window
|
||||
// whose backing layer matches the GPU API wgpu will drive.
|
||||
//
|
||||
// - Linux/Windows: OpenGLSurface gives us a hardware-rendering-ready
|
||||
// native window (XCB/HWND); we never bind a GL context on top.
|
||||
// - macOS: MetalSurface tells Qt to back the NSView with a
|
||||
// CAMetalLayer, which wgpu-native wraps via
|
||||
// WGPUSurfaceSourceMetalLayer in createSurface().
|
||||
#if defined(Q_OS_MAC)
|
||||
setSurfaceType(QSurface::MetalSurface);
|
||||
#else
|
||||
// - All platforms: OpenGLSurface gives us a hardware-rendering-ready
|
||||
// native window (XCB/HWND/NSView). We never bind a GL context on
|
||||
// top.
|
||||
//
|
||||
// - macOS specifically: we *don't* use QSurface::MetalSurface even
|
||||
// though it'd be the "obvious" choice. Doing so makes Qt install
|
||||
// its own CAMetalLayer subclass (QMetalLayer) on the NSView and
|
||||
// keep an internal reference to it. Once wgpu-native (Rust) bridge-
|
||||
// retains that layer and re-publishes its drawable pool in
|
||||
// configureSurface, Qt's QMetalLayer winds up deallocated while
|
||||
// Qt's internal reference still points at it, and the next Qt
|
||||
// expose event aborts with:
|
||||
// *** -[QMetalLayer displayLock]:
|
||||
// message sent to deallocated instance ...
|
||||
// With OpenGLSurface (which on macOS still gives us a layer-backed
|
||||
// NSView), Qt doesn't install QMetalLayer; the
|
||||
// WgpuMetalSurface_mac.mm bridge attaches a vanilla CAMetalLayer
|
||||
// we fully own, and wgpu-native can do its lifetime gymnastics
|
||||
// without stepping on Qt's bookkeeping.
|
||||
setSurfaceType(QSurface::OpenGLSurface);
|
||||
#endif
|
||||
}
|
||||
|
||||
WgpuViewportWindow::~WgpuViewportWindow() {
|
||||
|
||||
Reference in New Issue
Block a user