mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-10-25 16:21:51 +00:00
The CPU fallback moved a scanout four times: the producer packed it, the kernel carried it, next_raw allocated and zeroed a fresh buffer to read it into, and the consumer copied that into the slot. At 4K30 the last two are about 8 GB/s of memory traffic that does nothing. next_raw_into reads the body straight into a buffer the caller owns, so the kernel copy lands where the frame is going to live, and resize costs nothing once a buffer has seen one frame of that size. The frame buffers then circulate instead of being freed and reallocated: whatever a new frame displaces goes back on offer, both when the encoder consumes one and when a frame is superseded before anyone reads it. The dma-buf path still copies once, because the convert output is borrowed from the render context and only lives until the next convert, but it copies into a recycled buffer and does it outside the slot lock, so a multi-megabyte memcpy no longer holds the encoder off the slot. Steady state is now one allocation for the whole session on both paths, and the CPU path carries the pixels twice instead of four times. The cursor body reads into its own buffer and is moved into the cursor cache rather than copied; it is small and rare, so it stays out of the frame recycler. Two tests: the raw body round trip now also covers a shorter body reusing the buffer, so a stale tail cannot survive into it, and a new test asserts the frame buffers circulate by allocation identity rather than by inspection. 100 tests pass, both configs build.