summaryrefslogtreecommitdiffstats
path: root/video/out/w32_common.c
diff options
context:
space:
mode:
authorJames Ross-Gowan <rossymiles@gmail.com>2015-02-03 15:25:50 +1100
committerwm4 <wm4@nowhere>2015-11-06 19:53:18 +0100
commit647b360a0aa0a3f8cce75812f9d7eac5a78b7a06 (patch)
tree4d6c7e98434975f2db2147d69f43183d47b8f8ee /video/out/w32_common.c
parent68ac45e4876dd8019fc46a2d4b0c20117142eb0b (diff)
downloadmpv-647b360a0aa0a3f8cce75812f9d7eac5a78b7a06.tar.bz2
mpv-647b360a0aa0a3f8cce75812f9d7eac5a78b7a06.tar.xz
w32: use DisplayConfig API to retrieve correct monitor refresh rate
This is based on an older patch by James Ross-Gowan. It was rebased and cleaned up. Also, the DWM API usage present in the older patch was removed, because DWM reports nonsense rates at least on Windows 8.1 (they are rounded to integers, just like with the old GDI API - except the GDI API had a good excuse, as it could report only integers). Signed-off-by: wm4 <wm4@nowhere>
Diffstat (limited to 'video/out/w32_common.c')
-rw-r--r--video/out/w32_common.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/video/out/w32_common.c b/video/out/w32_common.c
index f76384b451..09088df79d 100644
--- a/video/out/w32_common.c
+++ b/video/out/w32_common.c
@@ -34,6 +34,7 @@
#include "vo.h"
#include "win_state.h"
#include "w32_common.h"
+#include "win32/displayconfig.h"
#include "osdep/io.h"
#include "osdep/threads.h"
#include "osdep/w32_keyboard.h"
@@ -59,8 +60,8 @@ struct vo_w32_state {
HWND window;
HWND parent; // 0 normally, set in embedding mode
- // Size and virtual position of the current screen.
- struct mp_rect screenrc;
+ HMONITOR monitor; // Handle of the current screen
+ struct mp_rect screenrc; // Size and virtual position of the current screen
// last non-fullscreen extends (updated only on fullscreen or on initialization)
int prev_width;
@@ -567,22 +568,17 @@ static void wakeup_gui_thread(void *ctx)
PostMessage(w32->window, WM_USER, 0, 0);
}
-static double vo_w32_get_display_fps(struct vo_w32_state *w32)
+static double get_refresh_rate_from_gdi(const wchar_t *device)
{
- // Get the device name of the monitor containing the window
- HMONITOR mon = MonitorFromWindow(w32->window, MONITOR_DEFAULTTOPRIMARY);
- MONITORINFOEXW mi = { .cbSize = sizeof mi };
- GetMonitorInfoW(mon, (MONITORINFO*)&mi);
-
- DEVMODE dm = { .dmSize = sizeof dm };
- if (!EnumDisplaySettingsW(mi.szDevice, ENUM_CURRENT_SETTINGS, &dm))
- return -1;
+ DEVMODEW dm = { .dmSize = sizeof dm };
+ if (!EnumDisplaySettingsW(device, ENUM_CURRENT_SETTINGS, &dm))
+ return 0.0;
// May return 0 or 1 which "represent the display hardware's default refresh rate"
// https://msdn.microsoft.com/en-us/library/windows/desktop/dd183565%28v=vs.85%29.aspx
// mpv validates this value with a threshold of 1, so don't return exactly 1
if (dm.dmDisplayFrequency == 1)
- return 0;
+ return 0.0;
// dm.dmDisplayFrequency is an integer which is rounded down, so it's
// highly likely that 23 represents 24/1.001, 59 represents 60/1.001, etc.
@@ -606,14 +602,37 @@ static double vo_w32_get_display_fps(struct vo_w32_state *w32)
static void update_display_fps(struct vo_w32_state *w32)
{
- double fps = vo_w32_get_display_fps(w32);
- if (fps != w32->display_fps) {
- w32->display_fps = fps;
+ HMONITOR monitor = MonitorFromWindow(w32->window, MONITOR_DEFAULTTOPRIMARY);
+ if (w32->monitor == monitor)
+ return;
+ w32->monitor = monitor;
+
+ MONITORINFOEXW mi = { .cbSize = sizeof mi };
+ GetMonitorInfoW(monitor, (MONITORINFO*)&mi);
+
+ // Try to get the monitor refresh rate.
+ double freq = 0.0;
+
+ if (freq == 0.0)
+ freq = mp_w32_displayconfig_get_refresh_rate(mi.szDevice);
+ if (freq == 0.0)
+ freq = get_refresh_rate_from_gdi(mi.szDevice);
+
+ if (freq != w32->display_fps) {
+ MP_VERBOSE(w32, "display-fps: %f\n", freq);
+ if (freq == 0.0)
+ MP_WARN(w32, "Couldn't determine monitor refresh rate\n");
+ w32->display_fps = freq;
signal_events(w32, VO_EVENT_WIN_STATE);
- MP_VERBOSE(w32, "display-fps: %f\n", fps);
}
}
+static void force_update_display_fps(struct vo_w32_state *w32)
+{
+ w32->monitor = 0;
+ update_display_fps(w32);
+}
+
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
@@ -648,13 +667,14 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
if (GetClientRect(w32->window, &r) && r.right > 0 && r.bottom > 0) {
w32->dw = r.right;
w32->dh = r.bottom;
- update_display_fps(w32); // if we moved between monitors
signal_events(w32, VO_EVENT_RESIZE);
MP_VERBOSE(w32, "resize window: %d:%d\n", w32->dw, w32->dh);
}
// Window may have been minimized or restored
signal_events(w32, VO_EVENT_WIN_STATE);
+
+ update_display_fps(w32);
break;
}
case WM_SIZING:
@@ -799,7 +819,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
mouse_button |= MP_KEY_STATE_UP;
break;
case WM_DISPLAYCHANGE:
- update_display_fps(w32);
+ force_update_display_fps(w32);
break;
}