Workaround HDR being captured as SDR issue

This commit is contained in:
Yukino Song
2024-09-03 17:31:56 +08:00
parent d332f1dadb
commit 49adbd098f
4 changed files with 117 additions and 17 deletions

View File

@@ -8,6 +8,8 @@
#include <wrl/client.h>
#include <dxgi.h>
#include <highlevelmonitorconfigurationapi.h>
#include <physicalmonitorenumerationapi.h>
#include "virtual_display.h"
@@ -106,6 +108,83 @@ 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");
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");
return false;
}
for (const auto& path : pathArray) {
DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo = path.sourceInfo;
DISPLAYCONFIG_SOURCE_DEVICE_NAME deviceName = {};
deviceName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME;
deviceName.header.size = sizeof(deviceName);
deviceName.header.adapterId = sourceInfo.adapterId;
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;
}
}
wprintf(L"Display not found or HDR not supported: %ls\n", displayName);
return false;
}
void closeVDisplayDevice() {
if (SUDOVDA_DRIVER_HANDLE == INVALID_HANDLE_VALUE) {
return;
@@ -172,29 +251,29 @@ bool setRenderAdapterByName(const std::wstring& adapterName) {
return false;
}
Microsoft::WRL::ComPtr<IDXGIFactory1> factory;
if (!SUCCEEDED(CreateDXGIFactory1(IID_PPV_ARGS(&factory)))) {
return false;
}
Microsoft::WRL::ComPtr<IDXGIFactory1> factory;
if (!SUCCEEDED(CreateDXGIFactory1(IID_PPV_ARGS(&factory)))) {
return false;
}
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter;
Microsoft::WRL::ComPtr<IDXGIAdapter> adapter;
DXGI_ADAPTER_DESC desc;
int i = 0;
while (SUCCEEDED(factory->EnumAdapters(i, &adapter))) {
i += 1;
while (SUCCEEDED(factory->EnumAdapters(i, &adapter))) {
i += 1;
if (!SUCCEEDED(adapter->GetDesc(&desc))) {
continue;
}
if (!SUCCEEDED(adapter->GetDesc(&desc))) {
continue;
}
if (std::wstring_view(desc.Description) != adapterName) {
continue;
}
if (std::wstring_view(desc.Description) != adapterName) {
continue;
}
if (SetRenderAdapter(SUDOVDA_DRIVER_HANDLE, desc.AdapterLuid)) {
return true;
}
}
if (SetRenderAdapter(SUDOVDA_DRIVER_HANDLE, desc.AdapterLuid)) {
return true;
}
}
return false;
}

View File

@@ -25,6 +25,7 @@ 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);
void closeVDisplayDevice();
DRIVER_STATUS openVDisplayDevice();