diff options
author | Bram Moolenaar <Bram@vim.org> | 2018-01-31 20:51:47 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2018-01-31 20:51:47 +0100 |
commit | a338adcf222b6a24e26ea5ae6a2ad27f914acb38 (patch) | |
tree | 0ffe28d0a3a60c2c1444a991514505c448d4335b /src/gui_dwrite.cpp | |
parent | 37badc898b8d167e11553b6d05908ffd35928a6e (diff) | |
download | vim-git-a338adcf222b6a24e26ea5ae6a2ad27f914acb38.tar.gz |
patch 8.0.1449: slow redrawing with DirectXv8.0.1449
Problem: Slow redrawing with DirectX.
Solution: Avoid calling gui_mch_flush() unnecessarily, especially when
updating the cursor. (Ken Takata, closes #2560)
Diffstat (limited to 'src/gui_dwrite.cpp')
-rw-r--r-- | src/gui_dwrite.cpp | 98 |
1 files changed, 85 insertions, 13 deletions
diff --git a/src/gui_dwrite.cpp b/src/gui_dwrite.cpp index 3c940a304..8e03dff64 100644 --- a/src/gui_dwrite.cpp +++ b/src/gui_dwrite.cpp @@ -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), @@ -616,9 +622,6 @@ DWriteContext::DWriteContext() : _RPT2(_CRT_WARN, "D2D1CreateFactory: hr=%p p=%p\n", hr, mD2D1Factory); if (SUCCEEDED(hr)) - hr = CreateDeviceResources(); - - if (SUCCEEDED(hr)) { hr = DWriteCreateFactory( DWRITE_FACTORY_TYPE_SHARED, @@ -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); @@ -899,13 +898,36 @@ DWriteContext::SetFont(HFONT hFont) } void -DWriteContext::BindDC(HDC hdc, const RECT *rect) +DWriteContext::Rebind() { - Flush(); - mRT->BindDC(hdc, rect); + 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) +{ mHDC = hdc; mBindRect = *rect; + + if (mRT == NULL) + CreateDeviceResources(); + else + { + Flush(); + Rebind(); + } } HRESULT @@ -1081,6 +1103,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() { SetDrawingMode(DM_GDI); @@ -1240,6 +1305,13 @@ DWriteContext_SetPixel(DWriteContext *ctx, int x, int y, COLORREF 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) { if (ctx != NULL) |