Windows用EnumDisplaySettings获取名义刷新率,需先EnumDisplayDevices获取设备名;macOS用CGDisplayModeGetRefreshRate但ProMotion返回0.0;Linux应调用XRandR API计算dot_clock/(htotal*vtotal),而非解析xrandr输出。

Windows平台用 EnumDisplaySettings 获取当前显示器刷新率
Windows下最直接的方式是调用GDI API的 EnumDisplaySettings,它能返回当前活动显示模式的 dmDisplayFrequency 字段。注意:这个值是“名义刷新率”,即显卡驱动报告的设置值,不一定是硬件实时测量值。
常见错误是传入错误的设备名——必须用 EnumDisplayDevices 先获取主显示器名称(如 "\\.\DISPLAY1"),不能硬写 "DISPLAY1" 或空字符串;否则函数失败且返回0。
- 调用前需包含
<windows.h>和<winuser.h> - 使用
ENUM_CURRENT_SETTINGS作为参数,避免枚举所有模式降低性能 -
dmDisplayFrequency单位是Hz,但某些驱动会填0或错误值(尤其在多屏+缩放+HDR混合场景) - 若返回值为0,应 fallback 到
GetDeviceCaps(hdc, VREFRESH)(需先GetDC)
macOS上通过 CGDisplayRef + CGDisplayModeRef 查询
macOS不暴露“物理实时刷新率”,只提供当前显示模式声明的刷新率,来源是Core Graphics框架。实际值由系统策略动态调整(如ProMotion自适应刷新),API无法绕过此抽象层。
关键点在于:必须用 CGMainDisplayID() 获取主屏ID,再用 CGDisplayCopyDisplayMode() 拿到当前模式,最后读取 CGDisplayModeGetRefreshRate()。不要用 CGGetActiveDisplayList 后遍历——它可能返回已断开的旧显示器句柄。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
CGDisplayModeGetRefreshRate()返回double,典型值如60.0、120.0,但ProMotion设备可能返回0.0(表示动态范围,非错误) - 无法区分是60Hz固定还是10–120Hz自适应;系统不提供底层传感器数据接口
- 需要链接
-framework CoreGraphics,C++中直接调用无额外封装成本
Linux/X11下解析 xrandr --verbose 输出不可靠,应优先用 XRandR 扩展API
依赖shell命令解析 xrandr --verbose 输出是脆弱方案:输出格式随驱动版本变化,且无法反映运行时动态切换(如DPMS唤醒后新刷新率)。正确做法是用X11的 XRandR 扩展直接查 XRRGetScreenResources 和 XRRGetOutputInfo。
难点在于:刷新率信息藏在 XRRGetOutputInfo 返回的 XRRModeInfo 数组里,而“当前活动模式”需比对 output_info->current_mode 的 id 字段匹配数组元素;mode->dot_clock / (mode->htotal * mode->vtotal) 才是真实计算值,不是 mode->name 里带的字符串(如 "1920x1080_60" 可能不准)。
- 必须启用
XRANDR扩展(XRRQueryExtension验证),否则XRRGetScreenResources返回NULL - 部分Wayland会话下X11客户端无法访问真实刷新率,此时应检测
WAYLAND_DISPLAY环境变量并放弃X11路径 -
dot_clock单位是kHz,htotal/vtotal是总像素数,结果需四舍五入到整数Hz
跨平台实时性陷阱:所谓“实时”其实是驱动快照,不是传感器级采样
所有主流操作系统API返回的都不是每帧测量的物理刷新率,而是显卡驱动在模式切换时上报的标称值。即使显示器支持120Hz并正在以该频率运行,若驱动未触发重协商(如窗口全屏切换、DPMS唤醒),API仍返回旧值。
没有标准C++接口能绕过驱动直接读取显示器EDID或DP PHY层状态;厂商私有工具(如NVIDIA Inspector、Intel Graphics Command Center)才有此类能力,且需管理员权限和专用驱动支持。
真正需要毫秒级刷新率波动监测(比如防撕裂调试、VR同步验证),只能走专用硬件通道——例如通过USB连接的外部光传感器+时间戳记录,再与应用帧时间对齐。软件层面做到“准实时”已是极限。

















