Skip to main content

ScanoutBackend

Struct ScanoutBackend 

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

One output, one layer, and everything between a producer and the screen.

Discovers the output, reads the driver’s profile, negotiates a modifier against what the CRTC’s planes can scan out, asks the producer for a buffer in one of them, and drives a single-layer scene over it. What is left for the caller is rendering and pacing.

The backend does not dispatch the page-flip event, for the reason DumbScanoutSink does not: the scene deliberately has no commit() of its own, so the caller drives its own PageFlip and calls flip_landed.

§Teardown

Dropping the backend while a flip it armed is still outstanding waits, up to 100 ms, for the CRTC’s vblank sequence to move past that commit or for its flip event to be queued, before the scene lets go of its buffers. On a CRTC with no vblank counter the queued event is the only thing it waits on. It never reads the event queue, so the event stays queued for the caller. Dispatching it and calling flip_landed first means there is nothing to wait for. The device must outlive the backend: the wait polls it.

Implementations§

Source§

impl ScanoutBackend

Source

pub fn create( device: &Device, producer: &mut dyn ScanoutProducer, config: &Config, ) -> Result<Self, PresentError>

Discover an output and build everything needed to present on it.

§Errors

PresentError::Bind if no output can be found, the driver or the planes cannot be probed, or the producer cannot allocate.

Source

pub fn present( &mut self, device: &Device, flags: AtomicCommitFlags, out_fence: Option<&mut Option<OwnedFd>>, ) -> Result<CommitReport, PresentError>

Present one frame.

out_fence receives this commit’s OUT_FENCE where the CRTC exposes OUT_FENCE_PTR — it signals once the frame is on screen, which is what a producer waits on rather than blocking the CPU until the flip event.

§Errors

PresentError::Bind if the mode cannot be learned for the first, modesetting frame; PresentError::Build if the scene cannot build the frame; PresentError::Commit if the kernel refuses it.

Source

pub fn present_if_changed( &mut self, device: &Device, content_changed: bool, flags: AtomicCommitFlags, out_fence: Option<&mut Option<OwnedFd>>, ) -> Result<CommitReport, PresentError>

Present only if the content changed, suppressing an idle frame.

The first frame always commits, whatever content_changed says: nothing is on screen yet, so “unchanged” describes nothing, and a suppressed first frame leaves the scanout contents undefined.

A suppressed frame returns a report with skipped_idle set and every other field zero — there was no commit to count.

§Errors

As present.

Source

pub const fn set_vrr(&mut self, enable: bool)

Ask for variable refresh, or stop asking, from the next frame.

A no-op on a CRTC that exposes no VRR_ENABLED.

Source

pub const fn vrr_capable(&self) -> bool

Whether the discovered output can do variable refresh.

Source

pub const fn force_full_present(&mut self)

Make the next frame a full commit, whatever the economy would decide.

Source

pub const fn frames_committed(&self) -> u64

How many frames were sent for commit.

Counted when the frame is decided, before it is built: a frame whose mode could not be learned, that the scene could not build, or that the kernel refused is counted all the same.

Source

pub const fn frames_skipped(&self) -> u64

How many frames were suppressed as idle.

Source

pub const fn target(&self) -> &ScanoutTarget

The output this backend found.

Source

pub const fn profile(&self) -> &DriverProfile

The driver’s capabilities, as probed.

Source

pub fn modifiers(&self) -> &[u64]

The negotiated modifiers, most preferred first.

Empty when the backend fell back to LINEAR – no plane advertised IN_FORMATS, or none of them took a layout the producer could make – and the producer was allowed LINEAR alone.

Source

pub const fn scene(&self) -> &LayerScene

The scene, for a caller adding layers of its own.

Source

pub const fn scene_mut(&mut self) -> &mut LayerScene

The scene, mutably.

Source

pub const fn layer(&self) -> LayerHandle

The layer the producer’s buffer is presented on.

Source

pub fn flip_landed(&mut self)

Tell the scene the flip it armed has landed.

Until this is called the scene believes a flip is outstanding, which is what keeps teardown from releasing a buffer the display engine is still reading — invariant 5.

Trait Implementations§

Source§

impl Debug for ScanoutBackend

Source§

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

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

impl Drop for ScanoutBackend

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. 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.