1
0
Fork 0

Fixed a tile caching bug. When I was freeing tiles to make room in the

cache, I was only checking currently visible tiles, rather than checking
all the cache entries.
This commit is contained in:
curt 1999-07-25 01:52:36 +00:00
parent e5a87cf9fa
commit 8d58f64257
5 changed files with 53 additions and 22 deletions

View file

@ -500,7 +500,7 @@ void fgUpdateTimeDepCalcs(int multi_loop, int remainder) {
// printf("updating flight model x %d\n", multi_loop);
fgFDMUpdate( current_options.get_flight_model(),
cur_fdm_state, multi_loop, remainder );
cur_fdm_state, multi_loop * 1, remainder );
} else {
fgFDMUpdate( current_options.get_flight_model(),
cur_fdm_state, 0, remainder );

View file

@ -129,7 +129,14 @@ FGTileCache::exists( const FGBucket& p )
void
FGTileCache::fill_in( int index, const FGBucket& p )
{
// cout << "FILL IN CACHE ENTRY = " << index << endl;
cout << "FILL IN CACHE ENTRY = " << index << endl;
// Force some values in case the tile fails to load (i.e. fill
// doesn't exist)
tile_cache[index].center = Point3D( 0.0 );
tile_cache[index].vtlist = NULL;
tile_cache[index].vnlist = NULL;
tile_cache[index].tclist = NULL;
// Load the appropriate data file and build tile fragment list
FGPath tile_path( current_options.get_fg_root() );
@ -152,13 +159,13 @@ FGTileCache::fill_in( int index, const FGBucket& p )
terrain->addKid( tile_cache[index].select_ptr );
if ( tile_cache[index].is_scheduled_for_cache() ) {
// cout << "FOUND ONE SCHEDULED FOR CACHE" << endl;
cout << "FOUND ONE SCHEDULED FOR CACHE" << endl;
// load, but not needed now so disable
tile_cache[index].mark_loaded();
tile_cache[index].ssg_disable();
tile_cache[index].select_ptr->select(0);
} else {
// cout << "FOUND ONE READY TO LOAD" << endl;
cout << "FOUND ONE READY TO LOAD" << endl;
tile_cache[index].mark_loaded();
tile_cache[index].select_ptr->select(1);
}
@ -167,9 +174,10 @@ FGTileCache::fill_in( int index, const FGBucket& p )
// Free a tile cache entry
void
FGTileCache::entry_free( int index )
FGTileCache::entry_free( int cache_index )
{
tile_cache[index].free_tile();
cout << "FREEING CACHE ENTRY = " << cache_index << endl;
tile_cache[cache_index].free_tile();
}
@ -177,9 +185,10 @@ FGTileCache::entry_free( int index )
int
FGTileCache::next_avail( void )
{
Point3D delta, abs_view_pos;
// Point3D delta;
Point3D abs_view_pos;
int i;
float max, med, min, tmp;
// float max, med, min, tmp;
float dist, max_dist;
int max_index;
@ -194,7 +203,7 @@ FGTileCache::next_avail( void )
if ( tile_cache[i].is_unused() ) {
// favor unused cache slots
return(i);
} else if ( tile_cache[i].is_loaded() ) {
} else if ( tile_cache[i].is_loaded() || tile_cache[i].is_cached() ) {
// calculate approximate distance from view point
abs_view_pos = current_view.get_abs_view_pos();
@ -203,6 +212,7 @@ FGTileCache::next_avail( void )
FG_LOG( FG_TERRAIN, FG_DEBUG,
" ref point = " << tile_cache[i].center );
/*
delta.setx( fabs(tile_cache[i].center.x() - abs_view_pos.x() ) );
delta.sety( fabs(tile_cache[i].center.y() - abs_view_pos.y() ) );
delta.setz( fabs(tile_cache[i].center.z() - abs_view_pos.z() ) );
@ -215,6 +225,9 @@ FGTileCache::next_avail( void )
tmp = max; max = min; min = tmp;
}
dist = max + (med + min) / 4;
*/
dist = tile_cache[i].center.distance3D( abs_view_pos );
FG_LOG( FG_TERRAIN, FG_DEBUG, " distance = " << dist );
@ -228,9 +241,16 @@ FGTileCache::next_avail( void )
// If we made it this far, then there were no open cache entries.
// We will instead free the furthest cache entry and return it's
// index.
entry_free( max_index );
return( max_index );
if ( max_index >=0 ) {
FG_LOG( FG_TERRAIN, FG_INFO, " max_dist = " << max_dist );
FG_LOG( FG_TERRAIN, FG_INFO, " index = " << max_index );
entry_free( max_index );
return( max_index );
} else {
FG_LOG( FG_TERRAIN, FG_ALERT, "WHOOPS!!! Dying in next_avail()" );
exit( -1 );
}
}

View file

@ -64,24 +64,34 @@ FGTileEntry::~FGTileEntry ( void ) {
void
FGTileEntry::free_tile()
{
FG_LOG( FG_TERRAIN, FG_DEBUG,
FG_LOG( FG_TERRAIN, FG_INFO,
"FREEING TILE = (" << tile_bucket << ")" );
// mark tile unused
mark_unused();
// delete fragment list
FG_LOG( FG_TERRAIN, FG_INFO,
" deleting " << fragment_list.size() << " fragments" );
for_each( begin(), end(),
mem_fun_ref( &fgFRAGMENT::deleteDisplayList ));
fragment_list.erase( begin(), end() );
// delete the ssg used structures
FG_LOG( FG_TERRAIN, FG_INFO,
" deleting vertex, normal, and texture coordinate arrays" );
FG_LOG( FG_TERRAIN, FG_INFO,
" deleting vertex array" );
if ( vtlist != NULL ) {
delete vtlist;
}
FG_LOG( FG_TERRAIN, FG_INFO,
" deleting normal array" );
if ( vnlist != NULL ) {
delete vnlist;
}
FG_LOG( FG_TERRAIN, FG_INFO,
" deleting texture coordinate array" );
if ( tclist != NULL ) {
delete tclist;
}
@ -123,12 +133,12 @@ FGTileEntry::free_tile()
// selector to disable it from ever being drawn.
void
FGTileEntry::ssg_disable() {
// cout << "TILE STATE = " << state << endl;
cout << "TILE STATE = " << state << endl;
if ( state == Scheduled_for_use ) {
state = Scheduled_for_cache;
} else if ( (state == Loaded) || (state == Cached) ) {
state = Cached;
// cout << "DISABLING SSG NODE" << endl;
cout << "DISABLING SSG NODE" << endl;
select_ptr->select(0);
#if 0
@ -150,5 +160,5 @@ FGTileEntry::ssg_disable() {
"Trying to disable an unused tile! Dying" );
exit(-1);
}
// cout << "TILE STATE = " << state << endl;
cout << "TILE STATE = " << state << endl;
}

View file

@ -202,6 +202,7 @@ public:
return state == Scheduled_for_cache;
}
inline bool is_loaded() const { return state == Loaded; }
inline bool is_cached() const { return state == Cached; }
inline void mark_unused() { state = Unused; }
inline void mark_scheduled_for_use() { state = Scheduled_for_use; }

View file

@ -98,7 +98,7 @@ int FGTileMgr::init( void ) {
// schedule a tile for loading
static void disable_tile( int cache_index ) {
// see if tile already exists in the cache
// cout << "DISABLING CACHE ENTRY = " << cache_index << endl;
cout << "DISABLING CACHE ENTRY = " << cache_index << endl;
FGTileEntry *t = global_tile_cache.get_tile( cache_index );
t->ssg_disable();
}
@ -111,7 +111,7 @@ int FGTileMgr::sched_tile( const FGBucket& b ) {
if ( cache_index >= 0 ) {
// tile exists in cache, reenable it.
// cout << "REENABLING DISABLED TILE" << endl;
cout << "REENABLING DISABLED TILE" << endl;
FGTileEntry *t = global_tile_cache.get_tile( cache_index );
t->select_ptr->select( 1 );
t->mark_loaded();
@ -528,7 +528,7 @@ int FGTileMgr::update( void ) {
if ( (p1.get_lon() > p_last.get_lon()) ||
( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() > p_last.get_x()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << " tiles" );
" (East) Loading " << tile_diameter << " tiles" );
for ( j = 0; j < tile_diameter; j++ ) {
// scrolling East
disable_tile( tiles[(j*tile_diameter) + 0] );
@ -544,7 +544,7 @@ int FGTileMgr::update( void ) {
( (p1.get_lon() == p_last.get_lon()) &&
(p1.get_x() < p_last.get_x()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << " tiles" );
" (West) Loading " << tile_diameter << " tiles" );
for ( j = 0; j < tile_diameter; j++ ) {
// scrolling West
disable_tile( tiles[(j*tile_diameter) + tile_diameter - 1] );
@ -561,7 +561,7 @@ int FGTileMgr::update( void ) {
if ( (p1.get_lat() > p_last.get_lat()) ||
( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() > p_last.get_y()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << " tiles" );
" (North) Loading " << tile_diameter << " tiles" );
for ( i = 0; i < tile_diameter; i++ ) {
// scrolling North
disable_tile( tiles[0 + i] );
@ -577,7 +577,7 @@ int FGTileMgr::update( void ) {
} else if ( (p1.get_lat() < p_last.get_lat()) ||
( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() < p_last.get_y()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << " tiles" );
" (South) Loading " << tile_diameter << " tiles" );
for ( i = 0; i < tile_diameter; i++ ) {
// scrolling South
disable_tile( tiles[((tile_diameter-1) * tile_diameter) + i] );