protonscr

Steam Big Picture Mode lag worsens with each open/close cycle on Linux (steamwebhelper disables GPU acceleration after the first BPM cycle)

steamopen Big PictureDistro Family: UbuntuWeb Component
ValveSoftware/steam-for-linux#13278 · opened 2026-05-31 by philippthiele · updated 2026-06-01 · 1 comments · github
Pphilippthiele 2026-05-31 github

Affected version

  • Steam client BuildID: 1779918128
  • Steamwebhelper / CEF: Chrome/126.0.6478.183, ANGLE commit 5d4df51d1d7d
  • Skia: 126 be621ea04206d8fae23952783d1d588d6ce0d9b3
  • Behavior also reproduced on prior client BuildID 1779486452 (same logs).

System

  • OS: Linux Mint 22.3 (Ubuntu 24.04 base, codename noble/zena)
  • Kernel: 6.17.0-29-generic (PREEMPT_DYNAMIC, x86_64)
  • Desktop: Cinnamon (X-Cinnamon), session type x11 (not Wayland)
  • GPU: AMD Radeon RX 6900 XT (Navi 21, PCI 1002:73bf)
  • Driver: amdgpu kernel driver, Mesa 25.2.8-0ubuntu0.24.04.1, LLVM 20.1.2
  • VRAM: 16 GB, ~15.5 GB free at the time of the failure
  • Two displays: 3840×2160 @ scale 2 (so 1920×1080 logical) and 1920×1080 @ scale 2 (960×540 logical), both 60 Hz.
  • Steam install: Debian package, install path /home/philipp/.steam/debian-installation/
  • Renderer stack reported by webhelper: GL implementation parts: (gl=egl-angle, angle=opengl) — i.e. ANGLE on top of desktop OpenGL via Mesa. Vulkan path is disabled_off.
    • Opted into Steam client beta?: No difference with beta on/off

Summary

On Linux, opening Big Picture Mode (BPM) for the first time after launching Steam works smoothly. After closing BPM and reopening it, the second and subsequent BPM windows are extremly laggy, and the lag gets worse on each successive open/close cycle.

Logs show that this is not a progressive resource leak; it is a discrete state change inside steamwebhelper/CEF: somewhere between closing the first BPM window and opening the second, Steam's CEF GPU process is shut down and its renderer is permanently switched from hardware-accelerated rendering (mode: OpenGL) to software rendering (mode: System). The compositor never recovers within the same Steam session — the only fix is to fully restart Steam.

The GPU itself is healthy and idle at the time of the failure (16 GB VRAM free, no driver errors in dmesg, no shader-related issues).

