pub struct CpuCanvas { /* private fields */ }Expand description
A CPU canvas: an off-screen Pixmap (the vello_cpu raster target, per the
CONS-CORE spec) plus the batched SDF instances drawn onto it. The host pushes
quads + lines, then CpuCanvas::rasterize evaluates the sdf coverage for
every instance over its bounding box and alpha-composites it into the pixmap.
Coverage math is byte-for-byte the same the GPU lane runs, so a CPU frame
matches a GPU frame (the sdf_primitives parity test pins this).
Implementations§
Source§impl CpuCanvas
impl CpuCanvas
Sourcepub fn new(width: u32, height: u32, camera: Camera, background: [u8; 4]) -> Self
pub fn new(width: u32, height: u32, camera: Camera, background: [u8; 4]) -> Self
A fresh width × height canvas cleared to background (straight RGBA8),
under camera.
No serial clear here: the background is no longer painted up-front in a
single-threaded for over 1M pixels (that was a pure Amdahl serial tail).
Instead [raster_batches] fills each row’s background inside the gatling
scanline kernel — the workers that own a row clear it before compositing, so
the clear scales across all cores with zero extra alloc.
Sourcepub fn pixmap(&self) -> &Pixmap
pub fn pixmap(&self) -> &Pixmap
The raster target — the vello_cpu pixmap (spec §2: “CpuCanvas → vello_cpu
pixmap”). Exposed so a host can hand its glyph/curve overlay (L1 vello) the
same target later.
Sourcepub fn rasterize(&mut self) -> Frame
pub fn rasterize(&mut self) -> Frame
Rasterize every batched instance onto the pixmap (lines under quads, the
graph convention: chips draw on top of edges). Returns the straight
(un-premultiplied) RGBA8 Frame.
GATLING multicore (LAW 2): the raster fans across all cores by scanline
row — each row is owned by exactly one thread, so the blends never contend,
and the per-pixel compositing order (all lines in order, then all quads in
order) is preserved bit-for-bit vs the sequential path (the
parallel_raster_matches_sequential test pins this). Below a pixel-work
threshold the frame stays single-threaded (zero pool overhead on small draws).
Sourcepub fn rasterize_with_workers(&mut self, workers: usize) -> Frame
pub fn rasterize_with_workers(&mut self, workers: usize) -> Frame
rasterize with an explicit gatling worker count: 0 ⇒
one per core (the production path), 1 ⇒ the forced single-threaded path.
Exposed so a bench can time the same parallel region at 1 vs N workers and
report the real cores-busy / speedup (rather than guessing from a sweep
average). The output is identical for any worker count (the
parallel_raster_matches_sequential test pins bit-identity at N vs 1).
Sourcepub fn raster_only(&mut self, workers: usize)
pub fn raster_only(&mut self, workers: usize)
Run only the compositing raster (bg clear + y-bucketed SDF blend) at
workers gatling workers — the region the GATLING scanline kernel governs,
without the memory-bandwidth-bound un-premultiply (frame).
Exposed for the scaling bench so cores-busy can be measured on the part that
is CPU-bound, separate from the RAM-bandwidth-capped pixmap→RGBA8 conversion.
Sourcepub fn frame(&self) -> Frame
pub fn frame(&self) -> Frame
Snapshot the current pixmap as a straight-RGBA8 Frame (un-premultiplied)
without consuming the canvas.
Parallel un-premultiply: the per-pixel un-premultiply is embarrassingly
parallel, so it runs through the same gatling scanline kernel into a
pre-allocated output buffer (zero per-pixel alloc) instead of the old
single-threaded flat_map().collect() over the whole framebuffer — that
collect was the second half of the Amdahl serial tail.
Sourcepub fn frame_with_workers(&self, workers: usize) -> Frame
pub fn frame_with_workers(&self, workers: usize) -> Frame
frame with an explicit worker count (see
rasterize_with_workers).
Trait Implementations§
Source§impl Canvas for CpuCanvas
impl Canvas for CpuCanvas
Source§fn push_quads(&mut self, quads: &[QuadInstance])
fn push_quads(&mut self, quads: &[QuadInstance])
QuadInstance). Zero-copy slice — the canvas decides whether
it copies into a vertex buffer (GPU) or rasters in place (CPU).Source§fn push_lines(&mut self, lines: &[LineInstance])
fn push_lines(&mut self, lines: &[LineInstance])
Auto Trait Implementations§
impl Freeze for CpuCanvas
impl RefUnwindSafe for CpuCanvas
impl Send for CpuCanvas
impl Sync for CpuCanvas
impl Unpin for CpuCanvas
impl UnsafeUnpin for CpuCanvas
impl UnwindSafe for CpuCanvas
Blanket Implementations§
impl<T> Allocation for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more