diff options
author | Neil <nyamatongwe@gmail.com> | 2020-06-06 12:15:13 +1000 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2020-06-06 12:15:13 +1000 |
commit | 68db18e2b8e0217b2651e5e6f75051c1aa1564f9 (patch) | |
tree | ac9c59cb77090b25aa13bd9493e7fa25bf0c15e7 | |
parent | b5b2247de50e20e7db3c64e786aab788d9f49148 (diff) | |
download | scintilla-mirror-68db18e2b8e0217b2651e5e6f75051c1aa1564f9.tar.gz |
Use call_once for initialising Direct2D so only done once even with threads.
-rw-r--r-- | win32/PlatWin.cxx | 120 |
1 files changed, 61 insertions, 59 deletions
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index 96f642824..99885e5e4 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -19,6 +19,7 @@ #include <map> #include <algorithm> #include <memory> +#include <mutex> // Want to use std::min and std::max so don't want Windows.h version of min and max #if !defined(NOMINMAX) @@ -77,75 +78,76 @@ D2D1_DRAW_TEXT_OPTIONS d2dDrawTextOptions = D2D1_DRAW_TEXT_OPTIONS_NONE; static HMODULE hDLLD2D {}; static HMODULE hDLLDWrite {}; -bool LoadD2D() { - static bool triedLoadingD2D = false; - if (!triedLoadingD2D) { - DWORD loadLibraryFlags = 0; - HMODULE kernel32 = ::GetModuleHandleW(L"kernel32.dll"); - if (kernel32) { - if (::GetProcAddress(kernel32, "SetDefaultDllDirectories")) { - // Availability of SetDefaultDllDirectories implies Windows 8+ or - // that KB2533623 has been installed so LoadLibraryEx can be called - // with LOAD_LIBRARY_SEARCH_SYSTEM32. - loadLibraryFlags = LOAD_LIBRARY_SEARCH_SYSTEM32; - } - } - - typedef HRESULT (WINAPI *D2D1CFSig)(D2D1_FACTORY_TYPE factoryType, REFIID riid, - CONST D2D1_FACTORY_OPTIONS *pFactoryOptions, IUnknown **factory); - typedef HRESULT (WINAPI *DWriteCFSig)(DWRITE_FACTORY_TYPE factoryType, REFIID iid, - IUnknown **factory); - - hDLLD2D = ::LoadLibraryEx(TEXT("D2D1.DLL"), 0, loadLibraryFlags); - D2D1CFSig fnD2DCF = DLLFunction<D2D1CFSig>(hDLLD2D, "D2D1CreateFactory"); - if (fnD2DCF) { - // A single threaded factory as Scintilla always draw on the GUI thread - fnD2DCF(D2D1_FACTORY_TYPE_SINGLE_THREADED, - __uuidof(ID2D1Factory), - nullptr, - reinterpret_cast<IUnknown**>(&pD2DFactory)); - } - hDLLDWrite = ::LoadLibraryEx(TEXT("DWRITE.DLL"), 0, loadLibraryFlags); - DWriteCFSig fnDWCF = DLLFunction<DWriteCFSig>(hDLLDWrite, "DWriteCreateFactory"); - if (fnDWCF) { - const GUID IID_IDWriteFactory2 = // 0439fc60-ca44-4994-8dee-3a9af7b732ec - { 0x0439fc60, 0xca44, 0x4994, { 0x8d, 0xee, 0x3a, 0x9a, 0xf7, 0xb7, 0x32, 0xec } }; - - const HRESULT hr = fnDWCF(DWRITE_FACTORY_TYPE_SHARED, - IID_IDWriteFactory2, +void LoadD2DOnce() noexcept { + DWORD loadLibraryFlags = 0; + HMODULE kernel32 = ::GetModuleHandleW(L"kernel32.dll"); + if (kernel32) { + if (::GetProcAddress(kernel32, "SetDefaultDllDirectories")) { + // Availability of SetDefaultDllDirectories implies Windows 8+ or + // that KB2533623 has been installed so LoadLibraryEx can be called + // with LOAD_LIBRARY_SEARCH_SYSTEM32. + loadLibraryFlags = LOAD_LIBRARY_SEARCH_SYSTEM32; + } + } + + typedef HRESULT (WINAPI *D2D1CFSig)(D2D1_FACTORY_TYPE factoryType, REFIID riid, + CONST D2D1_FACTORY_OPTIONS *pFactoryOptions, IUnknown **factory); + typedef HRESULT (WINAPI *DWriteCFSig)(DWRITE_FACTORY_TYPE factoryType, REFIID iid, + IUnknown **factory); + + hDLLD2D = ::LoadLibraryEx(TEXT("D2D1.DLL"), 0, loadLibraryFlags); + D2D1CFSig fnD2DCF = DLLFunction<D2D1CFSig>(hDLLD2D, "D2D1CreateFactory"); + if (fnD2DCF) { + // A single threaded factory as Scintilla always draw on the GUI thread + fnD2DCF(D2D1_FACTORY_TYPE_SINGLE_THREADED, + __uuidof(ID2D1Factory), + nullptr, + reinterpret_cast<IUnknown**>(&pD2DFactory)); + } + hDLLDWrite = ::LoadLibraryEx(TEXT("DWRITE.DLL"), 0, loadLibraryFlags); + DWriteCFSig fnDWCF = DLLFunction<DWriteCFSig>(hDLLDWrite, "DWriteCreateFactory"); + if (fnDWCF) { + const GUID IID_IDWriteFactory2 = // 0439fc60-ca44-4994-8dee-3a9af7b732ec + { 0x0439fc60, 0xca44, 0x4994, { 0x8d, 0xee, 0x3a, 0x9a, 0xf7, 0xb7, 0x32, 0xec } }; + + const HRESULT hr = fnDWCF(DWRITE_FACTORY_TYPE_SHARED, + IID_IDWriteFactory2, + reinterpret_cast<IUnknown**>(&pIDWriteFactory)); + if (SUCCEEDED(hr)) { + // D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT + d2dDrawTextOptions = static_cast<D2D1_DRAW_TEXT_OPTIONS>(0x00000004); + } else { + fnDWCF(DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&pIDWriteFactory)); - if (SUCCEEDED(hr)) { - // D2D1_DRAW_TEXT_OPTIONS_ENABLE_COLOR_FONT - d2dDrawTextOptions = static_cast<D2D1_DRAW_TEXT_OPTIONS>(0x00000004); - } else { - fnDWCF(DWRITE_FACTORY_TYPE_SHARED, - __uuidof(IDWriteFactory), - reinterpret_cast<IUnknown**>(&pIDWriteFactory)); - } } + } - if (pIDWriteFactory) { - const HRESULT hr = pIDWriteFactory->CreateRenderingParams(&defaultRenderingParams); - if (SUCCEEDED(hr)) { - unsigned int clearTypeContrast; - if (::SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &clearTypeContrast, 0)) { + if (pIDWriteFactory) { + const HRESULT hr = pIDWriteFactory->CreateRenderingParams(&defaultRenderingParams); + if (SUCCEEDED(hr)) { + unsigned int clearTypeContrast; + if (::SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &clearTypeContrast, 0)) { - FLOAT gamma; - if (clearTypeContrast >= 1000 && clearTypeContrast <= 2200) - gamma = static_cast<FLOAT>(clearTypeContrast) / 1000.0f; - else - gamma = defaultRenderingParams->GetGamma(); + FLOAT gamma; + if (clearTypeContrast >= 1000 && clearTypeContrast <= 2200) + gamma = static_cast<FLOAT>(clearTypeContrast) / 1000.0f; + else + gamma = defaultRenderingParams->GetGamma(); - pIDWriteFactory->CreateCustomRenderingParams(gamma, defaultRenderingParams->GetEnhancedContrast(), defaultRenderingParams->GetClearTypeLevel(), - defaultRenderingParams->GetPixelGeometry(), defaultRenderingParams->GetRenderingMode(), &customClearTypeRenderingParams); - } + pIDWriteFactory->CreateCustomRenderingParams(gamma, defaultRenderingParams->GetEnhancedContrast(), defaultRenderingParams->GetClearTypeLevel(), + defaultRenderingParams->GetPixelGeometry(), defaultRenderingParams->GetRenderingMode(), &customClearTypeRenderingParams); } } - } - triedLoadingD2D = true; +} + +bool LoadD2D() { + static std::once_flag once; + std::call_once(once, LoadD2DOnce); return pIDWriteFactory && pD2DFactory; } + #endif struct FormatAndMetrics { |