forked from 1b-agent/opencadstudio-upstream
perf(scene): batch the selection-overlay wire pass too
Follow-up to 3.3. The selection xray pass still built one buffer + one draw call per selected wire, so select-all over a large drawing issued a draw per entity. That pass applies neither scissor nor mesh-edge skip, so all selected wires merge into one order-preserving run via from_run. Removes the now-dead WireGpu::new / build per-wire constructors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
c6e17deb7e
commit
0d18e0d1bf
2 files changed
+6
-33
No files matched your search
@@ -900,13 +900,6 @@ impl Pipeline {
|
||||
wires: &[WireModel],
|
||||
depth_map: &rustc_hash::FxHashMap<u64, f32>,
|
||||
) {
|
||||
let depth_of = |w: &WireModel| -> f32 {
|
||||
w.name
|
||||
.parse::<u64>()
|
||||
.ok()
|
||||
.and_then(|h| depth_map.get(&h).copied())
|
||||
.unwrap_or(0.0)
|
||||
};
|
||||
// Batch the wire pass: instead of one GPU buffer + one draw call per
|
||||
// WireModel (tens of thousands on a large drawing), merge maximal runs
|
||||
// of *consecutive* wires that share scissor + mesh-edge state into one
|
||||
@@ -934,13 +927,12 @@ impl Pipeline {
|
||||
self.gpu_wires = batches;
|
||||
|
||||
// Full-brightness copies of selected wires, drawn on top of everything
|
||||
// in the selection overlay pass so they're always visible. Kept
|
||||
// per-wire — the selection set is small and this overlay is separate.
|
||||
self.gpu_selected_wires = wires
|
||||
.iter()
|
||||
.filter(|w| w.selected)
|
||||
.map(|w| WireGpu::new(device, w, depth_of(w)))
|
||||
.collect();
|
||||
// in the selection overlay pass so they're always visible. The xray
|
||||
// pass applies neither scissor nor mesh-edge skip, so all selected
|
||||
// wires batch into one run (None / false) — select-all over a large
|
||||
// drawing no longer costs one draw call per entity. Order preserved.
|
||||
let selected: Vec<WireModel> = wires.iter().filter(|w| w.selected).cloned().collect();
|
||||
self.gpu_selected_wires = WireGpu::from_run(device, &selected, depth_map, None, false);
|
||||
}
|
||||
|
||||
/// Recompute pixel scissor rects for viewport-clipped wires from the current view_proj.
|
||||
|
||||
@@ -277,12 +277,6 @@ fn wire_draw_depth(wire: &WireModel, depth_map: &rustc_hash::FxHashMap<u64, f32>
|
||||
}
|
||||
|
||||
impl WireGpu {
|
||||
pub fn new(device: &wgpu::Device, wire: &WireModel, draw_depth: f32) -> Self {
|
||||
let mut g = Self::build(device, wire, wire.color, draw_depth);
|
||||
g.vp_scissor = wire.vp_scissor;
|
||||
g.is_3d_mesh_edge = !wire.fill_tris.is_empty();
|
||||
g
|
||||
}
|
||||
|
||||
/// Merge a run of WireModels that share scissor + mesh-edge state into one
|
||||
/// (or, past the 256 MB GPU limit, a few) instance buffer(s), then stamp
|
||||
@@ -382,17 +376,4 @@ impl WireGpu {
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn build(device: &wgpu::Device, wire: &WireModel, color: [f32; 4], draw_depth: f32) -> Self {
|
||||
let instances = emit_wire_instances(wire, color, draw_depth);
|
||||
let label = format!("wire.ibuf.{}", wire.name);
|
||||
let instance_buffer = instance_buffer_mapped(device, &label, &instances);
|
||||
|
||||
Self {
|
||||
instance_buffer,
|
||||
instance_count: instances.len() as u32,
|
||||
vp_scissor: None,
|
||||
is_3d_mesh_edge: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user