Hi,
I’d like to propose an improvement to WindowThumbnail (the QML type behind the Overview
and Window View thumbnails).
The current implementation allocates the thumbnail render target from the source window
geometry, even when the consumer displays the thumbnail at a substantially smaller size.
I believe the API could allow consumers to provide their required target resolution
instead.
This would be backward-compatible: the default could remain the current full-resolution
behavior.
1. Observed behavior
My setup has two native 3840×2160 displays and an RX 7900 XTX (24 GiB).
The LLM permanently occupies 22,180,327,424 bytes (~20.66 GiB) of VRAM. This leaves ~5.1 GiB for everything else. In normal operation, roughly 4.2 GiB of that is already in use, leaving only ~0.9 GiB free before transient allocations.
With 0.5 s sampling of the AMDGPU TTM counters over 31,500+ samples:
- Opening Overview produces a +0.5 to +0.8 GiB VRAM spike in under one second
(+0.52, +0.76 and +0.76 GiB in three measurements). - Free VRAM fell from roughly 1 GiB to as low as 0.23 GiB.
- The allocation is released after closing Overview, returning to baseline within 2–15
seconds.
During several incidents, this coincided with or was followed by GPU memory allocation
failures, GL context losses and, in one case, a GPU reset and complete session crash.
The important point is that this is not a suspected leak. It is a large transient
working-set allocation which becomes problematic when the system is already close to the
VRAM limit.
2. Source-level explanation
I checked KWin 6.7.4 (commit 8438567a). In src/scripting/windowthumbnailitem.cpp,
WindowThumbnailSource::update() contains:
const QRectF geometry = m_handle->visibleGeometry();
const qreal devicePixelRatio = m_view->devicePixelRatio();
const QSize textureSize = geometry.toAlignedRect().size() * devicePixelRatio;
if (!m_offscreenTexture || m_offscreenTexture->size() != textureSize) {
m_offscreenTexture = GLTexture::allocate(GL_RGBA8, textureSize);
...
}
Thus, for a 3840×2160 window at DPR 1, the thumbnail render target is a 3840×2160 RGBA8
texture:
3840 × 2160 × 4 = 33,177,600 bytes = 31.6 MiB per window.
The QML thumbnail can subsequently be displayed at a much smaller size; the source
texture itself remains full resolution.
Overview creates thumbnail items for the windows included by its model/delegate, in
addition to its own offscreen scene and other rendering resources.
3. The architectural issue
The source geometry and the target geometry are currently conflated.
WindowThumbnail knows the geometry of the window being rendered, so it uses that
geometry to determine the render-target size. But the consumer knows something
WindowThumbnail does not: how large the thumbnail actually needs to be for
presentation.
In Overview, that size is a consequence of the layout it computes:
- screen geometry;
- number of windows;
- grid layout and spacing;
- thumbnail size;
- view scale;
- required zoom range.
For example, if Overview lays out a thumbnail at 800×450 and wants it to remain sharp up
to 2× zoom, a target around 1600×900 could be sufficient. There is no reason for the
render target to remain 3840×2160 unless the presentation actually requires that
resolution.
The current API provides no way for Overview to communicate this requirement to
WindowThumbnail.
This is not necessarily an Overview-specific problem either: other consumers such as
Window View, Tab Box or scripts may have their own known presentation size.
4. Proposed direction
I would like to request an optional consumer-provided target size or render scale for
WindowThumbnail.
The important part is the separation between:
source window geometry 3840×2160
consumer's required target 1600×900
The target could then be determined approximately as:
consumer's layout
↓
required displayed size
↓
optional zoom headroom
↓
preserve source aspect ratio
↓
clamp to source size
↓
allocate render target
For example:
Overview layout: 800×450
Required zoom: 2×
↓
Thumbnail target: 1600×900
↓
WindowThumbnail
The exact API is deliberately open. It could be a targetSize property, a render scale,
or something internal to WindowThumbnailSource. The important requirement is simply
that the consumer should be able to communicate its rendering requirement instead of
forcing the thumbnail renderer to use the source window resolution.
The potential memory reduction is substantial. For a 4K window:
- 3840×2160 RGBA8: 31.6 MiB
- 1920×1080 RGBA8: 7.9 MiB
- 960×540 RGBA8: 2.0 MiB
So a 960×540 target would reduce the thumbnail render-target allocation by roughly 16×
per window.
The default behavior could remain unchanged, preserving full-resolution thumbnails for
consumers that need them.
5. Why this seems useful
This would allow consumers to make an explicit quality/memory trade-off instead of
having that decision implicitly determined by the source window size.
In particular, Overview could calculate its target from the actual layout it has
produced and the amount of zoom for which it wants thumbnails to remain sharp.
On systems with abundant VRAM, nothing would change.
On systems operating close to the VRAM limit, the same Overview could avoid allocating
hundreds of MiB of transient full-resolution thumbnail targets when much smaller targets
would satisfy the actual presentation requirements.
I am deliberately leaving compression and persistent thumbnail caching out of scope;
target-resolution rendering seems like the simpler and more direct abstraction.
To be precise about the evidence: the KWin source explains the observed allocation
mechanism and its order of magnitude. I am still verifying the exact attribution of the
~0.8 GiB TTM delta using AMDGPU BO data, so I do not want to claim that the entire
measured delta consists exclusively of these thumbnail textures.
There may also be a better architectural approach than the one described above. I don’t
have the KWin development expertise to implement the change myself, so I would
particularly appreciate feedback from the KWin developers on whether this separation
between source geometry and consumer-required target resolution makes sense, and what
API or implementation approach would fit the existing rendering architecture.
Environment: Plasma 6.7.4, KWin v6.7.4 (8438567a), kernel 7.2, Mesa 26.x, RX 7900 XTX.
I can provide the measurement data, raw CSV, journal excerpts and source references if useful.