perf(scene): parallelize block-definition build

Phase 2.1. build_defn stores nested INSERTs as by-name references and
never expands them at build time, so each block defn depends only on the
read-only doc — the builds are independent, not topologically ordered as
the roadmap assumed. Replace the serial loop with a rayon
par_iter().collect(). render_style_for / tessellate already run under
rayon in build_derived_caches, so thread-safety is established.

compute_block_aabbs stays serial (resolves nested refs, cheap post-pass).
Cuts first-frame block tessellation on insert-heavy drawings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-05 00:46:21 +03:00
commit 16050909f9
2 changed files with 19 additions and 10 deletions

View file

@ -107,12 +107,14 @@ sub-100 ms.
After `FileOpened`, `bump_geometry()` fires; the first frame tessellates
**every** model-space wire. Measurable hitch at ~100 k entities.
### 2.1 Parallelize block-definition build
### 2.1 Parallelize block-definition build ✅ DONE
[`block_cache::build`](src/scene/block_cache.rs#L238) is single-threaded —
the comment says "nested expansion is fiddly". Fix: stratify blocks in
**topological order** (leaf blocks → callers → …) and build each layer in
parallel via rayon. Dependency order is preserved.
[`block_cache::build`](src/scene/block_cache.rs#L127) was single-threaded.
No topological stratification was needed after all: `build_defn` stores
nested INSERTs as by-name references (`LocalSub::Nested`) and never expands
them at build time, so each defn depends only on the read-only `doc` — the
builds are embarrassingly parallel. Now a plain rayon `par_iter().collect()`.
`compute_block_aabbs` stays a serial post-pass (resolves nested refs, cheap).
### 2.2 Incremental wire cache (delta tessellation)