mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-03-30 22:50:51 +00:00
Improve the framerate limiter's timing for extreme stable FPS
This commit is contained in:
parent
66cc234be6
commit
685190fe40
2 changed files with 45 additions and 42 deletions
32
src/d_main.c
32
src/d_main.c
|
@ -804,25 +804,17 @@ void D_SRB2Loop(void)
|
|||
doDisplay = false;
|
||||
ticked = false;
|
||||
|
||||
frameCap = false;
|
||||
if (interp)
|
||||
{
|
||||
frameCap = D_CheckFrameCap();
|
||||
}
|
||||
frameCap = D_CheckFrameCap();
|
||||
|
||||
// Moved to here from I_FinishUpdate.
|
||||
// It doesn't track fades properly anymore by being here (might be easy fix),
|
||||
// but it's a little more accurate for actual rendering when its here.
|
||||
SCR_CalculateFPS();
|
||||
|
||||
if (!realtics && !singletics)
|
||||
{
|
||||
if (interp)
|
||||
{
|
||||
if (frameCap)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-interp sleep
|
||||
I_Sleep();
|
||||
if (frameCap)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HW3SOUND
|
||||
|
@ -920,6 +912,11 @@ void D_SRB2Loop(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (frameCap)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
renderdeltatics = realtics * FRACUNIT;
|
||||
rendertimefrac = FRACUNIT;
|
||||
}
|
||||
|
@ -943,11 +940,6 @@ void D_SRB2Loop(void)
|
|||
#endif
|
||||
|
||||
LUA_Step();
|
||||
|
||||
// Moved to here from I_FinishUpdate.
|
||||
// It doesn't track fades properly anymore by being here (might be easy fix),
|
||||
// but it's a little more accurate for actual game logic when its here.
|
||||
SCR_CalculateFPS();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2203,7 +2203,7 @@ void I_Sleep(void)
|
|||
|
||||
boolean I_CheckFrameCap(precise_t start, precise_t end)
|
||||
{
|
||||
UINT32 capFrames = R_GetFramerateCap();
|
||||
const UINT32 capFrames = R_GetFramerateCap();
|
||||
int capMicros = 0;
|
||||
|
||||
int elapsed;
|
||||
|
@ -2219,31 +2219,42 @@ boolean I_CheckFrameCap(precise_t start, precise_t end)
|
|||
|
||||
if (elapsed < capMicros)
|
||||
{
|
||||
// Wait to draw the next frame.
|
||||
UINT32 wait = ((capMicros - elapsed) / 1000);
|
||||
|
||||
if (cv_sleep.value > 1)
|
||||
// Experimental variable delay code.
|
||||
if (cv_sleep.value > 0)
|
||||
{
|
||||
// 1 is the default, and in non-interpolated mode is just the bare minimum wait.
|
||||
// Since we're already adding some wait with an FPS cap, only apply when it's above 1.
|
||||
wait += cv_sleep.value - 1;
|
||||
}
|
||||
const INT64 delayGranularity = 2000; // 2ms, I picked this as it's what GZDoom uses before it stops trying to sleep.
|
||||
INT64 wait = (capMicros - elapsed);
|
||||
|
||||
// If the wait's greater than our granularity value,
|
||||
// we'll just burn the couple extra cycles in the main loop
|
||||
// in order to get to the next frame.
|
||||
// This makes us get to the exact FPS cap more often.
|
||||
while (wait > 0)
|
||||
{
|
||||
precise_t sleepStart = I_GetPreciseTime();
|
||||
precise_t sleepEnd = sleepStart;
|
||||
int sleepElasped = 0;
|
||||
|
||||
// Higher values have more wasted CPU cycles, but the in-game frame performance is better.
|
||||
// 10ms is the average clock tick of most OS scheduling.
|
||||
// 15ms is a little more than that, for leniency on slow machines. (This helps mine reach a stable 60, at least!)
|
||||
// (https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdldelay.html)
|
||||
#define DELAY_GRANULARITY 15
|
||||
if (wait >= DELAY_GRANULARITY)
|
||||
{
|
||||
SDL_Delay(wait);
|
||||
if (wait > delayGranularity)
|
||||
{
|
||||
// Wait 1ms at a time (on default settings)
|
||||
// until we're close enough.
|
||||
SDL_Delay(cv_sleep.value);
|
||||
|
||||
sleepEnd = I_GetPreciseTime();
|
||||
sleepElasped = I_PreciseToMicros(sleepEnd - sleepStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
// When we have an extremely fine wait,
|
||||
// we do this to spin-lock the remaining time.
|
||||
|
||||
while (sleepElasped < wait)
|
||||
{
|
||||
sleepEnd = I_GetPreciseTime();
|
||||
sleepElasped = I_PreciseToMicros(sleepEnd - sleepStart);
|
||||
}
|
||||
}
|
||||
|
||||
wait -= sleepElasped;
|
||||
}
|
||||
}
|
||||
#undef DELAY_GRANULARITY
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue