Set HDR of screen according to client request
This commit is contained in:
@@ -108,25 +108,21 @@ bool setPrimaryDisplay(const wchar_t* primaryDeviceName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ensureDisplayHDR(const wchar_t* displayName) {
|
||||
UINT32 pathCount = 0, modeCount = 0;
|
||||
|
||||
if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount) != ERROR_SUCCESS) {
|
||||
printf("Failed to query display configuration.\n");
|
||||
bool findDisplayIds(const wchar_t* displayName, LUID& adapterId, uint32_t& targetId) {
|
||||
UINT pathCount;
|
||||
UINT modeCount;
|
||||
if (GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &pathCount, &modeCount)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<DISPLAYCONFIG_PATH_INFO> pathArray(pathCount);
|
||||
std::vector<DISPLAYCONFIG_MODE_INFO> modeArray(modeCount);
|
||||
|
||||
if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, pathArray.data(), &modeCount, modeArray.data(), NULL) != ERROR_SUCCESS) {
|
||||
printf("Failed to query display paths.\n");
|
||||
std::vector<DISPLAYCONFIG_PATH_INFO> paths(pathCount);
|
||||
std::vector<DISPLAYCONFIG_MODE_INFO> modes(modeCount);
|
||||
if (QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &pathCount, paths.data(), &modeCount, modes.data(), nullptr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& path : pathArray) {
|
||||
DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo = path.sourceInfo;
|
||||
auto path = std::find_if(paths.begin(), paths.end(), [&displayName](DISPLAYCONFIG_PATH_INFO _path) {
|
||||
DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo = _path.sourceInfo;
|
||||
|
||||
DISPLAYCONFIG_SOURCE_DEVICE_NAME deviceName = {};
|
||||
deviceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
|
||||
@@ -135,54 +131,67 @@ bool ensureDisplayHDR(const wchar_t* displayName) {
|
||||
deviceName.header.id = sourceInfo.id;
|
||||
|
||||
if (DisplayConfigGetDeviceInfo(&deviceName.header) != ERROR_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (std::wstring_view(displayName) == deviceName.viewGdiDeviceName) {
|
||||
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO hdrInfo = {};
|
||||
hdrInfo.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO;
|
||||
hdrInfo.header.size = sizeof(hdrInfo);
|
||||
hdrInfo.header.adapterId = path.targetInfo.adapterId;
|
||||
hdrInfo.header.id = path.targetInfo.id;
|
||||
|
||||
if (DisplayConfigGetDeviceInfo(&hdrInfo.header) != ERROR_SUCCESS) {
|
||||
wprintf(L"Failed to get HDR info for display: %ls\n", std::wstring(deviceName.viewGdiDeviceName));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hdrInfo.advancedColorSupported) {
|
||||
if (hdrInfo.advancedColorEnabled) {
|
||||
DISPLAYCONFIG_SET_ADVANCED_COLOR_STATE setHdrInfo = {};
|
||||
setHdrInfo.header.type = DISPLAYCONFIG_DEVICE_INFO_SET_ADVANCED_COLOR_STATE;
|
||||
setHdrInfo.header.size = sizeof(setHdrInfo);
|
||||
setHdrInfo.header.adapterId = path.targetInfo.adapterId;
|
||||
setHdrInfo.header.id = path.targetInfo.id;
|
||||
setHdrInfo.enableAdvancedColor = FALSE; // Disable HDR
|
||||
|
||||
if (DisplayConfigSetDeviceInfo(&setHdrInfo.header) == ERROR_SUCCESS) {
|
||||
wprintf(L"HDR toggled off for display: %ls\n", displayName);
|
||||
} else {
|
||||
wprintf(L"Failed to toggle HDR off for display: %ls\n", std::wstring(deviceName.viewGdiDeviceName));
|
||||
}
|
||||
|
||||
setHdrInfo.enableAdvancedColor = TRUE; // Enable HDR back on
|
||||
|
||||
if (DisplayConfigSetDeviceInfo(&setHdrInfo.header) == ERROR_SUCCESS) {
|
||||
wprintf(L"HDR toggled on for display: %ls\n", displayName);
|
||||
return true;
|
||||
} else {
|
||||
wprintf(L"Failed to toggle HDR on for display: %ls\n", std::wstring(deviceName.viewGdiDeviceName));
|
||||
}
|
||||
} else {
|
||||
wprintf(L"HDR is not enabled on display: %ls\n", displayName);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return std::wstring_view(displayName) == deviceName.viewGdiDeviceName;
|
||||
});
|
||||
|
||||
if (path == paths.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wprintf(L"Display not found or HDR not supported: %ls\n", displayName);
|
||||
return false;
|
||||
adapterId = path->sourceInfo.adapterId;
|
||||
targetId = path->targetInfo.id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getDisplayHDR(const LUID& adapterId, const uint32_t& targetId) {
|
||||
DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO hdrInfo = {};
|
||||
hdrInfo.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO;
|
||||
hdrInfo.header.size = sizeof(hdrInfo);
|
||||
hdrInfo.header.adapterId = adapterId;
|
||||
hdrInfo.header.id = targetId;
|
||||
|
||||
if (DisplayConfigGetDeviceInfo(&hdrInfo.header) != ERROR_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return hdrInfo.advancedColorSupported && hdrInfo.advancedColorEnabled;
|
||||
}
|
||||
|
||||
bool setDisplayHDR(const LUID& adapterId, const uint32_t& targetId, bool enableAdvancedColor) {
|
||||
DISPLAYCONFIG_SET_ADVANCED_COLOR_STATE setHdrInfo = {};
|
||||
setHdrInfo.header.type = DISPLAYCONFIG_DEVICE_INFO_SET_ADVANCED_COLOR_STATE;
|
||||
setHdrInfo.header.size = sizeof(setHdrInfo);
|
||||
setHdrInfo.header.adapterId = adapterId;
|
||||
setHdrInfo.header.id = targetId;
|
||||
setHdrInfo.enableAdvancedColor = enableAdvancedColor;
|
||||
|
||||
return DisplayConfigSetDeviceInfo(&setHdrInfo.header) == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
bool getDisplayHDRByName(const wchar_t* displayName) {
|
||||
LUID adapterId;
|
||||
uint32_t targetId;
|
||||
|
||||
if (!findDisplayIds(displayName, adapterId, targetId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getDisplayHDR(adapterId, targetId);
|
||||
}
|
||||
|
||||
bool setDisplayHDRByName(const wchar_t* displayName, bool enableAdvancedColor) {
|
||||
LUID adapterId;
|
||||
uint32_t targetId;
|
||||
|
||||
if (!findDisplayIds(displayName, adapterId, targetId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return setDisplayHDR(adapterId, targetId, enableAdvancedColor);
|
||||
}
|
||||
|
||||
void closeVDisplayDevice() {
|
||||
|
||||
@@ -25,7 +25,8 @@ namespace VDISPLAY {
|
||||
LONG changeDisplaySettings(const wchar_t* deviceName, int width, int height, int refresh_rate);
|
||||
std::wstring getPrimaryDisplay();
|
||||
bool setPrimaryDisplay(const wchar_t* primaryDeviceName);
|
||||
bool ensureDisplayHDR(const wchar_t* displayName);
|
||||
bool getDisplayHDRByName(const wchar_t* displayName);
|
||||
bool setDisplayHDRByName(const wchar_t* displayName, bool enableAdvancedColor);
|
||||
|
||||
void closeVDisplayDevice();
|
||||
DRIVER_STATUS openVDisplayDevice();
|
||||
|
||||
@@ -369,17 +369,28 @@ namespace proc {
|
||||
_app_launch_time = std::chrono::steady_clock::now();
|
||||
|
||||
#ifdef _WIN32
|
||||
auto resetHDRThread = std::thread([this]{
|
||||
auto resetHDRThread = std::thread([this, enable_hdr = launch_session->enable_hdr]{
|
||||
std::this_thread::sleep_for(1s);
|
||||
// Windows doesn't seem to be able to set HDR correctly when a display is just connected,
|
||||
// so we have tooggle HDR for the virtual display manually.
|
||||
// We should have got the actual streaming display by now
|
||||
std::string currentDisplay = this->display_name;
|
||||
if (!currentDisplay.empty()) {
|
||||
if (VDISPLAY::ensureDisplayHDR(platf::from_utf8(currentDisplay).c_str())) {
|
||||
BOOST_LOG(info) << "HDR rsestted for display " << currentDisplay;
|
||||
} else {
|
||||
BOOST_LOG(info) << "HDR not applied for display " << currentDisplay;
|
||||
};
|
||||
auto currentDisplayW = platf::from_utf8(currentDisplay).c_str();
|
||||
|
||||
this->initial_display = currentDisplay;
|
||||
this->initial_hdr = VDISPLAY::getDisplayHDRByName(currentDisplayW);
|
||||
if (!VDISPLAY::setDisplayHDRByName(currentDisplayW, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable_hdr) {
|
||||
if (VDISPLAY::setDisplayHDRByName(currentDisplayW, true)) {
|
||||
BOOST_LOG(info) << "HDR enabled for display " << currentDisplay;
|
||||
} else {
|
||||
BOOST_LOG(info) << "HDR enable failed for display " << currentDisplay;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -462,6 +473,14 @@ namespace proc {
|
||||
_pipe.reset();
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!this->initial_display.empty()) {
|
||||
if (VDISPLAY::setDisplayHDRByName(platf::from_utf8(this->initial_display).c_str(), this->initial_hdr)) {
|
||||
BOOST_LOG(info) << "HDR restored successfully for display " << this->initial_display;
|
||||
} else {
|
||||
BOOST_LOG(info) << "HDR restore failed for display " << this->initial_display;
|
||||
};
|
||||
}
|
||||
|
||||
if (vDisplayDriverStatus == VDISPLAY::DRIVER_STATUS::OK && _launch_session && this->virtual_display) {
|
||||
if (VDISPLAY::removeVirtualDisplay(_launch_session->display_guid)) {
|
||||
BOOST_LOG(info) << "Virtual Display removed successfully";
|
||||
|
||||
@@ -79,7 +79,9 @@ namespace proc {
|
||||
KITTY_DEFAULT_CONSTR_MOVE_THROW(proc_t)
|
||||
|
||||
std::string display_name;
|
||||
std::string initial_display;
|
||||
bool virtual_display;
|
||||
bool initial_hdr;
|
||||
|
||||
proc_t(
|
||||
boost::process::environment &&env,
|
||||
|
||||
4
third-party/sudovda/sudovda.h
vendored
4
third-party/sudovda/sudovda.h
vendored
@@ -228,6 +228,10 @@ static const bool GetAddedDisplayName(const VIRTUAL_DISPLAY_ADD_OUT& addedDispla
|
||||
return _path.targetInfo.id == addedDisplay.TargetId;
|
||||
});
|
||||
|
||||
if (path == paths.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DISPLAYCONFIG_SOURCE_DEVICE_NAME sourceName = {};
|
||||
sourceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
|
||||
sourceName.header.size = sizeof(DISPLAYCONFIG_SOURCE_DEVICE_NAME);
|
||||
|
||||
Reference in New Issue
Block a user