diff --git a/src/scene/mod.rs b/src/scene/mod.rs index 14b8f7506..e69ccd290 100644 --- a/src/scene/mod.rs +++ b/src/scene/mod.rs @@ -710,6 +710,11 @@ pub struct Scene { pub(crate) model_tiles: RefCell>, /// Index of the active model tile (camera input + overlays target it). pub(crate) active_model_tile: std::cell::Cell, + /// Cache of the SDF text vertex list, keyed on `(geometry_epoch, + /// anno_scale.to_bits())`, so the per-frame collector is not re-laid-out on + /// pan / zoom. See [`Scene::sdf_text_vertices`]. + sdf_text_cache: + RefCell>)>>, /// pane_grid layout tree for the Model tab — the source of truth for the /// tile split layout, resize and focus. `model_tiles` (the renderer's /// per-pane data: camera / render-mode / grid) is kept in lock-step with @@ -959,6 +964,7 @@ impl Scene { snap_on: false, }]), active_model_tile: std::cell::Cell::new(0), + sdf_text_cache: RefCell::new(None), // One pane mapped to tile 0 — matches the single default tile above. model_panes: iced::widget::pane_grid::State::new(0).0, selection: Rc::new(RefCell::new(SelectionState::default())), diff --git a/src/scene/view/render.rs b/src/scene/view/render.rs index ff6893da9..75dc8f5e2 100644 --- a/src/scene/view/render.rs +++ b/src/scene/view/render.rs @@ -783,8 +783,31 @@ impl Scene { #[allow(dead_code)] // consumed by the text render pass in the GPU integration step pub(in crate::scene) fn sdf_text_vertices( &self, - ) -> Vec { - self.sdf_text_vertices_enabled(crate::scene::text::sdf_atlas::sdf_text_enabled()) + ) -> std::sync::Arc> { + use std::sync::Arc; + if !crate::scene::text::sdf_atlas::sdf_text_enabled() { + return Arc::new(Vec::new()); + } + // Cache keyed on (geometry_epoch, annotation scale): the run layout only + // changes when geometry or the scale changes, so pan / zoom reuses it + // instead of re-laying-out every glyph each frame. + let anno = if self.current_layout == "Model" { + self.annotation_scale + } else { + 1.0 + }; + let key = (self.geometry_epoch, anno.to_bits()); + { + let cache = self.sdf_text_cache.borrow(); + if let Some((epoch, anno_bits, verts)) = cache.as_ref() { + if *epoch == key.0 && *anno_bits == key.1 { + return verts.clone(); + } + } + } + let verts = Arc::new(self.sdf_text_vertices_enabled(true)); + *self.sdf_text_cache.borrow_mut() = Some((key.0, key.1, verts.clone())); + verts } #[allow(dead_code)] @@ -1152,7 +1175,7 @@ impl Scene { let text_verts = if inst.paper_sheet { Arc::new(Vec::new()) } else { - Arc::new(self.sdf_text_vertices()) + self.sdf_text_vertices() }; Some(ViewportData { wires: all_wires,