Skip to content

~70 ms main-thread stalls: Steam integration during some online-match replays, and the open WebUI menu #7

Description

@topochico6969

FnQL: 0.1.0.94 (318b5e3), MSVC Win32 client, under Proton (proton-cachyos 11, winewayland), Vulkan renderer.
Hardware: i5-8600K, RTX 4060 Ti (NVIDIA 615.71.09), KDE Plasma 6.7.5 Wayland, 240 Hz VRR.
Settings: com_maxfps 250, com_yieldCPU 0, r_swapInterval 0.

All numbers are MangoHud per-frame logs, 60 s per run, from demo replays at 250 fps.

1. Steam integration: ~70 ms stalls in a replay of a busy public CA match

The demo was recorded by FnQL itself (.dm_68) from a public CA match.

config stalls >15 ms / min worst frame
Steam on, WebUI disabled (3 runs) 1-3 69-73 ms
Steam on, WebUI on with browser hidden (2 runs) 3-5 71-72 ms
+set com_steamIntegration 0 (2 runs) 0 4.5 / 6.1 ms

What the profile shows:

  • Nothing is rendered during a stall. A user-space perf profile of the main thread shows no driver or Vulkan samples for the ~70 ms.
  • The thread is waiting on Steam IPC. Most of the stall is spent off-CPU in short waits. The samples that do land are in steamclient.so / lsteamclient.dll (including poll), in engine code, and in libc.

The exact call is unconfirmed because the provider is closed source. My suspect is CL_RegisterSteamAvatarShader. It calls FNQL_Steam_GetAvatarRGBA twice synchronously (cl_webui.cpp:1157 and :1173) for LARGE avatars, is reached from the cgame's CG_QL_IMPORT_GET_AVATAR_IMAGE_HANDLE, and then calls RegisterShaderFromRGBA on the main thread.

The stalls did not reproduce on two retail-recorded (.dm_91) demos: a 3v3 CA match and a public CTF match. So the trigger looks match-specific; it might be players joining or changing, which forces avatar fetches. Retail QL was stall-free on those same two demos too, but it can't play the .dm_68 demo, so I have no retail control for the stall case.

Suggested fixes:

  • Fetch avatars asynchronously or on a worker thread, and upload the texture on a later frame.
  • Or prefetch avatars when a player connects.
  • Or use smaller avatars in-game.

2. An open WebUI main menu stalls the engine

While the web main menu is visible, I see two things:

  • Spikes: ~7.7 ms frames in ~4 s bursts every 10 s (about 85 per minute). They're in phase with awesomium_process CPU bursts, probably the friends list refresh.
  • Stalls: 54-78 ms frames several times a minute, even with com_steamIntegration 0.

Hiding the browser clears both in-game. The same replay with the browser hidden had 0 stalls, max 5.9 ms.

The menu also stays up in a way users are likely to hit. After demo <name> from the console, the web main menu stays over the playing demo and togglemenu doesn't close it. Only web_hideBrowser does, which is what the menu's "You are currently in-game. Click here to return to your match" bar calls.

3. com_speeds rf/bk always read 0 on the Vulkan renderer

ri.Milliseconds is CL_ScaledMilliseconds(), which returns the per-frame cls.realtime (cl_main.cpp:4661). Every renderer-internal delta is therefore 0, and all render, acquire and present time lands in cl.

Notes

  • Source line numbers refer to master e24b4df. The tested build was 0.1.0.94.
  • Tested under Proton. The synchronous call path is the same on every platform, but the Steam IPC route under Proton (steam_api.dll -> lsteamclient -> Linux steamclient.so) likely makes each stall longer than on native Windows.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions