如何找出实际的屏幕刷新率(不是四舍五入的数字) [英] How to find out real screen refresh rate (not the rounded number)

查看:740
本文介绍了如何找出实际的屏幕刷新率(不是四舍五入的数字)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 Microsoft的这篇文章用户设置的屏幕刷新率可以是(大部分是)小数。用户设置了59Hz,但屏幕以60Hz的屏幕显示速度运行,但实际上是59.94Hz。我需要一个非常平滑的动画,是59.94Hz。

According to this article by Microsoft the screen refresh rate set by the user can be (and is mostly) a fractional number. The user sets 59Hz but the screen runs according to the on screen display at 60Hz, but in reality it's 59.94Hz. What I need for a extremely smooth animation is the 59.94Hz.

使用 IDirect3DDevice9 :: GetDisplayMode 我只得到一个 int 值,根据定义它不能代表实际时间( EnumDisplaySettings )。我每秒遇到一个可见的卡顿现象,因为它报告了舍入/截断的59。如果我将应用程序中报告的定时手动更正为59.94,它将运行平稳。

Using IDirect3DDevice9::GetDisplayMode I only get an int value which cannot by definition represent the real timing (same goes for EnumDisplaySettings). I encounter a visible stutter about every second because it reports the rounded/truncated 59. If I manually correct the reported timing in my application to 59.94 it runs smooth.

任何人都知道我如何才能获取实际的屏幕刷新率?

Anybody knows how I can retrieve the real screen refresh rate?

我当前的解决方法是将60Hz和59Hz都映射到恒定的59.94Hz,但这并不令人满意。

My current workaround is mapping 60Hz and 59Hz both to constant 59.94Hz but that's not satisfying.

推荐答案

如果您的目标是Windows Vista或更高版本,则答案取决于应用程序运行的模式。

If you are targeting Windows Vista or later, the answer depends on the mode in which your app is running.

如果它是窗口应用程序(或窗口全屏显示),则根据用户设置和其他因素,通过桌面窗口管理器(DWM)控制刷新率。使用 DwmGetCompositionTimingInfo 并查看DWM_TIMING_INFO :: rateRefresh以获取监视器刷新率。

If it is a windowed app (or windowed full-screen), refresh rate is controlled via the Desktop Window Manager (DWM) according to user settings and other factors. Use DwmGetCompositionTimingInfo and look at DWM_TIMING_INFO::rateRefresh to get the monitor refresh rate.

如果应用程序是真正的全屏,则您创建的全屏交换链将覆盖系统默认值。但是,您选择的刷新率(DXGI_SWAP_CHAIN_FULLSCREEN_DESC :: RefreshRate)应该与监视器支持的刷新率之一匹配。您可以使用 IDXGIOutput获取支持的刷新率列表: :GetDisplayModeList 。以下是操作方法的示例:

If the app is true full-screen, then the full-screen swap chain you create overrides the system default. However, your selected refresh rate (DXGI_SWAP_CHAIN_FULLSCREEN_DESC::RefreshRate) should match one of the monitor-supported refresh rates. You can get the list of supported refresh rates using IDXGIOutput::GetDisplayModeList. Here's an example of how to do so:

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阶段出现漂移时都会出现故障(即使您具有理想的值,它也会逐渐发生)刷新率)。如果您要坚持使用三重缓冲,那么请尽可能快地进行呈现,并让OS负责演示时序。如果您使用自己的时间来驱动Present()(例如,获得低延迟响应),则应该拨打IDXGIOutput::WaitForVBlank 在另一个线程上有助于同步帧定时。如果最终这样做,还应该使用 IDXGISwapChain :: GetFrameStatistics 以确保您从任何虚假故障中恢复过来,否则最终将落后一帧。

In any case, you shouldn't see glitching if you're triple-buffered. You should just present as fast as you can and the OS will present on time. If you combine triple-buffering with custom managed frame timing, you're guaranteed to not actually get triple-buffering, and you'll get glitches any time there's drift in the vblank phase (which happens gradually even if you have a perfect value for refresh rate). If you want to stick with triple-buffering, just present as fast as you can and let the OS take care of presentation timing. If you're using your own timing to drive Present()s (for example, to get low-latency response), you should throw in a call to IDXGIOutput::WaitForVBlank on another thread to help synchronize frame timings. If you end up doing that, you should also use IDXGISwapChain::GetFrameStatistics to make sure you recover from any spurious glitches, otherwise you'll end up a frame behind.

祝你好运!

这篇关于如何找出实际的屏幕刷新率(不是四舍五入的数字)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