Consumer-driven target resolution for WindowThumbnail to reduce transient VRAM usage in Overview

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.

Correction: the 2× zoom example in the original post is incorrect — Overview doesn’t currently have thumbnail zoom. Please disregard that part.

The actual proposal is simply to let the consumer specify the required thumbnail resolution, rather than always allocating at the source window’s full resolution. The VRAM measurements and the rest of the proposal are independent of the zoom example.

I’d have corrected the post, but somehow I can’t edit it…? Anyway! sorry for the clutter.

That would be fine, indeed we can lower the allocation, we need to resize the origin texture anyway.

Instead of a AI-generated, would be contribution, block of text on discuss, you could ask your LLM to make a MR and test it, check it matches the coding style and convention of kwin and have a short description. This didn’t need as much text to describe the issue and the solution proposed at least not for KDE/KWin developers.

You will need at least two commits at the WindowThumbnail API to have a targetSize and one to have WindowThumbnail users use it.

Very low are the chances any-one will take suggestions on discuss and enact them. Contributors do what they want. Of course Bugs are more important.

2 Likes

Thank you for your response.

I have little technical background, aside from being somewhat familiar with Linux and using KDE, so proposing a fix is beyond my personal capabilities. The same limitations also prevent me from having much confidence when it comes to presenting a problem and an associated feature request, let alone determining whether it is pertinent enough, consistent with current development options, or whether the solution I am suggesting is actually appropriate.

I understand in broad strokes where the transient KDE video-memory spikes I described come from, after looking into the issue with my little local model, but I have no firm confidence in the LLM’s assessment or the options it proposed, as the excessive verbosity of the proposal probably made clear.

That’s by way of a disclaimer, and to explain my personal circumstances.

I’ve read with interest the post you attached to your message, and it was useful in understanding how things are actually done and how to manage expectations when reporting a bug or requesting a feature. I shall adjust my expectations accordingly.

As for the proposed actionable steps, specifically:

ask your LLM to make a MR and test it, check it matches the coding style and convention of kwin and have a short description.

I work with a small, local model, and I fear this may be beyond its capabilities. I have never touched code directly, aside from a very timid “Hello, World!”-like endeavour years ago. I can try to follow through with the steps you’re suggesting and see if something useful emerges. I’ll see whether it’s worth the endeavour, which is a bit daunting for me, to be perfectly honest, and perhaps eventually submit something for your consideration.

Thank you once again for your time. I’m also grateful for the work you put into this open-source project.