gogpu Backend Selection and macOS Resize Fixes

   |   4 minute read   |   Using 826 words

For Go developers using gogpu, a Go GPU and windowing toolkit, this week’s activity is mostly about fewer bad fallbacks and calmer resize behavior. The headline change is backend choice in auto mode: Windows and Linux can now ask wgpu to enumerate more than one native backend before falling back to software.

Auto mode now has more than one path

The most useful change for mixed desktop fleets is the backend choice update. In renderer.go, the renderer now creates a wgpu instance from a backend mask, not a single backend variant. That lets wgpu pick the best adapter it can find instead of treating auto mode as a quiet alias for one preferred API.

The practical case is older hardware. The changelog says Windows auto mode can now enumerate DX12, Vulkan, and GLES. Linux can enumerate Vulkan and GLES. macOS remains Metal. Browser builds remain WebGPU. The detail is also documented in docs/ARCHITECTURE.md, which is worth reading if you debug adapter selection.

  • GraphicsAPIAuto now asks for a wider backend mask.
  • GOGPU_GRAPHICS_API=dx12 still forces one backend when you need support data.
  • The selected adapter now drives the backend display name.

This is the right default shape for a graphics library. Users want hardware rendering when the machine can do it. They should not need to know that Vulkan is absent before the app tries DX12 or GLES.

macOS live resize gets a real render path

The largest patch is the macOS live resize fix. It changes the resize path from a direct surface resize on every AppKit geometry event into a render path that queues the new size for the render thread. The frame is then presented inside the AppKit resize tick.

The important files are app.go, internal/platform/darwin/window.go, internal/platform/platform.go, and framepool_darwin.go. Together they add phase hooks for the start and end of a live resize drag, toggle transaction based present on Metal surfaces, and run each Darwin frame inside an NSAutoreleasePool.

This matters because resize bugs are usually reported as visual glitches, but the real failure can be memory churn. The release notes call out IOSurface growth during drag, old drawable release behavior, and frame stretching. If a gogpu app on macOS used to show a stretched frame or a memory spike while the user dragged the window, this patch is the one to test first.

  • setupLiveResizeHook renders during the blocked AppKit resize loop.
  • LiveResizePhaser lets Darwin signal start and end of the drag.
  • runInFramePool drains transient Objective C objects once per frame.

Surface views and frame failure are less silent

The wgpu bump to v0.30.12 carried a SurfaceTexture.CreateView fix. That sits next to local renderer changes that make failed frame acquisition harder to ignore. In renderer.go, ensureFrameStarted no longer marks a frame as started when beginFrame fails.

That is a small behavior change with a real debugging payoff. DrawTextureEx now returns an error when no surface frame is available, instead of silently doing nothing. The tests were updated to expect that missing frame error. For UI code, this makes a lost frame visible enough to reschedule a redraw.

The docs update for v0.44.1 also records the 0x0 initial surface fix. macOS can report a zero physical size before first layout, so syncInitialSurfaceSize() runs after the window is shown. That keeps the first draw from disappearing before the resize path gets a chance to recover.

  • RequestRedraw before Run is stored in pendingRedraw.
  • Failed frame acquisition requests another redraw.
  • pollSubmissions now checks for a nil device before polling.

Dependency bumps carry user visible fixes

The latest dependency bump is not just bookkeeping. The wgpu v0.30.13 update notes software backend fullscreen quad detection, with the changelog reporting a move from 18 FPS to more than 50 FPS for the simple textured quad case. That is specific, and useful, because software rendering often shows up in fallback environments and CI screenshots.

Earlier in the week, the project also pulled in the goffi callback stack move fix. The note in CHANGELOG.md says return values could be lost when a callback grew the Go stack during a C to Go call. That is the kind of FFI bug that makes rendering failures look random.

The visible version trail is mostly in go.mod, go.sum, CHANGELOG.md, and ROADMAP.md. For maintainers, those files are the fastest way to confirm whether a downstream app has the callback fix, the surface view fix, and the software quad optimization.

How to prepare

Leave GraphicsAPIAuto enabled unless you are gathering data for a backend specific support case. The new selection logic only helps when gogpu can enumerate choices.

On macOS, test resize behavior if your app does custom layout in OnResize. The InSizeMove guard means expensive relayout should wait until the drag ends, while repainting can still follow the window.

If your users hit software rendering, run a simple textured quad path after the new wgpu pin lands in your build. The FPS note is promising, but it is scoped to that path, not every shader or draw pattern.



denis256 at denis256.dev