Skip to content

Composition

vicrodh edited this page Jul 24, 2026 · 4 revisions

Composition (Renderer & Graphics)

Since QBZ 2.0, the app is a native Slint program — there is no webview, no WebKitGTK, no HTML layer. QBZ paints its interface directly, choosing one of three rendering backends depending on your hardware:

Tier Backend Used when
GPU wgpu (Vulkan / GL / Metal) You have a capable GPU. Full speed, shader visualizers, and the dynamic album-art background.
GPU (compatibility) OpenGL via femtovg Weak or embedded GPUs (Raspberry Pi-class, Intel UHD 600 / Gemini Lake) where the real GPU path is the slow one.
Software CPU renderer No usable GPU — VMs without passthrough, broken drivers. Maximum compatibility.

Most users never touch any of this — QBZ auto-detects your hardware and picks the fastest tier that actually works. This page is for when you want to override that choice or recover from a bad one.

The old GTK/WebKit knobs (GSK renderer, GDK scale, Force X11, DMA-BUF, qbz --reset-graphics, QBZ_FORCE_X11, QBZ_SOFTWARE_RENDER) are gone with the Tauri frontend — they do nothing in 2.0+. If a guide still mentions them, it predates the native rebuild.

Quick Reference

Problem Solution
App feels slow / crawls at 60 fps CPU Force the GPU (compatibility) or Software tier, or check you're not on a software Vulkan adapter (llvmpipe) in a VM
Black screen or crash on launch, GPU-related QBZ_RENDERER=gl qbz — if still bad, QBZ_RENDERER=software qbz
Dynamic background / shader panels are missing You're on the GL or Software tier — those effects need the GPU (wgpu) tier
Hybrid laptop, want the discrete GPU to drive the UI Settings → Appearance → Renderer → Preferred GPU → discrete
Locked out after forcing a renderer Just relaunch — QBZ auto-reverts a forced renderer that never reached a usable state

Settings → Appearance → Renderer

The renderer controls live in Settings → Appearance, under the RENDERER group (Linux only — macOS always renders through Skia/Metal, so the group is hidden there). Both settings require an app restart.

Rendering backend

Option What it does
Auto (recommended) Detects your hardware and runs a fallback ladder: wgpu → GL → software. The default.
GPU Force the wgpu GPU tier.
GPU (compatibility) Force the OpenGL (femtovg) tier — the middle ground for weak GPUs.
Software Force the CPU renderer. Slowest, most compatible.

Only change this if the app feels slow or renders incorrectly. Leave it on Auto unless you have a reason not to.

Preferred GPU

On a hybrid laptop (integrated + discrete), this picks which adapter renders the app. Choosing the discrete GPU moves the dynamic-background and visualizer load off the integrated one — cooler on the iGPU, but more power draw. The list shows Auto plus each adapter QBZ detected. Auto is recommended.

Settings, Renderer group

How auto-detection works

When the renderer is on Auto, QBZ enumerates every GPU adapter on your machine (across Vulkan, GL and — on macOS — Metal), classifies each one, and picks the best tier it can actually drive:

  • A real, capable GPU → the wgpu tier. Everything on, including the immersive shader scenes and the app-wide dynamic background.
  • A weak / embedded GPU → the OpenGL (femtovg) tier. On this hardware Mesa's GL driver is the mature, fast path and the "real" Vulkan adapter is the slow (or flaky) one, so QBZ deliberately steps down.
  • No usable GPU (a VM with no passthrough, where wgpu would otherwise bind a software Vulkan adapter like llvmpipe and CPU-rasterize the whole UI every frame) → the pure Software renderer, which is far lighter than a CPU-emulated GPU path.

What QBZ counts as "weak" (any one of these routes you to the GL tier):

  • The adapter or driver name matches a known embedded/slow-Vulkan family — Raspberry Pi v3dv/videocore, ARM Mali panfrost/panvk/lima/mali, Mesa's legacy Intel gen7 hasvk (Ivy Bridge / Haswell), the software rasterizer llvmpipe, or Intel UHD Graphics 600 (Gemini Lake — flickers on wgpu, #578).
  • It's an integrated GPU on an ARM Linux board (a Pi and friends). This is deliberately not "any aarch64": Apple Silicon is integrated + aarch64 too and is a strong GPU, so it stays on the wgpu tier.
  • Its max_texture_dimension_2d is ≤ 4096 — a reliable "this is a small GPU" signal.

Hybrid machines (integrated + discrete). Which adapter drives the window matters, and the right pick differs between laptops and desktops:

  • On a hybrid laptop (a battery is present), QBZ keeps the UI on the integrated GPU — the panel is wired to it and this mostly-idle app doesn't need the discrete card burning power.
  • On a hybrid desktop (no system battery), it defaults to the discrete GPU, because the monitor is usually plugged into the discrete card and the display-less integrated one physically can't present the window — picking it is the classic "Invalid surface" crash (#542).
  • Override either way with Preferred GPU (below).

On the GL and Software tiers, QBZ turns on reduce-motion automatically — loading spinners and EQ bars step at a coarse rate instead of the display rate, because every animation frame is a full-window repaint there. The rest of the UI is fully intact and fast; only the shader eye-candy (immersive shader scenes, dynamic background) is unavailable, since those need the GPU tier.

The auto-degradation ladder

A single failed start is not fatal. On Auto, each start that dies before the app becomes usable steps one rung down and the next start tries the rung below:

wgpu (default adapter) → wgpu (alternate adapter) → GL → software

