mirror of
https://github.com/neovim/neovim.git
synced 2025-10-07 02:16:31 +00:00
perf(ui): reduce allocation overhead when encoding "redraw" events
Note for external UIs: Nvim can now emit multiple "redraw" event batches before a final "flush" event is received. To retain existing behavior, clients should make sure to update visible state at an explicit "flush" event, not just the end of a "redraw" batch of event. * Get rid of copy_object() blizzard in the auto-generated ui_event layer * Special case "grid_line" by encoding screen state directly to msgpack events with no intermediate API events. * Get rid of the arcane notion of referring to the screen as the "shell" * Array and Dictionary are kvec_t:s, so define them as such. * Allow kvec_t:s, such as Arrays and Dictionaries, to be allocated with a predetermined size within an arena. * Eliminate redundant capacity checking when filling such kvec_t:s with values.
This commit is contained in:
@@ -5578,9 +5578,9 @@ void check_for_delay(bool check_msg_scroll)
|
||||
///
|
||||
/// There may be some time between setting Rows and Columns and (re)allocating
|
||||
/// default_grid arrays. This happens when starting up and when
|
||||
/// (manually) changing the shell size. Always use default_grid.rows and
|
||||
/// (manually) changing the screen size. Always use default_grid.rows and
|
||||
/// default_grid.Columns to access items in default_grid.chars[]. Use Rows
|
||||
/// and Columns for positioning text etc. where the final size of the shell is
|
||||
/// and Columns for positioning text etc. where the final size of the screen is
|
||||
/// needed.
|
||||
void screenalloc(void)
|
||||
{
|
||||
@@ -5615,14 +5615,14 @@ retry:
|
||||
*/
|
||||
++RedrawingDisabled;
|
||||
|
||||
// win_new_shellsize will recompute floats position, but tell the
|
||||
// win_new_screensize will recompute floats position, but tell the
|
||||
// compositor to not redraw them yet
|
||||
ui_comp_set_screen_valid(false);
|
||||
if (msg_grid.chars) {
|
||||
msg_grid_invalid = true;
|
||||
}
|
||||
|
||||
win_new_shellsize(); // fit the windows in the new sized shell
|
||||
win_new_screensize(); // fit the windows in the new sized screen
|
||||
|
||||
comp_col(); // recompute columns for shown command and ruler
|
||||
|
||||
@@ -6341,35 +6341,49 @@ void draw_tabline(void)
|
||||
|
||||
void ui_ext_tabline_update(void)
|
||||
{
|
||||
Array tabs = ARRAY_DICT_INIT;
|
||||
Arena arena = ARENA_EMPTY;
|
||||
arena_start(&arena, &ui_ext_fixblk);
|
||||
|
||||
size_t n_tabs = 0;
|
||||
FOR_ALL_TABS(tp) {
|
||||
Dictionary tab_info = ARRAY_DICT_INIT;
|
||||
PUT(tab_info, "tab", TABPAGE_OBJ(tp->handle));
|
||||
n_tabs++;
|
||||
}
|
||||
|
||||
Array tabs = arena_array(&arena, n_tabs);
|
||||
FOR_ALL_TABS(tp) {
|
||||
Dictionary tab_info = arena_dict(&arena, 2);
|
||||
PUT_C(tab_info, "tab", TABPAGE_OBJ(tp->handle));
|
||||
|
||||
win_T *cwp = (tp == curtab) ? curwin : tp->tp_curwin;
|
||||
get_trans_bufname(cwp->w_buffer);
|
||||
PUT(tab_info, "name", STRING_OBJ(cstr_to_string((char *)NameBuff)));
|
||||
PUT_C(tab_info, "name", STRING_OBJ(arena_string(&arena, cstr_as_string((char *)NameBuff))));
|
||||
|
||||
ADD(tabs, DICTIONARY_OBJ(tab_info));
|
||||
ADD_C(tabs, DICTIONARY_OBJ(tab_info));
|
||||
}
|
||||
|
||||
Array buffers = ARRAY_DICT_INIT;
|
||||
size_t n_buffers = 0;
|
||||
FOR_ALL_BUFFERS(buf) {
|
||||
n_buffers += buf->b_p_bl ? 1 : 0;
|
||||
}
|
||||
|
||||
Array buffers = arena_array(&arena, n_buffers);
|
||||
FOR_ALL_BUFFERS(buf) {
|
||||
// Do not include unlisted buffers
|
||||
if (!buf->b_p_bl) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Dictionary buffer_info = ARRAY_DICT_INIT;
|
||||
PUT(buffer_info, "buffer", BUFFER_OBJ(buf->handle));
|
||||
Dictionary buffer_info = arena_dict(&arena, 2);
|
||||
PUT_C(buffer_info, "buffer", BUFFER_OBJ(buf->handle));
|
||||
|
||||
get_trans_bufname(buf);
|
||||
PUT(buffer_info, "name", STRING_OBJ(cstr_to_string((char *)NameBuff)));
|
||||
PUT_C(buffer_info, "name", STRING_OBJ(arena_string(&arena, cstr_as_string((char *)NameBuff))));
|
||||
|
||||
ADD(buffers, DICTIONARY_OBJ(buffer_info));
|
||||
ADD_C(buffers, DICTIONARY_OBJ(buffer_info));
|
||||
}
|
||||
|
||||
ui_call_tabline_update(curtab->handle, tabs, curbuf->handle, buffers);
|
||||
arena_mem_free(arena_finish(&arena), &ui_ext_fixblk);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6618,11 +6632,11 @@ static void win_redr_ruler(win_T *wp, bool always)
|
||||
}
|
||||
|
||||
if (ui_has(kUIMessages) && !part_of_status) {
|
||||
Array content = ARRAY_DICT_INIT;
|
||||
Array chunk = ARRAY_DICT_INIT;
|
||||
ADD(chunk, INTEGER_OBJ(attr));
|
||||
ADD(chunk, STRING_OBJ(cstr_to_string((char *)buffer)));
|
||||
ADD(content, ARRAY_OBJ(chunk));
|
||||
MAXSIZE_TEMP_ARRAY(content, 1);
|
||||
MAXSIZE_TEMP_ARRAY(chunk, 2);
|
||||
ADD_C(chunk, INTEGER_OBJ(attr));
|
||||
ADD_C(chunk, STRING_OBJ(cstr_as_string((char *)buffer)));
|
||||
ADD_C(content, ARRAY_OBJ(chunk));
|
||||
ui_call_msg_ruler(content);
|
||||
did_show_ext_ruler = true;
|
||||
} else {
|
||||
@@ -6744,7 +6758,7 @@ static void margin_columns_win(win_T *wp, int *left_col, int *right_col)
|
||||
prev_col_off = cur_col_off;
|
||||
}
|
||||
|
||||
/// Set dimensions of the Nvim application "shell".
|
||||
/// Set dimensions of the Nvim application "screen".
|
||||
void screen_resize(int width, int height)
|
||||
{
|
||||
// Avoid recursiveness, can happen when setting the window size causes
|
||||
@@ -6775,7 +6789,7 @@ void screen_resize(int width, int height)
|
||||
|
||||
Rows = height;
|
||||
Columns = width;
|
||||
check_shellsize();
|
||||
check_screensize();
|
||||
int max_p_ch = Rows - min_rows() + 1;
|
||||
if (!ui_has(kUIMessages) && p_ch > 0 && p_ch > max_p_ch) {
|
||||
p_ch = max_p_ch ? max_p_ch : 1;
|
||||
@@ -6852,49 +6866,23 @@ void screen_resize(int width, int height)
|
||||
resizing_screen = false;
|
||||
}
|
||||
|
||||
/// Check if the new Nvim application "shell" dimensions are valid.
|
||||
/// Check if the new Nvim application "screen" dimensions are valid.
|
||||
/// Correct it if it's too small or way too big.
|
||||
void check_shellsize(void)
|
||||
void check_screensize(void)
|
||||
{
|
||||
// Limit Rows and Columns to avoid an overflow in Rows * Columns.
|
||||
if (Rows < min_rows()) {
|
||||
// need room for one window and command line
|
||||
Rows = min_rows();
|
||||
} else if (Rows > 1000) {
|
||||
Rows = 1000;
|
||||
}
|
||||
limit_screen_size();
|
||||
}
|
||||
|
||||
// Limit Rows and Columns to avoid an overflow in Rows * Columns.
|
||||
void limit_screen_size(void)
|
||||
{
|
||||
if (Columns < MIN_COLUMNS) {
|
||||
Columns = MIN_COLUMNS;
|
||||
} else if (Columns > 10000) {
|
||||
Columns = 10000;
|
||||
}
|
||||
|
||||
if (Rows > 1000) {
|
||||
Rows = 1000;
|
||||
}
|
||||
}
|
||||
|
||||
void win_new_shellsize(void)
|
||||
{
|
||||
static long old_Rows = 0;
|
||||
static long old_Columns = 0;
|
||||
|
||||
if (old_Rows != Rows) {
|
||||
// If 'window' uses the whole screen, keep it using that.
|
||||
// Don't change it when set with "-w size" on the command line.
|
||||
if (p_window == old_Rows - 1 || (old_Rows == 0 && p_window == 0)) {
|
||||
p_window = Rows - 1;
|
||||
}
|
||||
old_Rows = Rows;
|
||||
shell_new_rows(); // update window sizes
|
||||
}
|
||||
if (old_Columns != Columns) {
|
||||
old_Columns = Columns;
|
||||
shell_new_columns(); // update window sizes
|
||||
}
|
||||
}
|
||||
|
||||
win_T *get_win_by_grid_handle(handle_T handle)
|
||||
|
Reference in New Issue
Block a user