mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2025-03-31 23:41:25 +00:00
When vsync is enabled, cap the desired rfps.
With vsync enabled the render times of consecutive frames can diverge. The first frame arrives right at the next display frame and is rendered without waiting time. The next frame has to wait 20ms. The leads to some problems with the move prediction if the client is asynchronous. Fix this by capping the desired frame rate at the display refresh rate. Also make sure that the network framerate is never higher then the renderer framerate. With the commit the timing is always correct: * With no limit as much frames as possible are rendered. In this case rfps > nfps and everything's good. * With vsync enabled rfps > nfps or rfps == nfps is given. Also rfps will never exceed the display refresh rate. * On slow hardware either rfps > nfps or an implicit rfpc == nfps is given.
This commit is contained in:
parent
0ba7614739
commit
4d9d555d8e
2 changed files with 58 additions and 3 deletions
|
@ -43,6 +43,8 @@
|
|||
|
||||
#ifdef SDL2
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_video.h>
|
||||
|
||||
#else // SDL1.2
|
||||
#include <SDL/SDL.h>
|
||||
#endif //SDL2
|
||||
|
@ -66,6 +68,7 @@ SDL_Surface* window = NULL;
|
|||
#endif
|
||||
|
||||
qboolean have_stencil = false;
|
||||
qboolean vsync_active;
|
||||
|
||||
#ifdef X11GAMMA
|
||||
XRRCrtcGamma** gammaRamps = NULL;
|
||||
|
@ -602,6 +605,7 @@ GLimp_InitGraphics(qboolean fullscreen)
|
|||
|
||||
/* Set vsync */
|
||||
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, gl_swapinterval->value ? 1 : 0);
|
||||
vsync_active = gl_swapinterval->value ? true : false;
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
|
@ -661,6 +665,7 @@ GLimp_InitGraphics(qboolean fullscreen)
|
|||
|
||||
/* Set vsync - TODO: -1 could be set for "late swap tearing" */
|
||||
SDL_GL_SetSwapInterval(gl_swapinterval->value ? 1 : 0);
|
||||
vsync_active = gl_swapinterval->value ? true : false;
|
||||
#endif
|
||||
|
||||
/* Initialize the stencil buffer */
|
||||
|
@ -750,6 +755,32 @@ void GLimp_GrabInput(qboolean grab)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the VSync state.
|
||||
*/
|
||||
qboolean GLimp_VsyncEnabled(void)
|
||||
{
|
||||
return vsync_active;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the current display refresh rate.
|
||||
*/
|
||||
int GLimp_GetRefreshRate(void)
|
||||
{
|
||||
int i;
|
||||
int refresh = 0;
|
||||
SDL_DisplayMode mode;
|
||||
|
||||
for (i = 0; i < SDL_GetNumVideoDisplays(); ++i)
|
||||
{
|
||||
SDL_GetCurrentDisplayMode(i, &mode);
|
||||
refresh = refresh < mode.refresh_rate ? mode.refresh_rate : refresh;
|
||||
}
|
||||
|
||||
return refresh;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shuts the SDL render backend down
|
||||
*/
|
||||
|
|
|
@ -707,9 +707,15 @@ CL_UpdateWindowedMouse(void)
|
|||
}
|
||||
}
|
||||
|
||||
qboolean GLimp_VsyncEnabled(void);
|
||||
int GLimp_GetRefreshRate(void);
|
||||
|
||||
void
|
||||
CL_Frame(int msec)
|
||||
{
|
||||
int nfps;
|
||||
int rfps;
|
||||
|
||||
static int lasttimecalled;
|
||||
|
||||
static int packetdelta = 1000;
|
||||
|
@ -725,6 +731,24 @@ CL_Frame(int msec)
|
|||
return;
|
||||
}
|
||||
|
||||
// Target render frame rate
|
||||
if (GLimp_VsyncEnabled())
|
||||
{
|
||||
rfps = GLimp_GetRefreshRate();
|
||||
|
||||
if (rfps > gl_maxfps->value)
|
||||
{
|
||||
rfps = (int)gl_maxfps->value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rfps = (int)gl_maxfps->value;
|
||||
}
|
||||
|
||||
// The network framerate must not be higher then the render framerate
|
||||
nfps = (cl_maxfps->value > rfps) ? rfps : cl_maxfps->value;
|
||||
|
||||
// Adjust deltas
|
||||
packetdelta += msec;
|
||||
renderdelta += msec;
|
||||
|
@ -764,7 +788,7 @@ CL_Frame(int msec)
|
|||
if (cl_async->value)
|
||||
{
|
||||
// Network frames
|
||||
if (packetdelta < (1000.0f / cl_maxfps->value))
|
||||
if (packetdelta < (1000.0f / nfps))
|
||||
{
|
||||
packetframe = false;
|
||||
}
|
||||
|
@ -774,7 +798,7 @@ CL_Frame(int msec)
|
|||
}
|
||||
|
||||
// Render frames
|
||||
if (renderdelta < (1000.0f / gl_maxfps->value))
|
||||
if (renderdelta < (1000.0f / rfps))
|
||||
{
|
||||
renderframe = false;
|
||||
}
|
||||
|
@ -788,7 +812,7 @@ CL_Frame(int msec)
|
|||
else
|
||||
{
|
||||
// Cap frames at gl_maxfps
|
||||
if (renderdelta < (1000.0f / gl_maxfps->value))
|
||||
if (renderdelta < (1000.0f / rfps))
|
||||
{
|
||||
renderframe = false;
|
||||
packetframe = false;
|
||||
|
|
Loading…
Reference in a new issue