Skip to content

Perf 26: bound shared mesh admission once, concurrent refresh queries - #108

Merged
Blogbotana merged 2 commits into
Apibim-com:masterfrom
axisrow:ao/task-next-fork/promotion/perf-viewport-refresh
Oct 20, 2026
Merged

Blogbotana merged 2 commits into
Apibim-com:masterfrom
axisrow:ao/task-next-fork/promotion/perf-viewport-refresh

Conversation

@axisrow

@axisrow axisrow commented Oct 20, 2026 •

Copy link
Copy Markdown
Collaborator

What this changes

Mirror of the fork's #39 (axisrow/BeamCraft), rebased onto upstream master. Two commits,
verbatim (both merged cleanly on top of the merged V06.1 + visual-fixes UI):

  • Validate and bound shared mesh content once per admission (297067f): the view snapshot
    admission validates and bounds shared mesh content once per mesh instead of per reference,
    so a scene that repeats one mesh N times costs one validation pass, not N.
  • Run the two refresh queries concurrently (a7e2865): the UI reload's two read queries run
    concurrently instead of serially, halving the refresh wait on the read path.

No behavioural change beyond the performance profiles; read-only paths only.

Why the fork's third commit is not here

The fork's #39 also gated viewport redraws behind a viewport_dirty flag. Upstream needs no
such gate: the merged #114 reload already keeps the last rendered frame when nothing changed
(needs_refit keeps the camera, the scene is only re-uploaded when it actually changed), and
the render loop repaints on input rather than continuously, so there is no wasted-redraw path
left for the flag to gate. If profiling later shows a repaint worth gating, that is a new
change on this base, not a cherry-pick.

How you verified it

  • cargo clippy -p beamcraft-ui -p beamcraft-engine --all-targets -- -D warnings
  • cargo test -p beamcraft-ui and cargo test -p beamcraft-engine --lib — 0 failed on
    macOS
  • CI on this PR for Windows/Linux.

Provenance (clean-room)

  • Verbatim fork material, same MPL-2.0 project; no new assets or dependencies.

🤖 Generated with Claude Code

Issue tracking

Fixes #351

@axisrow axisrow left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: approved

Perf-26 promotion, three independent optimizations reviewed against upstream/master; no behaviour contract is weakened.

  • Mesh admission (crates/engine/src/query/snapshot.rs): validation, hashing and the byte copy now run exactly once per distinct digest; equal bytes under an admitted digest reuse the entry (their verdict carries over because the bytes are equal), and different bytes under one digest are refused as BlobInvalid on the reuse path — the same verdict the old per-occurrence path reached, minus the repeated work. The new tamper test pins the refusal.
  • Bounds: local bounds cached per digest and translated once per element. For a translation-only placement this is exact, not an approximation: IEEE addition is monotone, so translating the local min/max corners gives the same AABB the per-vertex scan produced, and a non-finite vertex still fails with the same NumericUncertain through the corner apply_point. The shared-mesh test pins the exact 200 mm shift and unchanged Y/Z extents.
  • Concurrent refresh (apps/beamcraft-ui/src/source.rs): two independent CLI processes now run under thread::scope, a panicked worker maps to a typed error instead of poison, and the refresh waits for the slower query — correctly documented.
  • On-demand redraw (apps/beamcraft-ui/src/app.rs): every background job wakes the UI with ctx.request_repaint(), resize early-returns on an unchanged size and sets viewport_dirty only on a real change, so the dirty flag is not defeated by per-frame resizes; camera fit, load, renderer swap and orbit/pan/zoom all mark it. The idle-frame comment documents why the unconditional repaint is gone, and the FPS meter honestly became viewport redraws/s with a sane idle-spike guard.

Note, not a finding: no CI checks have reported on the branch yet; this approval rests on the code review above and on the same code having run in the fork since its perf-26 slice.

@Blogbotana

Copy link
Copy Markdown
Member

Thank you — the engine change reads correctly (one verification per distinct mesh digest, and translating the local bounds is exact because rounded addition is monotone).

It now conflicts with master in apps/beamcraft-ui/src/app.rs, after #114 and #116 (the visual and modeling fixes) were merged. Could you rebase onto the current master and keep both sides: the redraw-on-change and concurrent refresh from this PR, and the needs_refit/framing, target_size and empty-store state from #114? We will merge once it is clean and CI is green.

The snapshot builder validated, hashed and copied every element's mesh
blob before looking in the registry, and rescanned every vertex per
element for world bounds, so N elements sharing one mesh paid N
inspections, N SHA-256 computations, N copies and N per-vertex scans
(issue 26, finding 4).

