From c639c185d3cc6645a1b36aa451be8a3011baf7df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Sun, 17 Aug 2025 00:04:45 +0200 Subject: [PATCH] Fix naive merging logic in `layer::Stack` --- graphics/src/layer.rs | 13 ++++++++----- tiny_skia/src/layer.rs | 18 +++++++++++++++++- wgpu/src/layer.rs | 22 +++++++++++++++++++++- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/graphics/src/layer.rs b/graphics/src/layer.rs index f404ec20..4f4219fd 100644 --- a/graphics/src/layer.rs +++ b/graphics/src/layer.rs @@ -24,17 +24,20 @@ pub trait Layer: Default { /// Clears all the layers contents and resets its bounds. fn reset(&mut self); - /// Returns the level of the [`Layer`]. + /// Returns the start level of the [`Layer`]. /// - /// The level is the lowest "sublayer" index inside of a [`Layer`]. + /// A level is a "sublayer" index inside of a [`Layer`]. /// /// A [`Layer`] may draw multiple primitive types in a certain order. /// The level represents the lowest index of the primitive types it /// contains. /// /// Two layers A and B can therefore be merged if they have the same bounds, - /// and the level of A is lower or equal than the level of B. - fn level(&self) -> usize; + /// and the end level of A is lower or equal than the start level of B. + fn start(&self) -> usize; + + /// Returns the end level of the [`Layer`]. + fn end(&self) -> usize; /// Merges a [`Layer`] with the current one. fn merge(&mut self, _layer: &mut Self); @@ -106,7 +109,7 @@ impl Stack { let previous_layer = &mut head[previous]; let current_layer = &mut tail[self.current - previous - 1]; - if previous_layer.level() <= current_layer.level() + if previous_layer.end() <= current_layer.start() && previous_layer.bounds() == current_layer.bounds() { previous_layer.merge(current_layer); diff --git a/tiny_skia/src/layer.rs b/tiny_skia/src/layer.rs index 65e8d469..b14458b8 100644 --- a/tiny_skia/src/layer.rs +++ b/tiny_skia/src/layer.rs @@ -303,7 +303,23 @@ impl graphics::Layer for Layer { self.images.clear(); } - fn level(&self) -> usize { + fn start(&self) -> usize { + if !self.quads.is_empty() { + return 0; + } + + if !self.primitives.is_empty() { + return 1; + } + + if !self.images.is_empty() { + return 2; + } + + return 3; + } + + fn end(&self) -> usize { if !self.text.is_empty() { return 3; } diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index 10b1431d..93968886 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -293,7 +293,27 @@ impl graphics::Layer for Layer { self.pending_text.clear(); } - fn level(&self) -> usize { + fn start(&self) -> usize { + if !self.quads.is_empty() { + return 0; + } + + if !self.triangles.is_empty() { + return 1; + } + + if !self.primitives.is_empty() { + return 2; + } + + if !self.images.is_empty() { + return 3; + } + + 4 + } + + fn end(&self) -> usize { if !self.text.is_empty() { return 4; }