pub struct FramePacing {
pub now: FrameTime,
pub interval: Duration,
pub requested_interval: Option<Duration>,
}Expand description
The per-frame pacing context a shell hands to FrameGate::decide_paced:
this tick’s frame clock, the active theme’s paced-loop cap, and whatever
interval the previous paint’s paced request asked for.
All three are shell-owned: now is the platform frame clock
(Choreographer / CADisplayLink timestamp — never a wall clock read inside
frust-core), interval is 1 / MotionScheme::cosmetic_loop_rate resolved from the active theme each
frame (so an app that retunes the token via ThemeBuilder re-paces live),
and requested_interval is the previous paint’s
latched PaintOutcome::paced_interval. effective_interval
folds the last two into the one interval this tick actually paces at.
Fields§
§now: FrameTimeThis tick’s shell frame-clock reading. Only differences of two
FrameTimes from the same shell carry meaning (see FrameTime).
interval: DurationThe theme’s paced-loop cap: 1 / cosmetic_loop_rate from the active
theme, and so the shortest interval any paced (CosmeticLoop) frame
may be produced at. CosmeticLoopRate clamps its rate up to
FLOOR_HZ (10Hz), so this is never longer than 100ms.
requested_interval: Option<Duration>The tightest interval the previous paint’s paced requests named
(frust_core::PaintOutcome::paced_interval, latched by the shell beside
FrameInputs::last_needs_frame_paced_only), or None when that paint
named none.
None and Some(Duration::ZERO) both mean “at the theme’s own rate” —
a bare PaintCtx::request_frame_paced folds ZERO into the core-side
MIN-lattice — so both resolve to interval. A longer
value (a ~500ms caret blink against a 30Hz shimmer cap) paces that loop
slower than the theme’s own cadence; see
effective_interval.
Implementations§
Source§impl FramePacing
impl FramePacing
Sourcepub fn effective_interval(&self) -> Duration
pub fn effective_interval(&self) -> Duration
The interval this tick actually paces at: the longer of the theme’s
cap (interval) and the previous paint’s requested
interval (requested_interval).
The two-sided contract behind that max (the core-side half lives on
PaintCtx::request_frame_paced_at):
- The MIN fold already happened in core. Every paced request in a
paint pass folds to the tightest interval there, so this sees one
value: the fastest cadence anything onscreen asked for. A 30Hz shimmer
beside a 2Hz caret arrives here as
ZERO(the shimmer’s bare request) and paces at 30Hz — the caret is simply repainted more often than it needs, which is invisible and costs no frame the shimmer wasn’t already forcing. A slow request can never starve a fast one. - The theme rate is a ceiling.
cosmetic_loop_ratecaps decorative motion for battery’s sake, so a request tighter than the cap is clamped up to it rather than honored. Motion that must land every vsync is not cosmetic — it belongs toTickClass::Transition, which is never paced at all.