HostDisplay: Add GetHostRefreshRate() function

Only implemented in Windows for now.
This commit is contained in:
Connor McLaughlin
2021-01-11 03:50:10 +10:00
parent 5769830b72
commit bb572741ae
4 changed files with 66 additions and 0 deletions

View File

@ -15,6 +15,11 @@
#include <vector>
Log_SetChannel(HostDisplay);
#ifdef _WIN32
#include "common/windows_headers.h"
#include <dwmapi.h>
#endif
HostDisplayTexture::~HostDisplayTexture() = default;
HostDisplay::~HostDisplay() = default;
@ -85,6 +90,43 @@ bool HostDisplay::SetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32
return true;
}
bool HostDisplay::GetHostRefreshRate(float* refresh_rate)
{
#ifdef _WIN32
static HMODULE dwm_module = nullptr;
static HRESULT(STDAPICALLTYPE * get_timing_info)(HWND hwnd, DWM_TIMING_INFO * pTimingInfo) = nullptr;
static bool load_tried = false;
if (!load_tried)
{
load_tried = true;
dwm_module = LoadLibrary("dwmapi.dll");
if (dwm_module)
{
std::atexit([]() {
FreeLibrary(dwm_module);
dwm_module = nullptr;
});
get_timing_info =
reinterpret_cast<decltype(get_timing_info)>(GetProcAddress(dwm_module, "DwmGetCompositionTimingInfo"));
}
}
DWM_TIMING_INFO ti = {};
ti.cbSize = sizeof(ti);
HRESULT hr = get_timing_info(nullptr, &ti);
if (SUCCEEDED(hr))
{
if (ti.rateRefresh.uiNumerator == 0 || ti.rateRefresh.uiDenominator == 0)
return false;
*refresh_rate = static_cast<float>(ti.rateRefresh.uiNumerator) / static_cast<float>(ti.rateRefresh.uiDenominator);
return true;
}
#endif
return false;
}
void HostDisplay::SetSoftwareCursor(std::unique_ptr<HostDisplayTexture> texture, float scale /*= 1.0f*/)
{
m_cursor_texture = std::move(texture);

View File

@ -163,6 +163,7 @@ public:
static u32 GetDisplayPixelFormatSize(HostDisplayPixelFormat format);
virtual bool SupportsDisplayPixelFormat(HostDisplayPixelFormat format) const = 0;
virtual bool BeginSetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, void** out_buffer,
@ -170,6 +171,8 @@ public:
virtual void EndSetDisplayPixels() = 0;
virtual bool SetDisplayPixels(HostDisplayPixelFormat format, u32 width, u32 height, const void* buffer, u32 pitch);
virtual bool GetHostRefreshRate(float* refresh_rate);
void SetDisplayLinearFiltering(bool enabled) { m_display_linear_filtering = enabled; }
void SetDisplayTopMargin(s32 height) { m_display_top_margin = height; }
void SetDisplayIntegerScaling(bool enabled) { m_display_integer_scaling = enabled; }