diff options
author | CrystalP <crystalp@kodi.tv> | 2023-09-10 14:01:31 -0400 |
---|---|---|
committer | CrystalP <crystalp@kodi.tv> | 2023-10-15 02:50:19 -0400 |
commit | d8401a7d41fe79d7336942039402341d41e25613 (patch) | |
tree | 5c8848abca946a3511c5ed97bad6bc03ae2161d5 | |
parent | 0f3e65eaf08bda890154ee467960ac35d4642e78 (diff) | |
download | xbmc-d8401a7d41fe79d7336942039402341d41e25613.tar.xz |
[Windows] Retrieve the screen refresh rate without using the swap chain
The video clock runs on its own thread.
Previous implementation with DeviceResources::GetDisplayMode() used a swap chain method that sometimes
gets stalled by an internal dxgi lock held by the main thread calling Present(). The additional
information is not even useful here => skip
-rw-r--r-- | xbmc/windowing/windows/VideoSyncD3D.cpp | 36 | ||||
-rw-r--r-- | xbmc/windowing/windows/VideoSyncD3D.h | 3 |
2 files changed, 35 insertions, 4 deletions
diff --git a/xbmc/windowing/windows/VideoSyncD3D.cpp b/xbmc/windowing/windows/VideoSyncD3D.cpp index 2e4ed78a84..aad10fe707 100644 --- a/xbmc/windowing/windows/VideoSyncD3D.cpp +++ b/xbmc/windowing/windows/VideoSyncD3D.cpp @@ -20,6 +20,10 @@ #include <mutex> +#ifdef TARGET_WINDOWS_STORE +#include <winrt/Windows.Graphics.Display.Core.h> +#endif + using namespace std::chrono_literals; void CVideoSyncD3D::OnLostDisplay() @@ -54,6 +58,10 @@ bool CVideoSyncD3D::Setup() if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL)) CLog::Log(LOGDEBUG, "CVideoSyncD3D: SetThreadPriority failed"); + Microsoft::WRL::ComPtr<IDXGIOutput> pOutput; + DX::DeviceResources::Get()->GetOutput(&pOutput); + pOutput->GetDesc(&m_outputDesc); + return true; } @@ -74,6 +82,7 @@ void CVideoSyncD3D::Run(CEvent& stopEvent) // sleep until vblank Microsoft::WRL::ComPtr<IDXGIOutput> pOutput; DX::DeviceResources::Get()->GetOutput(&pOutput); + pOutput->GetDesc(&m_outputDesc); pOutput->WaitForVBlank(); // calculate how many vblanks happened @@ -112,14 +121,33 @@ void CVideoSyncD3D::Cleanup() float CVideoSyncD3D::GetFps() { - DXGI_MODE_DESC DisplayMode = {}; - DX::DeviceResources::Get()->GetDisplayMode(&DisplayMode); +#ifdef TARGET_WINDOWS_DESKTOP + DEVMODEW sDevMode = {}; + sDevMode.dmSize = sizeof(sDevMode); - m_fps = (DisplayMode.RefreshRate.Denominator != 0) ? (float)DisplayMode.RefreshRate.Numerator / (float)DisplayMode.RefreshRate.Denominator : 0.0f; + if (EnumDisplaySettingsW(m_outputDesc.DeviceName, ENUM_CURRENT_SETTINGS, &sDevMode)) + { + if ((sDevMode.dmDisplayFrequency + 1) % 24 == 0 || (sDevMode.dmDisplayFrequency + 1) % 30 == 0) + m_fps = static_cast<float>(sDevMode.dmDisplayFrequency + 1) / 1.001f; + else + m_fps = static_cast<float>(sDevMode.dmDisplayFrequency); + + if (sDevMode.dmDisplayFlags & DM_INTERLACED) + m_fps *= 2; + } +#else + using namespace winrt::Windows::Graphics::Display::Core; + + auto hdmiInfo = HdmiDisplayInformation::GetForCurrentView(); + if (hdmiInfo) // Xbox only + { + auto currentMode = hdmiInfo.GetCurrentDisplayMode(); + m_fps = static_cast<float>(currentMode.RefreshRate()); + } +#endif if (m_fps == 0.0) m_fps = 60.0f; return m_fps; } - diff --git a/xbmc/windowing/windows/VideoSyncD3D.h b/xbmc/windowing/windows/VideoSyncD3D.h index 8c706dd88d..aa9d80e6af 100644 --- a/xbmc/windowing/windows/VideoSyncD3D.h +++ b/xbmc/windowing/windows/VideoSyncD3D.h @@ -12,6 +12,8 @@ #include "threads/Event.h" #include "windowing/VideoSync.h" +#include <dxgi1_5.h> + class CVideoSyncD3D : public CVideoSync, IDispResource { public: @@ -33,5 +35,6 @@ private: volatile bool m_displayReset; CEvent m_lostEvent; int64_t m_lastUpdateTime; + DXGI_OUTPUT_DESC m_outputDesc{}; }; |