Skip to main content

CpuRenderer

Struct CpuRenderer 

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

A renderer that keeps a premultiplied RGBA surface between frames and repaints only the damaged rectangles of each frame.

Every frame leaves the surface equal to a full repaint of the display list. Each damaged rectangle is cleared and redrawn in place, and every other pixel is left untouched. A pixel’s value depends only on its position and the operations covering it, so redrawing a rectangle gives the same bytes a full repaint would.

Glyphs are drawn from a cache of alpha masks that survives between frames with the surface, so a glyph is rasterized once no matter how often it is repainted.

A frame allocates nothing once the surface has seen a frame like it: the per frame plan of drawable operations reuses its buffers, and a glyph seen before comes from the cache.

§Examples

use smudge_core::app::FrameOutput;
use smudge_core::geometry::{Color, PixelRect};
use smudge_core::paint::DisplayList;
use smudge_cpu::CpuRenderer;

let mut renderer = CpuRenderer::new(4, 4);
let list = DisplayList::new();
let damage = [PixelRect {
    x: 0,
    y: 0,
    width: 4,
    height: 4,
}];

renderer.render(&FrameOutput {
    list: &list,
    damage: &damage,
    full: true,
    clear_color: Color::WHITE,
    scale: 1.0,
});

assert_eq!(renderer.pixels().len(), 4 * 4 * 4);
assert_eq!(&renderer.pixels()[..4], &[255, 255, 255, 255]);

Implementations§

Source§

impl CpuRenderer

Source

pub fn new(width: u32, height: u32) -> CpuRenderer

Creates a renderer for a surface of width by height physical pixels.

The surface starts empty. A surface with a zero extent holds no pixels, and CpuRenderer::width, CpuRenderer::height, CpuRenderer::pixels and CpuRenderer::encode_png then report an empty surface.

Source

pub fn resize(&mut self, width: u32, height: u32)

Replaces the surface with one of width by height physical pixels.

The contents are undefined until the next frame that damages the whole surface, so callers resize only when they also force a full repaint. The glyph cache survives a resize, because a mask depends on the glyph and its size but not on the surface.

Source

pub fn render(&mut self, frame: &FrameOutput<'_>)

Repaints the damaged rectangles of frame into the surface.

Each rectangle of FrameOutput::damage is rendered separately, so the pixels outside every rectangle keep the value the previous frame left them with. The damage already covers everything that changed, so rendering it produces the same surface a full repaint of the frame would.

Only the damage is read. FrameOutput::full does not clear the surface by itself, and a full frame from the app already damages the whole surface.

§Panics

Panics when a damaged rectangle reaches outside the renderer’s surface, which means the frame was produced for a surface of a different size. That is a broken invariant of the caller, not input from outside the library.

Source

pub fn width(&self) -> u32

Returns the surface width in physical pixels.

Source

pub fn height(&self) -> u32

Returns the surface height in physical pixels.

Source

pub fn pixels(&self) -> &[u8] ⓘ

Returns the surface as premultiplied RGBA8 pixels, row-major with no padding between rows.

The slice is empty when the surface has no pixel.

Source

pub fn encode_png(&self) -> Vec<u8> ⓘ

Encodes the surface as a PNG image.

The result is empty when the surface has no pixel, because an image cannot have a zero extent.

§Panics

Panics when the PNG encoder fails. Encoding into memory cannot fail, so this reports a broken invariant of the encoder rather than anything a caller can provoke.

Trait Implementations§

Source§

impl Renderer for CpuRenderer

Source§

fn render(&mut self, frame: &FrameOutput<'_>)

Repaints frame onto the renderer’s surface.

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.