ReadbackSlot

A QRhiReadbackResult that lives as long as the QRhi holds it.

In the namespace rhi. Declared in src/libs/librhi/rhi/ReadbackSlot.hpp.

Detailed description

QRhi keeps a raw pointer to every QRhiReadbackResult handed to readBackTexture() or readBackBuffer() until the readback completes. On a good offscreen frame that is inside endOffscreenFrame(). On a LOST frame endOffscreenFrame() returns before the drain, the pointer stays in the backend's active list, and the next thing that drains it is QRhi::destroy(): it resizes the result's data, copies the staging buffer into it and calls its completion callback. A result on the stack of the function that rendered the lost frame is long gone by then, so the copy lands in whatever that stack holds now. That is the crash the owner met on 2026-09-06: a device loss while loading a scene, the worker host rebuilding its device, and a megabyte of viewport pixels written over the worker thread's stack. QRhi has no way to cancel a pending readback, so the result has to outlive the device instead.

The slot is heap-owned and its completion callback captures the owning shared_ptr. The backend copies that callback into its own list before invoking it, so the slot stays alive until the backend is done with it whatever the caller's frame did in between, and the self-reference is dropped when the callback runs. A caller keeps its own shared_ptr for the frame and reads `result` after endOffscreenFrame() as before.

Backends that execute readbacks synchronously (OpenGL, Null) call the callback inside the batch, and the slot simply outlives nothing.

In this section