2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "WinSystemWin10.h"
11 #include "ServiceBroker.h"
12 #include "WIN32Util.h"
13 #include "WinEventsWin10.h"
14 #include "application/Application.h"
15 #include "cores/AudioEngine/AESinkFactory.h"
16 #include "cores/AudioEngine/Sinks/AESinkWASAPI.h"
17 #include "cores/AudioEngine/Sinks/AESinkXAudio.h"
18 #include "rendering/dx/DirectXHelper.h"
19 #include "rendering/dx/RenderContext.h"
20 #include "rendering/dx/ScreenshotSurfaceWindows.h"
21 #include "settings/DisplaySettings.h"
22 #include "settings/Settings.h"
23 #include "settings/SettingsComponent.h"
24 #include "utils/SystemInfo.h"
25 #include "utils/log.h"
26 #include "windowing/GraphicContext.h"
27 #include "windowing/windows/VideoSyncD3D.h"
29 #include "platform/win10/AsyncHelpers.h"
30 #include "platform/win32/CharsetConverter.h"
39 #include <winrt/Windows.ApplicationModel.DataTransfer.h>
40 #include <winrt/Windows.Foundation.Metadata.h>
41 #include <winrt/Windows.Graphics.Display.h>
42 #include <winrt/Windows.Graphics.Display.Core.h>
44 using namespace winrt::Windows::ApplicationModel::DataTransfer
;
45 using namespace winrt::Windows::Foundation::Metadata
;
46 using namespace winrt::Windows::Graphics::Display
;
47 using namespace winrt::Windows::Graphics::Display::Core
;
48 using namespace winrt::Windows::UI::Core
;
49 using namespace winrt::Windows::UI::ViewManagement
;
51 using namespace std::chrono_literals
;
53 CWinSystemWin10::CWinSystemWin10()
55 , m_ValidWindowedPosition(false)
56 , m_IsAlteringWindow(false)
57 , m_delayDispReset(false)
58 , m_state(WINDOW_STATE_WINDOWED
)
59 , m_fullscreenState(WINDOW_FULLSCREEN_STATE_FULLSCREEN_WINDOW
)
60 , m_windowState(WINDOW_WINDOW_STATE_WINDOWED
)
64 m_winEvents
.reset(new CWinEventsWin10());
66 AE::CAESinkFactory::ClearSinks();
67 CAESinkXAudio::Register();
68 CAESinkWASAPI::Register();
69 CScreenshotSurfaceWindows::Register();
72 CWinSystemWin10::~CWinSystemWin10()
76 bool CWinSystemWin10::InitWindowSystem()
78 m_coreWindow
= CoreWindow::GetForCurrentThread();
79 dynamic_cast<CWinEventsWin10
&>(*m_winEvents
).InitEventHandlers(m_coreWindow
);
81 if (!CWinSystemBase::InitWindowSystem())
84 if (m_displays
.empty())
86 CLog::Log(LOGERROR
, "{} - no suitable monitor found, aborting...", __FUNCTION__
);
93 bool CWinSystemWin10::DestroyWindowSystem()
95 m_bWindowCreated
= false;
96 RestoreDesktopResolution();
100 bool CWinSystemWin10::CanDoWindowed()
102 return CSysInfo::GetWindowsDeviceFamily() == CSysInfo::Desktop
;
105 bool CWinSystemWin10::CreateNewWindow(const std::string
& name
, bool fullScreen
, RESOLUTION_INFO
& res
)
107 UpdateStates(fullScreen
);
108 // initialize the state
109 WINDOW_STATE state
= GetState(fullScreen
);
111 m_nWidth
= res
.iWidth
;
112 m_nHeight
= res
.iHeight
;
113 m_bFullScreen
= fullScreen
;
114 m_fRefreshRate
= res
.fRefreshRate
;
116 m_bWindowCreated
= true;
119 m_coreWindow
.Activate();
122 // dispatch all events currently pending in the queue to show window's content
123 // and hide UWP splash, without this the Kodi's splash will not be shown
124 m_coreWindow
.Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending
);
129 bool CWinSystemWin10::ResizeWindow(int newWidth
, int newHeight
, int newLeft
, int newTop
)
132 m_nHeight
= newHeight
;
145 void CWinSystemWin10::FinishWindowResize(int newWidth
, int newHeight
)
148 m_nHeight
= newHeight
;
150 float dpi
= DX::DeviceResources::Get()->GetDpi();
151 int dipsWidth
= round(DX::ConvertPixelsToDips(m_nWidth
, dpi
));
152 int dipsHeight
= round(DX::ConvertPixelsToDips(m_nHeight
, dpi
));
154 ApplicationView::PreferredLaunchViewSize(winrt::Windows::Foundation::Size(dipsWidth
, dipsHeight
));
155 ApplicationView::PreferredLaunchWindowingMode(ApplicationViewWindowingMode::PreferredLaunchViewSize
);
158 void CWinSystemWin10::ForceFullScreen(const RESOLUTION_INFO
& resInfo
)
160 ResizeWindow(resInfo
.iScreenWidth
, resInfo
.iScreenHeight
, 0, 0);
163 void CWinSystemWin10::AdjustWindow()
165 CLog::Log(LOGDEBUG
, __FUNCTION__
": adjusting window if required.");
167 auto appView
= ApplicationView::GetForCurrentView();
168 bool isInFullscreen
= appView
.IsFullScreenMode();
170 if (m_state
== WINDOW_STATE_FULLSCREEN_WINDOW
|| m_state
== WINDOW_STATE_FULLSCREEN
)
174 if (appView
.TryEnterFullScreenMode())
175 ApplicationView::PreferredLaunchWindowingMode(ApplicationViewWindowingMode::FullScreen
);
178 else // m_state == WINDOW_STATE_WINDOWED
182 appView
.ExitFullScreenMode();
185 int viewWidth
= appView
.VisibleBounds().Width
;
186 int viewHeight
= appView
.VisibleBounds().Height
;
188 float dpi
= DX::DeviceResources::Get()->GetDpi();
189 int dipsWidth
= round(DX::ConvertPixelsToDips(m_nWidth
, dpi
));
190 int dipsHeight
= round(DX::ConvertPixelsToDips(m_nHeight
, dpi
));
192 if (viewHeight
!= dipsHeight
|| viewWidth
!= dipsWidth
)
194 if (!appView
.TryResizeView(winrt::Windows::Foundation::Size(dipsWidth
, dipsHeight
)))
196 CLog::LogF(LOGDEBUG
, __FUNCTION__
, "resizing ApplicationView failed.");
200 ApplicationView::PreferredLaunchViewSize(winrt::Windows::Foundation::Size(dipsWidth
, dipsHeight
));
201 ApplicationView::PreferredLaunchWindowingMode(ApplicationViewWindowingMode::PreferredLaunchViewSize
);
205 bool CWinSystemWin10::SetFullScreen(bool fullScreen
, RESOLUTION_INFO
& res
, bool blankOtherDisplays
)
207 CWinSystemWin10::UpdateStates(fullScreen
);
208 WINDOW_STATE state
= GetState(fullScreen
);
210 CLog::Log(LOGDEBUG
, "{} ({}) with size {}x{}, refresh {:f}{}", __FUNCTION__
,
211 window_state_names
[state
], res
.iWidth
, res
.iHeight
, res
.fRefreshRate
,
212 (res
.dwFlags
& D3DPRESENTFLAG_INTERLACED
) ? "i" : "");
214 bool forceChange
= false; // resolution/display is changed but window state isn't changed
215 bool stereoChange
= IsStereoEnabled() != (CServiceBroker::GetWinSystem()->GetGfxContext().GetStereoMode() == RENDER_STEREO_MODE_HARDWAREBASED
);
217 if ( m_nWidth
!= res
.iWidth
|| m_nHeight
!= res
.iHeight
|| m_fRefreshRate
!= res
.fRefreshRate
||
218 stereoChange
|| m_bFirstResChange
)
223 if (state
== m_state
&& !forceChange
)
226 // entering to stereo mode, limit resolution to 1080p@23.976
227 if (stereoChange
&& !IsStereoEnabled() && res
.iWidth
> 1280)
229 res
= CDisplaySettings::GetInstance().GetResolutionInfo(CResolutionUtils::ChooseBestResolution(24.f
/ 1.001f
, 1920, 1080, true));
232 if (m_state
== WINDOW_STATE_WINDOWED
)
236 m_nLeft
= m_coreWindow
.Bounds().X
;
237 m_nTop
= m_coreWindow
.Bounds().Y
;
238 m_ValidWindowedPosition
= true;
242 m_IsAlteringWindow
= true;
245 m_bFirstResChange
= false;
246 m_bFullScreen
= fullScreen
;
247 m_nWidth
= res
.iWidth
;
248 m_nHeight
= res
.iHeight
;
249 m_bBlankOtherDisplay
= blankOtherDisplays
;
250 m_fRefreshRate
= res
.fRefreshRate
;
252 if (state
== WINDOW_STATE_FULLSCREEN
)
254 // isn't allowed in UWP
256 else if (m_state
== WINDOW_STATE_FULLSCREEN
|| m_state
== WINDOW_STATE_FULLSCREEN_WINDOW
) // we're in fullscreen state now
258 if (state
== WINDOW_STATE_WINDOWED
) // go to a windowed state
260 // need to restore resolution if it was changed to not native
261 // because we do not support resolution change in windowed mode
262 RestoreDesktopResolution();
264 else if (state
== WINDOW_STATE_FULLSCREEN_WINDOW
) // enter fullscreen window instead
266 ChangeResolution(res
, stereoChange
);
272 else // we're in windowed state now
274 if (state
== WINDOW_STATE_FULLSCREEN_WINDOW
)
276 ChangeResolution(res
, stereoChange
);
284 m_IsAlteringWindow
= false;
288 bool CWinSystemWin10::DPIChanged(WORD dpi
, RECT windowRect
) const
294 void CWinSystemWin10::RestoreDesktopResolution()
296 CLog::Log(LOGDEBUG
, __FUNCTION__
": restoring default desktop resolution");
297 ChangeResolution(CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP
));
300 const MONITOR_DETAILS
* CWinSystemWin10::GetDefaultMonitor() const
302 if (m_displays
.empty())
305 return &m_displays
.front();
308 bool CWinSystemWin10::ChangeResolution(const RESOLUTION_INFO
& res
, bool forceChange
/*= false*/)
310 const MONITOR_DETAILS
* details
= GetDefaultMonitor();
315 if (ApiInformation::IsTypePresent(L
"Windows.Graphics.Display.Core.HdmiDisplayInformation"))
317 bool changed
= false;
318 auto hdmiInfo
= HdmiDisplayInformation::GetForCurrentView();
319 const bool needHDR
= DX::DeviceResources::Get()->IsHDROutput();
321 if (hdmiInfo
!= nullptr)
323 // default mode not in list of supported display modes
324 // TO DO: is still necessary? (or now all modes are listed?)
325 if (!needHDR
&& res
.iScreenWidth
== details
->ScreenWidth
&&
326 res
.iScreenHeight
== details
->ScreenHeight
&&
327 fabs(res
.fRefreshRate
- details
->RefreshRate
) <= 0.00001)
329 Wait(hdmiInfo
.SetDefaultDisplayModeAsync());
334 bool needStereo
= CServiceBroker::GetWinSystem()->GetGfxContext().GetStereoMode() == RENDER_STEREO_MODE_HARDWAREBASED
;
335 auto hdmiModes
= hdmiInfo
.GetSupportedDisplayModes();
337 // For backward compatibility (also old Xbox models) only match color space for HDR modes
338 // and keep SDR modes selection as it is (any color space). Assumes SDR modes listed first.
339 // TO DO: for HDR modes make use of IsSmpte2084Supported() but has issues with current code.
340 // TO DO: for SDR implement preference for BT.709 color space but also fallback to sRGB.
341 HdmiDisplayMode selected
= nullptr;
342 for (const auto& mode
: hdmiModes
)
344 if ((!needHDR
|| (needHDR
&& mode
.ColorSpace() == HdmiDisplayColorSpace::BT2020
)) &&
345 res
.iScreenWidth
== mode
.ResolutionWidthInRawPixels() &&
346 res
.iScreenHeight
== mode
.ResolutionHeightInRawPixels() &&
347 fabs(res
.fRefreshRate
- mode
.RefreshRate()) <= 0.00001)
350 if (needStereo
== mode
.StereoEnabled())
355 if (selected
!= nullptr)
357 changed
= Wait(hdmiInfo
.RequestSetCurrentDisplayModeAsync(
358 selected
, needHDR
? HdmiDisplayHdrOption::Eotf2084
: HdmiDisplayHdrOption::None
));
363 // changing display mode doesn't fire CoreWindow::SizeChanged event
364 if (changed
&& m_bWindowCreated
)
366 // dispatch all events currently pending in the queue to change window's content
367 m_coreWindow
.Dispatcher().ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending
);
369 float dpi
= DisplayInformation::GetForCurrentView().LogicalDpi();
370 float dipsW
= DX::ConvertPixelsToDips(m_nWidth
, dpi
);
371 float dipsH
= DX::ConvertPixelsToDips(m_nHeight
, dpi
);
373 dynamic_cast<CWinEventsWin10
&>(*m_winEvents
).OnResize(dipsW
, dipsH
);
378 CLog::LogF(LOGDEBUG
, "Not supported.");
382 void CWinSystemWin10::UpdateResolutions()
386 CWinSystemBase::UpdateResolutions();
387 GetConnectedDisplays(m_displays
);
389 const MONITOR_DETAILS
* details
= GetDefaultMonitor();
394 int w
= details
->ScreenWidth
;
395 int h
= details
->ScreenHeight
;
396 uint32_t dwFlags
= details
->Interlaced
? D3DPRESENTFLAG_INTERLACED
: 0;;
398 if (details
->RefreshRate
== 59 || details
->RefreshRate
== 29 || details
->RefreshRate
== 23)
399 refreshRate
= static_cast<float>(details
->RefreshRate
+ 1) / 1.001f
;
401 refreshRate
= static_cast<float>(details
->RefreshRate
);
403 RESOLUTION_INFO
& primary_info
= CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP
);
404 UpdateDesktopResolution(primary_info
, "Default", w
, h
, refreshRate
, dwFlags
);
405 CLog::Log(LOGINFO
, "Primary mode: {}", primary_info
.strMode
);
407 // erase previous stored modes
408 CDisplaySettings::GetInstance().ClearCustomResolutions();
410 if (ApiInformation::IsTypePresent(L
"Windows.Graphics.Display.Core.HdmiDisplayInformation"))
412 auto hdmiInfo
= HdmiDisplayInformation::GetForCurrentView();
413 if (hdmiInfo
!= nullptr)
415 auto hdmiModes
= hdmiInfo
.GetSupportedDisplayModes();
416 for (const auto& mode
: hdmiModes
)
419 res
.iWidth
= mode
.ResolutionWidthInRawPixels();
420 res
.iHeight
= mode
.ResolutionHeightInRawPixels();
421 res
.bFullScreen
= true;
423 res
.fRefreshRate
= mode
.RefreshRate();
424 res
.fPixelRatio
= 1.0f
;
425 res
.iScreenWidth
= res
.iWidth
;
426 res
.iScreenHeight
= res
.iHeight
;
427 res
.iSubtitles
= res
.iHeight
;
428 res
.strMode
= StringUtils::Format("Default: {}x{} @ {:.2f}Hz", res
.iWidth
, res
.iHeight
,
430 GetGfxContext().ResetOverscan(res
);
432 if (AddResolution(res
))
433 CLog::Log(LOGINFO
, "Additional mode: {} {}", res
.strMode
,
434 mode
.Is2086MetadataSupported() ? "(HDR)" : "");
439 CDisplaySettings::GetInstance().ApplyCalibrations();
442 bool CWinSystemWin10::AddResolution(const RESOLUTION_INFO
&res
)
444 for (unsigned int i
= RES_CUSTOM
; i
< CDisplaySettings::GetInstance().ResolutionInfoSize(); i
++)
446 RESOLUTION_INFO
& info
= CDisplaySettings::GetInstance().GetResolutionInfo(i
);
447 if ( info
.iWidth
== res
.iWidth
448 && info
.iHeight
== res
.iHeight
449 && info
.iScreenWidth
== res
.iScreenWidth
450 && info
.iScreenHeight
== res
.iScreenHeight
451 && info
.fRefreshRate
== res
.fRefreshRate
452 && info
.dwFlags
== res
.dwFlags
)
453 return false; // already have this resolution
456 CDisplaySettings::GetInstance().AddResolutionInfo(res
);
460 void CWinSystemWin10::GetConnectedDisplays(std::vector
<MONITOR_DETAILS
>& outputs
)
462 auto dispatcher
= m_coreWindow
.Dispatcher();
463 DispatchedHandler
handler([&]()
465 MONITOR_DETAILS md
= {};
467 auto displayInfo
= DisplayInformation::GetForCurrentView();
468 bool flipResolution
= false;
469 switch (displayInfo
.NativeOrientation())
471 case DisplayOrientations::Landscape
:
472 switch (displayInfo
.CurrentOrientation())
474 case DisplayOrientations::Portrait
:
475 case DisplayOrientations::PortraitFlipped
:
476 flipResolution
= true;
480 case DisplayOrientations::Portrait
:
481 switch (displayInfo
.CurrentOrientation())
483 case DisplayOrientations::Landscape
:
484 case DisplayOrientations::LandscapeFlipped
:
485 flipResolution
= true;
490 md
.ScreenWidth
= flipResolution
? displayInfo
.ScreenHeightInRawPixels() : displayInfo
.ScreenWidthInRawPixels();
491 md
.ScreenHeight
= flipResolution
? displayInfo
.ScreenWidthInRawPixels() : displayInfo
.ScreenHeightInRawPixels();
493 if (ApiInformation::IsTypePresent(L
"Windows.Graphics.Display.Core.HdmiDisplayInformation"))
495 auto hdmiInfo
= HdmiDisplayInformation::GetForCurrentView();
496 if (hdmiInfo
!= nullptr)
498 auto currentMode
= hdmiInfo
.GetCurrentDisplayMode();
499 // On Xbox, 4K resolutions only are reported by HdmiDisplayInformation API
500 // so ScreenHeight & ScreenWidth are updated with info provided here
501 md
.ScreenHeight
= currentMode
.ResolutionHeightInRawPixels();
502 md
.ScreenWidth
= currentMode
.ResolutionWidthInRawPixels();
503 md
.RefreshRate
= currentMode
.RefreshRate();
504 md
.Bpp
= currentMode
.BitsPerPixel();
508 md
.RefreshRate
= 60.0;
514 // note that refresh rate information is not available on Win10 UWP
515 md
.RefreshRate
= 60.0;
518 md
.Interlaced
= false;
520 outputs
.push_back(md
);
523 if (dispatcher
.HasThreadAccess())
526 Wait(dispatcher
.RunAsync(CoreDispatcherPriority::High
, handler
));
529 void CWinSystemWin10::ShowOSMouse(bool show
)
534 DispatchedHandler
handler([this, show
]()
536 CoreCursor cursor
= nullptr;
538 cursor
= CoreCursor(CoreCursorType::Arrow
, 1);
539 m_coreWindow
.PointerCursor(cursor
);
542 if (m_coreWindow
.Dispatcher().HasThreadAccess())
545 m_coreWindow
.Dispatcher().RunAsync(CoreDispatcherPriority::Normal
, handler
);
548 bool CWinSystemWin10::Minimize()
550 CLog::Log(LOGDEBUG
, "{} is not implemented", __FUNCTION__
);
553 bool CWinSystemWin10::Restore()
555 CLog::Log(LOGDEBUG
, "{} is not implemented", __FUNCTION__
);
558 bool CWinSystemWin10::Hide()
560 CLog::Log(LOGDEBUG
, "{} is not implemented", __FUNCTION__
);
563 bool CWinSystemWin10::Show(bool raise
)
565 CLog::Log(LOGDEBUG
, "{} is not implemented", __FUNCTION__
);
569 void CWinSystemWin10::Register(IDispResource
*resource
)
571 std::unique_lock
<CCriticalSection
> lock(m_resourceSection
);
572 m_resources
.push_back(resource
);
575 void CWinSystemWin10::Unregister(IDispResource
* resource
)
577 std::unique_lock
<CCriticalSection
> lock(m_resourceSection
);
578 std::vector
<IDispResource
*>::iterator i
= find(m_resources
.begin(), m_resources
.end(), resource
);
579 if (i
!= m_resources
.end())
580 m_resources
.erase(i
);
583 void CWinSystemWin10::OnDisplayLost()
585 CLog::Log(LOGDEBUG
, "{} - notify display lost event", __FUNCTION__
);
588 std::unique_lock
<CCriticalSection
> lock(m_resourceSection
);
589 for (std::vector
<IDispResource
*>::iterator i
= m_resources
.begin(); i
!= m_resources
.end(); ++i
)
590 (*i
)->OnLostDisplay();
594 void CWinSystemWin10::OnDisplayReset()
596 if (!m_delayDispReset
)
598 CLog::Log(LOGDEBUG
, "{} - notify display reset event", __FUNCTION__
);
599 std::unique_lock
<CCriticalSection
> lock(m_resourceSection
);
600 for (std::vector
<IDispResource
*>::iterator i
= m_resources
.begin(); i
!= m_resources
.end(); ++i
)
601 (*i
)->OnResetDisplay();
605 void CWinSystemWin10::OnDisplayBack()
608 std::chrono::milliseconds(CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(
609 "videoscreen.delayrefreshchange") *
613 m_delayDispReset
= true;
614 m_dispResetTimer
.Set(delay
);
619 void CWinSystemWin10::ResolutionChanged()
625 std::unique_ptr
<CVideoSync
> CWinSystemWin10::GetVideoSync(CVideoReferenceClock
* clock
)
627 std::unique_ptr
<CVideoSync
> pVSync(new CVideoSyncD3D(clock
));
631 std::string
CWinSystemWin10::GetClipboardText()
633 std::wstring unicode_text
;
635 auto contentView
= Clipboard::GetContent();
636 if (contentView
.Contains(StandardDataFormats::Text()))
638 auto text
= Wait(contentView
.GetTextAsync());
639 unicode_text
.append(text
.c_str());
642 return KODI::PLATFORM::WINDOWS::FromW(unicode_text
);
645 bool CWinSystemWin10::UseLimitedColor()
647 return CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_VIDEOSCREEN_LIMITEDRANGE
);
650 void CWinSystemWin10::NotifyAppFocusChange(bool bGaining
)
652 m_inFocus
= bGaining
;
655 void CWinSystemWin10::UpdateStates(bool fullScreen
)
657 m_fullscreenState
= WINDOW_FULLSCREEN_STATE_FULLSCREEN_WINDOW
; // currently only this allowed
658 m_windowState
= WINDOW_WINDOW_STATE_WINDOWED
; // currently only this allowed
661 WINDOW_STATE
CWinSystemWin10::GetState(bool fullScreen
) const
663 return static_cast<WINDOW_STATE
>(fullScreen
? m_fullscreenState
: m_windowState
);
666 bool CWinSystemWin10::MessagePump()
668 return m_winEvents
->MessagePump();
672 * \brief Max luminance for GUI SDR content in HDR mode.
673 * \return Max luminance in nits, lower than 10000.
675 float CWinSystemWin10::GetGuiSdrPeakLuminance() const
677 const auto settings
= CServiceBroker::GetSettingsComponent()->GetSettings();
679 // use cached system value as this is called for each frame
680 if (settings
->GetBool(CSettings::SETTING_VIDEOSCREEN_USESYSTEMSDRPEAKLUMINANCE
) &&
681 m_validSystemSdrPeakLuminance
)
682 return m_systemSdrPeakLuminance
;
684 // Max nits for 100% UI setting = 1000 nits, < 10000 nits, min 80 nits for 0%
685 const int guiSdrPeak
= settings
->GetInt(CSettings::SETTING_VIDEOSCREEN_GUISDRPEAKLUMINANCE
);
686 return (80.0f
* std::pow(std::exp(1.0f
), 0.025257f
* guiSdrPeak
));
690 * \brief Test support of the OS for a SDR max luminance in HDR mode setting
691 * \return true when the OS supports that setting, false otherwise
693 bool CWinSystemWin10::HasSystemSdrPeakLuminance()
695 if (m_uiThreadId
== GetCurrentThreadId())
697 const bool hasSystemSdrPeakLum
= CWIN32Util::GetSystemSdrWhiteLevel(std::wstring(), nullptr);
698 m_cachedHasSystemSdrPeakLum
= hasSystemSdrPeakLum
;
699 return hasSystemSdrPeakLum
;
702 return m_cachedHasSystemSdrPeakLum
;
706 * \brief Cache the system HDR/SDR balance for use during rendering, instead of querying the API
709 void CWinSystemWin10::CacheSystemSdrPeakLuminance()
711 m_validSystemSdrPeakLuminance
=
712 CWIN32Util::GetSystemSdrWhiteLevel(std::wstring(), &m_systemSdrPeakLuminance
);