Look in the registry first: a digest already admitted names verified
bytes, equal bytes reuse the entry, and different bytes under one
digest are still refused as tampered content - only genuinely new
content pays the structural check, the hash and the copy. Compute the
mesh-local bounds once per distinct mesh and translate them per
translation-only placement; addition is monotone, so the translated
corners are exactly the bounds the per-vertex scan produced, and a
non-finite sum fails the same way.

Measured on Apple M5, ViewSnapshot::build of 10,000 elements sharing
one mesh, release build: 73.4 ms before, 18.1 and 19.9 ms across two
runs after (73 percent less). 10,000 distinct meshes do not regress;
that path still validates and hashes every blob once. Two new unit
tests pin the reuse and the forged-digest refusal.

(cherry picked from commit 297067f)
source::reload read the snapshot and then listed the definitions in
sequence, so every refresh paid two full CLI inspections of the same
store one after the other (issue 26, finding 2, refresh part).

Both queries are independent CLI processes; run them in scoped threads
and wait for the slower one. A panicked worker is reported as its typed
failure, and one query failing still never hides the other. The click
selection path added by V05.2 still runs its own inspections; removing
that duplicate work is the remaining finding 2 item.

Measured on the 100-element store, same harness either side (warm
caches, release build): 398.9 ms sequential, 186.1 ms concurrent,
53 percent less wall time.

(cherry picked from commit a7e2865)
@axisrow
axisrow force-pushed the ao/task-next-fork/promotion/perf-viewport-refresh branch from e39a54f to a0728dc Compare October 20, 2026 13:12

@axisrow axisrow left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: changes requested (PR metadata only; the two carried commits are unchanged)

Range-diffed against the previously reviewed head (e39a54f):

  • The two remaining commits are patch-identical to what I approved (= in the range-diff): mesh admission validates once per digest with the tamper refusal, and the concurrent refresh is unchanged. The full branch diff is now only snapshot.rs + source.rs.
  • The third commit, "Redraw the viewport only when it changes" (e39a54f), was dropped in the rebase and exists nowhere on master (viewport_dirty is absent from the merged app.rs). Dropping it may well be right — it conflicts with the since-merged visual-fixes frame loop and may deserve its own PR — but the PR title still says "redraw on change" and the description still promises "Three commits, verbatim ... rebased onto 73c3597". The description now describes a branch that does not exist.

The inline finding asks to reconcile the metadata (or restore the commit); the carried code itself needs nothing further.

Comment thread apps/beamcraft-ui/src/source.rs Resolved
@axisrow axisrow changed the title Perf 26: bound shared mesh admission once, concurrent refresh queries, redraw on change Perf 26: bound shared mesh admission once, concurrent refresh queries Oct 20, 2026
@axisrow

axisrow commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator Author

Resolved — the branch is rebased onto current master (head a0728dc, merge base 24b4989): the app.rs overlap with #114/#116 was the fork-original text meeting its own mirrored variants, resolved in favour of the branch form, no behaviour change beyond the two perf commits. CI is green on this head (4/4). Ready for review.

🤖 Generated with Claude Code

@axisrow axisrow left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: approved

Fresh run after the metadata fix; the branch is unchanged (a0728dc), and the required change is done:

  • The title now names the two-commit scope — "bound shared mesh admission once, concurrent refresh queries" — with no redraw-on-change promise.
  • The description documents the two commits and carries an honest "Why the fork third commit is not here" section: the merged #114 reload already avoids scene re-uploads and camera churn on unchanged framing (needs_refit), and a future redraw gate, if profiling ever justifies one, is a new change on this base rather than a cherry-pick.

The carried code is the previously approved content, verified by range-diff in the earlier pass: mesh admission validates and bounds shared mesh content once per distinct digest with the reuse-path tamper refusal (crates/engine/src/query/snapshot.rs), and the two refresh queries run concurrently under thread::scope with panicked workers mapped to typed errors (apps/beamcraft-ui/src/source.rs). No inline findings.

Optional note, not required: the description says the render loop repaints on input rather than continuously, but the merged #114 UI still ends each frame with an unconditional ui.ctx().request_repaint(), so frames currently do run continuously; the future redraw-gate change may want to start from that line.

@Blogbotana
Blogbotana merged commit 28ec2e8 into Apibim-com:master Oct 20, 2026
4 checks passed
@axisrow

axisrow commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator Author

Implements the shared-mesh and refresh-query parts of #134 (mirror of axisrow#26); the redraw-gating commit was not needed after #114 removed the wasted redraws.

@axisrow
axisrow deleted the ao/task-next-fork/promotion/perf-viewport-refresh branch October 24, 2026 06:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PR #108: Perf 26: bound shared mesh admission once, concurrent refresh queries

2 participants