patch 8.0.1449: slow redrawing with DirectX

Problem:    Slow redrawing with DirectX.
Solution:   Avoid calling gui_mch_flush() unnecessarily, especially when
            updating the cursor. (Ken Takata, closes #2560)
This commit is contained in:
Bram Moolenaar
2018-01-31 20:51:47 +01:00
parent 37badc898b
commit a338adcf22
19 changed files with 224 additions and 173 deletions

View File

@ -6122,7 +6122,7 @@ A jump table for the options with a short description can be found at |Q_op|.
geom pixelGeometry int 0 - 2 (see below) geom pixelGeometry int 0 - 2 (see below)
renmode renderingMode int 0 - 6 (see below) renmode renderingMode int 0 - 6 (see below)
taamode textAntialiasMode int 0 - 3 (see below) taamode textAntialiasMode int 0 - 3 (see below)
scrlines Scroll Lines int >= 0 (see below) scrlines Scroll Lines int (deprecated)
See this URL for detail (except for scrlines): See this URL for detail (except for scrlines):
https://msdn.microsoft.com/en-us/library/dd368190.aspx https://msdn.microsoft.com/en-us/library/dd368190.aspx
@ -6156,23 +6156,9 @@ A jump table for the options with a short description can be found at |Q_op|.
See this URL for detail: See this URL for detail:
https://msdn.microsoft.com/en-us/library/dd368170.aspx https://msdn.microsoft.com/en-us/library/dd368170.aspx
For scrlines: threshold for lines to be scrolled. For scrlines:
0 - Always use scrolling. (default) This was used for optimizing scrolling behavior, however this
1 - Use full page redrawing. is now deprecated. If specified, it is simply ignored.
> 1 - If the lines to be scrolled is grater or equal to the
specified value, use redrawing. Otherwise use
scrolling.
If you feel scrolling a page (CTRL-F) is too slow with DirectX
renderer, try this "scrlines" option.
When set it "1", Vim uses full page redrawing instead of
scrolling. Redrawing a page is faster than scrolling a
page in some environments.
After that, when you feel scrolling lines (CTRL-Y) becomes
slow, please try "2" or greater value for this option.
It works threshold line number to switch scrolling to
redrawing. Scrolling a few lines might be faster than
redrawing a page in some environments.
Example: > Example: >
set encoding=utf-8 set encoding=utf-8

View File

@ -2207,14 +2207,7 @@ channel_exe_cmd(channel_T *channel, ch_part_T part, typval_T *argv)
ex_redraw(&ea); ex_redraw(&ea);
showruler(FALSE); showruler(FALSE);
setcursor(); setcursor();
out_flush(); out_flush_cursor(TRUE, FALSE);
#ifdef FEAT_GUI
if (gui.in_use)
{
gui_update_cursor(TRUE, FALSE);
gui_mch_flush();
}
#endif
} }
else if (STRCMP(cmd, "expr") == 0 || STRCMP(cmd, "call") == 0) else if (STRCMP(cmd, "expr") == 0 || STRCMP(cmd, "call") == 0)
{ {

View File

@ -3451,7 +3451,7 @@ ins_compl_clear(void)
compl_orig_text = NULL; compl_orig_text = NULL;
compl_enter_selects = FALSE; compl_enter_selects = FALSE;
/* clear v:completed_item */ /* clear v:completed_item */
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc()); set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
} }
/* /*
@ -3553,8 +3553,7 @@ ins_compl_new_leader(void)
{ {
/* Show the cursor after the match, not after the redrawn text. */ /* Show the cursor after the match, not after the redrawn text. */
setcursor(); setcursor();
out_flush(); out_flush_cursor(FALSE, FALSE);
gui_update_cursor(FALSE, FALSE);
} }
#endif #endif
compl_restarting = TRUE; compl_restarting = TRUE;
@ -4704,7 +4703,7 @@ ins_compl_delete(void)
* flicker, thus we can't do that. */ * flicker, thus we can't do that. */
changed_cline_bef_curs(); changed_cline_bef_curs();
/* clear v:completed_item */ /* clear v:completed_item */
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc()); set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc_lock(VAR_FIXED));
} }
/* /*
@ -4724,7 +4723,7 @@ ins_compl_insert(int in_compl_func)
/* Set completed item. */ /* Set completed item. */
/* { word, abbr, menu, kind, info } */ /* { word, abbr, menu, kind, info } */
dict = dict_alloc(); dict = dict_alloc_lock(VAR_FIXED);
if (dict != NULL) if (dict != NULL)
{ {
dict_add_nr_str(dict, "word", 0L, dict_add_nr_str(dict, "word", 0L,
@ -4936,8 +4935,7 @@ ins_compl_next(
{ {
/* Show the cursor after the match, not after the redrawn text. */ /* Show the cursor after the match, not after the redrawn text. */
setcursor(); setcursor();
out_flush(); out_flush_cursor(FALSE, FALSE);
gui_update_cursor(FALSE, FALSE);
} }
#endif #endif

View File

@ -2972,16 +2972,10 @@ inchar(
if (wait_time == -1L || wait_time > 100L) /* flush output before waiting */ if (wait_time == -1L || wait_time > 100L) /* flush output before waiting */
{ {
cursor_on(); cursor_on();
out_flush(); out_flush_cursor(FALSE, FALSE);
#ifdef FEAT_GUI #if defined(FEAT_GUI) && defined(FEAT_MOUSESHAPE)
if (gui.in_use) if (gui.in_use && postponed_mouseshape)
{ update_mouseshape(-1);
gui_update_cursor(FALSE, FALSE);
# ifdef FEAT_MOUSESHAPE
if (postponed_mouseshape)
update_mouseshape(-1);
# endif
}
#endif #endif
} }

View File

@ -55,6 +55,7 @@ enum {
static void gui_attempt_start(void); static void gui_attempt_start(void);
static int can_update_cursor = TRUE; /* can display the cursor */ static int can_update_cursor = TRUE; /* can display the cursor */
static int disable_flush = 0; /* If > 0, gui_mch_flush() is disabled. */
/* /*
* The Athena scrollbars can move the thumb to after the end of the scrollbar, * The Athena scrollbars can move the thumb to after the end of the scrollbar,
@ -1976,7 +1977,7 @@ gui_write(
gui.dragged_sb = SBAR_NONE; gui.dragged_sb = SBAR_NONE;
#endif #endif
gui_mch_flush(); /* In case vim decides to take a nap */ gui_may_flush(); /* In case vim decides to take a nap */
} }
/* /*
@ -2004,6 +2005,34 @@ gui_can_update_cursor(void)
* after scrolling. */ * after scrolling. */
} }
/*
* Disable issuing gui_mch_flush().
*/
void
gui_disable_flush(void)
{
++disable_flush;
}
/*
* Enable issuing gui_mch_flush().
*/
void
gui_enable_flush(void)
{
--disable_flush;
}
/*
* Issue gui_mch_flush() if it is not disabled.
*/
void
gui_may_flush(void)
{
if (disable_flush == 0)
gui_mch_flush();
}
static void static void
gui_outstr(char_u *s, int len) gui_outstr(char_u *s, int len)
{ {
@ -3682,7 +3711,6 @@ gui_update_tabline(void)
/* Updating the tabline uses direct GUI commands, flush /* Updating the tabline uses direct GUI commands, flush
* outstanding instructions first. (esp. clear screen) */ * outstanding instructions first. (esp. clear screen) */
out_flush(); out_flush();
gui_mch_flush();
if (!showit != !shown) if (!showit != !shown)
gui_mch_show_tabline(showit); gui_mch_show_tabline(showit);
@ -4122,8 +4150,7 @@ gui_drag_scrollbar(scrollbar_T *sb, long value, int still_dragging)
setcursor(); setcursor();
} }
# endif # endif
out_flush(); out_flush_cursor(FALSE, TRUE);
gui_update_cursor(FALSE, TRUE);
#else #else
add_to_input_buf(bytes, byte_count); add_to_input_buf(bytes, byte_count);
add_long_to_buf((long_u)value, bytes); add_long_to_buf((long_u)value, bytes);
@ -4486,7 +4513,9 @@ gui_do_scroll(void)
* disappear when losing focus after a scrollbar drag. */ * disappear when losing focus after a scrollbar drag. */
if (wp->w_redr_type < type) if (wp->w_redr_type < type)
wp->w_redr_type = type; wp->w_redr_type = type;
mch_disable_flush();
updateWindow(wp); /* update window, status line, and cmdline */ updateWindow(wp); /* update window, status line, and cmdline */
mch_enable_flush();
} }
#ifdef FEAT_INS_EXPAND #ifdef FEAT_INS_EXPAND
@ -4797,8 +4826,7 @@ gui_focus_change(int in_focus)
*/ */
#if 1 #if 1
gui.in_focus = in_focus; gui.in_focus = in_focus;
out_flush(); /* make sure output has been written */ out_flush_cursor(TRUE, FALSE);
gui_update_cursor(TRUE, FALSE);
# ifdef FEAT_XIM # ifdef FEAT_XIM
xim_set_focus(in_focus); xim_set_focus(in_focus);
@ -5157,9 +5185,7 @@ gui_update_screen(void)
curwin->w_valid &= ~VALID_CROW; curwin->w_valid &= ~VALID_CROW;
} }
# endif # endif
out_flush(); /* make sure output has been written */ out_flush_cursor(TRUE, FALSE);
gui_update_cursor(TRUE, FALSE);
gui_mch_flush();
} }
#endif #endif
@ -5516,9 +5542,7 @@ gui_handle_drop(
maketitle(); maketitle();
#endif #endif
setcursor(); setcursor();
out_flush(); out_flush_cursor(FALSE, FALSE);
gui_update_cursor(FALSE, FALSE);
gui_mch_flush();
} }
entered = FALSE; entered = FALSE;

