最直接方式是调用 enumdisplaysettings 获取 devmode 中 dmdisplayfrequency 字段,传 enum_current_settings 参数;linux 则需 xrandr 解析或读取 /sys/class/drm/ 下模式文件;“垂直同步延迟”无法直接获取,仅能间接估算。

Windows 上用 EnumDisplaySettings 读取刷新率最直接
Windows 桌面环境下,显示器的垂直同步频率(即刷新率)是显卡驱动向系统报告的显示模式属性,不是运行时动态变化的参数。最可靠的方式是调用 EnumDisplaySettings 获取当前活动显示器的 DEVMODE,其中 dmDisplayFrequency 字段就是标称刷新率(单位:Hz)。
- 必须传入
ENUM_CURRENT_SETTINGS(而非-1或其他 magic number),否则可能返回默认/备用模式值 - 只对主显示器有效?不,需配合
EnumDisplayDevices遍历所有显示器,用DISPLAY_DEVICE_ATTACHED_TO_DESKTOP过滤物理连接设备 -
dmDisplayFrequency是整数,但部分高刷屏(如 144.01 Hz)会向下取整为 144 —— 这是 Windows API 层限制,不代表实际硬件不支持小数频率 - 示例片段:
DEVMODE dm = {};<br>dm.dmSize = sizeof(dm);<br>if (EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &dm)) {<br> int hz = dm.dmDisplayFrequency; // 如 60、120、144<br>}
Linux 下靠 xrandr 和 drm 接口两条路
Linux 没有统一内核接口暴露刷新率,得看图形栈:X11 用户走 xrandr 命令解析,Wayland 或底层开发则需直接读 /sys/class/drm/ 或调用 libdrm。
-
xrandr --verbose输出里找当前激活模式行(带+号),后面括号内的数字就是刷新率,例如1920x1080 60.00*+→60.00 - 解析时注意区分
*(当前模式)和+(首选模式),两者可能不同;脚本中建议用grep -E '^\s+\S+\s+[0-9.]+[*+]$'提取 - 纯 DRM 方式(无 X/Wayland)可读
/sys/class/drm/card0-DP-1/mode得到类似1920x1080p-60的字符串,再拆分提取数字部分;但路径中的DP-1需先从/sys/class/drm/下枚举确定 -
ioctl(DRM_IOCTL_MODE_GETCONNECTOR)能拿到完整 mode info,但需 root 权限且代码复杂度陡增,普通应用没必要
“垂直同步延迟”不是操作系统能直接提供的概念
操作系统不管理或暴露“垂直同步延迟”,它本质是图形管线中 VSync 信号触发帧提交的时间偏移,受 GPU 驱动、合成器(如 Windows DWM、Linux KWin/Mutter)、应用渲染逻辑共同影响,无法通过标准 API 读取。
- 有人误以为
SwapInterval = 1就等于“延迟 = 16.67ms(60Hz)”,这是错的:实际延迟取决于帧生成时机与下一个 VBlank 的距离,范围在 0 到 1 帧周期之间浮动 - Windows 上可用
DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING+Present(0)绕过 VSync 测基准延迟,再对比开启 VSync 后的帧时间差,但这属于间接估算,非真实延迟值 - Linux Wayland 下,
wp_presentation_time协议可获取服务器端上报的呈现时间戳,结合客户端渲染完成时间,能算出近似延迟,但需 compositor 支持且非所有桌面环境启用 - 别试图从
/proc/sys/vm/swappiness或类似系统参数里找答案 —— 它们和显示同步完全无关
跨平台封装要注意驱动行为差异
同一个显示器,在 Windows 和 Linux 上报告的刷新率可能不同,根源不在 API,而在驱动层对 EDID 数据的解析策略和用户设置覆盖逻辑。
- NVIDIA 驱动在 Windows 控制面板里允许手动创建自定义分辨率+刷新率,此时
EnumDisplaySettings返回的就是该自定义值;Linux 上xrandr --newmode创建的模式默认不激活,需显式--addmode+--output才生效 - 笔记本外接显示器时,Windows 可能因电源策略降频(如独显供电不足时切到 30Hz),而 Linux 可能坚持 EDID 报告的最高值 —— 这不是 bug,是策略差异
- 如果程序需要稳定帧定时(比如音视频同步),不要依赖 OS 报告的刷新率做 sleep 计算,改用
QueryPerformanceCounter(Windows)或clock_gettime(CLOCK_MONOTONIC)(Linux)测实际帧间隔更可靠
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











