Skip to main content

PresentMode

Enum PresentMode 

Source
pub enum PresentMode {
    Immediate,
    Vsync,
}
Expand description

When a queued flip actually reaches the panel.

A real trade, not a quality setting. Which way it should go depends on what is on the screen, and the default here is chosen for the kind of thing Denise is built for rather than for the kind of thing a compositor is built for.

Variants§

§

Immediate

Flip immediately, part-way through a scan-out if necessary. Tears.

The default, and measured on a Pi 3 A+ driving 1920x1080 the reason is plain: waiting for vblank costs about 17 ms of latency and was described by the person operating it as lagging several milliseconds behind the whole time. Flipping immediately removes that wait entirely.

The cost is a horizontal seam where the panel switched buffers mid-frame. With damage tracking most updates are a few thousand pixels, so the seam is small, brief and in practice invisible — a control panel redrawing a button is nothing like a compositor scrolling a window.

This used to say “reconsider for signage or anything with large fast-moving content, where a tear crosses something worth looking at”. A scrolling viewport turned out to be exactly that, and the flicker was reported from a Pi within a day of the gallery gaining one. So the mode is no longer a promise about every frame: a frame whose damage covers a quarter of the screen’s rows or more flips at vblank anyway, and this asks for async flips on the frames where the seam is short and the latency is felt. See flip_flags_for, including why it counts rows rather than pixels, and why it counts the rows covered rather than the rows spanned.

Requires DRM_CAP_ASYNC_PAGE_FLIP; drivers without it fall back to PresentMode::Vsync, and DrmSurface::present_mode reports what was actually obtained.

This mode paces the caller only on its large frames. See DrmSurface.

§

Vsync

Flip at the next vblank. Never tears.

A flip queued just after a vblank cannot land before the next one, so this costs on the order of one refresh period — about 17 ms at 60 Hz. Every tear-free system pays it.

In exchange, Surface::acquire blocks until the flip retires, so the display paces the render loop for free and an application needs no frame timing of its own.

Trait Implementations§

Source§

impl Clone for PresentMode

Source§

fn clone(&self) -> PresentMode

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for PresentMode

Source§

impl Debug for PresentMode

Source§

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

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

impl Default for PresentMode

Source§

fn default() -> PresentMode

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

impl Eq for PresentMode

Source§

impl PartialEq for PresentMode

Source§

fn eq(&self, other: &PresentMode) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for PresentMode

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.