Timer optimizations.
Made the list of pendinig timers ordered. Added a free list of used timer structures. git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@372 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
parent
e6de6c2e6f
commit
e7a19a5546
@ -76,6 +76,7 @@ SFG_State fgState = { { -1, -1, GL_FALSE }, /* Position */
|
||||
{ { 0, 0 }, GL_FALSE },
|
||||
#endif
|
||||
{ NULL, NULL }, /* Timers */
|
||||
{ NULL, NULL }, /* FreeTimers */
|
||||
NULL, /* IdleCallback */
|
||||
0, /* ActiveMenus */
|
||||
NULL, /* MenuStateCallback */
|
||||
@ -235,9 +236,15 @@ void fgDeinitialize( void )
|
||||
|
||||
fgDestroyStructure( );
|
||||
|
||||
while( timer = ( SFG_Timer * )fgState.Timers.First )
|
||||
while( (timer = fgState.Timers.First) )
|
||||
{
|
||||
fgListRemove ( &fgState.Timers, &timer->Node );
|
||||
fgListRemove( &fgState.Timers, &timer->Node );
|
||||
free( timer );
|
||||
}
|
||||
|
||||
while( (timer = fgState.FreeTimers.First) )
|
||||
{
|
||||
fgListRemove( &fgState.FreeTimers, &timer->Node );
|
||||
free( timer );
|
||||
}
|
||||
|
||||
@ -274,7 +281,9 @@ void fgDeinitialize( void )
|
||||
|
||||
fgState.Time.Set = GL_FALSE;
|
||||
|
||||
fgState.Timers.First = fgState.Timers.Last = NULL;
|
||||
fgListInit( &fgState.Timers );
|
||||
fgListInit( &fgState.FreeTimers );
|
||||
|
||||
fgState.IdleCallback = NULL;
|
||||
fgState.MenuStateCallback = ( FGCBMenuState )NULL;
|
||||
fgState.MenuStatusCallback = ( FGCBMenuStatus )NULL;
|
||||
|
@ -239,6 +239,7 @@ struct tagSFG_State
|
||||
|
||||
SFG_Time Time; /* Time that glutInit was called */
|
||||
SFG_List Timers; /* The freeglut timer hooks */
|
||||
SFG_List FreeTimers; /* The unused timer hooks */
|
||||
|
||||
FGCBIdle IdleCallback; /* The global idle callback */
|
||||
|
||||
|
@ -277,38 +277,20 @@ static void fghCheckJoystickPolls( void )
|
||||
static void fghCheckTimers( void )
|
||||
{
|
||||
long checkTime = fgElapsedTime( );
|
||||
SFG_Timer *timer, *next;
|
||||
SFG_List timedOut;
|
||||
SFG_Timer *timer;
|
||||
|
||||
fgListInit(&timedOut);
|
||||
|
||||
for( timer = (SFG_Timer *)fgState.Timers.First;
|
||||
timer;
|
||||
timer = (SFG_Timer *)next )
|
||||
while( timer = fgState.Timers.First )
|
||||
{
|
||||
next = (SFG_Timer *)timer->Node.Next;
|
||||
if( timer->TriggerTime > checkTime )
|
||||
break;
|
||||
|
||||
if( timer->TriggerTime <= checkTime )
|
||||
{
|
||||
fgListRemove( &fgState.Timers, &timer->Node );
|
||||
fgListAppend( &timedOut, &timer->Node );
|
||||
}
|
||||
}
|
||||
fgListRemove( &fgState.Timers, &timer->Node );
|
||||
fgListAppend( &fgState.FreeTimers, &timer->Node );
|
||||
|
||||
/*
|
||||
* Now feel free to execute all the hooked and timed out timer callbacks
|
||||
* And delete the timed out timers...
|
||||
*/
|
||||
while ( (timer = (SFG_Timer *)timedOut.First) )
|
||||
{
|
||||
if( timer->Callback != NULL )
|
||||
timer->Callback( timer->ID );
|
||||
fgListRemove( &timedOut, &timer->Node );
|
||||
free( timer );
|
||||
timer->Callback( timer->ID );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Elapsed Time
|
||||
*/
|
||||
@ -435,28 +417,16 @@ static int fgHavePendingRedisplays (void)
|
||||
fgEnumWindows( fgHavePendingRedisplaysCallback, &enumerator );
|
||||
return !!enumerator.data;
|
||||
}
|
||||
/*
|
||||
* Indicates whether there are any outstanding timers.
|
||||
*/
|
||||
#if 0 /* Not used */
|
||||
static int fgHaveTimers( void )
|
||||
{
|
||||
return !!fgState.Timers.First;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Returns the number of GLUT ticks (milliseconds) till the next timer event.
|
||||
*/
|
||||
static long fgNextTimer( void )
|
||||
{
|
||||
long now = fgElapsedTime();
|
||||
long ret = INT_MAX;
|
||||
SFG_Timer *timer;
|
||||
|
||||
for( timer = (SFG_Timer *)fgState.Timers.First;
|
||||
timer;
|
||||
timer = (SFG_Timer *)timer->Node.Next )
|
||||
ret = MIN( ret, MAX( 0, timer->TriggerTime - now ) );
|
||||
if( (timer = fgState.Timers.First) )
|
||||
ret = timer->TriggerTime - fgElapsedTime();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1011,7 +981,8 @@ void FGAPIENTRY glutMainLoopEvent( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
fghCheckTimers( );
|
||||
if( fgState.Timers.First )
|
||||
fghCheckTimers( );
|
||||
fghCheckJoystickPolls( );
|
||||
fghDisplayAll( );
|
||||
|
||||
|
@ -643,4 +643,26 @@ int fgListLength(SFG_List *list)
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
void fgListInsert(SFG_List *list, SFG_Node *next, SFG_Node *node)
|
||||
{
|
||||
SFG_Node *prev;
|
||||
|
||||
if( (node->Next = next) )
|
||||
{
|
||||
prev = next->Prev;
|
||||
next->Prev = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = list->Last;
|
||||
list->Last = node;
|
||||
}
|
||||
|
||||
if( (node->Prev = prev) )
|
||||
prev->Next = node;
|
||||
else
|
||||
list->First = node;
|
||||
}
|
||||
|
||||
/*** END OF FILE ***/
|
||||
|
Reference in New Issue
Block a user