Skip to content
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

[windows] Identify SDR WCG screens as non HDR-capable #24689

Merged
merged 2 commits into from
Jun 22, 2024

Conversation

CrystalP
Copy link
Contributor

@CrystalP CrystalP commented Feb 10, 2024

Description

(description modified since first version of the PR, which attempted to do the same thing but using poorly documented Win32 API and educated guesses)

Starting with Windows 11 22H2, Windows supports a new type of screen, "Wide Color Gamut" (WCG) and interop methods were added to allow retrieving the type of screen (including WCG) using a winrt API.
That API also works with Xbox so a new unified code path was created, and the legacy methods for Win32 and UWP remain for now, but are isolated for easy removal eventually.

The WCG screens caused a problem with Win11 because the Win32 API used until now was confusing them with an HDR capable screen, and as a result Kodi would attempt to switch Windows HDR on/off when playing videos, with bad visual results. At this time there is no documented way to detect WCG screens with the Win32 API.

Motivation and context

Helps with issue #24615, misdetection of WCG screen as HDR.

Some screens have wide color support and an on/off hdr software switch.
No problem with the on position, detected as expected by Kodi as HDR capable screen and used as such.
In the off position however, Microsoft added support for non-hdr wcg screens in Windows 11 and recent AMD drivers seem to take advantage of that, resulting in incorrect HDR detection by Kodi due to the way it's reported by the Win32 API.

Attempting to use the WCG capabilities with standard dynamic range is beyond the scope of v21 but at least the screen could be detected as SDR, which allows tonemapping.

How has this been tested?

Win11/Intel works fine, Xbox works
The Win32 detection still works on Windows 8 and 10.

What is the effect on users?

Avoid incorrect switch to non-working HDR mode when the screen is in SDR mode.

