diff options
author | Neil <nyamatongwe@gmail.com> | 2025-02-17 08:48:23 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2025-02-17 08:48:23 +1100 |
commit | dd58631f7a0193dd95523d1ebe4114753fef06c0 (patch) | |
tree | 6305ac65c588c555829c67d57eac998d56e48ef9 | |
parent | 99497f846e812b5333eca87fe9f9812eab7daaf0 (diff) | |
download | scintilla-mirror-dd58631f7a0193dd95523d1ebe4114753fef06c0.tar.gz |
Switch to using ComPtr from WRL for render target code for simplicity and
familiarity.
-rw-r--r-- | scripts/HeaderOrder.txt | 1 | ||||
-rw-r--r-- | win32/PlatWin.cxx | 55 | ||||
-rw-r--r-- | win32/PlatWin.h | 11 | ||||
-rw-r--r-- | win32/ScintillaWin.cxx | 122 | ||||
-rw-r--r-- | win32/WinTypes.h | 19 |
5 files changed, 74 insertions, 134 deletions
diff --git a/scripts/HeaderOrder.txt b/scripts/HeaderOrder.txt index eb0a16dd1..7274299b5 100644 --- a/scripts/HeaderOrder.txt +++ b/scripts/HeaderOrder.txt @@ -80,6 +80,7 @@ #include <shellscalingapi.h> #include <zmouse.h> #include <ole2.h> +#include <wrl.h> #include <d2d1_1.h> #include <d3d11_1.h> #include <dwrite_1.h> diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx index c055f68f4..2eb5d2fcd 100644 --- a/win32/PlatWin.cxx +++ b/win32/PlatWin.cxx @@ -39,6 +39,9 @@ #include <windowsx.h> #include <shellscalingapi.h> +#include <wrl.h> +using Microsoft::WRL::ComPtr; + #if !defined(DISABLE_D2D) #define USE_D2D 1 #endif @@ -143,9 +146,8 @@ void LoadD2DOnce() noexcept { } } -HRESULT CreateD3D(D3D11Device &device, D3D11DeviceContext &context) noexcept { - device.reset(); - context.reset(); +HRESULT CreateD3D(D3D11Device &device) noexcept { + device = nullptr; if (!fnDCD) { return E_FAIL; } @@ -160,47 +162,34 @@ HRESULT CreateD3D(D3D11Device &device, D3D11DeviceContext &context) noexcept { D3D_FEATURE_LEVEL_9_1 }; - // Create device and context. + // Create device. // Try for a hardware device but, if that fails, fall back to the Warp software rasterizer. - D3D_FEATURE_LEVEL returnedFeatureLevel{}; - ID3D11Device *pDevice{}; - ID3D11DeviceContext *pContext{}; + ComPtr<ID3D11Device> upDevice; HRESULT hr = S_OK; const D3D_DRIVER_TYPE typesToTry[] = { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP }; for (const D3D_DRIVER_TYPE type : typesToTry) { hr = fnDCD(nullptr, type, - 0, + {}, D3D11_CREATE_DEVICE_BGRA_SUPPORT, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, - &pDevice, - &returnedFeatureLevel, - &pContext); + upDevice.GetAddressOf(), + nullptr, + nullptr); if (SUCCEEDED(hr)) break; } if (FAILED(hr)) { - Platform::DebugPrintf("Failed to create D3D11 device and context 0x%lx\n", hr); + Platform::DebugPrintf("Failed to create D3D11 device 0x%lx\n", hr); return hr; } - // Ensure released - std::unique_ptr<ID3D11Device, UnknownReleaser> upDevice(pDevice); - std::unique_ptr<ID3D11DeviceContext, UnknownReleaser> upContext(pContext); - // Convert from D3D11 to D3D11.1 - hr = UniquePtrFromQI(upDevice.get(), __uuidof(ID3D11Device1), device); + hr = upDevice.As(&device); if (FAILED(hr)) { Platform::DebugPrintf("Failed to create D3D11.1 device 0x%lx\n", hr); - return hr; - } - hr = UniquePtrFromQI(upContext.get(), __uuidof(ID3D11DeviceContext1), context); - if (FAILED(hr)) { - // Either both device and context or neither - device.reset(); - Platform::DebugPrintf("Failed to create D3D11.1 device context 0x%lx\n", hr); } return hr; } @@ -216,13 +205,7 @@ bool LoadD2D() noexcept { } HRESULT CreateDCRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, DCRenderTarget &dcRT) noexcept { - dcRT.reset(); - ID2D1DCRenderTarget *pDCRT{}; - const HRESULT hr = pD2DFactory->CreateDCRenderTarget(renderTargetProperties, &pDCRT); - if (SUCCEEDED(hr) && pDCRT) { - dcRT.reset(pDCRT); - } - return hr; + return pD2DFactory->CreateDCRenderTarget(renderTargetProperties, dcRT.ReleaseAndGetAddressOf()); } constexpr D2D_COLOR_F ColorFromColourAlpha(ColourRGBA colour) noexcept { @@ -1659,9 +1642,9 @@ void SurfaceD2D::SetFontQuality(FontQuality extraFontFlag) { fontQuality = extraFontFlag; const D2D1_TEXT_ANTIALIAS_MODE aaMode = DWriteMapFontQuality(extraFontFlag); if (aaMode == D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE && renderingParams->customRenderingParams) { - pRenderTarget->SetTextRenderingParams(renderingParams->customRenderingParams.get()); + pRenderTarget->SetTextRenderingParams(renderingParams->customRenderingParams.Get()); } else if (renderingParams->defaultRenderingParams) { - pRenderTarget->SetTextRenderingParams(renderingParams->defaultRenderingParams.get()); + pRenderTarget->SetTextRenderingParams(renderingParams->defaultRenderingParams.Get()); } pRenderTarget->SetTextAntialiasMode(aaMode); } @@ -3050,11 +3033,11 @@ public: return false; } - if (const BrushSolid pBrushFill = BrushSolidCreate(pTarget.get(), fillColour)) { + if (const BrushSolid pBrushFill = BrushSolidCreate(pTarget.Get(), fillColour)) { pTarget->FillGeometry(geometry.get(), pBrushFill.get()); } - if (const BrushSolid pBrushStroke = BrushSolidCreate(pTarget.get(), strokeColour)) { + if (const BrushSolid pBrushStroke = BrushSolidCreate(pTarget.Get(), strokeColour)) { pTarget->DrawGeometry(geometry.get(), pBrushStroke.get(), scale); } @@ -3605,7 +3588,7 @@ void ListBoxX::Draw(DRAWITEMSTRUCT *pDrawItem) { hr = pDCRT->BindDC(pDrawItem->hDC, &rcItem); if (SUCCEEDED(hr)) { - surfaceItem->Init(pDCRT.get(), pDrawItem->hwndItem); + surfaceItem->Init(pDCRT.Get(), pDrawItem->hwndItem); pDCRT->BeginDraw(); const PRectangle rcImage = PRectangle::FromInts(0, 0, images.GetWidth(), rcItem.bottom - rcItem.top); surfaceItem->DrawRGBAImage(rcImage, diff --git a/win32/PlatWin.h b/win32/PlatWin.h index 1b5b7b1b9..192bdf6a7 100644 --- a/win32/PlatWin.h +++ b/win32/PlatWin.h @@ -71,17 +71,14 @@ extern bool LoadD2D() noexcept; extern ID2D1Factory1 *pD2DFactory; extern IDWriteFactory1 *pIDWriteFactory; -using DCRenderTarget = std::unique_ptr<ID2D1DCRenderTarget, UnknownReleaser>; -using HwndRenderTarget = std::unique_ptr<ID2D1HwndRenderTarget, UnknownReleaser>; -using D2DeviceContext = std::unique_ptr<ID2D1DeviceContext, UnknownReleaser>; +using DCRenderTarget = ComPtr<ID2D1DCRenderTarget>; -using D3D11Device = std::unique_ptr<ID3D11Device1, UnknownReleaser>; -using D3D11DeviceContext = std::unique_ptr<ID3D11DeviceContext1, UnknownReleaser>; +using D3D11Device = ComPtr<ID3D11Device1>; HRESULT CreateDCRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, DCRenderTarget &dcRT) noexcept; -extern HRESULT CreateD3D(D3D11Device &device, D3D11DeviceContext &context) noexcept; +extern HRESULT CreateD3D(D3D11Device &device) noexcept; -using WriteRenderingParams = std::unique_ptr<IDWriteRenderingParams1, UnknownReleaser>; +using WriteRenderingParams = ComPtr<IDWriteRenderingParams1>; struct RenderingParams { WriteRenderingParams defaultRenderingParams; diff --git a/win32/ScintillaWin.cxx b/win32/ScintillaWin.cxx index dcfcde2f6..52ccf8709 100644 --- a/win32/ScintillaWin.cxx +++ b/win32/ScintillaWin.cxx @@ -43,6 +43,9 @@ #include <zmouse.h> #include <ole2.h> +#include <wrl.h> +using Microsoft::WRL::ComPtr; + #if !defined(DISABLE_D2D) #define USE_D2D 1 #endif @@ -369,47 +372,44 @@ namespace Scintilla::Internal { #if defined(USE_D2D) +using HwndRenderTarget = ComPtr<ID2D1HwndRenderTarget>; + // There may be either a Hwnd or DC render target struct RenderTargets { HwndRenderTarget pHwndRT; DCRenderTarget pDCRT; - D2DeviceContext pDeviceContext; + ComPtr<ID2D1DeviceContext> pDeviceContext; bool valid = true; - ID2D1RenderTarget *RenderTarget() const noexcept { + [[nodiscard]] ID2D1RenderTarget *RenderTarget() const noexcept { if (pHwndRT) - return pHwndRT.get(); + return pHwndRT.Get(); if (pDCRT) - return pDCRT.get(); + return pDCRT.Get(); if (pDeviceContext) - return pDeviceContext.get(); + return pDeviceContext.Get(); return nullptr; } void Release() noexcept { - pHwndRT.reset(); - pDCRT.reset(); - pDeviceContext.reset(); + pHwndRT = nullptr; + pDCRT = nullptr; + pDeviceContext = nullptr; } }; -using D2D1Device = std::unique_ptr<ID2D1Device, UnknownReleaser>; -using DXGIDevice = std::unique_ptr<IDXGIDevice, UnknownReleaser>; - // These resources are device-dependent but not window-dependent struct DirectDevice { D3D11Device pDirect3DDevice; - D3D11DeviceContext pDirect3DContext; - D2D1Device pDirect2DDevice; - DXGIDevice pDXGIDevice; + ComPtr<ID2D1Device> pDirect2DDevice; + ComPtr<IDXGIDevice> pDXGIDevice; void Release() noexcept; HRESULT CreateDevice() noexcept; }; void DirectDevice::Release() noexcept { - pDirect3DDevice.reset(); - pDirect3DContext.reset(); - pDirect2DDevice.reset(); - pDXGIDevice.reset(); + pDirect3DDevice = nullptr; + pDirect2DDevice = nullptr; + pDXGIDevice = nullptr; } HRESULT DirectDevice::CreateDevice() noexcept { @@ -417,31 +417,26 @@ HRESULT DirectDevice::CreateDevice() noexcept { return E_FAIL; } - HRESULT hr = CreateD3D(pDirect3DDevice, pDirect3DContext); + HRESULT hr = CreateD3D(pDirect3DDevice); if (FAILED(hr)) { - Platform::DebugPrintf("Failed to create D3D device 0x%lx\n", hr); return hr; } - hr = UniquePtrFromQI(pDirect3DDevice.get(), __uuidof(IDXGIDevice), pDXGIDevice); + hr = pDirect3DDevice.As(&pDXGIDevice); if (FAILED(hr)) { Platform::DebugPrintf("Failed to create DXGI device 0x%lx\n", hr); return hr; } - ID2D1Device *pDirect2DDevice_{}; - hr = pD2DFactory->CreateDevice(pDXGIDevice.get(), &pDirect2DDevice_); + hr = pD2DFactory->CreateDevice(pDXGIDevice.Get(), pDirect2DDevice.ReleaseAndGetAddressOf()); if (FAILED(hr)) { Platform::DebugPrintf("Failed to create D2D device 0x%lx\n", hr); return hr; } - pDirect2DDevice.reset(pDirect2DDevice_); return S_OK; } -using DXGISwapChain = std::unique_ptr<IDXGISwapChain1, UnknownReleaser>; - #endif /** @@ -492,7 +487,7 @@ class ScintillaWin : #if defined(USE_D2D) DirectDevice device; - DXGISwapChain pDXGISwapChain; + ComPtr<IDXGISwapChain1> pDXGISwapChain; RenderTargets targets; // rendering parameters for current monitor HMONITOR hCurrentMonitor; @@ -764,25 +759,13 @@ void ScintillaWin::Finalise() { #if defined(USE_D2D) +namespace { + HRESULT CreateHwndRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, const D2D1_HWND_RENDER_TARGET_PROPERTIES *hwndRenderTargetProperties, HwndRenderTarget &hwndRT) noexcept { - hwndRT.reset(); - ID2D1HwndRenderTarget *pHwndRT{}; - const HRESULT hr = pD2DFactory->CreateHwndRenderTarget(renderTargetProperties, hwndRenderTargetProperties, &pHwndRT); - if (SUCCEEDED(hr) && pHwndRT) { - hwndRT.reset(pHwndRT); - } - return hr; + return pD2DFactory->CreateHwndRenderTarget(renderTargetProperties, hwndRenderTargetProperties, hwndRT.ReleaseAndGetAddressOf()); } -HRESULT CreateDeviceContext(ID2D1Device *pDirect2DDevice, D2DeviceContext &deviceContext) noexcept { - deviceContext.reset(); - ID2D1DeviceContext *pD2DC{}; - const HRESULT hr = pDirect2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &pD2DC); - if (SUCCEEDED(hr) && pD2DC) { - deviceContext.reset(pD2DC); - } - return hr; } bool ScintillaWin::UpdateRenderingParams(bool force) noexcept { @@ -799,18 +782,17 @@ bool ScintillaWin::UpdateRenderingParams(bool force) noexcept { return false; } - IDWriteRenderingParams *mrpTemp{}; - HRESULT hr = pIDWriteFactory->CreateMonitorRenderingParams(monitor, &mrpTemp); + ComPtr<IDWriteRenderingParams> upMrp; + HRESULT hr = pIDWriteFactory->CreateMonitorRenderingParams(monitor, upMrp.GetAddressOf()); if (FAILED(hr)) { return false; } - std::unique_ptr<IDWriteRenderingParams, UnknownReleaser> upMrp(mrpTemp); // Cast to IDWriteRenderingParams1 so can call GetGrayscaleEnhancedContrast WriteRenderingParams monitorRenderingParams{}; - hr = UniquePtrFromQI(upMrp.get(), __uuidof(IDWriteRenderingParams1), monitorRenderingParams); + hr = upMrp.As(&monitorRenderingParams); - IDWriteRenderingParams1 *customClearTypeRenderingParams{}; + WriteRenderingParams customClearTypeRenderingParams; UINT clearTypeContrast = 0; if (SUCCEEDED(hr) && monitorRenderingParams && ::SystemParametersInfo(SPI_GETFONTSMOOTHINGCONTRAST, 0, &clearTypeContrast, 0) != 0) { @@ -822,14 +804,14 @@ bool ScintillaWin::UpdateRenderingParams(bool force) noexcept { monitorRenderingParams->GetClearTypeLevel(), monitorRenderingParams->GetPixelGeometry(), monitorRenderingParams->GetRenderingMode(), - &customClearTypeRenderingParams); + customClearTypeRenderingParams.GetAddressOf()); } } hCurrentMonitor = monitor; deviceScaleFactor = Internal::GetDeviceScaleFactorWhenGdiScalingActive(hRootWnd); renderingParams->defaultRenderingParams = std::move(monitorRenderingParams); - renderingParams->customRenderingParams.reset(customClearTypeRenderingParams); + renderingParams->customRenderingParams = std::move(customClearTypeRenderingParams); return true; } @@ -838,7 +820,7 @@ HRESULT ScintillaWin::Create3D() noexcept { return S_OK; } targets.Release(); - pDXGISwapChain.reset(); + pDXGISwapChain = nullptr; device.Release(); const HRESULT hr = device.CreateDevice(); if (FAILED(hr)) { @@ -873,7 +855,8 @@ void ScintillaWin::CreateRenderTarget() { } else if (technology == Technology::DirectWrite1) { HRESULT hr = Create3D(); // Need pDirect2DDevice if (SUCCEEDED(hr)) { - hr = CreateDeviceContext(device.pDirect2DDevice.get(), targets.pDeviceContext); + hr = device.pDirect2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, + targets.pDeviceContext.ReleaseAndGetAddressOf()); if (FAILED(hr)) { Platform::DebugPrintf("Failed CreateDeviceContext 0x%lx\n", hr); } else { @@ -910,11 +893,10 @@ void ScintillaWin::CreateRenderTarget() { HRESULT ScintillaWin::SetBackBuffer(HWND hwnd, IDXGISwapChain1 *pSwapChain) { assert(targets.pDeviceContext); // Back buffer as an IDXGISurface - IDXGISurface *dxgiBackBuffer_{}; - HRESULT hr = pSwapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer_)); + ComPtr<IDXGISurface> dxgiBackBuffer; + HRESULT hr = pSwapChain->GetBuffer(0, IID_PPV_ARGS(dxgiBackBuffer.GetAddressOf())); if (FAILED(hr)) return hr; - std::unique_ptr<IDXGISurface, UnknownReleaser> dxgiBackBuffer(dxgiBackBuffer_); const FLOAT dpiX = static_cast<FLOAT>(DpiForWindow(hwnd)); const FLOAT dpiY = dpiX; @@ -923,14 +905,13 @@ HRESULT ScintillaWin::SetBackBuffer(HWND hwnd, IDXGISwapChain1 *pSwapChain) { const D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE), dpiX, dpiY); - ID2D1Bitmap1 *pDirect2DBackBuffer{}; - hr = targets.pDeviceContext->CreateBitmapFromDxgiSurface(dxgiBackBuffer.get(), &bitmapProperties, &pDirect2DBackBuffer); + ComPtr<ID2D1Bitmap1> pDirect2DBackBuffer; + hr = targets.pDeviceContext->CreateBitmapFromDxgiSurface(dxgiBackBuffer.Get(), &bitmapProperties, pDirect2DBackBuffer.GetAddressOf()); if (FAILED(hr)) return hr; // Bitmap is render target - targets.pDeviceContext->SetTarget(pDirect2DBackBuffer); - ReleaseUnknown(pDirect2DBackBuffer); + targets.pDeviceContext->SetTarget(pDirect2DBackBuffer.Get()); return S_OK; } @@ -938,22 +919,20 @@ HRESULT ScintillaWin::SetBackBuffer(HWND hwnd, IDXGISwapChain1 *pSwapChain) { HRESULT ScintillaWin::CreateSwapChain(HWND hwnd) { // Sets pDXGISwapChain but only when each call succeeds // Needs pDXGIDevice, pDirect3DDevice - pDXGISwapChain.reset(); + pDXGISwapChain = nullptr; assert(device.pDXGIDevice); // At each stage, place object in a unique_ptr to ensure release occurs - IDXGIAdapter *dxgiAdapter_{}; - HRESULT hr = device.pDXGIDevice->GetAdapter(&dxgiAdapter_); + ComPtr<IDXGIAdapter> dxgiAdapter; + HRESULT hr = device.pDXGIDevice->GetAdapter(dxgiAdapter.GetAddressOf()); if (FAILED(hr)) return hr; - std::unique_ptr<IDXGIAdapter, UnknownReleaser> dxgiAdapter(dxgiAdapter_); - IDXGIFactory2 *dxgiFactory_{}; - hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory_)); + ComPtr<IDXGIFactory2> dxgiFactory; + hr = dxgiAdapter->GetParent(IID_PPV_ARGS(dxgiFactory.GetAddressOf())); if (FAILED(hr)) return hr; - std::unique_ptr<IDXGIFactory2, UnknownReleaser> dxgiFactory(dxgiFactory_); DXGI_SWAP_CHAIN_DESC1 swapChainDesc{}; swapChainDesc.Width = 0; @@ -969,14 +948,13 @@ HRESULT ScintillaWin::CreateSwapChain(HWND hwnd) { swapChainDesc.Flags = 0; // DXGI swap chain for window - IDXGISwapChain1 *pSwapChain_{}; - hr = dxgiFactory->CreateSwapChainForHwnd(device.pDirect3DDevice.get(), hwnd, &swapChainDesc, - nullptr, nullptr, &pSwapChain_); + ComPtr<IDXGISwapChain1> pSwapChain; + hr = dxgiFactory->CreateSwapChainForHwnd(device.pDirect3DDevice.Get(), hwnd, &swapChainDesc, + nullptr, nullptr, pSwapChain.GetAddressOf()); if (FAILED(hr)) return hr; - DXGISwapChain pSwapChain(pSwapChain_); - hr = SetBackBuffer(hwnd, pSwapChain.get()); + hr = SetBackBuffer(hwnd, pSwapChain.Get()); if (FAILED(hr)) return hr; @@ -1810,7 +1788,7 @@ void ScintillaWin::SizeWindow() { targets.pDeviceContext->SetTarget(NULL); // ResizeBuffers fails if bitmap still owned by swap chain hrResize = pDXGISwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0); if (SUCCEEDED(hrResize)) { - hrResize = SetBackBuffer(MainHWND(), pDXGISwapChain.get()); + hrResize = SetBackBuffer(MainHWND(), pDXGISwapChain.Get()); } else { Platform::DebugPrintf("Failed ResizeBuffers 0x%lx\n", hrResize); } @@ -3988,7 +3966,7 @@ LRESULT PASCAL ScintillaWin::CTWndProc( // If above SUCCEEDED, then pCTRenderTarget not nullptr assert(pCTRenderTarget); if (pCTRenderTarget) { - surfaceWindow->Init(pCTRenderTarget.get(), hWnd); + surfaceWindow->Init(pCTRenderTarget.Get(), hWnd); pCTRenderTarget->BeginDraw(); } #endif diff --git a/win32/WinTypes.h b/win32/WinTypes.h index 9c930bb7c..c0d6c558d 100644 --- a/win32/WinTypes.h +++ b/win32/WinTypes.h @@ -38,25 +38,6 @@ struct UnknownReleaser { } }; -// Wrap COM IUnknown::QueryInterface to produce std::unique_ptr objects to help -// ensure safe reference counting. -template<typename T> -inline HRESULT UniquePtrFromQI(IUnknown *source, REFIID riid, std::unique_ptr<T, UnknownReleaser> &destination) noexcept { - T *ptr{}; - HRESULT hr = E_FAIL; - try { - hr = source->QueryInterface(riid, reinterpret_cast<void **>(&ptr)); - } catch (...) { - // Shouldn't have exceptions from QueryInterface but not marked noexcept - } - if (SUCCEEDED(hr)) { - destination.reset(ptr); - } else { - destination.reset(); - } - return hr; -} - /// Find a function in a DLL and convert to a function pointer. /// This avoids undefined and conditionally defined behaviour. template<typename T> |