aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2023-02-08 18:36:36 +0100
committerGitHub <noreply@github.com>2023-02-08 18:36:36 +0100
commit7404f481ba8eb2291bef14323c0e6f9ee0157dfb (patch)
tree7f5f38ce47a69489534ed289a624b3a791d6a769
parent2294210660056df2f8abb277776cfd68f3fb1156 (diff)
parent28e26e05bc4cd2bd8e1abc2dd4d720fd9199456d (diff)
downloadrneovim-7404f481ba8eb2291bef14323c0e6f9ee0157dfb.tar.gz
rneovim-7404f481ba8eb2291bef14323c0e6f9ee0157dfb.tar.bz2
rneovim-7404f481ba8eb2291bef14323c0e6f9ee0157dfb.zip
Merge pull request #22172 from bfredl/cells
perf(ui): mitigate redraw latency regression from TUI refactor
-rw-r--r--runtime/doc/options.txt14
-rw-r--r--src/nvim/api/ui.c10
-rw-r--r--src/nvim/option_defs.h2
-rw-r--r--src/nvim/optionstr.c3
-rw-r--r--src/nvim/ui.c6
-rw-r--r--src/nvim/ui.h2
6 files changed, 30 insertions, 7 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 1f91b89322..17f1c822ff 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -4765,7 +4765,7 @@ A jump table for the options with a short description can be found at |Q_op|.
Flags to change the way redrawing works, for debugging purposes.
Most useful with 'writedelay' set to some reasonable value.
Supports the following flags:
- compositor Indicate what redraws come from the compositor
+ compositor Indicate each redraw event handled by the compositor
by briefly flashing the redrawn regions in colors
indicating the redraw type. These are the highlight
groups used (and their default colors):
@@ -4777,6 +4777,11 @@ A jump table for the options with a short description can be found at |Q_op|.
RedrawDebugRecompose guibg=Red redraw generated by the
compositor itself, due to a
grid being moved or deleted.
+ line introduce a delay after each line drawn on the screen.
+ When using the TUI or another single-grid UI, "compositor"
+ gives more information and should be preferred (every
+ line is processed as a separate event by the compositor)
+ flush introduce a delay after each "flush" event.
nothrottle Turn off throttling of the message grid. This is an
optimization that joins many small scrolls to one
larger scroll when drawing the message area (with
@@ -4786,7 +4791,7 @@ A jump table for the options with a short description can be found at |Q_op|.
useful when running nvim inside a debugger (and
the test suite).
nodelta Send all internally redrawn cells to the UI, even if
- they are unchanged from the already displayed state.
+ they are unchanged from the already displayed state.
*'redrawtime'* *'rdt'*
'redrawtime' 'rdt' number (default 2000)
@@ -7372,8 +7377,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'writedelay'* *'wd'*
'writedelay' 'wd' number (default 0)
global
- The number of milliseconds to wait for each character sent to the
- screen. When positive, characters are sent to the UI one by one.
- See 'redrawdebug' for more options. For debugging purposes.
+ Only takes effect toghether with 'redrawdebug'.
+ The number of milliseconds to wait after each line or each flush
vim:tw=78:ts=8:noet:ft=help:norl:
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index e67607a7e4..3ad625234c 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -202,6 +202,7 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictiona
data->flushed_events = false;
data->ncalls_pos = NULL;
data->ncalls = 0;
+ data->ncells_pending = 0;
data->buf_wptr = data->buf;
data->temp_buf = NULL;
data->wildmenu_active = false;
@@ -854,18 +855,25 @@ void remote_ui_raw_line(UI *ui, Integer grid, Integer row, Integer startcol, Int
mpack_uint(buf, repeat);
}
}
+ data->ncells_pending += MIN(repeat, 2);
last_hl = attrs[i];
repeat = 0;
}
}
if (endcol < clearcol) {
nelem++;
+ data->ncells_pending += 1;
mpack_array(buf, 3);
mpack_str(buf, " ");
mpack_uint(buf, (uint32_t)clearattr);
mpack_uint(buf, (uint32_t)(clearcol - endcol));
}
mpack_w2(&lenpos, nelem);
+
+ if (data->ncells_pending > 500) {
+ // pass of cells to UI to let it start processing them
+ remote_ui_flush_buf(ui);
+ }
} else {
for (int i = 0; i < endcol - startcol; i++) {
remote_ui_cursor_goto(ui, row, startcol + i);
@@ -917,6 +925,8 @@ void remote_ui_flush_buf(UI *ui)
// we have sent events to the client, but possibly not yet the final "flush"
// event.
data->flushed_events = true;
+
+ data->ncells_pending = 0;
}
/// An intentional flush (vsync) when Nvim is finished redrawing the screen
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index d190fc5999..0e0cc4c983 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -630,6 +630,8 @@ EXTERN unsigned rdb_flags;
#define RDB_NOTHROTTLE 0x002
#define RDB_INVALID 0x004
#define RDB_NODELTA 0x008
+#define RDB_LINE 0x010
+#define RDB_FLUSH 0x020
EXTERN long p_rdt; // 'redrawtime'
EXTERN long p_re; // 'regexpengine'
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 901477d869..7efbeadb2f 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -125,7 +125,8 @@ static char *(p_spo_values[]) = { "camel", "noplainbuffer", NULL };
static char *(p_icm_values[]) = { "nosplit", "split", NULL };
static char *(p_jop_values[]) = { "stack", "view", NULL };
static char *(p_tpf_values[]) = { "BS", "HT", "FF", "ESC", "DEL", "C0", "C1", NULL };
-static char *(p_rdb_values[]) = { "compositor", "nothrottle", "invalid", "nodelta", NULL };
+static char *(p_rdb_values[]) = { "compositor", "nothrottle", "invalid", "nodelta", "line",
+ "flush", NULL };
static char *(p_sloc_values[]) = { "last", "statusline", "tabline", NULL };
/// All possible flags for 'shm'.
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index 9f1cb87eb0..b22dc4a661 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -419,7 +419,7 @@ void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol,
(const sattr_T *)grid->attrs + off);
// 'writedelay': flush & delay each time.
- if (p_wd && !(rdb_flags & RDB_COMPOSITOR)) {
+ if (p_wd && (rdb_flags & RDB_LINE)) {
// If 'writedelay' is active, set the cursor to indicate what was drawn.
ui_call_grid_cursor_goto(grid->handle, row,
MIN(clearcol, (int)grid->cols - 1));
@@ -510,6 +510,10 @@ void ui_flush(void)
pending_has_mouse = has_mouse;
}
ui_call_flush();
+
+ if (p_wd && (rdb_flags & RDB_FLUSH)) {
+ os_microdelay((uint64_t)labs(p_wd) * 1000U, true);
+ }
}
/// Check if 'mouse' is active for the current mode
diff --git a/src/nvim/ui.h b/src/nvim/ui.h
index 9140a9f1f3..e83f93eb07 100644
--- a/src/nvim/ui.h
+++ b/src/nvim/ui.h
@@ -79,6 +79,8 @@ typedef struct {
uint32_t ncalls; ///< number of calls made to the current event (plus one for the name!)
bool flushed_events; ///< events where sent to client without "flush" event
+ size_t ncells_pending; ///< total number of cells since last buffer flush
+
int hl_id; // Current highlight for legacy put event.
Integer cursor_row, cursor_col; // Intended visible cursor position.