From 4d1c5acf5748b9a9b9b40cfb6ee1118593bacecd Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Thu, 29 Oct 2026 12:12:35 +0100 Subject: sound: drop the OSD's canvas grain, it broke Qt's garbage collector The desktop shell's recurring 100% CPU spin is a Qt bug set off by the volume OSD. Its grain Canvas called createImageData on every paint, and Qt 6.11 subtracts that pixel buffer from the V4 unmanaged-heap counter without having added it. The first GC after an OSD show wrapped the size_t counter, and from then on every JS allocation ran a full GC until a restart. The OSD shows on volume keys, track changes and resume, which is why the spin followed all three. Found by running each always-on unit of the desktop in its own qs with GC stats: only the sound module wrapped, 3 s after a resume, and a volume nudge reproduced it on demand. Qt's qml tool with a bare Canvas confirms it is createImageData alone: 17,856 of 17,856 GCs wrapped, the same canvas drawing with fillRect 0 of 5. With the grain removed, 8 OSD shows under forced GCs left the counter intact. The grain was alpha 14/255, so the OSD looks nearly the same. vram.sh's comment blamed the fdinfo parse for the underflow; corrected, and the lesson is in AGENTS.md. Co-Authored-By: Claude Opus 5.5 --- desktop/modules/perf/vram.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'desktop/modules/perf') diff --git a/desktop/modules/perf/vram.sh b/desktop/modules/perf/vram.sh index 8ba61fb..83db27d 100755 --- a/desktop/modules/perf/vram.sh +++ b/desktop/modules/perf/vram.sh @@ -17,9 +17,9 @@ # instead of scanning, for test_vram.sh. # # Summed here rather than in JS: a process holding thousands of DRM fds -# makes the scan a few hundred KB, and parsing that in QML every 2 s drove -# Qt's unmanaged-heap counter to underflow, after which the V4 engine ran a -# GC on every allocation and the shell sat at 100% CPU (AGENTS.md). +# makes the scan a few hundred KB, which is a lot of string churn to parse +# in QML every 2 s. It was moved here while chasing a GC underflow that +# turned out to be the sound OSD's createImageData (AGENTS.md), not this. # # Fds of a repeated client id with different values: the first one awk's # for-in reaches counts, where Perf.js took the first in scan order. They -- cgit v1.2.3