forked from 1b-agent/opencadstudio-upstream
perf(render): reuse static wire set for model-space pick/snap
Every pan/rotate on a large drawing jerked once at the start of the gesture. Instrumentation traced it to `paper_sheet_wires_arc` re-running a full ~300 ms tessellation of the whole model block on the first hit-test after each camera move. `entity_wires_arc` (the pick/snap source in Model layout) delegated to the camera_generation-keyed, view-culled `paper_sheet_wires_arc`. A camera move bumps `camera_generation`, so the next hit-test cold-missed that cache and re-tessellated every visible entity — O(visible), which is why the jump grew with on-screen object count and shrank when zoomed in. The GPU render was unaffected (it holds the separate camera-independent `model_static_wires`), so only that one CPU frame stalled and the accumulated mouse motion applied at once, reading as a jump. Point the Model pick path at the same resident static set the render holds (keyed on geometry_epoch only). Pick wants every entity, not a view-culled subset, so this is also more correct — off-screen entities stay pickable — and it never re-tessellates on a camera move. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
845194e05b
commit
626031de00
1 file changed
+11
-5
+11
-5
@@ -2117,12 +2117,18 @@ impl Scene {
|
||||
}
|
||||
}
|
||||
let layout_block = self.current_layout_block_handle();
|
||||
// Model space: paper_sheet_wires_arc IS the full entity wire set — share the Arc,
|
||||
// no Vec clone needed.
|
||||
// Model space: reuse the resident, camera-independent static wire set the
|
||||
// render already holds (keyed on geometry_epoch only). This is the FULL
|
||||
// entity set — pick / snap want every entity, not a view-culled subset —
|
||||
// and it does NOT re-tessellate on a camera move. The old path went
|
||||
// through the camera_generation-keyed, view-culled paper_sheet set, so
|
||||
// every pan/rotate cold-missed it and paid a full O(visible) re-tess
|
||||
// (~300 ms on large drawings) the first time hit-testing ran after the
|
||||
// move — the "jump" at the start of each gesture. The tile args are
|
||||
// unused by `model_tile_wires_arc`.
|
||||
if self.current_layout == "Model" {
|
||||
let arc = self.paper_sheet_wires_arc();
|
||||
*self.wire_cache.borrow_mut() = Some((key, Arc::clone(&arc)));
|
||||
return arc;
|
||||
let cam = self.camera.borrow().clone();
|
||||
return self.model_tile_wires_arc(0, &cam, 1.0, 1.0);
|
||||
}
|
||||
// Paper space: extend sheet wires with projected viewport content.
|
||||
let mut wires = (*self.paper_sheet_wires_arc()).clone();
|
||||
|
||||
Reference in new issue
Block a user