Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find out real screen refresh rate (not the rounded number)

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.

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?

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

like image 532
Steffen Binas Avatar asked Sep 17 '13 08:09

Steffen Binas


People also ask

How to get the refresh rate of the screen?

I know of two ways of getting the screen refresh rate on Windows. The first is the simple EnumDisplaySettings function, which fills a struct that contains a rounded screen refresh rate value in fps.

Is there a way to get more precise refresh rate with DX?

There is no reason you cannot use DX to get the more precise refresh rate if you want, DX has been an Operating System component since Win95 OSR2 (which is incidentally when OpenGL was introduced as well). Getting the refresh rate is going to be platform-specific no matter how you look at it, so use whatever tools your platform offers.

Is a high refresh rate good or bad?

Although the perception of a screen with a high refresh rate is quite high, we realize just manipulating the interface of the terminal, it is true that we do not always have the certainty that the phone is working at the refresh rate promised by the manufacturer or that we have chosen in the terminal settings themselves.

Is there a list of supported refresh rates?

You can get the list of supported refresh rates using IDXGIOutput::GetDisplayModeList. Here's an example of how to do so: 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.


Video Answer


1 Answers

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

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.

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

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.

Good luck!

like image 111
MooseBoys Avatar answered Oct 22 '22 14:10

MooseBoys