Avoid merging into empty layers in layer::Stack

This commit is contained in:
Héctor Ramón Jiménez 2025-08-19 08:06:25 +02:00
parent 806500048d
commit 9490d735c5
No known key found for this signature in database
GPG key ID: 7CC46565708259A7

View file

@ -143,39 +143,56 @@ impl<T: Layer> Stack<T> {
pub fn merge(&mut self) { pub fn merge(&mut self) {
self.flush(); self.flush();
// These are the layers left to process
let mut left = self.active_count; let mut left = self.active_count;
// There must be at least 2 or more layers to merge
while left > 1 { while left > 1 {
// We set our target as the topmost layer left to process
let mut current = left - 1; let mut current = left - 1;
let mut last = &self.layers[current]; let mut target = &self.layers[current];
let mut last_start = last.start(); let mut target_start = target.start();
let mut target_index = current;
// We scan downwards for a contiguous block of mergeable layer candidates
while current > 0 { while current > 0 {
let candidate = &self.layers[current - 1]; let candidate = &self.layers[current - 1];
let start = candidate.start(); let start = candidate.start();
let end = candidate.end(); let end = candidate.end();
// We skip empty layers
if end == 0 { if end == 0 {
current -= 1; current -= 1;
continue; continue;
} }
if end > last_start || candidate.bounds() != last.bounds() { // Candidate can be merged if primitive sublayers do not overlap with
// previous targets and the clipping bounds match
if end > target_start || candidate.bounds() != target.bounds() {
break; break;
} }
last = candidate; // Candidate is not empty and can be merged into
last_start = start; target = candidate;
target_start = start;
target_index = current;
current -= 1; current -= 1;
} }
let (head, tail) = self.layers.split_at_mut(current + 1); // We merge all the layers scanned into the target
let layer = &mut head[current]; //
// Since we use `target_index` instead of `current`, we
// deliberately avoid merging into empty layers.
//
// If no candidates were mergeable, this is a no-op.
let (head, tail) = self.layers.split_at_mut(target_index + 1);
let layer = &mut head[target_index];
for middle in &mut tail[0..left - current - 1] { for middle in &mut tail[0..left - target_index - 1] {
layer.merge(middle); layer.merge(middle);
} }
// Empty layers found after the target can be skipped
left = current; left = current;
} }
} }