Skip to main content

CompositeCanvas

Struct CompositeCanvas 

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

A double-buffered software composition surface.

Owns two dumb buffers in the canvas format – ARGB8888 unless made with create_in – and alternates between them: the CPU paints the back while the kernel scans out the front. A single buffer tears visibly — the scanout reads the same memory the CPU is writing, so a horizontal seam appears wherever it caught a half-painted frame. The cost is one extra canvas-sized allocation: 3 MB at 1024×768, 33 MB at 4K.

Painting goes to a shadow in ordinary memory, not to the buffer. The kernel typically maps a dumb buffer write-combined, where scattered per-pixel writes are slow but one long linear copy runs at streaming bandwidth. flush is that copy.

Implementations§

Source§

impl CompositeCanvas

Source

pub fn create( device: &Device, width: u32, height: u32, ) -> Result<Self, DumbError>

Allocate the pair at width × height.

§Errors

DumbError if either allocation or its framebuffer fails.

Source

pub fn create_in( device: &Device, width: u32, height: u32, fourcc: u32, ) -> Result<Self, DumbError>

Allocate the pair in a format the target plane can scan out.

For the single-plane fallback: pass what canvas_format_for_plane returned, and the canvas emits that instead of ARGB8888. Blending still happens in ARGB8888, in a shadow buffer, so a 565 canvas quantizes once at flush rather than at every layer.

§Errors

DumbError::InvalidConfig if fourcc is not one the canvas can write, and otherwise as CompositeCanvas::create.

Source

pub const fn fourcc(&self) -> u32

What the canvas scans out as.

Source

pub const fn begin_frame(&mut self)

Swap back and front before painting.

Call once per frame, before the first paint. Calling it twice in one frame would paint into the buffer just handed to the kernel.

Source

pub fn clear(&mut self)

Zero the whole shadow: transparent black, the SRC_OVER identity.

Source

pub fn clear_rect(&mut self, rect: CompositeRect)

Zero one rectangle of the shadow.

Scrubbing only the union of last frame’s and this frame’s painted region turns the per-frame cost from width * height * 4 bytes into something proportional to what actually moved.

Source

pub fn blend( &mut self, src: &CompositeSrc<'_>, src_rect: CompositeRect, dst_rect: CompositeRect, )

Blend one source over the shadow.

Source

pub fn flush(&mut self)

Copy the painted shadow into the back buffer, converting it to the canvas format.

Row by row rather than one call, because the kernel is free to pad a dumb buffer’s stride above width * 4; copying straight through would walk the padding into the next row and shear the image.

Source

pub fn fb_id(&self) -> Option<u32>

The framebuffer to arm on the canvas plane — the one just painted.

Source

pub const fn width(&self) -> u32

Canvas width in pixels.

Source

pub const fn height(&self) -> u32

Canvas height in pixels.

Source

pub fn back_pixel(&self, x: u32, y: u32) -> u32

Read one pixel back out of the buffer being painted.

Reads the framebuffer’s own memory rather than the shadow, which is the only way to tell that flush actually reached the buffer the kernel will scan out. Zero for a pixel outside the canvas, or once the mapping has been dropped. Reads 32 bits at a 4-byte pitch, so it is only meaningful on a 32-bit canvas.

Source

pub fn armable(&self) -> bool

Whether the canvas can be armed.

False once forget has run, so a scene that resumes without re-allocating cannot commit a framebuffer id the kernel no longer knows.

Source

pub fn forget(&mut self)

Drop both buffers’ kernel state without issuing ioctls.

For session pause, where the descriptor has been revoked and cannot service the ioctls a normal teardown would make. The shadow survives — it is ordinary memory and owes the device nothing.

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.