Skip to main content

ReleaseQueue

Struct ReleaseQueue 

Source
pub struct ReleaseQueue { /* private fields */ }
Expand description

The two-deep ring of in-flight acquisitions.

§Invariant 1: release after the flip, not after the ioctl

A buffer goes back to its source only once the page flip that stops scanning it out has completed — two commits deep, never when commit’s ioctl returns. Releasing at ioctl return would let a producer overwrite a buffer the display engine is still reading, which tears on hardware whose producer driver attaches no reservation fence.

Three generations are tracked:

GenerationFrameState
currentNjust committed, about to be scanned out
previousN-1on screen; the flip for N displaces it
two_agoN-2off screen — safe to return

A successful commit returns two_ago, then rotates. That is the whole mechanism.

§Why this is not the scene’s own field

The queue never calls a source. It yields the buffers to hand back and lets the caller route each to the right source, because a source is owned by its layer and the queue has no business borrowing the layer table. It also means the entire contract is testable with no device, no source, and no kernel — which is what these tests do.

Implementations§

Source§

impl ReleaseQueue

Source

pub const fn new() -> Self

An empty queue.

Source

pub fn in_flight(&self) -> usize

How many buffers are held in flight.

Source

pub fn is_empty(&self) -> bool

Whether any buffer is held.

Source

pub fn commit_succeeded<F>( &mut self, current: Vec<Acquisition>, release_fence: Option<&SyncFence>, wants_fence: F, ) -> Released
where F: FnMut(LayerId) -> bool,

Record a successful real commit and return the buffers it retired.

Invariant 1. The returned buffers are frame N-2’s: the flip just armed displaces frame N-1, so N-2 is what has finished scanning out. Frame N’s buffers stay held.

release_fence is this commit’s OUT_FENCE. It signals when the buffers currently on screen — frame N-1 — leave it, so it is stamped onto those and rides down to be handed back next rotation. A source that wants it can then wait GPU-side instead of blocking the CPU until the later release edge.

wants_fence decides per layer whether to stamp, so a scene with no interested source pays nothing.

Source

pub fn release_displaced(&mut self) -> Released

Return frame N-2’s buffers now, ahead of the next commit.

Only sound once the flip of the most recent real commit has completed: that flip is what took them off screen. FrameLifecycle gates it on the commit’s sequence for that reason; see LayerScene::release_displaced.

Source

pub fn commit_failed(&mut self, current: Vec<Acquisition>) -> Released

Record a failed commit and return this frame’s buffers at once.

Invariant 2. No flip is in flight to gate them on, so deferring would just stall the source’s ring. Self-healing producer rings depend on reusing their buffers immediately after a rejection; the dropped frame heals on the next one.

The in-flight generations are not disturbed: the previous commit’s buffers are still on screen, and a failed commit did not displace them.

Source

pub fn test_committed(&mut self, current: Vec<Acquisition>) -> Released

Record a test commit and return its buffers at once.

A TEST_ONLY applies nothing to hardware, so nothing in the scanout pipeline references these buffers and deferring would only stall the ring. Distinguished from commit_failed because the caller reports them differently, not because the buffers are handled differently.

Source

pub fn drain(&mut self) -> Released

Return everything held, oldest first.

Invariant 5’s counterpart. For teardown, session pause, and rebind — paths where no flip is in flight, so holding buffers back from their sources would simply leak them.

This does not wait on the kernel and must not: the scene’s drop stays non-blocking, and landing an armed flip first is the caller’s job. See ScenePendingFlip.

Trait Implementations§

Source§

impl Debug for ReleaseQueue

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for ReleaseQueue

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.