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); // printf("updating flight model x %d\n", multi_loop);
fgFDMUpdate( current_options.get_flight_model(), fgFDMUpdate( current_options.get_flight_model(),
cur_fdm_state, multi_loop, remainder ); cur_fdm_state, multi_loop * 1, remainder );
} else { } else {
fgFDMUpdate( current_options.get_flight_model(), fgFDMUpdate( current_options.get_flight_model(),
cur_fdm_state, 0, remainder ); cur_fdm_state, 0, remainder );

View file

@ -129,7 +129,14 @@ FGTileCache::exists( const FGBucket& p )
void void
FGTileCache::fill_in( int index, const FGBucket& p ) 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 // Load the appropriate data file and build tile fragment list
FGPath tile_path( current_options.get_fg_root() ); 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 ); terrain->addKid( tile_cache[index].select_ptr );
if ( tile_cache[index].is_scheduled_for_cache() ) { 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 // load, but not needed now so disable
tile_cache[index].mark_loaded(); tile_cache[index].mark_loaded();
tile_cache[index].ssg_disable(); tile_cache[index].ssg_disable();
tile_cache[index].select_ptr->select(0); tile_cache[index].select_ptr->select(0);
} else { } else {
// cout << "FOUND ONE READY TO LOAD" << endl; cout << "FOUND ONE READY TO LOAD" << endl;
tile_cache[index].mark_loaded(); tile_cache[index].mark_loaded();
tile_cache[index].select_ptr->select(1); tile_cache[index].select_ptr->select(1);
} }
@ -167,9 +174,10 @@ FGTileCache::fill_in( int index, const FGBucket& p )
// Free a tile cache entry // Free a tile cache entry
void 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 int
FGTileCache::next_avail( void ) FGTileCache::next_avail( void )
{ {
Point3D delta, abs_view_pos; // Point3D delta;
Point3D abs_view_pos;
int i; int i;
float max, med, min, tmp; // float max, med, min, tmp;
float dist, max_dist; float dist, max_dist;
int max_index; int max_index;
@ -194,7 +203,7 @@ FGTileCache::next_avail( void )
if ( tile_cache[i].is_unused() ) { if ( tile_cache[i].is_unused() ) {
// favor unused cache slots // favor unused cache slots
return(i); 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 // calculate approximate distance from view point
abs_view_pos = current_view.get_abs_view_pos(); abs_view_pos = current_view.get_abs_view_pos();
@ -203,6 +212,7 @@ FGTileCache::next_avail( void )
FG_LOG( FG_TERRAIN, FG_DEBUG, FG_LOG( FG_TERRAIN, FG_DEBUG,
" ref point = " << tile_cache[i].center ); " ref point = " << tile_cache[i].center );
/*
delta.setx( fabs(tile_cache[i].center.x() - abs_view_pos.x() ) ); 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.sety( fabs(tile_cache[i].center.y() - abs_view_pos.y() ) );
delta.setz( fabs(tile_cache[i].center.z() - abs_view_pos.z() ) ); 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; tmp = max; max = min; min = tmp;
} }
dist = max + (med + min) / 4; dist = max + (med + min) / 4;
*/
dist = tile_cache[i].center.distance3D( abs_view_pos );
FG_LOG( FG_TERRAIN, FG_DEBUG, " distance = " << dist ); 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. // 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 // We will instead free the furthest cache entry and return it's
// index. // index.
entry_free( max_index ); if ( max_index >=0 ) {
return( max_index ); 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 void
FGTileEntry::free_tile() FGTileEntry::free_tile()
{ {
FG_LOG( FG_TERRAIN, FG_DEBUG, FG_LOG( FG_TERRAIN, FG_INFO,
"FREEING TILE = (" << tile_bucket << ")" ); "FREEING TILE = (" << tile_bucket << ")" );
// mark tile unused // mark tile unused
mark_unused(); mark_unused();
// delete fragment list // delete fragment list
FG_LOG( FG_TERRAIN, FG_INFO,
" deleting " << fragment_list.size() << " fragments" );
for_each( begin(), end(), for_each( begin(), end(),
mem_fun_ref( &fgFRAGMENT::deleteDisplayList )); mem_fun_ref( &fgFRAGMENT::deleteDisplayList ));
fragment_list.erase( begin(), end() ); fragment_list.erase( begin(), end() );
// delete the ssg used structures // 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 ) { if ( vtlist != NULL ) {
delete vtlist; delete vtlist;
} }
FG_LOG( FG_TERRAIN, FG_INFO,
" deleting normal array" );
if ( vnlist != NULL ) { if ( vnlist != NULL ) {
delete vnlist; delete vnlist;
} }
FG_LOG( FG_TERRAIN, FG_INFO,
" deleting texture coordinate array" );
if ( tclist != NULL ) { if ( tclist != NULL ) {
delete tclist; delete tclist;
} }
@ -123,12 +133,12 @@ FGTileEntry::free_tile()
// selector to disable it from ever being drawn. // selector to disable it from ever being drawn.
void void
FGTileEntry::ssg_disable() { FGTileEntry::ssg_disable() {
// cout << "TILE STATE = " << state << endl; cout << "TILE STATE = " << state << endl;
if ( state == Scheduled_for_use ) { if ( state == Scheduled_for_use ) {
state = Scheduled_for_cache; state = Scheduled_for_cache;
} else if ( (state == Loaded) || (state == Cached) ) { } else if ( (state == Loaded) || (state == Cached) ) {
state = Cached; state = Cached;
// cout << "DISABLING SSG NODE" << endl; cout << "DISABLING SSG NODE" << endl;
select_ptr->select(0); select_ptr->select(0);
#if 0 #if 0
@ -150,5 +160,5 @@ FGTileEntry::ssg_disable() {
"Trying to disable an unused tile! Dying" ); "Trying to disable an unused tile! Dying" );
exit(-1); exit(-1);
} }
// cout << "TILE STATE = " << state << endl; cout << "TILE STATE = " << state << endl;
} }

View file

@ -202,6 +202,7 @@ public:
return state == Scheduled_for_cache; return state == Scheduled_for_cache;
} }
inline bool is_loaded() const { return state == Loaded; } 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_unused() { state = Unused; }
inline void mark_scheduled_for_use() { state = Scheduled_for_use; } 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 // schedule a tile for loading
static void disable_tile( int cache_index ) { static void disable_tile( int cache_index ) {
// see if tile already exists in the cache // 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 ); FGTileEntry *t = global_tile_cache.get_tile( cache_index );
t->ssg_disable(); t->ssg_disable();
} }
@ -111,7 +111,7 @@ int FGTileMgr::sched_tile( const FGBucket& b ) {
if ( cache_index >= 0 ) { if ( cache_index >= 0 ) {
// tile exists in cache, reenable it. // 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 ); FGTileEntry *t = global_tile_cache.get_tile( cache_index );
t->select_ptr->select( 1 ); t->select_ptr->select( 1 );
t->mark_loaded(); t->mark_loaded();
@ -528,7 +528,7 @@ int FGTileMgr::update( void ) {
if ( (p1.get_lon() > p_last.get_lon()) || if ( (p1.get_lon() > p_last.get_lon()) ||
( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() > p_last.get_x()) ) ) { ( (p1.get_lon() == p_last.get_lon()) && (p1.get_x() > p_last.get_x()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO, FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << " tiles" ); " (East) Loading " << tile_diameter << " tiles" );
for ( j = 0; j < tile_diameter; j++ ) { for ( j = 0; j < tile_diameter; j++ ) {
// scrolling East // scrolling East
disable_tile( tiles[(j*tile_diameter) + 0] ); disable_tile( tiles[(j*tile_diameter) + 0] );
@ -544,7 +544,7 @@ int FGTileMgr::update( void ) {
( (p1.get_lon() == p_last.get_lon()) && ( (p1.get_lon() == p_last.get_lon()) &&
(p1.get_x() < p_last.get_x()) ) ) { (p1.get_x() < p_last.get_x()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO, FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << " tiles" ); " (West) Loading " << tile_diameter << " tiles" );
for ( j = 0; j < tile_diameter; j++ ) { for ( j = 0; j < tile_diameter; j++ ) {
// scrolling West // scrolling West
disable_tile( tiles[(j*tile_diameter) + tile_diameter - 1] ); 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()) || if ( (p1.get_lat() > p_last.get_lat()) ||
( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() > p_last.get_y()) ) ) { ( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() > p_last.get_y()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO, FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << " tiles" ); " (North) Loading " << tile_diameter << " tiles" );
for ( i = 0; i < tile_diameter; i++ ) { for ( i = 0; i < tile_diameter; i++ ) {
// scrolling North // scrolling North
disable_tile( tiles[0 + i] ); disable_tile( tiles[0 + i] );
@ -577,7 +577,7 @@ int FGTileMgr::update( void ) {
} else if ( (p1.get_lat() < p_last.get_lat()) || } else if ( (p1.get_lat() < p_last.get_lat()) ||
( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() < p_last.get_y()) ) ) { ( (p1.get_lat() == p_last.get_lat()) && (p1.get_y() < p_last.get_y()) ) ) {
FG_LOG( FG_TERRAIN, FG_INFO, FG_LOG( FG_TERRAIN, FG_INFO,
" Loading " << tile_diameter << " tiles" ); " (South) Loading " << tile_diameter << " tiles" );
for ( i = 0; i < tile_diameter; i++ ) { for ( i = 0; i < tile_diameter; i++ ) {
// scrolling South // scrolling South
disable_tile( tiles[((tile_diameter-1) * tile_diameter) + i] ); disable_tile( tiles[((tile_diameter-1) * tile_diameter) + i] );