mirror of
https://github.com/LizardByte/Sunshine.git
synced 2025-01-30 12:32:43 +00:00
Avoid display switching unexpectedly when the UAC secure desktop appears
This commit is contained in:
parent
1020d0c133
commit
a0d5973799
@ -358,8 +358,15 @@ namespace platf::dxgi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Tests to determine if the Desktop Duplication API can capture the given output.
|
||||||
|
* @details When testing for enumeration only, we avoid resyncing the thread desktop.
|
||||||
|
* @param adapter The DXGI adapter to use for capture.
|
||||||
|
* @param output The DXGI output to capture.
|
||||||
|
* @param enumeration_only Specifies whether this test is occurring for display enumeration.
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
test_dxgi_duplication(adapter_t &adapter, output_t &output) {
|
test_dxgi_duplication(adapter_t &adapter, output_t &output, bool enumeration_only) {
|
||||||
D3D_FEATURE_LEVEL featureLevels[] {
|
D3D_FEATURE_LEVEL featureLevels[] {
|
||||||
D3D_FEATURE_LEVEL_11_1,
|
D3D_FEATURE_LEVEL_11_1,
|
||||||
D3D_FEATURE_LEVEL_11_0,
|
D3D_FEATURE_LEVEL_11_0,
|
||||||
@ -397,14 +404,26 @@ namespace platf::dxgi {
|
|||||||
for (int x = 0; x < 2; ++x) {
|
for (int x = 0; x < 2; ++x) {
|
||||||
dup_t dup;
|
dup_t dup;
|
||||||
|
|
||||||
// Ensure we can duplicate the current display
|
// Only resynchronize the thread desktop when not enumerating displays.
|
||||||
syncThreadDesktop();
|
// During enumeration, the caller will do this only once to ensure
|
||||||
|
// a consistent view of available outputs.
|
||||||
|
if (!enumeration_only) {
|
||||||
|
syncThreadDesktop();
|
||||||
|
}
|
||||||
|
|
||||||
status = output1->DuplicateOutput((IUnknown *) device.get(), &dup);
|
status = output1->DuplicateOutput((IUnknown *) device.get(), &dup);
|
||||||
if (SUCCEEDED(status)) {
|
if (SUCCEEDED(status)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
std::this_thread::sleep_for(200ms);
|
|
||||||
|
// If we're not resyncing the thread desktop and we don't have permission to
|
||||||
|
// capture the current desktop, just bail immediately. Retrying won't help.
|
||||||
|
if (enumeration_only && status == E_ACCESSDENIED) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::this_thread::sleep_for(200ms);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_LOG(error) << "DuplicateOutput() test failed [0x"sv << util::hex(status).to_string_view() << ']';
|
BOOST_LOG(error) << "DuplicateOutput() test failed [0x"sv << util::hex(status).to_string_view() << ']';
|
||||||
@ -472,7 +491,7 @@ namespace platf::dxgi {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.AttachedToDesktop && test_dxgi_duplication(adapter_tmp, output_tmp)) {
|
if (desc.AttachedToDesktop && test_dxgi_duplication(adapter_tmp, output_tmp, false)) {
|
||||||
output = std::move(output_tmp);
|
output = std::move(output_tmp);
|
||||||
|
|
||||||
offset_x = desc.DesktopCoordinates.left;
|
offset_x = desc.DesktopCoordinates.left;
|
||||||
@ -1068,6 +1087,13 @@ namespace platf {
|
|||||||
BOOST_LOG(warning) << "Failed to set GPU preference. Capture may not work!"sv;
|
BOOST_LOG(warning) << "Failed to set GPU preference. Capture may not work!"sv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We sync the thread desktop once before we start the enumeration process
|
||||||
|
// to ensure test_dxgi_duplication() returns consistent results for all GPUs
|
||||||
|
// even if the current desktop changes during our enumeration process.
|
||||||
|
// It is critical that we either fully succeed in enumeration or fully fail,
|
||||||
|
// otherwise it can lead to the capture code switching monitors unexpectedly.
|
||||||
|
syncThreadDesktop();
|
||||||
|
|
||||||
dxgi::factory1_t factory;
|
dxgi::factory1_t factory;
|
||||||
status = CreateDXGIFactory1(IID_IDXGIFactory1, (void **) &factory);
|
status = CreateDXGIFactory1(IID_IDXGIFactory1, (void **) &factory);
|
||||||
if (FAILED(status)) {
|
if (FAILED(status)) {
|
||||||
@ -1111,7 +1137,7 @@ namespace platf {
|
|||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
// Don't include the display in the list if we can't actually capture it
|
// Don't include the display in the list if we can't actually capture it
|
||||||
if (desc.AttachedToDesktop && dxgi::test_dxgi_duplication(adapter, output)) {
|
if (desc.AttachedToDesktop && dxgi::test_dxgi_duplication(adapter, output, true)) {
|
||||||
display_names.emplace_back(std::move(device_name));
|
display_names.emplace_back(std::move(device_name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user