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 // 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 // Free "n" leaf elements of an ssg tree. returns the number of
// elements freed. An empty branch node is considered a leaf. This // elements freed. An empty branch node is considered a leaf. This
// is intended to spread the load of freeing a complex tile out over // is intended to spread the load of freeing a complex tile out over
// several frames. // several frames.
static int fgPartialFreeSSGtree( ssgBranch *b, int n ) { static int fgPartialFreeSSGtree( ssgBranch *b, int n ) {
int num_deletes = 0;
if ( n > 0 ) { if ( n > 0 ) {
// we still have some delete budget left // we still have some delete budget left
int num_deletes = 0;
for ( int i = 0; i < b->getNumKids(); ++i ) { for ( int i = 0; i < b->getNumKids(); ++i ) {
ssgEntity *kid = b->getKid(i); ssgEntity *kid = b->getKid(i);
if ( kid->isAKindOf( ssgTypeBranch() ) && kid->getRef() <= 1 ) { if ( kid->isAKindOf( ssgTypeBranch() ) && kid->getRef() <= 1 ) {
@ -719,12 +711,17 @@ static int fgPartialFreeSSGtree( ssgBranch *b, int n ) {
num_deletes++; num_deletes++;
} }
} }
return num_deletes; // remove the parent if it is empty
} else { if ( b->getNumKids() < 0 ) {
return 0; ssgDeRefDelete( b );
num_deletes++;
n--;
} }
} }
return num_deletes;
}
// Clean up the memory used by this tile and delete the arrays used by // Clean up the memory used by this tile and delete the arrays used by
// ssg as well as the whole ssg branch // ssg as well as the whole ssg branch
@ -767,7 +764,6 @@ bool FGTileEntry::free_tile() {
// disconnected from the scene graph) // disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING terra_transform" ); SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING terra_transform" );
if ( fgPartialFreeSSGtree( terra_transform, delete_size ) == 0 ) { if ( fgPartialFreeSSGtree( terra_transform, delete_size ) == 0 ) {
ssgDeRefDelete( terra_transform ); // polish off the parent
free_tracker |= TERRA_NODE; free_tracker |= TERRA_NODE;
} }
} else if ( !(free_tracker & GROUND_LIGHTS) && gnd_lights_transform ) { } else if ( !(free_tracker & GROUND_LIGHTS) && gnd_lights_transform ) {
@ -775,7 +771,6 @@ bool FGTileEntry::free_tile() {
// disconnected from the scene graph) // disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING gnd_lights_transform" ); SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING gnd_lights_transform" );
if ( fgPartialFreeSSGtree( gnd_lights_transform, delete_size ) == 0 ) { if ( fgPartialFreeSSGtree( gnd_lights_transform, delete_size ) == 0 ) {
ssgDeRefDelete( gnd_lights_transform ); // polish off the parent
free_tracker |= GROUND_LIGHTS; free_tracker |= GROUND_LIGHTS;
} }
} else if ( !(free_tracker & RWY_LIGHTS) && rwy_lights_transform ) { } else if ( !(free_tracker & RWY_LIGHTS) && rwy_lights_transform ) {
@ -783,7 +778,6 @@ bool FGTileEntry::free_tile() {
// disconnected from the scene graph) // disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING rwy_lights_transform" ); SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING rwy_lights_transform" );
if ( fgPartialFreeSSGtree( rwy_lights_transform, delete_size ) == 0 ) { if ( fgPartialFreeSSGtree( rwy_lights_transform, delete_size ) == 0 ) {
ssgDeRefDelete( rwy_lights_transform ); // polish off the parent
free_tracker |= RWY_LIGHTS; free_tracker |= RWY_LIGHTS;
} }
} else if ( !(free_tracker & LIGHTMAPS) && lightmaps_transform ) { } else if ( !(free_tracker & LIGHTMAPS) && lightmaps_transform ) {
@ -792,7 +786,6 @@ bool FGTileEntry::free_tile() {
// disconnected from the scene graph) // disconnected from the scene graph)
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING lightmaps_transform" ); SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING lightmaps_transform" );
if ( fgPartialFreeSSGtree( lightmaps_transform, delete_size ) == 0 ) { if ( fgPartialFreeSSGtree( lightmaps_transform, delete_size ) == 0 ) {
ssgDeRefDelete( lightmaps_transform ); // polish off the parent
free_tracker |= LIGHTMAPS; free_tracker |= LIGHTMAPS;
} }
} else { } else {

View file

@ -218,11 +218,6 @@ public:
// Destructor // Destructor
~FGTileEntry(); ~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 // 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 // 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 // partial clean up and exits so we can spread the load across

View file

@ -362,8 +362,24 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters,
// cout << "Adding ssg nodes for " // cout << "Adding ssg nodes for "
} }
// cout << "delete queue = " << delete_queue.size() << endl;
if ( !delete_queue.empty() ) { if ( !delete_queue.empty() ) {
// 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(); FGTileEntry* e = delete_queue.front();
if ( e->free_tile() ) { if ( e->free_tile() ) {
delete_queue.pop(); delete_queue.pop();