windowsbrightnesshdr

Controlling SDR content brightness programmatically in Windows 11


When using an HDR-enabled display in Windows 11, we can use the "SDR content brightness" slider in Settings > System > Display > HDR to control how bright the regular non-HDR elements are on screen.

E.g. if the display has a max of 400nit and the slider is set to 60%, the SDR content is shown at 240nit brightness.

Windows 10 has something similar too.

I'd like to be able to change the value of the slider programmatically, so I can have a brighter desktop during the day, and a dimmer one during the evening.

The "old" ways changing brightness through WMI or DDC/CI don't work on HDR-enabled displayed.

I used ProcessMonitor to see what the slider does, but it generates way too many entries, and the only relevant bits I can see are that it changes the registry key Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\MonitorDataStore\DELA1E4#G7IYMxgwAAgX_10_07E6_A1\SDRWhiteLevel.

The value is from 1000 (0%) to 3500 (50%) to 6000 (100%) in dec on my display, where 1000 equals 80nit.

Once the SystemSettings.exe has changed the registry value, it calls something in D3D12 to actually apply the change.

Looking through the Microsoft documentation on Win32 API, I can't find any relevant information.

Anyone knows how to get it to work please? Any language will do, PowerShell, C#, C++, Python...

Thank you.


Solution

  • After a bunch of digging i found how SDR brightness is set:

    dwmapi.dll has a function HRESULT DwmpSDRToHDRBoost(HMONITOR monitor, double brightness) that is exported by ordinal 171, where brightness must be 1.0 (80 nits) or greater. The maximum the settings app allows is 6.0 (480 nits), but it can be set higher. If you set a value higher than the brightness your monitor supports, you get clipping.

    The settings app additionally sets the registry key you mentioned, however i didn't find anything that references that key.

    Here is a minimal example:

    #include <Windows.h>
    
    using DwmpSDRToHDRBoostPtr = HRESULT(__stdcall *)(HMONITOR, double);
    
    HMONITOR GetPrimaryMonitor(){
        return MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY);
    }
    
    int main()
    {
        double brightness = 6.0;
        HMODULE hmodule_dwmapi = LoadLibraryW(L"dwmapi.dll");
        DwmpSDRToHDRBoostPtr DwmpSDRToHDRBoost = reinterpret_cast<DwmpSDRToHDRBoostPtr>(GetProcAddress(hmodule_dwmapi, MAKEINTRESOURCE(171)));
        DwmpSDRToHDRBoost(GetPrimaryMonitor(), brightness);
    }
    

    Keep in mind, that this is undocumented API and the ordinal and behaviour might change in the future.


    Update:

    Atleast in the latest Windows 11 insider previews, setting SDR brightness with DwmpSdrToHdrBoost does not update the slider in Windows settings anymore. The value reported by DisplayAdvancedColorInfo.SdrWhiteLevelInNits also doesn't update. They probably cache the values somewhere or read it from registry.