Some more fixes to the timing calculations.

If the vsync is enabled missuse it to slow the client down, e.g.
calculate the target framerate, add an security margin of 20% and
let the vsync handle the rest. This hopefully solves some problems
with frametime spikes. This is an idea by @DanielGibson.

If the vsync is disabled use a simple 1s / fps calculation.
This commit is contained in:
Yamagi Burmeister 2019-04-02 19:51:48 +02:00
parent 5bb5e52879
commit b2874ab656

View file

@ -417,16 +417,6 @@ Qcommon_Frame(int usec)
about 1000 microseconds. */
qboolean renderframe = true;
// Average time needed to process a render frame.
static int avgrenderframetime;
static int renderframetimes[60];
static qboolean last_was_renderframe;
// Average time needed to process a packet frame.
static int avgpacketframetime;
static int packetframetimes[60];
static qboolean last_was_packetframe;
/* Tells the client to shutdown.
Used by the signal handlers. */
@ -543,104 +533,47 @@ Qcommon_Frame(int usec)
pfps = (cl_maxfps->value > (rfps * 0.95)) ? floor(rfps * 0.95) : cl_maxfps->value;
/* Calculate average time spend to process a render
frame. This is highly depended on the GPU and the
scenes complexity. Take the last 60 render frames
into account and add a security margin of 1%.
Note: We don't take only pure render frames, but
all render frames into account because on the
popular 60hz displays at least all render frames
are also packet frames if the vsync is enabled. */
if (last_was_renderframe)
{
int measuredframes = 0;
static int renderframenum;
avgrenderframetime = 0;
renderframetimes[renderframenum] = usec;
for (int i = 0; i < 60; i++)
{
if (renderframetimes[i] != 0)
{
avgrenderframetime += renderframetimes[i];
measuredframes++;
}
}
avgrenderframetime /= measuredframes;
avgrenderframetime += (avgrenderframetime * 0.01f);
renderframenum++;
if (renderframenum > 59)
{
renderframenum = 0;
}
last_was_renderframe = false;
}
/* Calculate the average time spend to process a packet
frame. Packet frames are mostly dependend on the CPU
speed and the network delay. Take the last 60 packet
frames into account and add a security margin of 1%.
Note: Like with the render frames we take all packet
frames into account and not only pure packet frames.
The reasons are the same, on popular 60hz displays
most packet frames are also render frames.
*/
if (last_was_packetframe)
{
int measuredframes = 0;
static int packetframenum;
avgpacketframetime = 0;
packetframetimes[packetframenum] = usec;
for (int i = 0; i < 60; i++)
{
if (packetframetimes[i] != 0)
{
avgpacketframetime += packetframetimes[i];
measuredframes++;
}
}
avgpacketframetime /= measuredframes;
avgpacketframetime += (avgpacketframetime * 0.01f);
packetframenum++;
if (packetframenum > 59)
{
packetframenum = 0;
}
last_was_packetframe = false;
}
// Calculate timings.
packetdelta += usec;
renderdelta += usec;
clienttimedelta += usec;
servertimedelta += usec;
if (!cl_timedemo->value) {
if (cl_async->value) {
// Network frames.
if (packetdelta < ((1000000.0f + avgpacketframetime) / pfps)) {
if (!cl_timedemo->value)
{
if (cl_async->value)
{
if (R_IsVSyncActive())
{
// Netwwork frames.
if (packetdelta < (0.8 * (1000000.0f / pfps)))
{
packetframe = false;
}
// Render frames.
if (renderdelta < ((1000000.0f + avgrenderframetime) / rfps)) {
if (renderdelta < (0.8 * (1000000.0f / rfps)))
{
renderframe = false;
}
} else {
}
else
{
// Network frames.
if (packetdelta < (1000000.0f / pfps))
{
packetframe = false;
}
// Render frames.
if (renderdelta < (1000000.0f ) / rfps)
{
renderframe = false;
}
}
}
else
{
// Cap frames at target framerate.
if (renderdelta < (1000000.0f / rfps)) {
renderframe = false;
@ -711,12 +644,10 @@ Qcommon_Frame(int usec)
// Reset deltas and mark frame.
if (packetframe) {
packetdelta = 0;
last_was_packetframe = true;
}
if (renderframe) {
renderdelta = 0;
last_was_renderframe = true;
}
}
#else