From ce14fa860b7760f5511e5bf81e7611a4f788a359 Mon Sep 17 00:00:00 2001 From: xue-blood Date: Sat, 6 Feb 2021 23:59:46 +0800 Subject: [PATCH] Speed up fractal_clock painting (#152) clip unwatchable line before drawing --- egui/src/painter.rs | 3 +++ egui_demo_lib/src/apps/fractal_clock.rs | 12 ++++++++++-- emath/src/rect.rs | 8 ++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/egui/src/painter.rs b/egui/src/painter.rs index e6f368c1..531837d9 100644 --- a/egui/src/painter.rs +++ b/egui/src/painter.rs @@ -116,6 +116,9 @@ impl Painter { .add(self.clip_rect, shape) } + /// Add many shapes at once. + /// + /// Calling this once is generally faster than calling [`Self::add`] multiple times. pub fn extend(&self, shapes: Vec) { if !shapes.is_empty() { self.ctx diff --git a/egui_demo_lib/src/apps/fractal_clock.rs b/egui_demo_lib/src/apps/fractal_clock.rs index c158f96d..54c7f554 100644 --- a/egui_demo_lib/src/apps/fractal_clock.rs +++ b/egui_demo_lib/src/apps/fractal_clock.rs @@ -13,6 +13,7 @@ pub struct FractalClock { length_factor: f32, luminance_factor: f32, width_factor: f32, + line_count: usize, } impl Default for FractalClock { @@ -26,6 +27,7 @@ impl Default for FractalClock { length_factor: 0.8, luminance_factor: 0.8, width_factor: 0.9, + line_count: 0, } } } @@ -79,6 +81,7 @@ impl FractalClock { } else { ui.label("The fractal_clock clock is not showing the correct time"); }; + ui.label(format!("Painted line count: {}", self.line_count)); ui.checkbox(&mut self.paused, "Paused"); ui.add(Slider::f32(&mut self.zoom, 0.0..=1.0).text("zoom")); @@ -128,13 +131,16 @@ impl FractalClock { ]; let scale = self.zoom * rect.width().min(rect.height()); - let paint_line = |points: [Pos2; 2], color: Color32, width: f32| { + let mut shapes: Vec = Vec::new(); + let mut paint_line = |points: [Pos2; 2], color: Color32, width: f32| { let line = [ rect.center() + scale * points[0].to_vec2(), rect.center() + scale * points[1].to_vec2(), ]; - painter.line_segment([line[0], line[1]], (width, color)); + if rect.intersects(Rect::from_two_pos(line[0], line[1])) { + shapes.push(Shape::line_segment(line, (width, color))); + } }; let hand_rotations = [ @@ -199,5 +205,7 @@ impl FractalClock { std::mem::swap(&mut nodes, &mut new_nodes); } + self.line_count = shapes.len(); + painter.extend(shapes); } } diff --git a/emath/src/rect.rs b/emath/src/rect.rs index 177b6ba5..2f14f063 100644 --- a/emath/src/rect.rs +++ b/emath/src/rect.rs @@ -91,6 +91,14 @@ impl Rect { max: pos2(*x_range.end(), *y_range.end()), } } + pub fn from_two_pos(a: Pos2, b: Pos2) -> Self { + let (left, right) = if a.x > b.x { (b.x, a.x) } else { (a.x, b.x) }; + let (top, bottom) = if a.y > b.y { (b.y, a.y) } else { (a.y, b.y) }; + Rect { + min: pos2(left, top), + max: pos2(right, bottom), + } + } /// Expand by this much in each direction, keeping the center #[must_use]