Restructuring how tiles are freed to allow us to eventually spread the task
out over multiple frames.
This commit is contained in:
parent
d86a513997
commit
96d499f4f1
4 changed files with 87 additions and 12 deletions
|
@ -171,6 +171,54 @@ bool FGNewCache::make_space() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Return the index of the oldest tile in the cache, return -1 if
|
||||||
|
// nothing available to be removed.
|
||||||
|
long FGNewCache::get_oldest_tile() {
|
||||||
|
// we need to free the furthest entry
|
||||||
|
long max_index = -1;
|
||||||
|
double timestamp = 0.0;
|
||||||
|
double min_time = 2419200000.0f; // one month should be enough
|
||||||
|
double max_time = 0;
|
||||||
|
|
||||||
|
tile_map_iterator current = tile_cache.begin();
|
||||||
|
tile_map_iterator end = tile_cache.end();
|
||||||
|
|
||||||
|
for ( ; current != end; ++current ) {
|
||||||
|
long index = current->first;
|
||||||
|
FGTileEntry *e = current->second;
|
||||||
|
if ( e->is_loaded() && (e->get_pending_models() == 0) ) {
|
||||||
|
|
||||||
|
timestamp = e->get_timestamp();
|
||||||
|
if ( timestamp < min_time ) {
|
||||||
|
max_index = index;
|
||||||
|
min_time = timestamp;
|
||||||
|
}
|
||||||
|
if ( timestamp > max_time ) {
|
||||||
|
max_time = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
SG_LOG( SG_TERRAIN, SG_DEBUG, "loaded = " << e->is_loaded()
|
||||||
|
<< " pending models = " << e->get_pending_models()
|
||||||
|
<< " time stamp = " << e->get_timestamp() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, " min_time = " << min_time );
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, " index = " << max_index );
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, " max_time = " << max_time );
|
||||||
|
|
||||||
|
return max_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Clear a cache entry, note that the cache only holds pointers
|
||||||
|
// and this does not free the object which is pointed to.
|
||||||
|
void FGNewCache::clear_entry( long cache_index ) {
|
||||||
|
tile_cache.erase( cache_index );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Clear all completely loaded tiles (ignores partially loaded tiles)
|
// Clear all completely loaded tiles (ignores partially loaded tiles)
|
||||||
void FGNewCache::clear_cache() {
|
void FGNewCache::clear_cache() {
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,14 @@ public:
|
||||||
// Ensure at least one entry is free in the cache
|
// Ensure at least one entry is free in the cache
|
||||||
bool make_space();
|
bool make_space();
|
||||||
|
|
||||||
|
// Return the index of the oldest tile in the cache, return -1 if
|
||||||
|
// nothing available to be removed.
|
||||||
|
long get_oldest_tile();
|
||||||
|
|
||||||
|
// Clear a cache entry, note that the cache only holds pointers
|
||||||
|
// and this does not free the object which is pointed to.
|
||||||
|
void clear_entry( long cache_entry );
|
||||||
|
|
||||||
// Clear all completely loaded tiles (ignores partially loaded tiles)
|
// Clear all completely loaded tiles (ignores partially loaded tiles)
|
||||||
void clear_cache();
|
void clear_cache();
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ SGLockedQueue<FGDeferredModel *> FGTileMgr::model_queue;
|
||||||
queue<FGTileEntry *> FGTileMgr::attach_queue;
|
queue<FGTileEntry *> FGTileMgr::attach_queue;
|
||||||
queue<FGDeferredModel *> FGTileMgr::model_queue;
|
queue<FGDeferredModel *> FGTileMgr::model_queue;
|
||||||
#endif // ENABLE_THREADS
|
#endif // ENABLE_THREADS
|
||||||
|
queue<FGTileEntry *> FGTileMgr::delete_queue;
|
||||||
|
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -69,7 +70,8 @@ FGTileMgr::FGTileMgr():
|
||||||
state( Start ),
|
state( Start ),
|
||||||
current_tile( NULL ),
|
current_tile( NULL ),
|
||||||
vis( 16000 ),
|
vis( 16000 ),
|
||||||
counter_hack(0)
|
counter_hack(0),
|
||||||
|
max_cache_size(100)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,6 +130,19 @@ void FGTileMgr::sched_tile( const SGBucket& b ) {
|
||||||
FGTileEntry *t = tile_cache.get_tile( b );
|
FGTileEntry *t = tile_cache.get_tile( b );
|
||||||
|
|
||||||
if ( t == NULL ) {
|
if ( t == NULL ) {
|
||||||
|
// make space in the cache
|
||||||
|
while ( tile_cache.get_size() > max_cache_size ) {
|
||||||
|
long index = tile_cache.get_oldest_tile();
|
||||||
|
if ( index >= 0 ) {
|
||||||
|
FGTileEntry *old = tile_cache.get_tile( index );
|
||||||
|
delete_queue.push( old );
|
||||||
|
tile_cache.clear_entry( index );
|
||||||
|
} else {
|
||||||
|
// nothing to free ?!? forge ahead
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create a new entry
|
// create a new entry
|
||||||
FGTileEntry *e = new FGTileEntry( b );
|
FGTileEntry *e = new FGTileEntry( b );
|
||||||
|
|
||||||
|
@ -174,7 +189,7 @@ void FGTileMgr::schedule_needed( double vis, SGBucket curr_bucket) {
|
||||||
// cout << "xrange = " << xrange << " yrange = " << yrange << endl;
|
// cout << "xrange = " << xrange << " yrange = " << yrange << endl;
|
||||||
|
|
||||||
// note * 2 at end doubles cache size (for fdm and viewer)
|
// note * 2 at end doubles cache size (for fdm and viewer)
|
||||||
tile_cache.set_max_cache_size( (2*xrange + 2) * (2*yrange + 2) * 2 );
|
max_cache_size = (2*xrange + 2) * (2*yrange + 2) * 2;
|
||||||
|
|
||||||
SGBucket b;
|
SGBucket b;
|
||||||
|
|
||||||
|
@ -345,6 +360,14 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters,
|
||||||
// cout << "Adding ssg nodes for "
|
// cout << "Adding ssg nodes for "
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( !delete_queue.empty() ) {
|
||||||
|
FGTileEntry* e = delete_queue.front();
|
||||||
|
delete_queue.pop();
|
||||||
|
e->disconnect_ssg_nodes();
|
||||||
|
e->free_tile();
|
||||||
|
delete e;
|
||||||
|
}
|
||||||
|
|
||||||
// no reason to update this if we haven't moved...
|
// no reason to update this if we haven't moved...
|
||||||
if ( longitude != last_longitude || latitude != last_latitude ) {
|
if ( longitude != last_longitude || latitude != last_latitude ) {
|
||||||
// update current elevation...
|
// update current elevation...
|
||||||
|
@ -364,7 +387,8 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters,
|
||||||
// timer event driven call to scheduler for the purpose of refreshing the tile timestamps
|
// timer event driven call to scheduler for the purpose of refreshing the tile timestamps
|
||||||
void FGTileMgr::refresh_view_timestamps() {
|
void FGTileMgr::refresh_view_timestamps() {
|
||||||
SG_LOG( SG_TERRAIN, SG_INFO,
|
SG_LOG( SG_TERRAIN, SG_INFO,
|
||||||
"Refreshing timestamps for " << current_bucket.get_center_lon() << " " << current_bucket.get_center_lat() );
|
"Refreshing timestamps for " << current_bucket.get_center_lon()
|
||||||
|
<< " " << current_bucket.get_center_lat() );
|
||||||
schedule_needed(fgGetDouble("/environment/visibility-m"), current_bucket);
|
schedule_needed(fgGetDouble("/environment/visibility-m"), current_bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* tile cache
|
* tile cache
|
||||||
*/
|
*/
|
||||||
|
int max_cache_size;
|
||||||
FGNewCache tile_cache;
|
FGNewCache tile_cache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,6 +130,7 @@ private:
|
||||||
static queue<FGTileEntry *> attach_queue;
|
static queue<FGTileEntry *> attach_queue;
|
||||||
static queue<FGDeferredModel *> model_queue;
|
static queue<FGDeferredModel *> model_queue;
|
||||||
#endif // ENABLE_THREADS
|
#endif // ENABLE_THREADS
|
||||||
|
static queue<FGTileEntry *> delete_queue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -137,13 +139,6 @@ public:
|
||||||
*/
|
*/
|
||||||
static void ready_to_attach( FGTileEntry *t ) { attach_queue.push( t ); }
|
static void ready_to_attach( FGTileEntry *t ) { attach_queue.push( t ); }
|
||||||
|
|
||||||
#ifdef WISH_PLIB_WAS_THREADED // but it isn't
|
|
||||||
/**
|
|
||||||
* Tile is detatched from scene graph and is ready to delete
|
|
||||||
*/
|
|
||||||
inline void ready_to_delete( FGTileEntry *t ) { loader.remove( t ); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a pending model to the 'deferred model load' queue
|
* Add a pending model to the 'deferred model load' queue
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Reference in a new issue