perf: cache hatch/wipeout/image/mesh models per geometry epoch (F+G+H)
Add Arc<Vec<...>>-backed epoch caches for hatches, wipeouts, images, and meshes — the same pattern used for wires. build_primitive() now returns an O(1) Arc refcount bump on navigation frames instead of rebuilding every collection from scratch. Also wrap ImageModel.pixels in Arc<Vec<u8>> so cloning an ImageModel is O(1) regardless of image resolution. Navigation frames no longer copy pixel data, tessellated hatch boundaries, or mesh geometry — all per-frame CPU work on unchanged geometry is now eliminated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2bf4a348bf
commit
81db3c37d0
5 changed files with 209 additions and 20 deletions
|
|
@ -80,6 +80,14 @@ pub struct Scene {
|
|||
/// Maps block_handle → (entity_handle.value() → sort_handle.value()).
|
||||
/// Replaces the O(objects) linear scan inside `wires_for_block()` with an O(1) lookup.
|
||||
sort_cache: RefCell<Option<(u64, HashMap<Handle, HashMap<u64, u64>>)>>,
|
||||
/// Cached hatch fill models, keyed by geometry_epoch.
|
||||
hatch_cache: RefCell<Option<(u64, Arc<Vec<HatchModel>>)>>,
|
||||
/// Cached wipeout fill models, keyed by geometry_epoch.
|
||||
wipeout_cache: RefCell<Option<(u64, Arc<Vec<HatchModel>>)>>,
|
||||
/// Cached image models, keyed by geometry_epoch.
|
||||
image_cache: RefCell<Option<(u64, Arc<Vec<ImageModel>>)>>,
|
||||
/// Cached mesh models, keyed by geometry_epoch.
|
||||
mesh_cache: RefCell<Option<(u64, Arc<Vec<MeshModel>>)>>,
|
||||
/// Active layout name — "Model" or a paper space layout name.
|
||||
pub current_layout: String,
|
||||
/// GPU render data for hatch fills, keyed by the DXF entity Handle.
|
||||
|
|
@ -112,6 +120,10 @@ impl Scene {
|
|||
geometry_epoch: GEOMETRY_EPOCH.fetch_add(1, Ordering::Relaxed),
|
||||
wire_cache: RefCell::new(None),
|
||||
sort_cache: RefCell::new(None),
|
||||
hatch_cache: RefCell::new(None),
|
||||
wipeout_cache: RefCell::new(None),
|
||||
image_cache: RefCell::new(None),
|
||||
mesh_cache: RefCell::new(None),
|
||||
current_layout: "Model".to_string(),
|
||||
hatches: HashMap::new(),
|
||||
meshes: HashMap::new(),
|
||||
|
|
@ -397,6 +409,62 @@ impl Scene {
|
|||
(*self.entity_wires_arc()).clone()
|
||||
}
|
||||
|
||||
pub(super) fn hatch_models_arc(&self) -> Arc<Vec<HatchModel>> {
|
||||
{
|
||||
let cache = self.hatch_cache.borrow();
|
||||
if let Some((cached_epoch, ref arc)) = *cache {
|
||||
if cached_epoch == self.geometry_epoch {
|
||||
return Arc::clone(arc);
|
||||
}
|
||||
}
|
||||
}
|
||||
let arc = Arc::new(self.synced_hatch_models());
|
||||
*self.hatch_cache.borrow_mut() = Some((self.geometry_epoch, Arc::clone(&arc)));
|
||||
arc
|
||||
}
|
||||
|
||||
pub(super) fn wipeout_models_arc(&self) -> Arc<Vec<HatchModel>> {
|
||||
{
|
||||
let cache = self.wipeout_cache.borrow();
|
||||
if let Some((cached_epoch, ref arc)) = *cache {
|
||||
if cached_epoch == self.geometry_epoch {
|
||||
return Arc::clone(arc);
|
||||
}
|
||||
}
|
||||
}
|
||||
let arc = Arc::new(self.wipeout_models());
|
||||
*self.wipeout_cache.borrow_mut() = Some((self.geometry_epoch, Arc::clone(&arc)));
|
||||
arc
|
||||
}
|
||||
|
||||
pub(super) fn images_arc(&self) -> Arc<Vec<ImageModel>> {
|
||||
{
|
||||
let cache = self.image_cache.borrow();
|
||||
if let Some((cached_epoch, ref arc)) = *cache {
|
||||
if cached_epoch == self.geometry_epoch {
|
||||
return Arc::clone(arc);
|
||||
}
|
||||
}
|
||||
}
|
||||
let arc = Arc::new(self.images.values().cloned().collect());
|
||||
*self.image_cache.borrow_mut() = Some((self.geometry_epoch, Arc::clone(&arc)));
|
||||
arc
|
||||
}
|
||||
|
||||
pub(super) fn meshes_arc(&self) -> Arc<Vec<MeshModel>> {
|
||||
{
|
||||
let cache = self.mesh_cache.borrow();
|
||||
if let Some((cached_epoch, ref arc)) = *cache {
|
||||
if cached_epoch == self.geometry_epoch {
|
||||
return Arc::clone(arc);
|
||||
}
|
||||
}
|
||||
}
|
||||
let arc = Arc::new(self.meshes.values().cloned().collect());
|
||||
*self.mesh_cache.borrow_mut() = Some((self.geometry_epoch, Arc::clone(&arc)));
|
||||
arc
|
||||
}
|
||||
|
||||
/// Wires that should participate in hit-testing, snapping, and selection.
|
||||
///
|
||||
/// - Model layout: all entity wires (same as entity_wires).
|
||||
|
|
|
|||
Loading…
Reference in a new issue