The alternate-adapter rung exists for hybrid machines: the heuristically-preferred adapter may be unable to present while the other one works perfectly, so QBZ tries the other GPU before surrendering the whole GPU tier. (macOS stays out of the ladder — it degrades straight back to wgpu, there's no GL tier there.)

A new build re-probes Auto once, in case a driver update or a renderer fix has landed since the last degradation.

Auto-revert safety net

When you force a specific renderer (via Settings or QBZ_RENDERER), QBZ arms a sentinel before the risky backend/window init and disarms it on your first real input (or after 30 s). If the next launch finds the sentinel still armed — proof the forced renderer never reached a usable state — QBZ reverts to Auto and re-detects. You cannot lock yourself out by picking the wrong renderer.

Which tier should I pick?

Short answer: leave it on Auto. The detection above is good, and the ladder recovers from a bad guess on its own. Only reach for a manual tier when Auto is demonstrably wrong for your box:

Your situation Pick
Normal desktop/laptop, everything works Auto — don't touch it.
Auto dropped you to GL/Software but your GPU is genuinely capable (a fresh driver, a card Auto was too cautious about) GPU — force the wgpu tier. If it flickers or crashes, Auto was right; go back.
The GPU tier flickers, tears, or shows shader artifacts (some Mesa/embedded drivers, old Intel) GPU (compatibility) — you keep hardware acceleration through OpenGL and only lose the wgpu-only eye-candy.
VM with no GPU passthrough, or broken/missing GL+Vulkan drivers Software — skips the CPU-emulated GPU path entirely; lighter and always renders.
Hybrid laptop running hot / draining battery under the dynamic background Preferred GPU → discrete (moves the load off the iGPU) — or turn the dynamic background off in Themes and Visualization.
Hybrid desktop with the monitor on the integrated GPU (unusual) Preferred GPU → integrated.

The trade-off is only ever the shader effects — the immersive shader scenes and the app-wide dynamic album-art background need the GPU (wgpu) tier. Track browsing, playback, artwork, lyrics and every normal view look and perform the same on all three tiers. So: if you don't use the shader background, GL vs GPU is a wash — pick whichever is stable. If you do want it, you need the GPU tier and a GPU that can actually drive it.

You can confirm what you ended up on in Settings → Developer → Diagnostics (it reports the active tier, why it was chosen, and the adapters it saw), or by launching from a terminal and reading the [renderer] log lines.

Environment Variables

For one-off testing or a permanent workaround, QBZ_RENDERER overrides the persisted setting:

Value Effect
QBZ_RENDERER=auto Auto-detect (same as the default)
QBZ_RENDERER=gpu (aliases: wgpu, hardware, hw) Force the GPU (wgpu) tier
QBZ_RENDERER=gl (aliases: gles, femtovg) Force the OpenGL compatibility tier
QBZ_RENDERER=software (aliases: cpu, soft) Force the CPU renderer
# Force the compatibility GL tier
QBZ_RENDERER=gl qbz

# Nuclear option: pure software rendering
QBZ_RENDERER=software qbz

# Flatpak
QBZ_RENDERER=software flatpak run com.blitzfc.qbz

An env override always wins over the Settings choice; it's evaluated once at startup.

Advanced background-look knobs

These fine-tune the dynamic album-art background live (so its look can be dialed in without a rebuild). Values are 0.01.0:

Variable Effect
QBZ_BG_DIM How much the backdrop is dimmed behind the content
QBZ_BG_SURFACE_ALPHA Translucency of panels/surfaces over the backdrop
QBZ_BG_BAR_ALPHA Translucency of the top/bottom bars over the backdrop

Making an override permanent

# In ~/.bashrc or ~/.zshrc
export QBZ_RENDERER=gl

# Or a wrapper script
echo 'QBZ_RENDERER=software exec qbz "$@"' > ~/.local/bin/qbz-soft
chmod +x ~/.local/bin/qbz-soft

Common Scenarios

App is slow / pegs the CPU in a VM

A VM without GPU passthrough makes wgpu bind a software Vulkan adapter and CPU-rasterize everything at 60 fps. Force the lighter pure-software renderer:

QBZ_RENDERER=software qbz

Or set Rendering backend → Software in Settings.

Raspberry Pi / weak GPU: choppy or slow

Auto should already pick the GL tier on these boards. If you forced GPU earlier, put it back to Auto (or QBZ_RENDERER=gl). For a truly headless streamer, you likely want the Headless Daemon instead of the desktop UI at all.

Black screen or GPU crash on launch

  1. QBZ_RENDERER=gl qbz — most GPU-init crashes clear on the compatibility tier.
  2. Still failing? QBZ_RENDERER=software qbz.
  3. If a previous forced choice caused it, just relaunch normally — the auto-revert net drops you back to Auto after a start that never became usable.

Dynamic background or shader visualizers greyed out

These require the GPU (wgpu) tier. If the picker row is disabled, you're on GL or Software — switch Rendering backend → GPU (and make sure your GPU is actually capable). See Themes and Visualization for the background modes.

Recovery

QBZ can't be permanently bricked by a renderer choice — the auto-revert net handles the common case. If you want to wipe the persisted renderer choice by hand, the setting lives in your UI preferences file:

# Renderer / interface prefs (renderer key lives here):
# ~/.local/share/qbz/ui_prefs.json

Delete or edit that file (or reset just the renderer key to "auto") and relaunch. QBZ logs every renderer decision at startup — launch from a terminal to watch the tier selection and any fallbacks:

qbz
# [renderer] ... -> forcing/auto-detecting ...

The graphics settings shrank a lot in the native rebuild: the sprawling Tauri-era graphics panel (GSK renderer, DPI/scale, DMA-BUF, force-X11…) is gone, replaced by the two controls above — Rendering backend and Preferred GPU — plus the QBZ_RENDERER / QBZ_BG_* env knobs. Everything else the old panel exposed is now decided automatically.

See also

Themes and Visualization · Troubleshooting · Headless Daemon

Clone this wiki locally