pub(crate) fn wayland_encode_loop<B: WlPayload>(
pool: &WlFramePool<B>,
cfg: WlEncodeConfig,
) -> Option<FrameEncoder>Expand description
Encode-thread body for the Wayland captures: drain published frames and run the full encode dispatch, driving the encoders for the life of the capture.
Driving the encoders on this one thread is what lets the calloop overlap the next render
with this encode — the same capture‖encode split used on X11, minus the renderer, which is
genuinely calloop-affine (EGL/GBM/dmabuf and the pixman targets). A readback path’s
encoders are created, driven, and dropped here; a zero-copy session is opened by the
calloop and driven here on the GPU buffers it composites into (ZeroCopySession). Each
published frame is processed in order so the H.264 reference chain stays contiguous:
- Apply cross-thread changes: live tunables and rate/VBV/fps updates are read here, on the
thread that drives the encoders (each
Acquireswap pairs with the command handler’sReleasestore, so a payload is never seen half-applied). The IDR request is swapped as late as possible, so a request that arrived while this frame was in flight is honored one pipeline stage earlier than the next publish. - Dispatch by encoder: a full-frame session runs
decide_hw_fullframe, then hands only the frames actually being encoded to it (WlPayload::encode): a zero-copy session’s GPU buffer in place, or the packed rows as they are (RGBA vs BGRA source chosen by the renderer) — NVENC uploads and converts in hardware, a VA-API session uploads and converts on the GPU, a software session converts on its encode threads; otherwiseencode_cpuruns the CPU path with compositor damage — striped JPEG, or H.264 through the build’s software encoder. The software H.264 path keeps an infinite GOP, forcing an IDR only on an explicit request or the configured interval, and an explicit request also forces a full JPEG resend for joiners. - Recycle then deliver: the capture buffer is recycled BEFORE delivery so a slow consumer
never pins one, then the stripes go to the delivery thread through a single-slot
sendwhose blocking is the backpressure that overlaps delivery with the next render + encode.
A zero-copy session that keeps failing is rebuilt once, as a readback one is; one that
cannot be ends the thread, and the calloop demotes the capture to a readback path. On exit
a readback hardware session is handed back to the calloop so a restart can reuse it in
place when the new settings stay compatible (a plain StopCapture just drops it); a
zero-copy one stays in its ZeroCopySession.