根据 this article by Microsoft 用户设置的屏幕刷新率可以是(并且主要是)一个小数。用户设置为 59Hz,但屏幕根据屏幕显示以 60Hz 运行,但实际上它是 59.94Hz。我需要一个非常流畅的动画是 59.94Hz。
使用 IDirect3DDevice9::GetDisplayMode 我只能得到一个 int 值,根据定义它不能代表实际时间(EnumDisplaySettings 也是如此)。我每秒钟都会遇到明显的卡顿,因为它报告了舍入/截断的 59。如果我手动将应用程序中报告的时间更正为 59.94,它运行流畅。
有谁知道我如何检索真实的屏幕刷新率?
我目前的解决方法是将 60Hz 和 59Hz 都映射到恒定的 59.94Hz,但这并不令人满意。
最佳答案
如果您的目标是 Windows Vista 或更高版本,答案取决于您的应用程序运行的模式。
如果是窗口化应用程序(或窗口化全屏),则根据用户设置和其他因素通过桌面窗口管理器 (DWM) 控制刷新率。使用DwmGetCompositionTimingInfo并查看DWM_TIMING_INFO::rateRefresh以获取监视器的刷新率。
如果应用程序是真正的全屏,那么您创建的全屏交换链会覆盖系统默认值。但是,您选择的刷新率(DXGI_SWAP_CHAIN_FULLSCREEN_DESC::RefreshRate)应该与监视器支持的刷新率之一匹配。您可以使用 IDXGIOutput::GetDisplayModeList 获取支持的刷新率列表。这是一个这样做的例子:
UINT numModes = 0;
dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, NULL);
DXGI_MODE_DESC* modes = new DXGI_MODE_DESC[numModes];
dxgiOutput->GetDisplayModeList(DXGI_FORMAT_B8G8R8A8_UNORM, 0, &numModes, modes);
// see modes[i].RefreshRate
在任何情况下,如果您使用三重缓冲,您就不应该看到故障。您应该尽可能快地呈现,操作系统会准时呈现。如果您将三重缓冲与自定义管理的帧时序相结合,您可以保证实际上不会获得三重缓冲,并且在 vblank 阶段出现漂移时,您就会出现故障(即使您有一个完美的值,也会逐渐发生)刷新率)。如果您想坚持使用三重缓冲,请尽可能快地呈现并让操作系统处理呈现时间。如果您使用自己的时序来驱动 Present()s(例如,为了获得低延迟响应),您应该在另一个线程上调用 IDXGIOutput::WaitForVBlank 以帮助同步帧时序。如果你最终这样做了,你还应该使用 IDXGISwapChain::GetFrameStatistics 来确保你从任何虚假故障中恢复,否则你最终会落后一帧。
祝你好运!
关于windows - 如何找出真实的屏幕刷新率(不是四舍五入的数字),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18844654/