mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.1.1753: use of popup window mask is inefficient
Problem: Use of popup window mask is inefficient. Solution: Precompute and cache the mask.
This commit is contained in:
@@ -673,6 +673,7 @@ apply_general_options(win_T *wp, dict_T *dict)
|
|||||||
{
|
{
|
||||||
wp->w_popup_mask = di->di_tv.vval.v_list;
|
wp->w_popup_mask = di->di_tv.vval.v_list;
|
||||||
++wp->w_popup_mask->lv_refcount;
|
++wp->w_popup_mask->lv_refcount;
|
||||||
|
VIM_CLEAR(wp->w_popup_mask_cells);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
semsg(_(e_invargval), "mask");
|
semsg(_(e_invargval), "mask");
|
||||||
@@ -2417,21 +2418,27 @@ popup_check_cursor_pos()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return TRUE if "col" / "line" matches with an entry in w_popup_mask.
|
* Update "w_popup_mask_cells".
|
||||||
* "col" and "line" are screen coordinates.
|
|
||||||
*/
|
*/
|
||||||
static int
|
static void
|
||||||
popup_masked(win_T *wp, int screencol, int screenline)
|
popup_update_mask(win_T *wp, int width, int height)
|
||||||
{
|
{
|
||||||
int col = screencol - wp->w_wincol + 1 + wp->w_popup_leftoff;
|
|
||||||
int line = screenline - wp->w_winrow + 1;
|
|
||||||
listitem_T *lio, *li;
|
listitem_T *lio, *li;
|
||||||
int width, height;
|
char_u *cells;
|
||||||
|
int row, col;
|
||||||
|
|
||||||
if (wp->w_popup_mask == NULL)
|
if (wp->w_popup_mask == NULL)
|
||||||
return FALSE;
|
return;
|
||||||
width = popup_width(wp);
|
if (wp->w_popup_mask_cells != NULL
|
||||||
height = popup_height(wp);
|
&& wp->w_popup_mask_height == height
|
||||||
|
&& wp->w_popup_mask_width == width)
|
||||||
|
return; // cache is still valid
|
||||||
|
|
||||||
|
vim_free(wp->w_popup_mask_cells);
|
||||||
|
wp->w_popup_mask_cells = alloc_clear(width * height);
|
||||||
|
if (wp->w_popup_mask_cells == NULL)
|
||||||
|
return;
|
||||||
|
cells = wp->w_popup_mask_cells;
|
||||||
|
|
||||||
for (lio = wp->w_popup_mask->lv_first; lio != NULL; lio = lio->li_next)
|
for (lio = wp->w_popup_mask->lv_first; lio != NULL; lio = lio->li_next)
|
||||||
{
|
{
|
||||||
@@ -2442,29 +2449,38 @@ popup_masked(win_T *wp, int screencol, int screenline)
|
|||||||
cols = tv_get_number(&li->li_tv);
|
cols = tv_get_number(&li->li_tv);
|
||||||
if (cols < 0)
|
if (cols < 0)
|
||||||
cols = width + cols + 1;
|
cols = width + cols + 1;
|
||||||
if (col < cols)
|
|
||||||
continue;
|
|
||||||
li = li->li_next;
|
li = li->li_next;
|
||||||
cole = tv_get_number(&li->li_tv);
|
cole = tv_get_number(&li->li_tv);
|
||||||
if (cole < 0)
|
if (cole < 0)
|
||||||
cole = width + cole + 1;
|
cole = width + cole + 1;
|
||||||
if (col > cole)
|
|
||||||
continue;
|
|
||||||
li = li->li_next;
|
li = li->li_next;
|
||||||
lines = tv_get_number(&li->li_tv);
|
lines = tv_get_number(&li->li_tv);
|
||||||
if (lines < 0)
|
if (lines < 0)
|
||||||
lines = height + lines + 1;
|
lines = height + lines + 1;
|
||||||
if (line < lines)
|
|
||||||
continue;
|
|
||||||
li = li->li_next;
|
li = li->li_next;
|
||||||
linee = tv_get_number(&li->li_tv);
|
linee = tv_get_number(&li->li_tv);
|
||||||
if (linee < 0)
|
if (linee < 0)
|
||||||
linee = height + linee + 1;
|
linee = height + linee + 1;
|
||||||
if (line > linee)
|
|
||||||
continue;
|
for (row = lines - 1; row < linee && row < height; ++row)
|
||||||
return TRUE;
|
for (col = cols - 1; col < cole && col < width; ++col)
|
||||||
|
cells[row * width + col] = 1;
|
||||||
}
|
}
|
||||||
return FALSE;
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return TRUE if "col" / "line" matches with an entry in w_popup_mask.
|
||||||
|
* "col" and "line" are screen coordinates.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
popup_masked(win_T *wp, int width, int height, int screencol, int screenline)
|
||||||
|
{
|
||||||
|
int col = screencol - wp->w_wincol + wp->w_popup_leftoff;
|
||||||
|
int line = screenline - wp->w_winrow;
|
||||||
|
|
||||||
|
return col >= 0 && col < width
|
||||||
|
&& line >= 0 && line < height
|
||||||
|
&& wp->w_popup_mask_cells[line * width + col];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2574,8 +2590,8 @@ may_update_popup_mask(int type)
|
|||||||
popup_reset_handled();
|
popup_reset_handled();
|
||||||
while ((wp = find_next_popup(TRUE)) != NULL)
|
while ((wp = find_next_popup(TRUE)) != NULL)
|
||||||
{
|
{
|
||||||
int height;
|
|
||||||
int width;
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
popup_visible = TRUE;
|
popup_visible = TRUE;
|
||||||
|
|
||||||
@@ -2584,13 +2600,16 @@ may_update_popup_mask(int type)
|
|||||||
|| wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
|
|| wp->w_popup_last_changedtick != CHANGEDTICK(wp->w_buffer))
|
||||||
popup_adjust_position(wp);
|
popup_adjust_position(wp);
|
||||||
|
|
||||||
|
width = popup_width(wp);
|
||||||
height = popup_height(wp);
|
height = popup_height(wp);
|
||||||
width = popup_width(wp) - wp->w_popup_leftoff;
|
popup_update_mask(wp, width, height);
|
||||||
for (line = wp->w_winrow;
|
for (line = wp->w_winrow;
|
||||||
line < wp->w_winrow + height && line < screen_Rows; ++line)
|
line < wp->w_winrow + height && line < screen_Rows; ++line)
|
||||||
for (col = wp->w_wincol;
|
for (col = wp->w_wincol;
|
||||||
col < wp->w_wincol + width && col < screen_Columns; ++col)
|
col < wp->w_wincol + width - wp->w_popup_leftoff
|
||||||
if (!popup_masked(wp, col, line))
|
&& col < screen_Columns; ++col)
|
||||||
|
if (wp->w_popup_mask_cells == NULL
|
||||||
|
|| !popup_masked(wp, width, height, col, line))
|
||||||
mask[line * screen_Columns + col] = wp->w_zindex;
|
mask[line * screen_Columns + col] = wp->w_zindex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -777,6 +777,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1753,
|
||||||
/**/
|
/**/
|
||||||
1752,
|
1752,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user