forked from 1b-agent/opencadstudio-upstream
Build the selection highlight in one pass instead of four
Highlighting a whole-drawing selection took 299 ms, and it runs when the selection changes — directly between the click that completes a selection and seeing it. Most of that was asking the same question twice. Each wire went through the circle and ellipse extractors at its draw depth to build the analytic instances, then through both again at depth 0.0 purely to ask *whether* it is a circle or an ellipse, allocating a vector each time and dropping it. Neither extractor's `Some`/`None` answer depends on the depth: every `return None` in them turns on the geometry — which `TangentGeom` variant, the radius, the axis lengths, the parameters — and the depth is only written into the instance, never read to decide. So the extraction that builds the instances already answers the classification. One pass now does both, and fans out across cores, since it reads a wire and writes nothing shared. That took 173 ms of shape extraction and splitting down to 19 ms, and the whole highlight from 299 ms to 150 ms. Gathering the highlighted wires also cloned each handle's slot vector and sorted the copy — one allocation and one sort per selected entity. The slots are already ascending: both builders walk the wires in order and push as they go, and `patch_handle_index` shifts a handle's slots by a constant, which preserves it. A `debug_assert` on the slots actually read holds that in place. The compat path of `from_highlight_refs` emitted its instances sequentially while the native path beside it fans out; it now matches. Nothing renders in a test, so a wrong bucket in the classification would surface only as circles drawn wrong when selected. Two tests cover it: each wire lands where the old predicate put it, and the colour override — always for hover, and the configured tint or `SELECTED` for a selection — reaches the instances. `wire-highlight-detail` reports the phases: gathering, classifying, uploading the analytic instances, the regular wires and the block ones.
This commit is contained in:
1 parent
d5bf919414
commit
f128ed3eaf
2 files changed
+236
-77
No files matched your search
@@ -1148,8 +1148,14 @@ impl WireGpu {
|
||||
|
||||
let _ = const_bgl;
|
||||
let max_packed_instances = super::gpu_budget::max_elements::<PackedWireInstance>(device);
|
||||
// Same fan-out the native path above uses: emitting a wire reads that
|
||||
// wire and the depth map and writes nothing shared, and a selection
|
||||
// large enough to be slow is exactly where it pays. `collect` on an
|
||||
// indexed parallel iterator keeps the order, which the instance indices
|
||||
// depend on.
|
||||
use crate::par::prelude::*;
|
||||
let per: Vec<Vec<PackedWireInstance>> = wires
|
||||
.iter()
|
||||
.par_iter()
|
||||
.map(|wire| {
|
||||
emit_wire_packed(wire, color, wire_draw_depth(wire, depth_map))
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user