forked from 1b-agent/opencadstudio-upstream
perf(render): split the wire arena into regular + mesh-edge batches
The single-batch arena required a set with no mesh/solid edges, so any drawing with a 3D solid or mesh (this one: 1693 mesh-edge wires of 12200) disqualified the WHOLE set — every edit fell back to build_wire_buffers re-uploading ~265 MB (4.4M instances), stalling ~1s per edit on a shared-memory GPU. Split the resident set into a regular-2D arena and a mesh-edge arena (the wires that need the draw loops mesh-edge skip/black treatment), one WireArena each, passed as &[&WireModel] subsets (no clone). Both patch incrementally; the mesh arena carries is_3d_mesh_edge so the existing draw loop handles it. A changed handle absent from an arenas subset is a no-op for it, so each edit touches only the batch it belongs to. Result: the wire block drops from ~300ms + a 265 MB GPU upload to ~2ms. Two correctness points folded in from adversarial review: - mesh-edge wires are stamped draw_depth 0 (matching WireGpu::from_run) so their hidden back edges dont peek through the shaded fill; the mesh arena also always bails on append (all its wires share depth 0, so relocation would reorder coincident edges). - buffers are capped at wgpus 256 MB limit — a batch larger than one buffer returns None so the caller chunks it via the batched path (fixes a create_buffer panic on the 355 MB regular batch). Still behind OCS_WIRE_GPU_PATCH (default off). OCS_PERF prints the per-edit wire timing + outcome. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
9761423b84
commit
95ef3b3890
3 files changed
+157
-55
No files matched your search
@@ -154,7 +154,12 @@ pub struct Pipeline {
|
||||
/// edit patches one entity's slab in place instead of rebuilding every wire.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) wire_arena: Option<wire_arena::WireArena>,
|
||||
/// The Model content id `wire_arena` currently mirrors (`u64::MAX` = none).
|
||||
/// Second arena for the mesh/solid EDGE wires (drawn with the mesh-edge skip /
|
||||
/// black treatment); the resident set is split into this + `wire_arena` so
|
||||
/// both patch incrementally. Shares `wire_arena_id`.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) wire_arena_mesh: Option<wire_arena::WireArena>,
|
||||
/// The Model content id both arenas currently mirror (`u64::MAX` = none).
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub(crate) wire_arena_id: u64,
|
||||
/// Pixel scissor rects [x, y, w, h] for viewport-clipped wires. Recomputed each frame.
|
||||
@@ -1320,6 +1325,8 @@ impl Pipeline {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wire_arena: None,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wire_arena_mesh: None,
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
wire_arena_id: u64::MAX,
|
||||
wire_pixel_scissors: vec![],
|
||||
gpu_selected_wires: vec![],
|
||||
|
||||
Reference in new issue
Block a user