[videodb] remove unused seasons table from episode_view
[xbmc.git] / xbmc / windowing / win10 / WinSystemWin10.cpp
blob1461d797b04cca3dac36dd9da8dd986c7dc906ca
1 /*
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.
7 */
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"
32 #include <cmath>
33 #include <mutex>
35 #pragma pack(push,8)
37 #include <tpcshrd.h>
38 #include <ppltasks.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()
54 : CWinSystemBase()
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)
61 , m_inFocus(false)
62 , m_bMinimized(false)
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())
82 return false;
84 if (m_displays.empty())
86 CLog::Log(LOGERROR, "{} - no suitable monitor found, aborting...", __FUNCTION__);
87 return false;
90 return true;
93 bool CWinSystemWin10::DestroyWindowSystem()
95 m_bWindowCreated = false;
96 RestoreDesktopResolution();
97 return true;
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;
115 m_inFocus = true;
116 m_bWindowCreated = true;
117 m_state = state;
119 m_coreWindow.Activate();
121 AdjustWindow();
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);
126 return true;
129 bool CWinSystemWin10::ResizeWindow(int newWidth, int newHeight, int newLeft, int newTop)
131 m_nWidth = newWidth;
132 m_nHeight = newHeight;
134 if (newLeft > 0)
135 m_nLeft = newLeft;
137 if (newTop > 0)
138 m_nTop = newTop;
140 AdjustWindow();
142 return true;
145 void CWinSystemWin10::FinishWindowResize(int newWidth, int newHeight)
147 m_nWidth = newWidth;
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)
172 if (!isInFullscreen)
174 if (appView.TryEnterFullScreenMode())
175 ApplicationView::PreferredLaunchWindowingMode(ApplicationViewWindowingMode::FullScreen);
178 else // m_state == WINDOW_STATE_WINDOWED
180 if (isInFullscreen)
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)
220 forceChange = true;
223 if (state == m_state && !forceChange)
224 return true;
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)
234 if (m_coreWindow)
236 m_nLeft = m_coreWindow.Bounds().X;
237 m_nTop = m_coreWindow.Bounds().Y;
238 m_ValidWindowedPosition = true;
242 m_IsAlteringWindow = true;
243 ReleaseBackBuffer();
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);
269 m_state = state;
270 AdjustWindow();
272 else // we're in windowed state now
274 if (state == WINDOW_STATE_FULLSCREEN_WINDOW)
276 ChangeResolution(res, stereoChange);
278 m_state = state;
279 AdjustWindow();
283 CreateBackBuffer();
284 m_IsAlteringWindow = false;
285 return true;
288 bool CWinSystemWin10::DPIChanged(WORD dpi, RECT windowRect) const
290 (void)dpi;
291 return true;
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())
303 return nullptr;
305 return &m_displays.front();
308 bool CWinSystemWin10::ChangeResolution(const RESOLUTION_INFO& res, bool forceChange /*= false*/)
310 const MONITOR_DETAILS* details = GetDefaultMonitor();
312 if (!details)
313 return false;
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());
330 changed = true;
332 else
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)
349 selected = mode;
350 if (needStereo == mode.StereoEnabled())
351 break;
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);
375 return changed;
378 CLog::LogF(LOGDEBUG, "Not supported.");
379 return false;
382 void CWinSystemWin10::UpdateResolutions()
384 m_displays.clear();
386 CWinSystemBase::UpdateResolutions();
387 GetConnectedDisplays(m_displays);
389 const MONITOR_DETAILS* details = GetDefaultMonitor();
390 if (!details)
391 return;
393 float refreshRate;
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;
400 else
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)
418 RESOLUTION_INFO res;
419 res.iWidth = mode.ResolutionWidthInRawPixels();
420 res.iHeight = mode.ResolutionHeightInRawPixels();
421 res.bFullScreen = true;
422 res.dwFlags = 0;
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,
429 res.fRefreshRate);
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);
457 return true;
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;
477 break;
479 break;
480 case DisplayOrientations::Portrait:
481 switch (displayInfo.CurrentOrientation())
483 case DisplayOrientations::Landscape:
484 case DisplayOrientations::LandscapeFlipped:
485 flipResolution = true;
486 break;
488 break;
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();
506 else
508 md.RefreshRate = 60.0;
509 md.Bpp = 24;
512 else
514 // note that refresh rate information is not available on Win10 UWP
515 md.RefreshRate = 60.0;
516 md.Bpp = 24;
518 md.Interlaced = false;
520 outputs.push_back(md);
523 if (dispatcher.HasThreadAccess())
524 handler();
525 else
526 Wait(dispatcher.RunAsync(CoreDispatcherPriority::High, handler));
529 void CWinSystemWin10::ShowOSMouse(bool show)
531 if (!m_coreWindow)
532 return;
534 DispatchedHandler handler([this, show]()
536 CoreCursor cursor = nullptr;
537 if (show)
538 cursor = CoreCursor(CoreCursorType::Arrow, 1);
539 m_coreWindow.PointerCursor(cursor);
542 if (m_coreWindow.Dispatcher().HasThreadAccess())
543 handler();
544 else
545 m_coreWindow.Dispatcher().RunAsync(CoreDispatcherPriority::Normal, handler);
548 bool CWinSystemWin10::Minimize()
550 CLog::Log(LOGDEBUG, "{} is not implemented", __FUNCTION__);
551 return true;
553 bool CWinSystemWin10::Restore()
555 CLog::Log(LOGDEBUG, "{} is not implemented", __FUNCTION__);
556 return true;
558 bool CWinSystemWin10::Hide()
560 CLog::Log(LOGDEBUG, "{} is not implemented", __FUNCTION__);
561 return true;
563 bool CWinSystemWin10::Show(bool raise)
565 CLog::Log(LOGDEBUG, "{} is not implemented", __FUNCTION__);
566 return true;
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()
607 auto delay =
608 std::chrono::milliseconds(CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(
609 "videoscreen.delayrefreshchange") *
610 100);
611 if (delay > 0ms)
613 m_delayDispReset = true;
614 m_dispResetTimer.Set(delay);
616 OnDisplayReset();
619 void CWinSystemWin10::ResolutionChanged()
621 OnDisplayLost();
622 OnDisplayBack();
625 std::unique_ptr<CVideoSync> CWinSystemWin10::GetVideoSync(CVideoReferenceClock* clock)
627 std::unique_ptr<CVideoSync> pVSync(new CVideoSyncD3D(clock));
628 return pVSync;
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
707 for each frame.
709 void CWinSystemWin10::CacheSystemSdrPeakLuminance()
711 m_validSystemSdrPeakLuminance =
712 CWIN32Util::GetSystemSdrWhiteLevel(std::wstring(), &m_systemSdrPeakLuminance);
715 #pragma pack(pop)