Optimize inserting lots of primitives with the same StackingOrder

Antonio Scandurra created

Change summary

crates/gpui2/src/scene.rs | 29 +++++++++++++++++++++--------
1 file changed, 21 insertions(+), 8 deletions(-)

Detailed changes

crates/gpui2/src/scene.rs 🔗

@@ -17,6 +17,7 @@ pub type LayerId = u32;
 pub type DrawOrder = u32;
 
 pub(crate) struct SceneBuilder {
+    last_order: Option<(StackingOrder, LayerId)>,
     layers_by_order: BTreeMap<StackingOrder, LayerId>,
     splitter: BspSplitter<(PrimitiveKind, usize)>,
     shadows: Vec<Shadow>,
@@ -31,6 +32,7 @@ pub(crate) struct SceneBuilder {
 impl Default for SceneBuilder {
     fn default() -> Self {
         SceneBuilder {
+            last_order: None,
             layers_by_order: BTreeMap::new(),
             splitter: BspSplitter::new(),
             shadows: Vec::new(),
@@ -156,14 +158,7 @@ impl SceneBuilder {
             return;
         }
 
-        let layer_id = if let Some(layer_id) = self.layers_by_order.get(order) {
-            *layer_id
-        } else {
-            let next_id = self.layers_by_order.len() as LayerId;
-            self.layers_by_order.insert(order.clone(), next_id);
-            next_id
-        };
-
+        let layer_id = self.layer_id_for_order(order);
         match primitive {
             Primitive::Shadow(mut shadow) => {
                 shadow.order = layer_id;
@@ -196,6 +191,24 @@ impl SceneBuilder {
             }
         }
     }
+
+    fn layer_id_for_order(&mut self, order: &StackingOrder) -> u32 {
+        if let Some((last_order, last_layer_id)) = self.last_order.as_ref() {
+            if last_order == order {
+                return *last_layer_id;
+            }
+        };
+
+        let layer_id = if let Some(layer_id) = self.layers_by_order.get(order) {
+            *layer_id
+        } else {
+            let next_id = self.layers_by_order.len() as LayerId;
+            self.layers_by_order.insert(order.clone(), next_id);
+            next_id
+        };
+        self.last_order = Some((order.clone(), layer_id));
+        layer_id
+    }
 }
 
 pub struct Scene {