Browse Source

engine: common: host: implement adaptive sleeptime, log time to first time for debug purposes

pull/2/head
Alibek Omarov 2 years ago
parent
commit
7d0d6b8e0d
  1. 5
      engine/common/common.h
  2. 101
      engine/common/host.c

5
engine/common/common.h

@ -393,6 +393,11 @@ typedef struct host_parm_s
// bug compatibility level, for very "special" games // bug compatibility level, for very "special" games
bugcomp_t bugcomp; bugcomp_t bugcomp;
// measure time to first frame
double starttime;
// count of sleeps can be inserted between frames
double pureframetime;
} host_parm_t; } host_parm_t;
extern host_parm_t host; extern host_parm_t host;

101
engine/common/host.c

@ -269,43 +269,35 @@ void Host_AbortCurrentFrame( void )
/* /*
================== ==================
Host_CheckSleep Host_CalcSleep
================== ==================
*/ */
void Host_CheckSleep( void ) static int Host_CalcSleep( void )
{ {
int sleeptime = host_sleeptime->value;
#ifndef XASH_DEDICATED #ifndef XASH_DEDICATED
// never sleep in timedemo for benchmarking purposes // never sleep in timedemo for benchmarking purposes
// also don't sleep with vsync for less lag // also don't sleep with vsync for less lag
if( CL_IsTimeDemo( ) || CVAR_TO_BOOL( gl_vsync )) if( CL_IsTimeDemo( ) || CVAR_TO_BOOL( gl_vsync ))
return; return 0;
#endif #endif
if( Host_IsDedicated() ) if( Host_IsDedicated() )
{ {
// let the dedicated server some sleep // let the dedicated server some sleep
Sys_Sleep( sleeptime ); return host_sleeptime->value;
} }
else else if( host.status == HOST_NOFOCUS )
{ {
if( host.status == HOST_NOFOCUS ) if( SV_Active() && CL_IsInGame( ))
{ return host_sleeptime->value; // listenserver
if( SV_Active() && CL_IsInGame( )) return 20; // sleep 20 ms otherwise
Sys_Sleep( sleeptime ); // listenserver }
else Sys_Sleep( 20 ); // sleep 20 ms otherwise else if( host.status == HOST_SLEEP )
} {
else if( host.status == HOST_SLEEP ) return 20;
{
// completely sleep in minimized state
Sys_Sleep( 20 );
}
else
{
Sys_Sleep( sleeptime );
}
} }
return host_sleeptime->value;
} }
void Host_NewInstance( const char *name, const char *finalmsg ) void Host_NewInstance( const char *name, const char *finalmsg )
@ -631,27 +623,53 @@ Returns false if the time is too short to run a frame
qboolean Host_FilterTime( float time ) qboolean Host_FilterTime( float time )
{ {
static double oldtime; static double oldtime;
double fps; double fps, scale = sys_timescale.value;
double scale = sys_timescale.value;
host.realtime += time * scale; host.realtime += time * scale;
fps = Host_CalcFPS( ); fps = Host_CalcFPS();
// clamp the fps in multiplayer games // clamp the fps in multiplayer games
if( fps != 0.0 ) if( fps != 0.0 )
{ {
static int sleeps;
double targetframetime;
int sleeptime = Host_CalcSleep();
// limit fps to withing tolerable range // limit fps to withing tolerable range
fps = bound( MIN_FPS, fps, MAX_FPS ); fps = bound( MIN_FPS, fps, MAX_FPS );
if( Host_IsDedicated() ) if( Host_IsDedicated( ))
targetframetime = ( 1.0 / ( fps + 1.0 ));
else targetframetime = ( 1.0 / fps );
if(( host.realtime - oldtime ) < targetframetime * scale )
{ {
if(( host.realtime - oldtime ) < ( 1.0 / ( fps + 1.0 )) * scale) if( sleeptime > 0 && sleeps > 0 )
return false; {
Sys_Sleep( sleeptime );
sleeps--;
}
return false;
} }
else
if( sleeptime > 0 && sleeps <= 0 )
{ {
if(( host.realtime - oldtime ) < ( 1.0 / fps ) * scale ) if( host.status == HOST_FRAME )
return false; {
// give few sleeps this frame with small margin
double targetsleeptime = targetframetime - host.pureframetime * 2;
// don't sleep if we can't keep up with the framerate
if( targetsleeptime > 0 )
sleeps = targetsleeptime / ( sleeptime * 0.001 );
else sleeps = 0;
}
else
{
// always sleep at least once in minimized/nofocus state
sleeps = 1;
}
} }
} }
@ -674,19 +692,16 @@ Host_Frame
*/ */
void Host_Frame( float time ) void Host_Frame( float time )
{ {
static qboolean slept = false; double t1, t2;
// decide the simulation time // decide the simulation time
if( !Host_FilterTime( time )) if( !Host_FilterTime( time ))
{
if( !slept )
{
Host_CheckSleep();
slept = true;
}
return; return;
}
slept = false; t1 = Sys_DoubleTime();
if( host.framecount == 0 )
Con_DPrintf( "Time to first frame: %.3f seconds\n", t1 - host.starttime );
Host_InputFrame (); // input frame Host_InputFrame (); // input frame
Host_ClientBegin (); // begin client Host_ClientBegin (); // begin client
@ -695,6 +710,10 @@ void Host_Frame( float time )
Host_ClientFrame (); // client frame Host_ClientFrame (); // client frame
HTTP_Run(); // both server and client HTTP_Run(); // both server and client
t2 = Sys_DoubleTime();
host.pureframetime = t2 - t1;
host.framecount++; host.framecount++;
} }
@ -1113,6 +1132,8 @@ int EXPORT Host_Main( int argc, char **argv, const char *progname, int bChangeGa
{ {
static double oldtime, newtime; static double oldtime, newtime;
host.starttime = Sys_DoubleTime();
pChangeGame = func; // may be NULL pChangeGame = func; // may be NULL
Host_InitCommon( argc, argv, progname, bChangeGame ); Host_InitCommon( argc, argv, progname, bChangeGame );

Loading…
Cancel
Save