Skip to content

Commit 95d3ffd

Browse files
committed
[rasterize][active-edge] do not use vecdeque
1 parent 6089675 commit 95d3ffd

File tree

2 files changed

+46
-46
lines changed

2 files changed

+46
-46
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rasterize"
3-
version = "0.4.3"
3+
version = "0.4.4"
44
authors = ["Pavel Aslanov <asl.pavel@gmail.com>"]
55
description = "Simple and small 2D rendering library"
66
edition = "2021"

src/rasterize.rs

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::{
3131
};
3232
#[cfg(feature = "serde")]
3333
use serde::{Deserialize, Serialize};
34-
use std::{cmp::min, collections::VecDeque, fmt, rc::Rc, sync::Arc};
34+
use std::{cmp::min, fmt, rc::Rc, sync::Arc};
3535

3636
/// Size of the rectangular area with integer width and height
3737
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
@@ -577,9 +577,9 @@ impl Rasterizer for ActiveEdgeRasterizer {
577577
/// Iterator over rasterized pixels, by active-edge rasterizer
578578
pub struct ActiveEdgeIter {
579579
// all edges sorted by `Edge::row` in descending order
580-
edge_inactive: Vec<Vec<Edge>>,
580+
edge_inactive: Vec<Edge>,
581581
// edge is activated when `Edge::row` is reached
582-
edge_active: VecDeque<Edge>,
582+
edge_active: Vec<Edge>,
583583
// row iterators are created for all active edges on
584584
iters_inactive: Vec<EdgeRowIter>,
585585
// accumulated iterator over all active (x >= EdgeRowIter::column) row iterators
@@ -598,21 +598,19 @@ pub struct ActiveEdgeIter {
598598

599599
impl ActiveEdgeIter {
600600
pub fn new(size: Size, fill_rule: FillRule, lines: impl Iterator<Item = Line>) -> Self {
601-
let mut edge_table: Vec<Vec<Edge>> = Vec::new();
602-
edge_table.resize_with(size.height, Default::default);
603-
for line in lines.flat_map(|line| {
604-
let (line, rest) = split_at_zero_x(line);
605-
std::iter::once(line).chain(rest)
606-
}) {
607-
if let Some(edge) = Edge::new(line) {
608-
if edge.row >= size.height {
609-
continue;
610-
}
611-
edge_table[size.height - edge.row - 1].push(edge);
612-
}
613-
}
601+
let mut edge_inactive: Vec<Edge> = lines
602+
.flat_map(|line| {
603+
let (line, rest) = split_at_zero_x(line);
604+
std::iter::once(line).chain(rest)
605+
})
606+
.filter_map(|line| {
607+
let edge = Edge::new(line)?;
608+
(edge.row < size.height).then_some(edge)
609+
})
610+
.collect();
611+
edge_inactive.sort_unstable_by(|l, r| l.row.cmp(&r.row).reverse());
614612
let mut this = Self {
615-
edge_inactive: edge_table,
613+
edge_inactive,
616614
edge_active: Default::default(),
617615
iters_inactive: Default::default(),
618616
iters_active: EdgeAccIter::new(),
@@ -633,25 +631,28 @@ impl ActiveEdgeIter {
633631
self.iters_active.clear();
634632

635633
// create new row iterators for all active edges
636-
for _ in 0..self.edge_active.len() {
637-
if let Some(edge) = self.edge_active.pop_front() {
638-
// split edge into row iterator and the rest part
639-
if let Some((edge_rest, iter)) = edge.next_row() {
640-
self.iters_inactive.push(iter);
641-
self.edge_active.push_back(edge_rest);
642-
}
634+
self.edge_active.retain_mut(|edge| {
635+
// split edge into row iterator and the rest part
636+
if let Some((edge_rest, iter)) = edge.next_row() {
637+
self.iters_inactive.push(iter);
638+
*edge = edge_rest;
639+
true
640+
} else {
641+
false
643642
}
644-
}
643+
});
645644

646645
// activate new edges
647-
if let Some(edges) = self.edge_inactive.pop() {
648-
for edge in edges {
649-
if let Some((edge, iter)) = edge.next_row() {
650-
self.iters_inactive.push(iter);
651-
self.edge_active.push_back(edge);
652-
}
653-
}
654-
}
646+
let activate_index = self
647+
.edge_inactive
648+
.partition_point(|edge| edge.row > self.row);
649+
self.edge_inactive
650+
.drain(activate_index..)
651+
.filter_map(|edge| edge.next_row())
652+
.for_each(|(edge, iter)| {
653+
self.iters_inactive.push(iter);
654+
self.edge_active.push(edge);
655+
});
655656

656657
// sort iterator by column
657658
self.iters_inactive
@@ -738,7 +739,7 @@ fn next_ceil(value: Scalar) -> Scalar {
738739
/// Edge represents unconsumed part of the line segments
739740
///
740741
/// `Edge::line` is always directed from point with lower to higher `y` coordinate.
741-
#[derive(Debug)]
742+
#[derive(Debug, Clone, Copy)]
742743
struct Edge {
743744
// unconsumed part of the line segment
744745
line: Line,
@@ -791,8 +792,8 @@ impl Edge {
791792

792793
/// Split edge into row iterator and reminder of the edge not covered by
793794
/// the row iterator.
794-
fn next_row(self) -> Option<(Edge, EdgeRowIter)> {
795-
EdgeRowIter::new(self)
795+
fn next_row(&self) -> Option<(Edge, EdgeRowIter)> {
796+
EdgeRowIter::new(*self)
796797
}
797798
}
798799

@@ -878,7 +879,7 @@ impl Iterator for EdgeRowIter {
878879
///
879880
/// Sums all values returned by sub-iterators and returns it as an item.
880881
struct EdgeAccIter {
881-
iters: VecDeque<EdgeRowIter>,
882+
iters: Vec<EdgeRowIter>,
882883
}
883884

884885
impl EdgeAccIter {
@@ -890,7 +891,7 @@ impl EdgeAccIter {
890891

891892
// push new row iterator
892893
fn push(&mut self, iter: EdgeRowIter) {
893-
self.iters.push_back(iter)
894+
self.iters.push(iter)
894895
}
895896

896897
// remove all row iterator
@@ -907,14 +908,13 @@ impl Iterator for EdgeAccIter {
907908
return None;
908909
}
909910
let mut acc = 0.0;
910-
for _ in 0..self.iters.len() {
911-
if let Some(mut iter) = self.iters.pop_front() {
912-
if let Some(value) = iter.next() {
913-
acc += value;
914-
self.iters.push_back(iter);
915-
}
911+
self.iters.retain_mut(|iter| match iter.next() {
912+
Some(value) => {
913+
acc += value;
914+
true
916915
}
917-
}
916+
None => false,
917+
});
918918
Some(acc)
919919
}
920920
}

0 commit comments

Comments
 (0)