Skip to content

Commit

Permalink
Split the client into two timezones.
Browse files Browse the repository at this point in the history
* Implement some kind of break, i.e. slow the main loop a little bit
  down and use special OPCODES to tell the CPU that we are in a very
  tight spin loop. This prevent overheating.
* Introduce the render timezone for the renderer, call the renderer up
  to 300 times a second. This is currently hartcoded, a cvar will be
  introduced in a later commit.
* Everything else is the game timezone, hartcoded to 60 frames. The game
  can't run faster anyways.
* COmment old timeer based break. The code isn't removed because we need
  it to optionally support the old behaviour without time zones.
  • Loading branch information
Yamagi committed Aug 31, 2020
1 parent 83f500d commit 064bb3f
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 29 deletions.
116 changes: 87 additions & 29 deletions neo/framework/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2385,51 +2385,109 @@ idCommonLocal::Frame
=================
*/
void idCommonLocal::Frame( void ) {
try {
// pump all the events
Sys_GenerateEvents();
// Slow things a little bit down.
unsigned long long spintime = Sys_Microseconds();

// write config file if anything changed
WriteConfiguration();
while ( 1 ) {
#if defined (__GNUC__) && (__i386 || __x86_64__)
asm("pause");
#elif defined(__aarch64__) || (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || defined(__ARM_ARCH_6K__)
asm("yield");
#endif

// change SIMD implementation if required
if ( com_forceGenericSIMD.IsModified() ) {
InitSIMD();
if ( Sys_Microseconds() >= ( spintime - 5 ) ) {
break;
}
}

eventLoop->RunEventLoop();
// Calculate timings.
static unsigned long long oldframetime;
unsigned long long newframetime = Sys_Microseconds();
unsigned long long frametime = newframetime - oldframetime;
oldframetime = newframetime;

com_frameTime = com_ticNumber * USERCMD_MSEC;
static int clientdelta = 1000000;
static int renderdelta = 1000000;
clientdelta += frametime;
renderdelta += frametime;

idAsyncNetwork::RunFrame();
bool clientframe = true;
bool renderframe = true;

if ( clientdelta < ( 1000000 / 60 ) ) {
clientframe = false;
} else {
clientdelta = 0;
}

if ( renderdelta < ( 1000000 / 300 ) ) {
renderframe = false;
} else {
renderdelta = 0;
}

// Early return if no work has to be done.
if ( !clientframe && !renderframe ) {
return;
}

// Rund the game.
try {
if ( clientframe ) {
// Pump the events.
Sys_GenerateEvents();

// Write config file (if anything changed).
WriteConfiguration();

// Change SIMD implementation if required.
if ( com_forceGenericSIMD.IsModified() ) {
InitSIMD();
}

eventLoop->RunEventLoop();
com_frameTime = com_ticNumber * USERCMD_MSEC;
idAsyncNetwork::RunFrame();
}

if ( idAsyncNetwork::IsActive() ) {
if ( idAsyncNetwork::serverDedicated.GetInteger() != 1 ) {
session->GuiFrameEvents();
session->UpdateScreen( false );
if ( clientframe ) {
session->GuiFrameEvents();
}

if ( renderframe ) {
session->UpdateScreen( false );
}
}
} else {
session->Frame();
if ( clientframe ) {
session->Frame();
}

// normal, in-sequence screen update
session->UpdateScreen( false );
if ( renderframe ) {
// normal, in-sequence screen update
session->UpdateScreen( false );
}
}

// report timing information
if ( com_speeds.GetBool() ) {
static int lastTime;
int nowTime = Sys_Milliseconds();
int com_frameMsec = nowTime - lastTime;
lastTime = nowTime;
Printf( "frame:%i all:%3i gfr:%3i rf:%3i bk:%3i\n", com_frameNumber, com_frameMsec, time_gameFrame, time_frontend, time_backend );
time_gameFrame = 0;
time_gameDraw = 0;
}
if ( clientframe ) {
// report timing information
if ( com_speeds.GetBool() ) {
static int lastTime;
int nowTime = Sys_Milliseconds();
int com_frameMsec = nowTime - lastTime;
lastTime = nowTime;
Printf( "frame:%i all:%3i gfr:%3i rf:%3i bk:%3i\n", com_frameNumber, com_frameMsec, time_gameFrame, time_frontend, time_backend );
time_gameFrame = 0;
time_gameDraw = 0;
}

com_frameNumber++;
com_frameNumber++;

// set idLib frame number for frame based memory dumps
idLib::frameNumber = com_frameNumber;
// set idLib frame number for frame based memory dumps
idLib::frameNumber = com_frameNumber;
}
}

catch( idException & ) {
Expand Down
4 changes: 4 additions & 0 deletions neo/framework/Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2606,13 +2606,17 @@ void idSessionLocal::Frame() {
minTic = latchedTicNumber;
}

/*
while( 1 ) {
latchedTicNumber = com_ticNumber;
if ( latchedTicNumber >= minTic ) {
break;
}
Sys_WaitForEvent( TRIGGER_EVENT_ONE );
}
*/

latchedTicNumber = com_ticNumber;

if ( authEmitTimeout ) {
// waiting for a game auth
Expand Down

0 comments on commit 064bb3f

Please sign in to comment.