# vello\_cpu

[github.com/linebender/vello](https://github.com/linebender/vello) · Apache-2.0 OR MIT

## For hotty-blitz

2 patches on `0.1.0`. Blitz paints through anyrender, and hotty-blitz renders surfaces on the CPU with anyrender's vello_cpu backend, which brings vello_cpu 0.1.0 from crates.io: the published package, not the vello repository, because its dependencies are the crates.io ones anyrender builds against. A terminal repaints small parts of its surfaces many times a second, which is where these two patches save. We mod vello_cpu rather than fork it so that they stay two changes on the version we build with. Both still apply to vello_cpu 0.3.0.

The patches, each with its upstream fit:

1. [Flushing waits for the workers without spinning](https://neuroplast.io/modding/vello-cpu#flushing-waits-for-the-workers-without-spinning) — **yes**
2. [A render context takes at most 4 workers by default](https://neuroplast.io/modding/vello-cpu#a-render-context-takes-at-most-4-workers-by-default) — **maybe**

### Flushing waits for the workers without spinning

> Upstream fit: **yes** · [patch 0001](https://github.com/neuroplastio/hotty-blitz/blob/079f6ae967aed32326797f8b7423d0f073aa4550/mods/vello_cpu/0001-vello_cpu-flushing-waits-for-the-workers-without-spi.patch)

**What it changes:** `MultiThreadedDispatcher::flush` drained the workers'
recorded commands by looping on `try_recv` until every worker had hung up,
so the painting thread spun at full speed for as long as the workers took
on the last batch. It now blocks in the ordered channel's `recv`, which
hands out the tasks in the same order and fails once the senders are gone
and nothing is buffered. Counting instructions with `perf` on a 10 Hz
dashboard in hottyterm: the painting thread did 39% fewer, the process 23%
fewer, and frame times stayed the same.

**Why we carry it:** a quarter of hotty-blitz's instructions on that
dashboard were this spin.

**For upstream:** yes. It is a fix with no trade-off: the order and the
results are the same, and only the busy wait goes. vello_cpu 0.3.0 still
drains this way, and the patch applies there.

### A render context takes at most 4 workers by default

> Upstream fit: **maybe** · [patch 0002](https://github.com/neuroplastio/hotty-blitz/blob/079f6ae967aed32326797f8b7423d0f073aa4550/mods/vello_cpu/0002-vello_cpu-a-render-context-takes-at-most-4-workers-b.patch)

**What it changes:** the default thread count was one worker per core but
one, up to 8; it is now up to 4. Measured with a 300-frame dashboard replay
and hotty-blitz's benchmark on a Ryzen 5 5600X and a laptop: past 2
workers a full paint barely gets faster, since the main thread's share
dominates, while each worker adds dispatch and idle spinning to every
small paint. With 4, replay paint time fell about 16% and CPU time about
35% on the 5600X, and a full paint stayed within a millisecond.

**Why we carry it:** HOTTY repaints are mostly small, and a host keeps 8
render contexts, so this halves its threads, from 64 to 32. The
maintainer chose 4 (2026-10-10).

**For upstream:** maybe. The measurement is worth having: on two machines,
past 2 workers a full paint barely gets faster, and every worker costs
each small paint. But the right default depends on what a renderer
paints, upstream's benchmarks may differ, and a caller can already set
`num_threads`. vello_cpu 0.3.0 still takes up to 8.

---

[neuroplast.io](https://neuroplast.io/) · [Modding](https://neuroplast.io/modding) · [github.com/neuroplastio](https://github.com/neuroplastio)
