You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
macOS: CpuFrames reuses one CVPixelBuffer, and only the per-frame GPU sync makes that safe #586
mac_frames::CpuFrames keeps a singleCVPixelBufferRef and rewrites it for every decoded frame (ensure_pixel_buffer only reallocates when the dimensions change). The compositor then wraps that buffer as Metal textures and reads it.
This is correct today, but for a reason that is nowhere written down next to it: Compositor::rgb_to_nv12 ends with self.sync(), a full waitUntilCompleted on every frame. By the time the decoder overwrites the buffer for frame N+1, the GPU has finished reading it for frame N.
So the synchronisation that costs 40 % of the export's wall clock (gpu.wait, 7.5 s of an 18.7 s walk — see #583's profile) is also the only thing preventing a data race.
Why this matters now: the obvious next optimisation is to stop waiting per frame and let the GPU run one or more frames behind. Anyone who does that reintroduces exactly the bug 18eb7fdf ("do not reuse memory the encoder is still reading") fixed on Linux — except here it is the decoder's buffer being overwritten under the GPU, and it will show up as intermittent tearing or a frame from the wrong time, not as a crash.
Two things worth doing, independent of whether anyone pipelines:
Write the invariant down in CpuFrames, pointing at the sync() that upholds it.
Give CpuFrames a ring of pixel buffers deep enough for the frames in flight, so the invariant stops depending on a sync() in a different file.
Note this only affects the software-decode path — which, since #583, is the default for H.264 8-bit exports, so it is now the common path rather than the rare one.
Moved into technical-documentation/engineering/rendering-performance.md (#594), as a subsection of the new macOS chapter: The single reused CVPixelBuffer, and what makes it safe.
The invariant spans two files — the buffer is in mac_frames.rs, the waitUntilCompleted that makes reusing it safe is in compositor_macos.rs — and neither one states it. An issue is the wrong home for that: nobody about to pipeline the GPU reads the tracker first. It now sits beside the measurement showing that same wait costs 40 % of the walk, which is exactly the temptation it guards against.
Activity
EtienneLescot commentedon Sep 4, 2026
Moved into
technical-documentation/engineering/rendering-performance.md(#594), as a subsection of the new macOS chapter: The single reusedCVPixelBuffer, and what makes it safe.The invariant spans two files — the buffer is in
mac_frames.rs, thewaitUntilCompletedthat makes reusing it safe is incompositor_macos.rs— and neither one states it. An issue is the wrong home for that: nobody about to pipeline the GPU reads the tracker first. It now sits beside the measurement showing that same wait costs 40 % of the walk, which is exactly the temptation it guards against.