I just nailed an especially annoying tile cache scheduling bug.
What was happening was that we screwed up and scheduled tiles for (lon,lon) rather than (lon,lat) ... note the typo. This generated bogus tile id's which the system happily accepted, put into the tile cache system, and attempted to load. The problem was that these bogus tile id's were negative where as all valid tile id's should be >= 0. These negative tile id's up the logic used to remove tiles from the cache. When identifying tiles for removal, we look for the furthest tile away from us by starting out the furthest id at -1 and if we find something further, we update the furthest tile id. Then at the end we check if the furthest tile id >= 0 to see if we found anything we could remove. However, the furthest tile id was these bogus tiles with negative tile id's so the system always assumed there was nothing appropriate for removal. This made it impossible to ever remove a tile from the cache meaning it quickly filled up and no more tiles could be loaded. I fixed the one instance of scheduling tiles for a bogus location, and added a sanity check so if it ever happens again we'll bomb with an appropriate error message.
This commit is contained in:
parent
a3bce2f219
commit
36de63366b
4 changed files with 33 additions and 47 deletions
|
@ -100,7 +100,7 @@ void AptDialog_OK (puObject *)
|
||||||
// if ( global_tile_mgr.init() ) {
|
// if ( global_tile_mgr.init() ) {
|
||||||
// Load the local scenery data
|
// Load the local scenery data
|
||||||
global_tile_mgr.update( longitude->getDoubleValue(),
|
global_tile_mgr.update( longitude->getDoubleValue(),
|
||||||
longitude->getDoubleValue() );
|
latitude->getDoubleValue() );
|
||||||
// } else {
|
// } else {
|
||||||
// SG_LOG( SG_GENERAL, SG_ALERT,
|
// SG_LOG( SG_GENERAL, SG_ALERT,
|
||||||
// "Error in Tile Manager initialization!" );
|
// "Error in Tile Manager initialization!" );
|
||||||
|
|
|
@ -88,7 +88,7 @@ void FGNewCache::init( void ) {
|
||||||
SG_LOG( SG_TERRAIN, SG_INFO, " current cache size = "
|
SG_LOG( SG_TERRAIN, SG_INFO, " current cache size = "
|
||||||
<< tile_cache.size() );
|
<< tile_cache.size() );
|
||||||
|
|
||||||
#if 0 // don't clear the cache right now
|
#if 0 // don't clear the cache
|
||||||
clear_cache();
|
clear_cache();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -105,36 +105,6 @@ bool FGNewCache::exists( const SGBucket& b ) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// depricated for threading
|
|
||||||
#if 0
|
|
||||||
// Fill in a tile cache entry with real data for the specified bucket
|
|
||||||
void FGNewCache::fill_in( const SGBucket& b ) {
|
|
||||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "FILL IN CACHE ENTRY = " << b.gen_index() );
|
|
||||||
|
|
||||||
// clear out a distant entry in the cache if needed.
|
|
||||||
make_space();
|
|
||||||
|
|
||||||
// create the entry
|
|
||||||
FGTileEntry *e = new FGTileEntry( b );
|
|
||||||
|
|
||||||
// register it in the cache
|
|
||||||
long tile_index = b.gen_index();
|
|
||||||
tile_cache[tile_index] = e;
|
|
||||||
|
|
||||||
SGPath tile_path;
|
|
||||||
if ( globals->get_fg_scenery() != (string)"" ) {
|
|
||||||
tile_path.set( globals->get_fg_scenery() );
|
|
||||||
} else {
|
|
||||||
tile_path.set( globals->get_fg_root() );
|
|
||||||
tile_path.append( "Scenery" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the appropriate data file
|
|
||||||
e->load( tile_path, true );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Ensure at least one entry is free in the cache
|
// Ensure at least one entry is free in the cache
|
||||||
bool FGNewCache::make_space() {
|
bool FGNewCache::make_space() {
|
||||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "Make space in cache" );
|
SG_LOG( SG_TERRAIN, SG_DEBUG, "Make space in cache" );
|
||||||
|
@ -160,7 +130,7 @@ bool FGNewCache::make_space() {
|
||||||
long index = current->first;
|
long index = current->first;
|
||||||
FGTileEntry *e = current->second;
|
FGTileEntry *e = current->second;
|
||||||
|
|
||||||
if ( e->is_loaded() && e->get_pending_models() == 0 ) {
|
if ( e->is_loaded() && (e->get_pending_models() == 0) ) {
|
||||||
// calculate approximate distance from view point
|
// calculate approximate distance from view point
|
||||||
sgdCopyVec3( abs_view_pos,
|
sgdCopyVec3( abs_view_pos,
|
||||||
globals->get_current_view()->get_abs_view_pos() );
|
globals->get_current_view()->get_abs_view_pos() );
|
||||||
|
@ -183,20 +153,23 @@ bool FGNewCache::make_space() {
|
||||||
max_dist = dist;
|
max_dist = dist;
|
||||||
max_index = index;
|
max_index = index;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, "loaded = " << e->is_loaded()
|
||||||
|
<< " pending models = " << e->get_pending_models() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we made it this far, then there were no open cache entries.
|
// If we made it this far, then there were no open cache entries.
|
||||||
// We will instead free the furthest cache entry and return true
|
// We will instead free the furthest cache entry and return true
|
||||||
|
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, " max_dist = " << max_dist );
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO, " index = " << max_index );
|
||||||
if ( max_index >= 0 ) {
|
if ( max_index >= 0 ) {
|
||||||
SG_LOG( SG_TERRAIN, SG_DEBUG, " max_dist = " << max_dist );
|
|
||||||
SG_LOG( SG_TERRAIN, SG_DEBUG, " index = " << max_index );
|
|
||||||
entry_free( max_index );
|
entry_free( max_index );
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
SG_LOG( SG_TERRAIN, SG_ALERT, "WHOOPS!!! can't make_space(), tile "
|
SG_LOG( SG_TERRAIN, SG_ALERT, "WHOOPS!!! can't make_space(), tile "
|
||||||
"cache is full, but no entries available to removal." );
|
"cache is full, but no entries available for removal." );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,7 +188,7 @@ void FGNewCache::clear_cache() {
|
||||||
long index = current->first;
|
long index = current->first;
|
||||||
SG_LOG( SG_TERRAIN, SG_DEBUG, "clearing " << index );
|
SG_LOG( SG_TERRAIN, SG_DEBUG, "clearing " << index );
|
||||||
FGTileEntry *e = current->second;
|
FGTileEntry *e = current->second;
|
||||||
if ( e->is_loaded() && e->get_pending_models() == 0 ) {
|
if ( e->is_loaded() && (e->get_pending_models() == 0) ) {
|
||||||
e->tile_bucket.make_bad();
|
e->tile_bucket.make_bad();
|
||||||
entry_free(index);
|
entry_free(index);
|
||||||
}
|
}
|
||||||
|
@ -232,14 +205,14 @@ void FGNewCache::clear_cache() {
|
||||||
bool FGNewCache::insert_tile( FGTileEntry *e ) {
|
bool FGNewCache::insert_tile( FGTileEntry *e ) {
|
||||||
// clear out a distant entry in the cache if needed.
|
// clear out a distant entry in the cache if needed.
|
||||||
if ( make_space() ) {
|
if ( make_space() ) {
|
||||||
// register it in the cache
|
// register it in the cache
|
||||||
long tile_index = e->get_tile_bucket().gen_index();
|
long tile_index = e->get_tile_bucket().gen_index();
|
||||||
tile_cache[tile_index] = e;
|
tile_cache[tile_index] = e;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// failed to find cache space
|
// failed to find cache space
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,7 +154,20 @@ void FGTileMgr::sched_tile( const SGBucket& b ) {
|
||||||
|
|
||||||
// schedule a needed buckets for loading
|
// schedule a needed buckets for loading
|
||||||
void FGTileMgr::schedule_needed() {
|
void FGTileMgr::schedule_needed() {
|
||||||
cout << "scheduling needed tiles for " << longitude << " " << latitude << endl;
|
// sanity check (unfortunately needed!)
|
||||||
|
if ( longitude < -180.0 || longitude > 180.0
|
||||||
|
|| latitude < -90.0 || latitude > 90.0 )
|
||||||
|
{
|
||||||
|
SG_LOG( SG_TERRAIN, SG_ALERT,
|
||||||
|
"Attempting to schedule tiles for bogus latitude and" );
|
||||||
|
SG_LOG( SG_TERRAIN, SG_ALERT,
|
||||||
|
"longitude. This is a FATAL error. Exiting!" );
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SG_LOG( SG_TERRAIN, SG_INFO,
|
||||||
|
"scheduling needed tiles for " << longitude << " " << latitude );
|
||||||
|
|
||||||
#ifndef FG_OLD_WEATHER
|
#ifndef FG_OLD_WEATHER
|
||||||
if ( WeatherDatabase != NULL ) {
|
if ( WeatherDatabase != NULL ) {
|
||||||
vis = WeatherDatabase->getWeatherVisibility();
|
vis = WeatherDatabase->getWeatherVisibility();
|
||||||
|
|
|
@ -157,7 +157,7 @@ FGFX::update ()
|
||||||
// Update the engine sound.
|
// Update the engine sound.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
if (_engine_running_prop->getBoolValue()) {
|
if (cur_fdm_state->get_num_engines() > 0 && _engine_running_prop->getBoolValue()) {
|
||||||
// pitch corresponds to rpm
|
// pitch corresponds to rpm
|
||||||
// volume corresponds to manifold pressure
|
// volume corresponds to manifold pressure
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue