[Fixed] [Linux/mac/SDL] Stuttering with uncapped framerate (w/patch)

Bugs that have been investigated and resolved somehow.

Moderator: GZDoom Developers

[Linux/mac/SDL] Stuttering with uncapped framerate (w/patch)

Postby Barnaby Crungerson » Sun Sep 14, 2014 8:11 pm

Patch here: http://pastebin.com/sm8H6vRk

I_GetTimeFrac(), which is used for frame interpolation, uses the interval between the last gametic (at TicStart) and the upcoming one (at TicNext) to scale its output. This interval should always be 1000/TICRATE, but right now for some reason it is calculated for every tic separately.

The following expression is used:
sig_next = Scale((Scale (sig_start, TICRATE, 1000) + 1), 1000, TICRATE);
basically meaning
sig_next = (sig_start * TICRATE / 1000 + 1) * 1000 / TICRATE;
which _would_ rearrange _mathematically_ to
sig_next = sig_start + 1000/TICRATE;
which is correct (it's also used in the win32 equivalent).

Because of truncated integer division the result will instead be sig_start rounded up to the next multiple of 1000/TICRATE. Thus sig_next - sig_start will be anything between 0 and 1000/TICRATE (or about 28.57 ms), while it should always be the latter. sig_start is updated (using SDL_GetTicks()) on an interval of 1000/TICRATE, so the rounding error will persist with all the following tics aswell, with its magnitude determined by the value of SDL_GetTicks() when sig_start was set for the first time.

If the error is small, I_GetTimeFrac() returns values close to what they should be, but the larger it gets, the larger a factor they get multiplied with and eventually clamped to what would represent the next gametic, meaning interpolation gets screwed up badly.

This causes the following behavior: at every restart there's about 50% of a chance of seeing ugly stuttering that resembles low framerate (which vid_fps doesn't indicate). Sometimes everything seems to work almost perfectly. Switching between ZDoom/software renderer and GZDoom/OpenGL makes no difference. The stuttering may also appear or disappear after playing for some time. (I couldn't figure out why that's even possible. Perhaps one of the timers can somehow get delayed so the error changes? But it no longer matters, the bug is fixed.)

In the patch it would have been enough to modify the relevant expressions similarly as above, but it turns out the variables sig_next and TicNext could be removed altogether if I_GetTimeFrac() was modified a little, so I decided to just do that. (It's also very, VERY slightly (<2%) more precise because the division by the integer "step" was replaced.)
Barnaby Crungerson

Re: [Linux/mac/SDL] Stuttering with uncapped framerate (w/pa

Postby Graf Zahl » Mon Sep 15, 2014 1:03 am

It wouldn't surprise me the least if this was a failed attempt to work around that 1000/TICRATE does not produce an accurate 35 fps but something slightly faster...
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Joined: 19 Jul 2003
Location: Germany

Re: [Linux/mac/SDL] Stuttering with uncapped framerate (w/pa

Postby Blzut3 » Mon Sep 15, 2014 11:02 am

Patch seems to work as advertised. I noticed the intermittent stuttering while testing the native OS X back end at school. I thought all this time that it was a blitting issue since I managed to get rid of most of the issue on my machine by using SDL's async blit. (I typically prefer to play capped so it didn't bother me too much.)
Pronounced: B-l-zut
Joined: 24 Nov 2004
Github ID: Blzut3
Operating System: Debian-like Linux (Debian, Ubuntu, Mint, etc) 64-bit
Graphics Processor: ATI/AMD with Vulkan Support

Return to Closed Bugs

Who is online

Users browsing this forum: No registered users and 1 guest