1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-25 14:05:41 -05:00

Shave a few cycles off Grid::scroll_up

This implementation avoids a few extra transformations by operating in
buffer-space. However, there is still a transformation from the logical
buffer-space to the underlying vector.
This commit is contained in:
Joe Wilm 2018-05-19 14:47:16 -07:00
parent f897c998e9
commit 63de0559dd
2 changed files with 36 additions and 7 deletions

View file

@ -334,7 +334,6 @@ impl<T: Copy + Clone> Grid<T> {
/// scroll_up moves lines at the bottom towards the top
///
/// This is the performance-sensitive part of scrolling.
#[inline]
pub fn scroll_up(
&mut self,
region: &Range<index::Line>,
@ -356,17 +355,21 @@ impl<T: Copy + Clone> Grid<T> {
selection.rotate(*positions as isize);
}
// Now, restore any lines outside the scroll region
for idx in (*region.end .. *self.num_lines()).rev() {
// First do the swap
self.raw.swap_lines(Line(idx), Line(idx) - positions);
// // This next loop swaps "fixed" lines outside of a scroll region
// // back into place after the rotation. The work is done in buffer-
// // space rather than terminal-space to avoid redundant
// // transformations.
let fixed_lines = *self.num_lines() - *region.end;
for i in 0..fixed_lines {
self.raw.swap(i, i + *positions);
}
// Finally, reset recycled lines
//
// Recycled lines are just above the end of the scrolling region.
for i in 0..*positions {
self.raw[region.end - i - 1].reset(&template);
self.raw[i + fixed_lines].reset(&template);
}
} else {
// Subregion rotation

View file

@ -171,12 +171,25 @@ impl<T> Storage<T> {
self.len
}
/// Compute actual index in underlying storage given the requested index.
#[inline]
pub fn raw_len(&self) -> usize {
self.inner.len()
}
/// Compute actual index in underlying storage given the requested index.
fn compute_index(&self, requested: usize) -> usize {
(requested + self.zero) % self.inner.len()
}
#[inline]
pub fn line_offset(&self) -> usize {
self.inner.len() + self.zero + *self.visible_lines
}
pub fn compute_line_index(&self, a: Line) -> usize {
(self.line_offset() - *a) % self.inner.len()
}
pub fn swap_lines(&mut self, a: Line, b: Line) {
let offset = self.inner.len() + self.zero + *self.visible_lines;
let a = (offset - *a) % self.inner.len();
@ -184,6 +197,19 @@ impl<T> Storage<T> {
self.inner.swap(a, b);
}
/// Swap two lines in raw buffer
///
/// # Panics
///
/// `swap` will panic if either `a` or `b` are out-of-bounds of the
/// underlying storage.
pub fn swap(&mut self, a: usize, b: usize) {
let a = self.compute_index(a);
let b = self.compute_index(b);
self.inner.swap(a, b);
}
/// Iterator over *logical* entries in the storage
///
/// This *does not* iterate over hidden entries.