pub struct FrameTap { /* private fields */ }Expand description
A persistent offscreen target plus readback buffer, built once and reused for every frame of a sustained tap.
The difference from the rest of this file is lifetime, not stage. Every other
capture entry point builds its target and buffer per call — right for QA
tooling that takes one frame, and wrong for a source that takes 864,000 of
them, where per-frame texture and buffer creation is GPU allocation inside
the loop. capture_stream already reuses its pair, but only for the length
of one fixed-dt, one-preset run it drives itself; this type hands that
reuse to a caller who owns the loop.
§One frame in flight, and a wait only when the GPU is behind
The cycle is the preview readback’s, three steps across two frames: take the previous submission’s map, record this frame’s copy into the freed buffer, and arm the map after the submission. So a caller sees frame N while frame N+1 is being drawn, and the very first call yields nothing at all.
The take waits when the previous map has not landed
(take_previous). That wait is the only backpressure
a windowless loop has: the window is held to the GPU’s pace by the
swapchain, and nothing holds a tap to it but this. Without it, an adapter
whose frame costs more GPU time than the caller’s loop costs CPU time queues
submissions without bound, the one map in flight lands only behind all of
them, and nearly every frame drawn meanwhile is never copied out. On an
adapter that keeps up, the map has landed by the next call and nothing
waits.
The buffer cannot be re-recorded while it is mapped, which is why the take comes before the record: a second copy into a mapped buffer is a validation error, not a dropped frame.
Sized at construction and never resized. record_copy’s extent, the
buffer’s length and padded_bpr are all fixed against width×height, so a
renderer that resizes underneath a live tap needs a new one — open_tap
is the only thing that sets these.
Implementations§
Source§impl FrameTap
impl FrameTap
Sourcepub fn times_passes(&self) -> bool
pub fn times_passes(&self) -> bool
Whether this tap can report per-pass GPU costs at all. false on an
adapter without TIMESTAMP_QUERY — the software rasterizers — where a
caller says so once rather than printing an empty table every window.
Sourcepub fn pass_costs(&self) -> &PassCosts
pub fn pass_costs(&self) -> &PassCosts
What every labelled pass has cost since the last reset.
Sourcepub fn reset_pass_costs(&mut self)
pub fn reset_pass_costs(&mut self)
Start a fresh measurement window, so each report covers the interval since the last one rather than the whole run to date.