1
0
Fork 0

Various tweaks, enhancements, and optimizations surrounding tile paging

(specifically freeing tiles when we need to remove them from the tile cache.)
This commit is contained in:
curt 2002-07-29 05:07:38 +00:00
parent edaac686a2
commit b3c5a8fb95
3 changed files with 28 additions and 24 deletions

View file

@ -682,24 +682,16 @@ ssgBranch* FGTileEntry::gen_runway_lights( ssgVertexArray *points,ssgVertexArray
}
// ADA
#ifdef WISH_PLIB_WAS_THREADED // but it isn't
// Schedule tile to be freed/removed
void FGTileEntry::sched_removal() {
global_tile_mgr.ready_to_delete( this );
}
#endif
// Free "n" leaf elements of an ssg tree. returns the number of
// elements freed. An empty branch node is considered a leaf. This
// is intended to spread the load of freeing a complex tile out over
// several frames.
static int fgPartialFreeSSGtree( ssgBranch *b, int n ) {
int num_deletes = 0;
if ( n > 0 ) {
// we still have some delete budget left
int num_deletes = 0;
for ( int i = 0; i < b->getNumKids(); ++i ) {
ssgEntity *kid = b->getKid(i);
if ( kid->isAKindOf( ssgTypeBranch() ) && kid->getRef() <= 1 ) {
@ -719,10 +711,15 @@ static int fgPartialFreeSSGtree( ssgBranch *b, int n ) {
num_deletes++;
}
}
return num_deletes;
} else {
return 0;
// remove the parent if it is empty
if ( b->getNumKids() < 0 ) {
ssgDeRefDelete( b );
num_deletes++;
n--;
}
}
return num_deletes;
}
@ -767,7 +764,6 @@ bool FGTileEntry::free_tile() {
// disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING terra_transform" );
if ( fgPartialFreeSSGtree( terra_transform, delete_size ) == 0 ) {
ssgDeRefDelete( terra_transform ); // polish off the parent
free_tracker |= TERRA_NODE;
}
} else if ( !(free_tracker & GROUND_LIGHTS) && gnd_lights_transform ) {
@ -775,7 +771,6 @@ bool FGTileEntry::free_tile() {
// disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING gnd_lights_transform" );
if ( fgPartialFreeSSGtree( gnd_lights_transform, delete_size ) == 0 ) {
ssgDeRefDelete( gnd_lights_transform ); // polish off the parent
free_tracker |= GROUND_LIGHTS;
}
} else if ( !(free_tracker & RWY_LIGHTS) && rwy_lights_transform ) {
@ -783,7 +778,6 @@ bool FGTileEntry::free_tile() {
// disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING rwy_lights_transform" );
if ( fgPartialFreeSSGtree( rwy_lights_transform, delete_size ) == 0 ) {
ssgDeRefDelete( rwy_lights_transform ); // polish off the parent
free_tracker |= RWY_LIGHTS;
}
} else if ( !(free_tracker & LIGHTMAPS) && lightmaps_transform ) {
@ -792,7 +786,6 @@ bool FGTileEntry::free_tile() {
// disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING lightmaps_transform" );
if ( fgPartialFreeSSGtree( lightmaps_transform, delete_size ) == 0 ) {
ssgDeRefDelete( lightmaps_transform ); // polish off the parent
free_tracker |= LIGHTMAPS;
}
} else {

View file

@ -218,11 +218,6 @@ public:
// Destructor
~FGTileEntry();
#ifdef WISH_PLIB_WAS_THREADED // but it isn't
// Schedule tile to be freed/removed
void sched_removal();
#endif
// Clean up the memory used by this tile and delete the arrays
// used by ssg as well as the whole ssg branch. This does a
// partial clean up and exits so we can spread the load across

View file

@ -362,9 +362,25 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters,
// cout << "Adding ssg nodes for "
}
// cout << "delete queue = " << delete_queue.size() << endl;
if ( !delete_queue.empty() ) {
FGTileEntry* e = delete_queue.front();
// cout << "delete queue = " << delete_queue.size() << endl;
while ( delete_queue.size() > 30 ) {
// uh oh, delete queue is blowing up, we aren't clearing
// it fast enough. Let's just panic, well not panic, but
// get real serious and agressively free up some tiles so
// we don't explode our memory usage.
SG_LOG( SG_TERRAIN, SG_ALERT,
"Alert: catching up on tile delete queue" );
FGTileEntry* e = delete_queue.front();
while ( !e->free_tile() );
delete_queue.pop();
delete e;
}
FGTileEntry* e = delete_queue.front();
if ( e->free_tile() ) {
delete_queue.pop();
delete e;