diff --git a/graphics/src/layer.rs b/graphics/src/layer.rs index 116a24f3..ea7911f9 100644 --- a/graphics/src/layer.rs +++ b/graphics/src/layer.rs @@ -103,27 +103,7 @@ impl Stack { pub fn pop_clip(&mut self) { self.flush(); - let previous = self.previous.pop().unwrap(); - - // Try to merge contiguous layers - if previous + 1 == self.current { - let (head, tail) = self.layers.split_at_mut(previous + 1); - let previous_layer = &mut head[previous]; - let current_layer = &mut tail[0]; - - if previous_layer.end() <= current_layer.start() - && previous_layer.bounds() == current_layer.bounds() - { - previous_layer.merge(current_layer); - - // We can reuse the last layer - if self.current + 1 == self.active_count { - self.active_count -= 1; - } - } - } - - self.current = previous; + self.current = self.previous.pop().unwrap(); } /// Pushes a new [`Transformation`] in the [`Stack`]. @@ -142,13 +122,6 @@ impl Stack { let _ = self.transformations.pop(); } - /// Returns an iterator over mutable references to the layers in the [`Stack`]. - pub fn iter_mut(&mut self) -> impl Iterator { - self.flush(); - - self.layers[..self.active_count].iter_mut() - } - /// Returns an iterator over immutable references to the layers in the [`Stack`]. pub fn iter(&self) -> impl Iterator { self.layers[..self.active_count].iter() @@ -159,11 +132,37 @@ impl Stack { &self.layers[..self.active_count] } - /// Flushes and settles any primitives in the current layer of the [`Stack`]. + /// Flushes and settles any primitives in the [`Stack`]. pub fn flush(&mut self) { self.layers[self.current].flush(); } + /// Performs layer merging wherever possible. + /// + /// Flushes and settles any primitives in the [`Stack`]. + pub fn merge(&mut self) { + self.flush(); + + let mut current = 0; + + while current < self.active_count { + let (head, tail) = self.layers.split_at_mut(current + 1); + + let layer = &mut head[current]; + let mut candidate = 0; + + while let Some(next_layer) = tail.get_mut(candidate) + && layer.end() <= next_layer.start() + && layer.bounds() == next_layer.bounds() + { + layer.merge(next_layer); + candidate += 1; + } + + current += candidate + 1; + } + } + /// Clears the layers of the [`Stack`], allowing reuse. /// /// It resizes the base layer bounds to the `new_bounds`. diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index c8850e25..1ad709d0 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -301,7 +301,7 @@ impl graphics::Layer for Layer { return 0; } - if !self.triangles.is_empty() || !self.pending_meshes.is_empty() { + if !self.triangles.is_empty() { return 1; } @@ -313,7 +313,7 @@ impl graphics::Layer for Layer { return 3; } - if !self.text.is_empty() || !self.pending_text.is_empty() { + if !self.text.is_empty() { return 4; } @@ -321,7 +321,7 @@ impl graphics::Layer for Layer { } fn end(&self) -> usize { - if !self.text.is_empty() || !self.pending_text.is_empty() { + if !self.text.is_empty() { return 4; } @@ -333,7 +333,7 @@ impl graphics::Layer for Layer { return 2; } - if !self.triangles.is_empty() || !self.pending_meshes.is_empty() { + if !self.triangles.is_empty() { return 1; } diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 28f6cb48..a24677bd 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -311,7 +311,9 @@ impl Renderer { viewport.physical_size(), )); - for layer in self.layers.iter_mut() { + self.layers.merge(); + + for layer in self.layers.iter() { if physical_bounds .intersection(&(layer.bounds * scale_factor)) .and_then(Rectangle::snap)