View File

@ -286,6 +286,7 @@ struct DWriteContext {
ID2D1DCRenderTarget *mRT; ID2D1DCRenderTarget *mRT;
ID2D1GdiInteropRenderTarget *mGDIRT; ID2D1GdiInteropRenderTarget *mGDIRT;
ID2D1SolidColorBrush *mBrush; ID2D1SolidColorBrush *mBrush;
ID2D1Bitmap *mBitmap;
IDWriteFactory *mDWriteFactory; IDWriteFactory *mDWriteFactory;
#ifdef FEAT_DIRECTX_COLOR_EMOJI #ifdef FEAT_DIRECTX_COLOR_EMOJI
@ -319,6 +320,8 @@ struct DWriteContext {
void SetFont(HFONT hFont); void SetFont(HFONT hFont);
void Rebind();
void BindDC(HDC hdc, const RECT *rect); void BindDC(HDC hdc, const RECT *rect);
HRESULT SetDrawingMode(DrawingMode mode); HRESULT SetDrawingMode(DrawingMode mode);
@ -335,6 +338,8 @@ struct DWriteContext {
void SetPixel(int x, int y, COLORREF color); void SetPixel(int x, int y, COLORREF color);
void Scroll(int x, int y, const RECT *rc);
void Flush(); void Flush();
void SetRenderingParams( void SetRenderingParams(
@ -596,6 +601,7 @@ DWriteContext::DWriteContext() :
mRT(NULL), mRT(NULL),
mGDIRT(NULL), mGDIRT(NULL),
mBrush(NULL), mBrush(NULL),
mBitmap(NULL),
mDWriteFactory(NULL), mDWriteFactory(NULL),
#ifdef FEAT_DIRECTX_COLOR_EMOJI #ifdef FEAT_DIRECTX_COLOR_EMOJI
mDWriteFactory2(NULL), mDWriteFactory2(NULL),
@ -615,9 +621,6 @@ DWriteContext::DWriteContext() :
reinterpret_cast<void**>(&mD2D1Factory)); reinterpret_cast<void**>(&mD2D1Factory));
_RPT2(_CRT_WARN, "D2D1CreateFactory: hr=%p p=%p\n", hr, mD2D1Factory); _RPT2(_CRT_WARN, "D2D1CreateFactory: hr=%p p=%p\n", hr, mD2D1Factory);
if (SUCCEEDED(hr))
hr = CreateDeviceResources();
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = DWriteCreateFactory( hr = DWriteCreateFactory(
@ -662,6 +665,7 @@ DWriteContext::~DWriteContext()
#ifdef FEAT_DIRECTX_COLOR_EMOJI #ifdef FEAT_DIRECTX_COLOR_EMOJI
SafeRelease(&mDWriteFactory2); SafeRelease(&mDWriteFactory2);
#endif #endif
SafeRelease(&mBitmap);
SafeRelease(&mBrush); SafeRelease(&mBrush);
SafeRelease(&mGDIRT); SafeRelease(&mGDIRT);
SafeRelease(&mRT); SafeRelease(&mRT);
@ -704,13 +708,7 @@ DWriteContext::CreateDeviceResources()
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ Rebind();
if (mHDC != NULL)
{
mRT->BindDC(mHDC, &mBindRect);
mRT->SetTransform(D2D1::IdentityMatrix());
}
}
return hr; return hr;
} }
@ -718,6 +716,7 @@ DWriteContext::CreateDeviceResources()
void void
DWriteContext::DiscardDeviceResources() DWriteContext::DiscardDeviceResources()
{ {
SafeRelease(&mBitmap);
SafeRelease(&mBrush); SafeRelease(&mBrush);
SafeRelease(&mGDIRT); SafeRelease(&mGDIRT);
SafeRelease(&mRT); SafeRelease(&mRT);
@ -898,14 +897,37 @@ DWriteContext::SetFont(HFONT hFont)
mFontCache.put(item); mFontCache.put(item);
} }
void
DWriteContext::Rebind()
{
SafeRelease(&mBitmap);
mRT->BindDC(mHDC, &mBindRect);
mRT->SetTransform(D2D1::IdentityMatrix());
D2D1_BITMAP_PROPERTIES props = {
{DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE},
96.0f, 96.0f
};
mRT->CreateBitmap(
D2D1::SizeU(mBindRect.right - mBindRect.left,
mBindRect.bottom - mBindRect.top),
props, &mBitmap);
}
void void
DWriteContext::BindDC(HDC hdc, const RECT *rect) DWriteContext::BindDC(HDC hdc, const RECT *rect)
{ {
Flush();
mRT->BindDC(hdc, rect);
mRT->SetTransform(D2D1::IdentityMatrix());
mHDC = hdc; mHDC = hdc;
mBindRect = *rect; mBindRect = *rect;
if (mRT == NULL)
CreateDeviceResources();
else
{
Flush();
Rebind();
}
} }
HRESULT HRESULT
@ -1080,6 +1102,49 @@ DWriteContext::SetPixel(int x, int y, COLORREF color)
} }
} }
void
DWriteContext::Scroll(int x, int y, const RECT *rc)
{
SetDrawingMode(DM_DIRECTX);
mRT->Flush();
D2D1_RECT_U srcRect;
D2D1_POINT_2U destPoint;
if (x >= 0)
{
srcRect.left = rc->left;
srcRect.right = rc->right - x;
destPoint.x = rc->left + x;
}
else
{
srcRect.left = rc->left - x;
srcRect.right = rc->right;
destPoint.x = rc->left;
}
if (y >= 0)
{
srcRect.top = rc->top;
srcRect.bottom = rc->bottom - y;
destPoint.y = rc->top + y;
}
else
{
srcRect.top = rc->top - y;
srcRect.bottom = rc->bottom;
destPoint.y = rc->top;
}
mBitmap->CopyFromRenderTarget(&destPoint, mRT, &srcRect);
D2D1_RECT_F destRect = {
FLOAT(destPoint.x), FLOAT(destPoint.y),
FLOAT(destPoint.x + srcRect.right - srcRect.left),
FLOAT(destPoint.y + srcRect.bottom - srcRect.top)
};
mRT->DrawBitmap(mBitmap, destRect, 1.0F,
D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, destRect);
}
void void
DWriteContext::Flush() DWriteContext::Flush()
{ {
@ -1239,6 +1304,13 @@ DWriteContext_SetPixel(DWriteContext *ctx, int x, int y, COLORREF color)
ctx->SetPixel(x, y, color); ctx->SetPixel(x, y, color);
} }
void
DWriteContext_Scroll(DWriteContext *ctx, int x, int y, const RECT *rc)
{
if (ctx != NULL)
ctx->Scroll(x, y, rc);
}
void void
DWriteContext_Flush(DWriteContext *ctx) DWriteContext_Flush(DWriteContext *ctx)
{ {

View File

@ -74,6 +74,7 @@ void DWriteContext_FillRect(DWriteContext *ctx, const RECT *rc, COLORREF color);
void DWriteContext_DrawLine(DWriteContext *ctx, int x1, int y1, int x2, int y2, void DWriteContext_DrawLine(DWriteContext *ctx, int x1, int y1, int x2, int y2,
COLORREF color); COLORREF color);
void DWriteContext_SetPixel(DWriteContext *ctx, int x, int y, COLORREF color); void DWriteContext_SetPixel(DWriteContext *ctx, int x, int y, COLORREF color);
void DWriteContext_Scroll(DWriteContext *ctx, int x, int y, const RECT *rc);
void DWriteContext_Flush(DWriteContext *ctx); void DWriteContext_Flush(DWriteContext *ctx);
void DWriteContext_Close(DWriteContext *ctx); void DWriteContext_Close(DWriteContext *ctx);

View File

@ -36,7 +36,6 @@
static DWriteContext *s_dwc = NULL; static DWriteContext *s_dwc = NULL;
static int s_directx_enabled = 0; static int s_directx_enabled = 0;
static int s_directx_load_attempted = 0; static int s_directx_load_attempted = 0;
static int s_directx_scrlines = 0;
# define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL && enc_utf8) # define IS_ENABLE_DIRECTX() (s_directx_enabled && s_dwc != NULL && enc_utf8)
static int directx_enabled(void); static int directx_enabled(void);
static void directx_binddc(void); static void directx_binddc(void);
@ -61,7 +60,6 @@ gui_mch_set_rendering_options(char_u *s)
int dx_geom = 0; int dx_geom = 0;
int dx_renmode = 0; int dx_renmode = 0;
int dx_taamode = 0; int dx_taamode = 0;
int dx_scrlines = 0;
/* parse string as rendering options. */ /* parse string as rendering options. */
for (p = s; p != NULL && *p != NUL; ) for (p = s; p != NULL && *p != NUL; )
@ -124,7 +122,7 @@ gui_mch_set_rendering_options(char_u *s)
} }
else if (STRCMP(name, "scrlines") == 0) else if (STRCMP(name, "scrlines") == 0)
{ {
dx_scrlines = atoi((char *)value); /* Deprecated. Simply ignore it. */
} }
else else
return FAIL; return FAIL;
@ -159,7 +157,6 @@ gui_mch_set_rendering_options(char_u *s)
} }
} }
s_directx_enabled = dx_enable; s_directx_enabled = dx_enable;
s_directx_scrlines = dx_scrlines;
return OK; return OK;
# else # else
@ -3129,9 +3126,6 @@ gui_mch_delete_lines(
int num_lines) int num_lines)
{ {
RECT rc; RECT rc;
#if defined(FEAT_DIRECTX)
int use_redraw = 0;
#endif
rc.left = FILL_X(gui.scroll_region_left); rc.left = FILL_X(gui.scroll_region_left);
rc.right = FILL_X(gui.scroll_region_right + 1); rc.right = FILL_X(gui.scroll_region_right + 1);
@ -3141,16 +3135,10 @@ gui_mch_delete_lines(
#if defined(FEAT_DIRECTX) #if defined(FEAT_DIRECTX)
if (IS_ENABLE_DIRECTX()) if (IS_ENABLE_DIRECTX())
{ {
if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines) DWriteContext_Scroll(s_dwc, 0, -num_lines * gui.char_height, &rc);
{ DWriteContext_Flush(s_dwc);
gui_redraw(rc.left, rc.top,
rc.right - rc.left + 1, rc.bottom - rc.top + 1);
use_redraw = 1;
}
else
DWriteContext_Flush(s_dwc);
} }
if (!use_redraw) else
#endif #endif
{ {
intel_gpu_workaround(); intel_gpu_workaround();
@ -3180,9 +3168,6 @@ gui_mch_insert_lines(
int num_lines) int num_lines)
{ {
RECT rc; RECT rc;
#if defined(FEAT_DIRECTX)
int use_redraw = 0;
#endif
rc.left = FILL_X(gui.scroll_region_left); rc.left = FILL_X(gui.scroll_region_left);
rc.right = FILL_X(gui.scroll_region_right + 1); rc.right = FILL_X(gui.scroll_region_right + 1);
@ -3192,16 +3177,10 @@ gui_mch_insert_lines(
#if defined(FEAT_DIRECTX) #if defined(FEAT_DIRECTX)
if (IS_ENABLE_DIRECTX()) if (IS_ENABLE_DIRECTX())
{ {
if (s_directx_scrlines > 0 && s_directx_scrlines <= num_lines) DWriteContext_Scroll(s_dwc, 0, num_lines * gui.char_height, &rc);
{ DWriteContext_Flush(s_dwc);
gui_redraw(rc.left, rc.top,
rc.right - rc.left + 1, rc.bottom - rc.top + 1);
use_redraw = 1;
}
else
DWriteContext_Flush(s_dwc);
} }
if (!use_redraw) else
#endif #endif
{ {
intel_gpu_workaround(); intel_gpu_workaround();
@ -4024,7 +4003,10 @@ _OnScroll(
* position, but don't actually scroll by setting "dont_scroll". */ * position, but don't actually scroll by setting "dont_scroll". */
dont_scroll = !allow_scrollbar; dont_scroll = !allow_scrollbar;
mch_disable_flush();
gui_drag_scrollbar(sb, val, dragging); gui_drag_scrollbar(sb, val, dragging);
mch_enable_flush();
gui_may_flush();
s_busy_processing = FALSE; s_busy_processing = FALSE;
dont_scroll = dont_scroll_save; dont_scroll = dont_scroll_save;
@ -4651,6 +4633,7 @@ _OnMouseWheel(
if (mouse_scroll_lines == 0) if (mouse_scroll_lines == 0)
init_mouse_wheel(); init_mouse_wheel();
mch_disable_flush();
if (mouse_scroll_lines > 0 if (mouse_scroll_lines > 0
&& mouse_scroll_lines < (size > 2 ? size - 2 : 1)) && mouse_scroll_lines < (size > 2 ? size - 2 : 1))
{ {
@ -4659,6 +4642,8 @@ _OnMouseWheel(
} }
else else
_OnScroll(hwnd, hwndCtl, zDelta >= 0 ? SB_PAGEUP : SB_PAGEDOWN, 0); _OnScroll(hwnd, hwndCtl, zDelta >= 0 ? SB_PAGEUP : SB_PAGEDOWN, 0);
mch_enable_flush();
gui_may_flush();
} }
#ifdef USE_SYSMENU_FONT #ifdef USE_SYSMENU_FONT

View File

@ -365,6 +365,17 @@
* HIKEY2DI() converts a hashitem key pointer to a dictitem pointer. * HIKEY2DI() converts a hashitem key pointer to a dictitem pointer.
* HI2DI() converts a hashitem pointer to a dictitem pointer. * HI2DI() converts a hashitem pointer to a dictitem pointer.
*/ */
# define DI2HIKEY(di) ((di)->di_key) #define DI2HIKEY(di) ((di)->di_key)
# define HIKEY2DI(p) ((dictitem_T *)(p - offsetof(dictitem_T, di_key))) #define HIKEY2DI(p) ((dictitem_T *)(p - offsetof(dictitem_T, di_key)))
# define HI2DI(hi) HIKEY2DI((hi)->hi_key) #define HI2DI(hi) HIKEY2DI((hi)->hi_key)
/*
* Flush control functions.
*/
#ifdef FEAT_GUI
# define mch_enable_flush() gui_enable_flush()
# define mch_disable_flush() gui_disable_flush()
#else
# define mch_enable_flush()
# define mch_disable_flush()
#endif

View File

@ -1242,7 +1242,11 @@ main_loop(
if (VIsual_active) if (VIsual_active)
update_curbuf(INVERTED);/* update inverted part */ update_curbuf(INVERTED);/* update inverted part */
else if (must_redraw) else if (must_redraw)
{
mch_disable_flush(); /* Stop issuing gui_mch_flush(). */
update_screen(0); update_screen(0);
mch_enable_flush();
}
else if (redraw_cmdline || clear_cmdline) else if (redraw_cmdline || clear_cmdline)
showmode(); showmode();
redraw_statuslines(); redraw_statuslines();
@ -1283,11 +1287,13 @@ main_loop(
|| conceal_cursor_line(curwin) || conceal_cursor_line(curwin)
|| need_cursor_line_redraw)) || need_cursor_line_redraw))
{ {
mch_disable_flush(); /* Stop issuing gui_mch_flush(). */
if (conceal_old_cursor_line != conceal_new_cursor_line if (conceal_old_cursor_line != conceal_new_cursor_line
&& conceal_old_cursor_line && conceal_old_cursor_line
<= curbuf->b_ml.ml_line_count) <= curbuf->b_ml.ml_line_count)
update_single_line(curwin, conceal_old_cursor_line); update_single_line(curwin, conceal_old_cursor_line);
update_single_line(curwin, conceal_new_cursor_line); update_single_line(curwin, conceal_new_cursor_line);
mch_enable_flush();
curwin->w_valid &= ~VALID_CROW; curwin->w_valid &= ~VALID_CROW;
} }
# endif # endif
@ -4212,11 +4218,7 @@ eval_client_expr_to_string(char_u *expr)
/* A client can tell us to redraw, but not to display the cursor, so do /* A client can tell us to redraw, but not to display the cursor, so do
* that here. */ * that here. */
setcursor(); setcursor();
out_flush(); out_flush_cursor(FALSE, FALSE);
#ifdef FEAT_GUI
if (gui.in_use)
gui_update_cursor(FALSE, FALSE);
#endif
return res; return res;
} }

View File

@ -2316,7 +2316,9 @@ msg_scroll_up(void)
gui_undraw_cursor(); gui_undraw_cursor();
#endif #endif
/* scrolling up always works */ /* scrolling up always works */
mch_disable_flush();
screen_del_lines(0, 0, 1, (int)Rows, TRUE, 0, NULL); screen_del_lines(0, 0, 1, (int)Rows, TRUE, 0, NULL);
mch_enable_flush();
if (!can_clear((char_u *)" ")) if (!can_clear((char_u *)" "))
{ {

View File

@ -121,14 +121,7 @@ netbeans_close(void)
update_screen(CLEAR); update_screen(CLEAR);
setcursor(); setcursor();
cursor_on(); cursor_on();
out_flush(); out_flush_cursor(TRUE, FALSE);
#ifdef FEAT_GUI
if (gui.in_use)
{
gui_update_cursor(TRUE, FALSE);
gui_mch_flush();
}
#endif
} }
#define NB_DEF_HOST "localhost" #define NB_DEF_HOST "localhost"
@ -1848,14 +1841,8 @@ nb_do_cmd(
update_screen(VALID); update_screen(VALID);
setcursor(); setcursor();
cursor_on(); cursor_on();
out_flush(); out_flush_cursor(TRUE, FALSE);
#ifdef FEAT_GUI
if (gui.in_use)
{
gui_update_cursor(TRUE, FALSE);
gui_mch_flush();
}
#endif
/* Quit a hit-return or more prompt. */ /* Quit a hit-return or more prompt. */
if (State == HITRETURN || State == ASKMORE) if (State == HITRETURN || State == ASKMORE)
{ {
@ -2248,14 +2235,8 @@ nb_do_cmd(
update_screen(NOT_VALID); update_screen(NOT_VALID);
setcursor(); setcursor();
cursor_on(); cursor_on();
out_flush(); out_flush_cursor(TRUE, FALSE);
#ifdef FEAT_GUI
if (gui.in_use)
{
gui_update_cursor(TRUE, FALSE);
gui_mch_flush();
}
#endif
/* Quit a hit-return or more prompt. */ /* Quit a hit-return or more prompt. */
if (State == HITRETURN || State == ASKMORE) if (State == HITRETURN || State == ASKMORE)
{ {
@ -2307,15 +2288,7 @@ coloncmd(char *cmd, ...)
/* ALT_INPUT_LOCK_OFF; */ /* ALT_INPUT_LOCK_OFF; */
setcursor(); /* restore the cursor position */ setcursor(); /* restore the cursor position */
out_flush(); /* make sure output has been written */ out_flush_cursor(TRUE, FALSE);
#ifdef FEAT_GUI
if (gui.in_use)
{
gui_update_cursor(TRUE, FALSE);
gui_mch_flush();
}
#endif
} }
@ -2569,14 +2542,7 @@ netbeans_open(char *params, int doabort)
update_screen(CLEAR); update_screen(CLEAR);
setcursor(); setcursor();
cursor_on(); cursor_on();
out_flush(); out_flush_cursor(TRUE, FALSE);
#ifdef FEAT_GUI
if (gui.in_use)
{
gui_update_cursor(TRUE, FALSE);
gui_mch_flush();
}
#endif
} }
/* /*

View File

@ -25,6 +25,9 @@ void gui_update_cursor_later(void);
void gui_write(char_u *s, int len); void gui_write(char_u *s, int len);
void gui_dont_update_cursor(int undraw); void gui_dont_update_cursor(int undraw);
void gui_can_update_cursor(void); void gui_can_update_cursor(void);
void gui_disable_flush(void);
void gui_enable_flush(void);
void gui_may_flush(void);
int gui_outstr_nowrap(char_u *s, int len, int flags, guicolor_T fg, guicolor_T bg, int back); int gui_outstr_nowrap(char_u *s, int len, int flags, guicolor_T fg, guicolor_T bg, int back);
void gui_undraw_cursor(void); void gui_undraw_cursor(void);
void gui_redraw(int x, int y, int w, int h); void gui_redraw(int x, int y, int w, int h);

View File

@ -12,6 +12,7 @@ int term_is_gui(char_u *name);
char_u *tltoa(unsigned long i); char_u *tltoa(unsigned long i);
void termcapinit(char_u *name); void termcapinit(char_u *name);
void out_flush(void); void out_flush(void);
void out_flush_cursor(int force, int clear_selection);
void out_flush_check(void); void out_flush_check(void);
void out_trash(void); void out_trash(void);
void out_char(unsigned c); void out_char(unsigned c);

View File

@ -468,16 +468,14 @@ redraw_after_callback(int call_update_screen)
setcursor(); setcursor();
} }
cursor_on(); cursor_on();
out_flush();
#ifdef FEAT_GUI #ifdef FEAT_GUI
if (gui.in_use) if (gui.in_use && !gui_mch_is_blink_off())
{
/* Don't update the cursor when it is blinking and off to avoid /* Don't update the cursor when it is blinking and off to avoid
* flicker. */ * flicker. */
if (!gui_mch_is_blink_off()) out_flush_cursor(FALSE, FALSE);
gui_update_cursor(FALSE, FALSE); else
gui_mch_flush(); #else
} out_flush();
#endif #endif
--redrawing_for_callback; --redrawing_for_callback;
@ -800,9 +798,12 @@ update_screen(int type_arg)
* done. */ * done. */
if (gui.in_use) if (gui.in_use)
{ {
out_flush(); /* required before updating the cursor */
if (did_undraw && !gui_mch_is_blink_off()) if (did_undraw && !gui_mch_is_blink_off())
{ {
mch_disable_flush();
out_flush(); /* required before updating the cursor */
mch_enable_flush();
/* Put the GUI position where the cursor was, gui_update_cursor() /* Put the GUI position where the cursor was, gui_update_cursor()
* uses that. */ * uses that. */
gui.col = gui_cursor_col; gui.col = gui_cursor_col;
@ -811,9 +812,12 @@ update_screen(int type_arg)
gui.col = mb_fix_col(gui.col, gui.row); gui.col = mb_fix_col(gui.col, gui.row);
# endif # endif
gui_update_cursor(FALSE, FALSE); gui_update_cursor(FALSE, FALSE);
gui_may_flush();
screen_cur_col = gui.col; screen_cur_col = gui.col;
screen_cur_row = gui.row; screen_cur_row = gui.row;
} }
else
out_flush();
gui_update_scrollbars(FALSE); gui_update_scrollbars(FALSE);
} }
#endif #endif
@ -863,8 +867,7 @@ update_finish(void)
* done. */ * done. */
if (gui.in_use) if (gui.in_use)
{ {
out_flush(); /* required before updating the cursor */ out_flush_cursor(FALSE, FALSE);
gui_update_cursor(FALSE, FALSE);
gui_update_scrollbars(FALSE); gui_update_scrollbars(FALSE);
} }
# endif # endif

View File

@ -2675,14 +2675,8 @@ showmatch(
showruler(FALSE); showruler(FALSE);
setcursor(); setcursor();
cursor_on(); /* make sure that the cursor is shown */ cursor_on(); /* make sure that the cursor is shown */
out_flush(); out_flush_cursor(TRUE, FALSE);
#ifdef FEAT_GUI
if (gui.in_use)
{
gui_update_cursor(TRUE, FALSE);
gui_mch_flush();
}
#endif
/* Restore dollar_vcol(), because setcursor() may call curs_rows() /* Restore dollar_vcol(), because setcursor() may call curs_rows()
* which resets it if the matching position is in a previous line * which resets it if the matching position is in a previous line
* and has a higher column number. */ * and has a higher column number. */

View File

@ -2501,6 +2501,27 @@ out_flush(void)
} }
} }
/*
* out_flush_cursor(): flush the output buffer and redraw the cursor
*/
void
out_flush_cursor(
int force UNUSED, /* when TRUE, update cursor even when not moved */
int clear_selection UNUSED) /* clear selection under cursor */
{
mch_disable_flush();
out_flush();
mch_enable_flush();
#ifdef FEAT_GUI
if (gui.in_use)
{
gui_update_cursor(force, clear_selection);
gui_may_flush();
}
#endif
}
#if defined(FEAT_MBYTE) || defined(PROTO) #if defined(FEAT_MBYTE) || defined(PROTO)
/* /*
* Sometimes a byte out of a multi-byte character is written with out_char(). * Sometimes a byte out of a multi-byte character is written with out_char().

View File

@ -245,7 +245,7 @@ ui_wait_for_chars_or_timer(
if (interrupted != NULL && *interrupted) if (interrupted != NULL && *interrupted)
/* Nothing available, but need to return so that side effects get /* Nothing available, but need to return so that side effects get
* handled, such as handling a message on a channel. */ * handled, such as handling a message on a channel. */
return FALSE; return FAIL;
if (wtime > 0) if (wtime > 0)
remaining -= due_time; remaining -= due_time;
} }
@ -578,11 +578,7 @@ clip_lose_selection(VimClipboard *cbd)
update_curbuf(INVERTED_ALL); update_curbuf(INVERTED_ALL);
setcursor(); setcursor();
cursor_on(); cursor_on();
out_flush(); out_flush_cursor(TRUE, FALSE);
# ifdef FEAT_GUI
if (gui.in_use)
gui_update_cursor(TRUE, FALSE);
# endif
} }
} }
#endif #endif
@ -3331,13 +3327,10 @@ ui_focus_change(
setcursor(); setcursor();
} }
cursor_on(); /* redrawing may have switched it off */ cursor_on(); /* redrawing may have switched it off */
out_flush(); out_flush_cursor(FALSE, TRUE);
# ifdef FEAT_GUI # ifdef FEAT_GUI
if (gui.in_use) if (gui.in_use)
{
gui_update_cursor(FALSE, TRUE);
gui_update_scrollbars(FALSE); gui_update_scrollbars(FALSE);
}
# endif # endif
} }
#ifdef FEAT_TITLE #ifdef FEAT_TITLE

View File

@ -771,6 +771,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 */
/**/
1449,
/**/ /**/
1448, 1448,
/**/ /**/