0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

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

@@ -286,6 +286,7 @@ struct DWriteContext {
ID2D1DCRenderTarget *mRT;
ID2D1GdiInteropRenderTarget *mGDIRT;
ID2D1SolidColorBrush *mBrush;
ID2D1Bitmap *mBitmap;
IDWriteFactory *mDWriteFactory;
#ifdef FEAT_DIRECTX_COLOR_EMOJI
@@ -319,6 +320,8 @@ struct DWriteContext {
void SetFont(HFONT hFont);
void Rebind();
void BindDC(HDC hdc, const RECT *rect);
HRESULT SetDrawingMode(DrawingMode mode);
@@ -335,6 +338,8 @@ struct DWriteContext {
void SetPixel(int x, int y, COLORREF color);
void Scroll(int x, int y, const RECT *rc);
void Flush();
void SetRenderingParams(
@@ -596,6 +601,7 @@ DWriteContext::DWriteContext() :
mRT(NULL),
mGDIRT(NULL),
mBrush(NULL),
mBitmap(NULL),
mDWriteFactory(NULL),
#ifdef FEAT_DIRECTX_COLOR_EMOJI
mDWriteFactory2(NULL),
@@ -615,9 +621,6 @@ DWriteContext::DWriteContext() :
reinterpret_cast<void**>(&mD2D1Factory));
_RPT2(_CRT_WARN, "D2D1CreateFactory: hr=%p p=%p\n", hr, mD2D1Factory);
if (SUCCEEDED(hr))
hr = CreateDeviceResources();
if (SUCCEEDED(hr))
{
hr = DWriteCreateFactory(
@@ -662,6 +665,7 @@ DWriteContext::~DWriteContext()
#ifdef FEAT_DIRECTX_COLOR_EMOJI
SafeRelease(&mDWriteFactory2);
#endif
SafeRelease(&mBitmap);
SafeRelease(&mBrush);
SafeRelease(&mGDIRT);
SafeRelease(&mRT);
@@ -704,13 +708,7 @@ DWriteContext::CreateDeviceResources()
}
if (SUCCEEDED(hr))
{
if (mHDC != NULL)
{
mRT->BindDC(mHDC, &mBindRect);
mRT->SetTransform(D2D1::IdentityMatrix());
}
}
Rebind();
return hr;
}
@@ -718,6 +716,7 @@ DWriteContext::CreateDeviceResources()
void
DWriteContext::DiscardDeviceResources()
{
SafeRelease(&mBitmap);
SafeRelease(&mBrush);
SafeRelease(&mGDIRT);
SafeRelease(&mRT);
@@ -898,14 +897,37 @@ DWriteContext::SetFont(HFONT hFont)
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
DWriteContext::BindDC(HDC hdc, const RECT *rect)
{
Flush();
mRT->BindDC(hdc, rect);
mRT->SetTransform(D2D1::IdentityMatrix());
mHDC = hdc;
mBindRect = *rect;
if (mRT == NULL)
CreateDeviceResources();
else
{
Flush();
Rebind();
}
}
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
DWriteContext::Flush()
{
@@ -1239,6 +1304,13 @@ DWriteContext_SetPixel(DWriteContext *ctx, int x, int y, COLORREF 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
DWriteContext_Flush(DWriteContext *ctx)
{