diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index 9578166b14d..71ccfed50a0 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -554,21 +554,21 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation // This event is only registered during terminal initialization, // so we don't need to check _initializedTerminal. // We also don't lock for things that come back from the renderer. - auto chain = _renderEngine->GetSwapChain(); + auto chainHandle = _renderEngine->GetSwapChainHandle(); auto weakThis{ get_weak() }; co_await winrt::resume_foreground(Dispatcher()); if (auto control{ weakThis.get() }) { - _AttachDxgiSwapChainToXaml(chain.Get()); + _AttachDxgiSwapChainToXaml(chainHandle); } } - void TermControl::_AttachDxgiSwapChainToXaml(IDXGISwapChain1* swapChain) + void TermControl::_AttachDxgiSwapChainToXaml(HANDLE swapChainHandle) { - auto nativePanel = SwapChainPanel().as(); - nativePanel->SetSwapChain(swapChain); + auto nativePanel = SwapChainPanel().as(); + nativePanel->SetSwapChainHandle(swapChainHandle); } bool TermControl::_InitializeTerminal() @@ -672,7 +672,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation THROW_IF_FAILED(dxEngine->Enable()); _renderEngine = std::move(dxEngine); - _AttachDxgiSwapChainToXaml(_renderEngine->GetSwapChain().Get()); + _AttachDxgiSwapChainToXaml(_renderEngine->GetSwapChainHandle()); // Tell the DX Engine to notify us when the swap chain changes. // We do this after we initially set the swapchain so as to avoid unnecessary callbacks (and locking problems) diff --git a/src/cascadia/TerminalControl/TermControl.h b/src/cascadia/TerminalControl/TermControl.h index 3879c4b3835..81fa53940c4 100644 --- a/src/cascadia/TerminalControl/TermControl.h +++ b/src/cascadia/TerminalControl/TermControl.h @@ -81,7 +81,7 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation void ToggleRetroEffect(); winrt::fire_and_forget RenderEngineSwapChainChanged(); - void _AttachDxgiSwapChainToXaml(IDXGISwapChain1* swapChain); + void _AttachDxgiSwapChainToXaml(HANDLE swapChainHandle); winrt::fire_and_forget _RendererEnteredErrorState(); void _RenderRetryButton_Click(IInspectable const& button, IInspectable const& args); diff --git a/src/common.build.post.props b/src/common.build.post.props index 64ac5f12228..4c3829c773a 100644 --- a/src/common.build.post.props +++ b/src/common.build.post.props @@ -13,7 +13,7 @@ ProgramDatabase - onecoreuap_apiset.lib;d3dcompiler.lib;dwmapi.lib;uxtheme.lib;shlwapi.lib;ntdll.lib;%(AdditionalDependencies) + onecoreuap_apiset.lib;d3dcompiler.lib;dwmapi.lib;uxtheme.lib;shlwapi.lib;ntdll.lib;dcomp.lib;%(AdditionalDependencies) diff --git a/src/renderer/dx/DxRenderer.cpp b/src/renderer/dx/DxRenderer.cpp index 1714b6e10bd..b59ccf692f6 100644 --- a/src/renderer/dx/DxRenderer.cpp +++ b/src/renderer/dx/DxRenderer.cpp @@ -83,6 +83,7 @@ DxEngine::DxEngine() : _glyphCell{}, _boxDrawingEffect{}, _haveDeviceResources{ false }, + _swapChainHandle{ INVALID_HANDLE_VALUE }, _swapChainDesc{ 0 }, _swapChainFrameLatencyWaitableObject{ INVALID_HANDLE_VALUE }, _recreateDeviceRequested{ false }, @@ -455,8 +456,7 @@ try switch (_chainMode) { - case SwapChainMode::ForHwnd: - { + case SwapChainMode::ForHwnd: { // use the HWND's dimensions for the swap chain dimensions. RECT rect = { 0 }; RETURN_IF_WIN32_BOOL_FALSE(GetClientRect(_hwndTarget, &rect)); @@ -485,8 +485,11 @@ try break; } - case SwapChainMode::ForComposition: - { + case SwapChainMode::ForComposition: { + RETURN_IF_FAILED(DCompositionCreateSurfaceHandle(GENERIC_ALL, nullptr, &_swapChainHandle)); + + RETURN_IF_FAILED(_dxgiFactory2.As(&_dxgiFactoryMedia)); + // Use the given target size for compositions. _swapChainDesc.Width = _displaySizePixels.width(); _swapChainDesc.Height = _displaySizePixels.height(); @@ -496,10 +499,11 @@ try // It's 100% required to use scaling mode stretch for composition. There is no other choice. _swapChainDesc.Scaling = DXGI_SCALING_STRETCH; - RETURN_IF_FAILED(_dxgiFactory2->CreateSwapChainForComposition(_d3dDevice.Get(), - &_swapChainDesc, - nullptr, - &_dxgiSwapChain)); + RETURN_IF_FAILED(_dxgiFactoryMedia->CreateSwapChainForCompositionSurfaceHandle(_d3dDevice.Get(), + _swapChainHandle.get(), + &_swapChainDesc, + nullptr, + &_dxgiSwapChain)); break; } default: @@ -825,14 +829,14 @@ try } CATCH_LOG() -Microsoft::WRL::ComPtr DxEngine::GetSwapChain() +HANDLE DxEngine::GetSwapChainHandle() { - if (_dxgiSwapChain.Get() == nullptr) + if (!_swapChainHandle) { THROW_IF_FAILED(_CreateDeviceResources(true)); } - return _dxgiSwapChain; + return _swapChainHandle.get(); } void DxEngine::_InvalidateRectangle(const til::rectangle& rc) @@ -989,15 +993,13 @@ CATCH_RETURN(); { switch (_chainMode) { - case SwapChainMode::ForHwnd: - { + case SwapChainMode::ForHwnd: { RECT clientRect = { 0 }; LOG_IF_WIN32_BOOL_FALSE(GetClientRect(_hwndTarget, &clientRect)); return til::rectangle{ clientRect }.size(); } - case SwapChainMode::ForComposition: - { + case SwapChainMode::ForComposition: { return _sizeTarget; } default: @@ -2229,12 +2231,10 @@ CATCH_RETURN(); switch (_chainMode) { - case SwapChainMode::ForHwnd: - { + case SwapChainMode::ForHwnd: { return D2D1::ColorF(rgb); } - case SwapChainMode::ForComposition: - { + case SwapChainMode::ForComposition: { // Get the A value we've snuck into the highest byte const BYTE a = ((color >> 24) & 0xFF); const float aFloat = a / 255.0f; diff --git a/src/renderer/dx/DxRenderer.hpp b/src/renderer/dx/DxRenderer.hpp index 708f3418e87..363f2466944 100644 --- a/src/renderer/dx/DxRenderer.hpp +++ b/src/renderer/dx/DxRenderer.hpp @@ -63,7 +63,7 @@ namespace Microsoft::Console::Render void SetSoftwareRendering(bool enable) noexcept; - ::Microsoft::WRL::ComPtr GetSwapChain(); + HANDLE GetSwapChainHandle(); // IRenderEngine Members [[nodiscard]] HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept override; @@ -190,9 +190,11 @@ namespace Microsoft::Console::Render ::Microsoft::WRL::ComPtr _d2dBrushBackground; ::Microsoft::WRL::ComPtr _dxgiFactory2; + ::Microsoft::WRL::ComPtr _dxgiFactoryMedia; ::Microsoft::WRL::ComPtr _dxgiDevice; ::Microsoft::WRL::ComPtr _dxgiSurface; + wil::unique_handle _swapChainHandle; DXGI_SWAP_CHAIN_DESC1 _swapChainDesc; ::Microsoft::WRL::ComPtr _dxgiSwapChain; wil::unique_handle _swapChainFrameLatencyWaitableObject; diff --git a/src/renderer/dx/precomp.h b/src/renderer/dx/precomp.h index 1d17a00bb4e..f1bbe6a4298 100644 --- a/src/renderer/dx/precomp.h +++ b/src/renderer/dx/precomp.h @@ -21,6 +21,8 @@ #include #include +#include + #include #include #include