Baseline: Improve selection rendering for large quantities from 270ms to 90ms
This commit is contained in:
parent
e3a4d174de
commit
ca21626064
2 changed files with 86 additions and 45 deletions
|
@ -90,7 +90,7 @@ use std::{
|
||||||
cmp::{self, Ordering, Reverse},
|
cmp::{self, Ordering, Reverse},
|
||||||
mem,
|
mem,
|
||||||
num::NonZeroU32,
|
num::NonZeroU32,
|
||||||
ops::{ControlFlow, Deref, DerefMut, Range},
|
ops::{ControlFlow, Deref, DerefMut, Range, RangeInclusive},
|
||||||
path::Path,
|
path::Path,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
|
@ -7549,6 +7549,68 @@ impl Editor {
|
||||||
results
|
results
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn selected_rows<T: 'static>(
|
||||||
|
&self,
|
||||||
|
search_range: Range<Anchor>,
|
||||||
|
display_snapshot: &DisplaySnapshot,
|
||||||
|
theme: &Theme,
|
||||||
|
) -> Vec<RangeInclusive<u32>> {
|
||||||
|
let mut results = Vec::new();
|
||||||
|
let buffer = &display_snapshot.buffer_snapshot;
|
||||||
|
let Some((color_fetcher, ranges)) = self.background_highlights
|
||||||
|
.get(&TypeId::of::<T>()) else {
|
||||||
|
return vec![];
|
||||||
|
};
|
||||||
|
|
||||||
|
let color = color_fetcher(theme);
|
||||||
|
let start_ix = match ranges.binary_search_by(|probe| {
|
||||||
|
let cmp = probe.end.cmp(&search_range.start, buffer);
|
||||||
|
if cmp.is_gt() {
|
||||||
|
Ordering::Greater
|
||||||
|
} else {
|
||||||
|
Ordering::Less
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Ok(i) | Err(i) => i,
|
||||||
|
};
|
||||||
|
let mut push_region = |start, end| {
|
||||||
|
if let (Some(start_display), Some(end_display)) = (start, end) {
|
||||||
|
results.push(start_display..=end_display);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut start_row = None;
|
||||||
|
let mut end_row = None;
|
||||||
|
for range in &ranges[start_ix..] {
|
||||||
|
if range.start.cmp(&search_range.end, buffer).is_ge() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let start = range.start.to_point(buffer).row;
|
||||||
|
let end = range.end.to_point(buffer).row;
|
||||||
|
if start_row.is_none() {
|
||||||
|
assert_eq!(end_row, None);
|
||||||
|
start_row = Some(start);
|
||||||
|
end_row = Some(end);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if let Some(current_end) = end_row.as_mut() {
|
||||||
|
if start > *current_end + 1 {
|
||||||
|
push_region(start_row, end_row);
|
||||||
|
start_row = Some(start);
|
||||||
|
end_row = Some(end);
|
||||||
|
} else {
|
||||||
|
// Merge two hunks.
|
||||||
|
*current_end = end;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// We might still have a hunk that was not rendered (if there was a search hit on the last line)
|
||||||
|
push_region(start_row, end_row);
|
||||||
|
|
||||||
|
results
|
||||||
|
}
|
||||||
|
|
||||||
pub fn highlight_text<T: 'static>(
|
pub fn highlight_text<T: 'static>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ranges: Vec<Range<Anchor>>,
|
ranges: Vec<Range<Anchor>>,
|
||||||
|
|
|
@ -1107,8 +1107,6 @@ impl EditorElement {
|
||||||
if layout.is_singleton && scrollbar_settings.selections {
|
if layout.is_singleton && scrollbar_settings.selections {
|
||||||
let start_anchor = Anchor::min();
|
let start_anchor = Anchor::min();
|
||||||
let end_anchor = Anchor::max();
|
let end_anchor = Anchor::max();
|
||||||
let mut start_row = None;
|
|
||||||
let mut end_row = None;
|
|
||||||
let color = scrollbar_theme.selections;
|
let color = scrollbar_theme.selections;
|
||||||
let border = Border {
|
let border = Border {
|
||||||
width: 1.,
|
width: 1.,
|
||||||
|
@ -1119,54 +1117,35 @@ impl EditorElement {
|
||||||
bottom: false,
|
bottom: false,
|
||||||
left: true,
|
left: true,
|
||||||
};
|
};
|
||||||
let mut push_region = |start, end| {
|
let mut push_region = |start: u32, end: u32| {
|
||||||
if let (Some(start_display), Some(end_display)) = (start, end) {
|
let start_y = y_for_row(start as f32);
|
||||||
let start_y = y_for_row(start_display as f32);
|
let mut end_y = y_for_row(end as f32);
|
||||||
let mut end_y = y_for_row(end_display as f32);
|
if end_y - start_y < 1. {
|
||||||
if end_y - start_y < 1. {
|
end_y = start_y + 1.;
|
||||||
end_y = start_y + 1.;
|
|
||||||
}
|
|
||||||
let bounds = RectF::from_points(vec2f(left, start_y), vec2f(right, end_y));
|
|
||||||
|
|
||||||
scene.push_quad(Quad {
|
|
||||||
bounds,
|
|
||||||
background: Some(color),
|
|
||||||
border,
|
|
||||||
corner_radius: style.thumb.corner_radius,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
let bounds = RectF::from_points(vec2f(left, start_y), vec2f(right, end_y));
|
||||||
|
|
||||||
|
scene.push_quad(Quad {
|
||||||
|
bounds,
|
||||||
|
background: Some(color),
|
||||||
|
border,
|
||||||
|
corner_radius: style.thumb.corner_radius,
|
||||||
|
})
|
||||||
};
|
};
|
||||||
for (row, _) in &editor
|
let start = std::time::Instant::now();
|
||||||
.background_highlights_in_range_for::<crate::items::BufferSearchHighlights>(
|
|
||||||
|
let background_ranges = editor
|
||||||
|
.selected_rows::<crate::items::BufferSearchHighlights>(
|
||||||
start_anchor..end_anchor,
|
start_anchor..end_anchor,
|
||||||
&layout.position_map.snapshot,
|
&layout.position_map.snapshot,
|
||||||
&theme,
|
&theme,
|
||||||
)
|
);
|
||||||
{
|
dbg!(start.elapsed().as_millis());
|
||||||
let start_display = row.start;
|
for row in background_ranges {
|
||||||
let end_display = row.end;
|
let start = row.start();
|
||||||
|
let end = row.end();
|
||||||
if start_row.is_none() {
|
push_region(*start, *end);
|
||||||
assert_eq!(end_row, None);
|
|
||||||
start_row = Some(start_display.row());
|
|
||||||
end_row = Some(end_display.row());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if let Some(current_end) = end_row.as_mut() {
|
|
||||||
if start_display.row() > *current_end + 1 {
|
|
||||||
push_region(start_row, end_row);
|
|
||||||
start_row = Some(start_display.row());
|
|
||||||
end_row = Some(end_display.row());
|
|
||||||
} else {
|
|
||||||
// Merge two hunks.
|
|
||||||
*current_end = end_display.row();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
unreachable!();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// We might still have a hunk that was not rendered (if there was a search hit on the last line)
|
|
||||||
push_region(start_row, end_row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if layout.is_singleton && scrollbar_settings.git_diff {
|
if layout.is_singleton && scrollbar_settings.git_diff {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue