aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2018-05-19 14:47:16 -0700
committerJoe Wilm <joe@jwilm.com>2018-05-29 21:01:44 -0700
commit63de0559dd3105000ffe56376af4641b0908c34b (patch)
tree01fc0f36ee05b839e7a14eea6a06d2e471fb4d67
parentf897c998e9166a1fd9e2889ad806a7af954f754d (diff)
downloadalacritty-63de0559dd3105000ffe56376af4641b0908c34b.tar.gz
alacritty-63de0559dd3105000ffe56376af4641b0908c34b.zip
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.
-rw-r--r--src/grid/mod.rs15
-rw-r--r--src/grid/storage.rs28
2 files changed, 36 insertions, 7 deletions
diff --git a/src/grid/mod.rs b/src/grid/mod.rs
index 9b36fcdf..0998d640 100644
--- a/src/grid/mod.rs
+++ b/src/grid/mod.rs
@@ -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
diff --git a/src/grid/storage.rs b/src/grid/storage.rs
index e7c1a307..eb87c622 100644
--- a/src/grid/storage.rs
+++ b/src/grid/storage.rs
@@ -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.