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
impl CpuRenderer
Sourcepub fn new(width: u32, height: u32) -> CpuRenderer
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.
Sourcepub fn resize(&mut self, width: u32, height: u32)
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.
Sourcepub fn render(&mut self, frame: &FrameOutput<'_>)
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.
Sourcepub fn pixels(&self) -> &[u8] ⓘ
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.
Sourcepub fn encode_png(&self) -> Vec<u8> ⓘ
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
impl Renderer for CpuRenderer
Source§fn render(&mut self, frame: &FrameOutput<'_>)
fn render(&mut self, frame: &FrameOutput<'_>)
frame onto the renderer’s surface.