From 5d15a41b0fbd1c72a852918ff67a61dc9df283f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= Date: Sun, 14 Jun 2026 05:21:10 +0200 Subject: [PATCH] vo/win32/d3d11_helpers: add mp_dxgi_sdr_white_level_from_hwnd() --- video/out/gpu/d3d11_helpers.c | 35 +++++++++++++++++++++++++++++++++++ video/out/gpu/d3d11_helpers.h | 7 +++++++ 2 files changed, 42 insertions(+) diff --git a/video/out/gpu/d3d11_helpers.c b/video/out/gpu/d3d11_helpers.c index 92f412542c..93510d705b 100644 --- a/video/out/gpu/d3d11_helpers.c +++ b/video/out/gpu/d3d11_helpers.c @@ -26,6 +26,7 @@ #include "osdep/io.h" #include "osdep/threads.h" #include "osdep/windows_utils.h" +#include "video/out/win32/displayconfig.h" #include "d3d11_helpers.h" @@ -992,6 +993,8 @@ void mp_dxgi_factory_uninit(struct mp_dxgi_factory_ctx *ctx) SAFE_RELEASE(ctx->factory); SAFE_RELEASE(ctx->last_matched_output); + ctx->white_level_monitor = NULL; + ctx->sdr_white_level = 0; } bool mp_dxgi_output_desc_from_hwnd(struct mp_dxgi_factory_ctx *ctx, @@ -1006,6 +1009,10 @@ bool mp_dxgi_output_desc_from_hwnd(struct mp_dxgi_factory_ctx *ctx, return false; if (!ctx->factory || !IDXGIFactory1_IsCurrent(ctx->factory)) { + // This also clears `white_level_monitor`, to invalidate cached value. + // While we are using displayconfig API to get reference luminance, + // DXGI IsCurrent() is actually tracking reference luminance changes in + // settings. There is no window message sent on this change. mp_dxgi_factory_uninit(ctx); PFN_CREATE_DXGI_FACTORY pCreateDXGIFactory1 = get_CreateDXGIFactory1(); if (FAILED(pCreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&ctx->factory))) @@ -1067,6 +1074,34 @@ bool mp_dxgi_output_desc_from_swapchain(struct mp_dxgi_factory_ctx *ctx, return false; } +float mp_dxgi_sdr_white_level_from_hwnd(struct mp_dxgi_factory_ctx *ctx, + HWND hwnd) +{ +#if HAVE_WIN32_DESKTOP + DXGI_OUTPUT_DESC1 desc; + if (!mp_dxgi_output_desc_from_hwnd(ctx, hwnd, &desc)) + return 0; + + if (ctx && ctx->white_level_monitor == desc.Monitor) + return ctx->sdr_white_level; + + MONITORINFOEXW mi = { .cbSize = sizeof(mi) }; + if (!GetMonitorInfoW(desc.Monitor, (MONITORINFO*)&mi)) + return 0; + + float white_level = mp_w32_displayconfig_get_sdr_white_level(mi.szDevice); + + if (ctx) { + ctx->white_level_monitor = desc.Monitor; + ctx->sdr_white_level = white_level; + } + + return white_level; +#else + return 0; +#endif +} + struct pl_color_space mp_dxgi_desc_to_color_space(const DXGI_OUTPUT_DESC1 *desc) { struct pl_color_space ret = {0}; diff --git a/video/out/gpu/d3d11_helpers.h b/video/out/gpu/d3d11_helpers.h index 669348df1b..f3d4908a17 100644 --- a/video/out/gpu/d3d11_helpers.h +++ b/video/out/gpu/d3d11_helpers.h @@ -65,6 +65,8 @@ struct d3d11_device_opts { struct mp_dxgi_factory_ctx { IDXGIFactory1 *factory; IDXGIOutput6 *last_matched_output; + HMONITOR white_level_monitor; + float sdr_white_level; }; void mp_dxgi_factory_uninit(struct mp_dxgi_factory_ctx *ctx); @@ -79,6 +81,11 @@ bool mp_dxgi_output_desc_from_swapchain(struct mp_dxgi_factory_ctx *ctx, IDXGISwapChain *swapchain, DXGI_OUTPUT_DESC1 *desc); +// Returns the system SDR white level for the monitor the window is on, in nits, +// or 0 if unknown. +float mp_dxgi_sdr_white_level_from_hwnd(struct mp_dxgi_factory_ctx *ctx, + HWND hwnd); + struct pl_color_space mp_dxgi_desc_to_color_space(const DXGI_OUTPUT_DESC1 *desc); OPT_STRING_VALIDATE_FUNC(mp_dxgi_validate_adapter);