Reproduction

  1. Cold-launch Steam (or restart Steam so a fresh steamwebhelper is started).
  2. Open Big Picture Mode (gamepad icon / steam://open/bigpicture). Observe smooth UI.
  3. Close Big Picture Mode (back to desktop client).
  4. Open Big Picture Mode again.
    • Expected: same fluidity as step 2.
    • Actual: BPM is noticeably laggier — input latency is up, scrolling stutters, animations drop frames.
  5. Repeat steps 3–4. Each cycle remains in the degraded state; subjectively the lag accumulates further with use.

100% reproducible on this system. The only known workaround is a full Steam client restart.

Concrete observations from logs (single Steam session, today)

All times are local. Logs are from ~/.steam/debian-installation/logs/.

Cycle 1 — first open after Steam start (smooth)

webhelper.txt:

[2026-05-31 10:24:51] SP Shared JS Context-'SharedJSCo': CreatingPopup name:SP BPM_uid0 ... useragent=Valve%20Steam%20Gamepad
[2026-05-31 10:24:51] SP BPM_uid0: Created window: size: 1280,800 ... mode: OpenGL window: 0x6c00087
[2026-05-31 10:24:51] SP BPM_uid0: AfterCreated handle:1114126 type:3
[2026-05-31 10:24:51] SP BPM_uid0-'Steam Big ': WasHidden 0

→ Window mode is OpenGL (hardware-accelerated CEF compositor).

Cycle 1 close

[2026-05-31 10:34:40] SP BPM_uid0-'Steam Big ': Applying safe browser shutdown workaround

GPU process disabled between cycles

webhelper_gpu.txt:

[2026-05-31 10:35:30] Disabling GPU acceleration: Disabled/RuntimeDetect

There is no preceding error in webhelper_gpu.txt — no GL error, no driver crash, no context lost, no GPU process crashed, nothing in dmesg, no entry in /tmp/dumps. The runtime simply decides to disable GPU acceleration ~50 seconds after BPM is closed.

Cycle 2 — second open (laggy)

[2026-05-31 10:36:17] SP Shared JS Context-'SharedJSCo': CreatingPopup name:SP BPM_uid0 ...
[2026-05-31 10:36:17] SP BPM_uid0: Created window: size: 1280,800 ... mode: System window: 0x6c0012a

→ Window mode is now System instead of OpenGL: the BPM browser has fallen back to CPU/software compositing for a 1280×800 (logical, 2× HiDPI) full-window surface that animates at the display refresh rate. This matches the user-visible lag exactly.

Cycle 3 — third open (laggy again)

[2026-05-31 10:36:47] SP BPM_uid0-'Steam Big ': Applying safe browser shutdown workaround
[2026-05-31 10:37:09] SP BPM_uid0: Created window: size: 1280,800 ... mode: System window: 0x6c001ac

Still mode: System. The Disabling GPU acceleration: Disabled/RuntimeDetect decision is sticky for the rest of the session.

Renderer process is never released

Process 5872 (the CEF renderer zygote that hosts BPM) remains alive across all three BPM cycles with:

  • VmPeak: 57,795,736 kB (≈55 GiB virtual address space; resident is ~820 MiB)
  • 30 threads
  • Open file descriptors steadily rise across cycles

This is consistent with each BPM open reattaching to the same renderer rather than spawning a fresh GPU-backed one.

This is not a one-off — it has happened repeatedly

Searching the rotating webhelper logs:

$ grep -c "Disabling GPU acceleration" ~/.steam/debian-installation/logs/webhelper_gpu.txt
14

14 occurrences in the last 8 days, each one preceded by one or more BPM_uid0: Created window … mode: OpenGL and followed by subsequent BPM_uid0: Created window … mode: System until Steam is restarted. Examples of the OpenGL → System transition pattern:

[2026-05-23 11:29:37] SP BPM_uid0: Created window … mode: OpenGL
[2026-05-23 11:33:37] Disabling GPU acceleration: Disabled/RuntimeDetect
[2026-05-23 11:51:55] SP BPM_uid0: Created window … mode: System
[2026-05-23 11:52:34] SP BPM_uid0: Created window … mode: System
[2026-05-23 16:46:19] SP BPM_uid0: Created window … mode: System
[2026-05-23 16:51:31] SP BPM_uid0: Created window … mode: OpenGL   (Steam was restarted here)
[2026-05-23 17:11:44] SP BPM_uid0: Created window … mode: System

Every transition from OpenGL to System for BPM_uid0 lines up with a Disabling GPU acceleration: Disabled/RuntimeDetect event in webhelper_gpu.txt, and every OpenGL reappearance corresponds to a new Steam process tree (i.e. a Steam restart).

Suspected cause

Some interaction between BPM tear-down (the Applying safe browser shutdown workaround path on the BPM CEF browser) and CEF's GPU process watchdog / runtime feature detection trips the RuntimeDetect path that disables GPU compositing for the rest of the steamwebhelper lifetime. Concrete clues:

  • The CEF GPU report enumerates an AMD/Linux workaround called exit_on_context_lost (problems[9]: "Some drivers can't recover after OUT_OF_MEM and context lost"). It is enabled. If BPM shutdown triggers anything that CEF interprets as "context lost," exit_on_context_lost would terminate the GPU process; combined with whatever heuristic emits Disabled/RuntimeDetect, that would prevent CEF from spinning up a fresh GPU process for the next BPM open.
  • The BPM window is created with the hard-coded user agent Valve Steam Gamepad and the fixed window name SP BPM_uid0, suggesting BPM uses a single dedicated CEF browser that is destroyed and recreated rather than being kept alive across cycles. The shutdown of that browser appears to be what perturbs the GPU process.
  • ANGLE feature loseContextOnOutOfMemory: enabled is set, and direct_rendering_display_compositor: disabled_off_ok, which is the typical CEF/Linux configuration on AMD/Mesa. Vulkan is disabled_off.

I'm not in a position to pinpoint the exact trigger inside steamwebhelper, but the externally visible state machine is unambiguous: BPM open → BPM close → CEF GPU disabled → BPM reopens in software.

Why it presents as "gets worse with each open"

  • Cycle 1 is fully GPU-accelerated.
  • Cycle 2+ is software compositing for a HiDPI BPM surface plus software rasterization for all CEF browser tiles in the desktop client, plus the Chromium tab/process bookkeeping that piles up across BPM tear-down/teardown sequences (e.g. several Returning a speculative frame warnings on the BPM browser at 10:25:24 after the renderer was reattached).
  • Subsequent cycles continue to add CEF widget instances (MainMenu_uidNN, QuickAccess_uidNN, notificationtoasts_uidNN, gamepadoverlay_uidNN) — the uid counter monotonically increases — which the software path has to composite together. This matches the observation that lag accumulates with each cycle rather than being constant after the first regression.

Expected behavior

  • Either: closing and reopening BPM should retain the GPU process and produce a mode: OpenGL window every time within a single Steam session.
  • Or: if steamwebhelper decides to disable GPU acceleration at runtime, it should log the actual reason (which GL/EGL error, which watchdog timeout, which heuristic) so users and Valve can act on it, and it should attempt to re-enable GPU acceleration when reopening BPM (instead of silently falling back to mode: System for the rest of the session).

Workaround

Launching the Steam client with the -cef-force-gpu flag fully avoids the regression in this session. With it set:

  • BPM open/close cycles 1 → 2 → 3 all produce a mode: OpenGL window in webhelper.txt.
  • No Disabling GPU acceleration: Disabled/RuntimeDetect event is emitted between cycles.
  • BPM remains fluid across all subsequent reopens for the lifetime of the Steam process.

Comparison from a test run on this system:

Cycle 1 (open) Cycle 2 (reopen) Cycle 3 (reopen) Disabling GPU acceleration event?
Default mode: OpenGL mode: System (laggy) mode: System (still laggy) Yes, between cycles 1 and 2
-cef-force-gpu mode: OpenGL mode: OpenGL mode: OpenGL No

Since the regression turns hardware compositing off and the flag prevents that, the most plausible interpretation is that BPM teardown trips the runtime feature-disable path, and -cef-force-gpu overrides it (or at least overrides the parts of it that gate mode: OpenGL window creation). Either way, this is a strong signal that the right place to fix the bug is whichever heuristic in steamwebhelper's GPU process management decides to flip GPU off after BPM tear-down.

Note: a ~/.steam/steam/steam_dev.cfg with @cef_command_line_args … was tested and produced no observable change — the only Steam-recognized GPU-related switches in this build are the seven -cef-* flags hard-coded into the Steam launcher binary (-cef-disable-gpu, -cef-disable-gpu-sandbox, -cef-disable-sandbox, -cef-disable-seccomp-sandbox, -cef-force-accessibility, -cef-force-gpu, -no-cef-sandbox). There does not appear to be a generic CEF command-line passthrough exposed in the public Steam Linux build.

Restarting Steam without the flag is also a valid workaround, but only on a per-cycle basis.

Useful files I can attach if needed

  • ~/.steam/debian-installation/logs/webhelper.txt (and .previous.txt) — BPM window create/destroy lifecycle, mode changes
  • ~/.steam/debian-installation/logs/webhelper_gpu.txtDisabling GPU acceleration: Disabled/RuntimeDetect events, full GPU info report
  • ~/.steam/debian-installation/logs/webhelper_js.txt
  • ~/.steam/debian-installation/logs/cef_log.txt — CEF/Chromium internals, Returning a speculative frame warnings during BPM reopens
  • ~/.steam/debian-installation/logs/console-linux.txt
  • ~/.steam/debian-installation/logs/controller_ui.txt

I'd be happy to capture a fresh trace with steamwebhelper started under --enable-logging --vmodule=*gpu*=2,*compositor*=2 (or whatever flag set you'd like) — just let me know.

Pphilippthiele 2026-06-01 github

Update: the -cef-force-gpu workaround I posted earlier turns out not to fix this on a fresh boot. CEF still hits Disabling GPU acceleration: Disabled/RuntimeDetect after the first BPM close, and BPM cycle 2 still falls back to mode:
▎ System. Reproduced on the same machine after a reboot, with -cef-force-gpu confirmed in argv (the steamwebhelper child shows --ignore-gpu-blocklist as expected).

▎ Concrete log timeline from this attempt:

▎ 18:49:41 GPU process started: start count: 0
▎ 18:49:49 SP BPM_uid0: Created window … mode: OpenGL ← cycle 1
▎ 18:51:18 SP BPM_uid0-'Steam Big ': Applying safe browser shutdown workaround
▎ 18:51:43 Disabling GPU acceleration: Disabled/RuntimeDetect ← fires anyway
▎ 18:52:12 SP BPM_uid0: Created window … mode: System ← cycle 2, laggy

▎ So the runtime feature-disable path is independent of the static GPU blocklist that --ignore-gpu-blocklist controls. The RuntimeDetect code path itself is what needs investigating — it disables GPU acceleration without logging a
▎ reason. The only working workaround on Linux remains a full Steam restart between BPM uses.

Nothing extracted yet.