-
Notifications
You must be signed in to change notification settings - Fork 8.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use DComp surface handle for Swap Chain management #10023
Changes from all commits
21a97b6
2e861d8
445bdf6
12b78f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -79,6 +79,7 @@ DxEngine::DxEngine() : | |
_backgroundColor{ 0 }, | ||
_selectionBackground{}, | ||
_haveDeviceResources{ false }, | ||
_swapChainHandle{ INVALID_HANDLE_VALUE }, | ||
_swapChainDesc{ 0 }, | ||
_swapChainFrameLatencyWaitableObject{ INVALID_HANDLE_VALUE }, | ||
_recreateDeviceRequested{ false }, | ||
|
@@ -478,6 +479,29 @@ void DxEngine::_ComputePixelShaderSettings() noexcept | |
} | ||
} | ||
|
||
// Method Description: | ||
// - Use DCompositionCreateSurfaceHandle to create a swapchain handle. This API | ||
// is only present in Windows 8.1+, so we need to delay-load it to make sure | ||
// we can still load on Windows 7. | ||
// - We can't actually hit this on Windows 7, because only the WPF control uses | ||
// us on Windows 7, and they're using the ForHwnd path, which doesn't hit this | ||
// at all. | ||
// Arguments: | ||
// - <none> | ||
// Return Value: | ||
// - An HRESULT for failing to load dcomp.dll, or failing to find the API, or an | ||
// actual failure from the API itself. | ||
[[nodiscard]] HRESULT DxEngine::_CreateSurfaceHandle() noexcept | ||
{ | ||
wil::unique_hmodule hDComp{ LoadLibraryEx(L"Dcomp.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32) }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The library is technically called
|
||
RETURN_LAST_ERROR_IF(hDComp.get() == nullptr); | ||
|
||
auto fn = GetProcAddressByFunctionDeclaration(hDComp.get(), DCompositionCreateSurfaceHandle); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WHAT?? THIS IS SO COOL There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HECK YEA IT IS. |
||
RETURN_LAST_ERROR_IF(fn == nullptr); | ||
|
||
return fn(GENERIC_ALL, nullptr, &_swapChainHandle); | ||
} | ||
|
||
// Routine Description; | ||
// - Creates device-specific resources required for drawing | ||
// which generally means those that are represented on the GPU and can | ||
|
@@ -618,6 +642,13 @@ try | |
} | ||
case SwapChainMode::ForComposition: | ||
{ | ||
if (!_swapChainHandle) | ||
{ | ||
RETURN_IF_FAILED(_CreateSurfaceHandle()); | ||
} | ||
|
||
RETURN_IF_FAILED(_dxgiFactory2.As(&_dxgiFactoryMedia)); | ||
|
||
// Use the given target size for compositions. | ||
_swapChainDesc.Width = _displaySizePixels.width<UINT>(); | ||
_swapChainDesc.Height = _displaySizePixels.height<UINT>(); | ||
|
@@ -627,10 +658,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: | ||
|
@@ -1003,14 +1035,14 @@ try | |
} | ||
CATCH_LOG() | ||
|
||
Microsoft::WRL::ComPtr<IDXGISwapChain1> 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) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wil::unique_*
types have default constructors and you don't need to initialize them here.