From fffd18193541999b2b5c00905dea0f1effa0ec07 Mon Sep 17 00:00:00 2001 From: Christopher John Purnell Date: Fri, 28 Nov 2003 19:19:59 +0000 Subject: [PATCH] Timer optimizations. Made the list of pendinig timers ordered. Added a free list of used timer structures. git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@372 7f0cb862-5218-0410-a997-914c9d46530a --- src/freeglut_init.c | 15 +++++++++--- src/freeglut_internal.h | 1 + src/freeglut_main.c | 57 ++++++++++++---------------------------------- src/freeglut_structure.c | 22 ++++++++++++++++++ 4 files changed, 49 insertions(+), 46 deletions(-) diff --git a/src/freeglut_init.c b/src/freeglut_init.c index b23e152..0289ddd 100644 --- a/src/freeglut_init.c +++ b/src/freeglut_init.c @@ -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; diff --git a/src/freeglut_internal.h b/src/freeglut_internal.h index e7f1100..03b08bf 100644 --- a/src/freeglut_internal.h +++ b/src/freeglut_internal.h @@ -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 */ diff --git a/src/freeglut_main.c b/src/freeglut_main.c index 8350e32..55e033a 100644 --- a/src/freeglut_main.c +++ b/src/freeglut_main.c @@ -277,38 +277,20 @@ static void fghCheckJoystickPolls( void ) static void fghCheckTimers( void ) { long checkTime = fgElapsedTime( ); - SFG_Timer *timer, *next; - SFG_List timedOut; - - fgListInit(&timedOut); + SFG_Timer *timer; - 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 */ @@ -319,12 +301,12 @@ long fgElapsedTime( void ) #if TARGET_HOST_UNIX_X11 struct timeval now; long elapsed; - + gettimeofday( &now, NULL ); - + elapsed = (now.tv_usec - fgState.Time.Value.tv_usec) / 1000; elapsed += (now.tv_sec - fgState.Time.Value.tv_sec) * 1000; - + return elapsed; #elif TARGET_HOST_WIN32 return timeGetTime() - fgState.Time.Value; @@ -436,27 +418,15 @@ static int fgHavePendingRedisplays (void) 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( ); diff --git a/src/freeglut_structure.c b/src/freeglut_structure.c index 292ce7b..583f744 100644 --- a/src/freeglut_structure.c +++ b/src/freeglut_structure.c @@ -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 ***/ -- 1.7.10.4