aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCrystalP <crystalp@kodi.tv>2023-09-10 14:01:31 -0400
committerCrystalP <crystalp@kodi.tv>2023-10-15 02:50:19 -0400
commitd8401a7d41fe79d7336942039402341d41e25613 (patch)
tree5c8848abca946a3511c5ed97bad6bc03ae2161d5
parent0f3e65eaf08bda890154ee467960ac35d4642e78 (diff)
downloadxbmc-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.cpp36
-rw-r--r--xbmc/windowing/windows/VideoSyncD3D.h3
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{};
};