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
impl CompositeCanvas
Sourcepub fn create_in(
device: &Device,
width: u32,
height: u32,
fourcc: u32,
) -> Result<Self, DumbError>
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.
Sourcepub const fn begin_frame(&mut self)
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.
Sourcepub fn clear_rect(&mut self, rect: CompositeRect)
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.
Sourcepub fn blend(
&mut self,
src: &CompositeSrc<'_>,
src_rect: CompositeRect,
dst_rect: CompositeRect,
)
pub fn blend( &mut self, src: &CompositeSrc<'_>, src_rect: CompositeRect, dst_rect: CompositeRect, )
Blend one source over the shadow.
Sourcepub fn flush(&mut self)
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.
Sourcepub fn fb_id(&self) -> Option<u32>
pub fn fb_id(&self) -> Option<u32>
The framebuffer to arm on the canvas plane — the one just painted.
Sourcepub fn back_pixel(&self, x: u32, y: u32) -> u32
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.