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:
parent
edaac686a2
commit
b3c5a8fb95
3 changed files with 28 additions and 24 deletions
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Add table
Reference in a new issue