batch
Mojo module đźˇ
batch
Rendering a Canvas batch: the primitives recorded between begin_batch and end_batch, drawn in one banded pass.
Every op was recorded under the state in force when it was called
(_BatchOp), so rendering is one walk over the ops per row band, in
submission order, each op restricted to the band’s rows by the
row-restricted body its shape already had: the area accumulator’s
band, the sampled sweep’s band, the closed-form disk and ellipse
rows, _fill_region on a rectangle’s rows. Bands own disjoint rows
and read the batch only, which is the whole safety argument, the same
one fill_circles_aa makes. Order within a band is what makes
overlapping translucent shapes come out as drawing them one at a time
would.
A row’s pixels do not depend on which band computes it – each row
body starts from the op’s own geometry – so the bytes are those of
drawing every op at once, at any band count (tests/test_batch.mojo).
Before the band pass, the strokes and paths recorded as geometry are
built into edges (_build_ops), in parallel over the ops. Drawn one
call at a time, that build ran on one core ahead of every stroke’s
raster stage; it is the serial prologue #383 and #373 measured. Each
build task appends what it builds into one edge table of its own,
allocated and filled by the same thread and read by the bands, so a
batch of thousands of small shapes costs a few allocations rather
than several per op: with one table per op the parallel build spent
its time in the allocator and the teardown ran serially over
thousands of tables, and a batch of 2,000 small paths was slower than
drawing them one at a time.