Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reuse allocations if available when swapping alternate state #3182

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 33 additions & 18 deletions zellij-server/src/panes/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use super::sixel::{PixelRect, SixelGrid, SixelImageStore};
use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::HashMap;
use std::mem;
use std::rc::Rc;
use zellij_utils::data::Style;
use zellij_utils::errors::prelude::*;
Expand Down Expand Up @@ -2628,25 +2629,39 @@ impl Perform for Grid {
},
1049 => {
// enter alternate buffer
let current_lines_above =
std::mem::replace(&mut self.lines_above, VecDeque::new());
let current_viewport =
std::mem::replace(&mut self.viewport, vec![Row::new().canonical()]);
let current_cursor = std::mem::replace(
&mut self.cursor,
Cursor::new(0, 0, self.styled_underlines),
);
let next_cursor = Cursor::new(0, 0, self.styled_underlines);
let canonical_row = Row::new().canonical();
let char_cell_size = self.character_cell_size.clone();
let sixel_image_store = self.sixel_grid.sixel_image_store.clone();
let alternate_sixelgrid = std::mem::replace(
&mut self.sixel_grid,
SixelGrid::new(self.character_cell_size.clone(), sixel_image_store),
);
self.alternate_screen_state = Some(AlternateScreenState::new(
current_lines_above,
current_viewport,
current_cursor,
alternate_sixelgrid,
));

let mut next_state =
if let Some(mut alt_state) = self.alternate_screen_state.take() {
// Reuse the alternate state's allocations if available
alt_state.lines_above.clear();
alt_state.viewport.clear();
alt_state.viewport.push(canonical_row);
alt_state.cursor = next_cursor;
alt_state
.sixel_grid
.reset(char_cell_size, sixel_image_store);
alt_state
} else {
// If not available, recreate a default state
AlternateScreenState::new(
VecDeque::new(),
vec![canonical_row],
next_cursor,
SixelGrid::new(char_cell_size, sixel_image_store),
)
};

// Swap the current state with the default state constructed above
mem::swap(&mut self.lines_above, &mut next_state.lines_above);
mem::swap(&mut self.viewport, &mut next_state.viewport);
mem::swap(&mut self.cursor, &mut next_state.cursor);
mem::swap(&mut self.sixel_grid, &mut next_state.sixel_grid);
self.alternate_screen_state = Some(next_state);

self.clear_viewport_before_rendering = true;
self.scrollback_buffer_lines =
self.recalculate_scrollback_buffer_count();
Expand Down
22 changes: 22 additions & 0 deletions zellij-server/src/panes/sixel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,28 @@ impl SixelGrid {
..Default::default()
}
}

/// Create the same structure as [`new`] but reuse allocations
pub fn reset(
&mut self,
character_cell_size: Rc<RefCell<Option<SizeInPixels>>>,
sixel_image_store: Rc<RefCell<SixelImageStore>>,
) {
let previous_cell_size = *character_cell_size.borrow();

self.sixel_image_locations.clear();
self.image_ids_to_reap.clear();

*self = SixelGrid {
sixel_image_locations: std::mem::take(&mut self.sixel_image_locations),
image_ids_to_reap: std::mem::take(&mut self.image_ids_to_reap),
previous_cell_size,
character_cell_size,
sixel_image_store,
..Default::default()
};
}

pub fn handle_byte(&mut self, byte: u8) {
self.sixel_parser
.as_mut()
Expand Down
Loading