Types of change

  • Bug fix (non-breaking change which fixes an issue)
  • Clean up (non-breaking change which removes non-working, unmaintained functionality)
  • Improvement (non-breaking change which improves existing functionality)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that will cause existing functionality to change)
  • Cosmetic change (non-breaking change that doesn't touch code)
  • Student submission (PR was done for educational purposes and will be treated as such)
  • None of the above (please explain below)

Checklist:

  • My code follows the Code Guidelines of this project
  • My change requires a change to the documentation, either Doxygen or wiki
  • I have updated the documentation accordingly
  • I have read the Contributing document
  • I have added tests to cover my change
  • All new and existing tests passed

@CrystalP CrystalP added Type: Improvement non-breaking change which improves existing functionality Platform: Windows Component: DirectX rendering v21 Omega labels Feb 10, 2024
@CrystalP CrystalP added this to the Omega 21.0 Beta 3 milestone Feb 10, 2024
@CrystalP CrystalP requested a review from thexai February 10, 2024 22:04
xbmc/platform/win32/WIN32Util.cpp Outdated Show resolved Hide resolved
@CrystalP CrystalP force-pushed the fix-wcg-detection branch 2 times, most recently from 2b1236e to e3facc4 Compare April 19, 2024 21:45
@CrystalP
Copy link
Contributor Author

Freshened up the code, renamed a variable for clarity.
If this doesn't work , would result in some users saying their screen is not detected as HDR anymore.

Doc from MS hasn't improved in the meantime.

In https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ne-wingdi-displayconfig_device_info_type there are additional values that I didn't notice before
DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO_2
DISPLAYCONFIG_DEVICE_INFO_SET_HDR_STATE
DISPLAYCONFIG_DEVICE_INFO_SET_WCG_STATE

They seem interesting but the Windows 11 SDK 10.0.22621.0 bundled with Visual Studio doesn't have them or the structs they need to work. Not sure where to get a more recent SDK?

An alternative is to change Kodi to call WinRT. Not sure what it takes and consequences. What do you think?

thexai
thexai previously approved these changes Apr 20, 2024
Copy link
Member

@thexai thexai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved but I think this will cause regressions that you will have to take care of later.

For same reason we should not backport.

@CrystalP
Copy link
Contributor Author

The safe way is the WinRT API, but do you have an idea what it would take?

@CrystalP
Copy link
Contributor Author

CrystalP commented Jun 18, 2024

Pushed some changes using the WinRT API, made possible by a couple interop methods added in Win11 22H2 to retrieve a DisplayInformation object for a Win32 monitor or window.
I attempted some unification of the UWP and Win32 winrt code but it's still a work in progress and the #ifdefs are ugly...

I had limited access to a Win11 system and could check that the IsAdvancedColorKindAvailable() API works to detect screens capable of HDR even with HDR off in Windows (Intel GPU).

I don't know what happens on Xbox or UWP on Win11 though, it would help a lot if you could give it a try.

Either IsAdvancedColorKindAvailable() works or we still need the original detection code based on DisplayManager(), that I kept around for now.

Also tested on Win8 and Win10 and it doesn't prevent Kodi from starting and the usual Win32 path is followed successfully.

@CrystalP CrystalP force-pushed the fix-wcg-detection branch 2 times, most recently from 59be259 to 4c07577 Compare June 18, 2024 11:31
@CrystalP
Copy link
Contributor Author

Windows build bot failure is likely due to a requirement for a more recent Windows SDK (PR builds fine locally with Windows 11 SDK 10.0.22621.0)

@thexai thexai dismissed their stale review June 18, 2024 16:34

PR has changed

Copy link
Member

@thexai thexai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only initial review, not tested yet...

xbmc/platform/win10/CMakeLists.txt Outdated Show resolved Hide resolved
xbmc/platform/win10/WinRtUtil.h Outdated Show resolved Hide resolved
xbmc/rendering/dx/DirectXHelper.h Show resolved Hide resolved
xbmc/rendering/dx/DeviceResources.cpp Outdated Show resolved Hide resolved
@thexai
Copy link
Member

thexai commented Jun 19, 2024

Tested on Xbox Series S and confirmed this code is working to detect HDR off but supported:

    // TODO: Combine with desktop case if works for Xbox
    if (colorInfo.IsAdvancedColorKindAvailable(AdvancedColorKind::HighDynamicRange))
      return HDR_STATUS::HDR_OFF;
    else
      return HDR_STATUS::HDR_UNSUPPORTED;

This is very good a allows use same HDR detection code for x64 desktop (Windows 11 only) and Xbox

EDIT: maybe detection code based on DisplayManager() can be moved for clarity to a separated method similar to GetWindowsHDRStatusWin32, maybe "GetWindowsHDRStatusUWP" or similar and only used in case of UWP but not in Xbox. This is only legacy case with no public usage because even .msix can be installed on Windows desktop is not available from MS Store.

Then from main CWIN32Util::GetWindowsHDRStatus()

Call:

  • CWinRtUtil::GetWindowsHDRStatus for Windows 11 and Xbox
  • GetWindowsHDRStatusWin32 for desktop not Win11
  • GetWindowsHDRStatusUWP for UWP not Xbox

xbmc/platform/win32/WinRtUtil.cpp Outdated Show resolved Hide resolved
xbmc/platform/win32/WinRtUtil.cpp Outdated Show resolved Hide resolved
xbmc/rendering/dx/DeviceResources.cpp Outdated Show resolved Hide resolved
@CrystalP
Copy link
Contributor Author

Added a commit to address yesterday's comments.
It's very good news that the Xbox can use the same detection as Win 11 desktop. Thanks for the testing.

Copy link
Member

@thexai thexai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested also on Intel NUC with Windows 11 23H2 and no issues found.

xbmc/platform/win32/WIN32Util.cpp Show resolved Hide resolved
@CrystalP
Copy link
Contributor Author

CrystalP commented Jun 21, 2024

Pushed a commit with requested changes and small refactor of advanced color kind logging.
Also a commit with Windows 11 SDK bump requirement for build, which will not be squashed with the rest at the end
Modifed the PR description to reflect this v2 of the PR.

@CrystalP
Copy link
Contributor Author

Squashed all commits except the SDK version requirement bump.
Thanks to the SDK bump on the builder the PR builds successfully.

xbmc/platform/win32/WinRtUtil.cpp Outdated Show resolved Hide resolved
xbmc/platform/win32/WinRtUtil.cpp Outdated Show resolved Hide resolved
@thexai
Copy link
Member

thexai commented Jun 21, 2024

Windows SDK also should be increased here:

set(VS_MINIMUM_SDK_VERSION 10.0.18362.0)

and:

set(VS_MINIMUM_SDK_VERSION 10.0.18362.0)

Commit with SDK bump should come first to not have intermediate broken state if someone builds commits one to one.

@thexai thexai linked an issue Jun 21, 2024 that may be closed by this pull request
7 tasks
Win 11 22621 (22H2) supports WCG screens and also has some interop functions with Win32 to use
the new WinRT API for the detection.
Unify the Win11 desktop and Xbox paths, kept the older code for older desktop and UWP desktop.
The older code can also be used as fallback in case the new method doesn't work.
@CrystalP
Copy link
Contributor Author

Thanks for finding the cmake SDK version check, my text search missed it.
Updated, as well as the rest of the comments.

@CrystalP CrystalP merged commit 6818de7 into xbmc:master Jun 22, 2024
2 checks passed
@CrystalP CrystalP deleted the fix-wcg-detection branch June 22, 2024 23:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Kodi mistakenly believed that the monitor still supports HDR
2 participants