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:
parent
e5a87cf9fa
commit
8d58f64257
5 changed files with 53 additions and 22 deletions
|
@ -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 );
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
||||||
|
@ -229,8 +242,15 @@ FGTileCache::next_avail( void )
|
||||||
// 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.
|
||||||
|
|
||||||
|
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 );
|
entry_free( max_index );
|
||||||
return( max_index );
|
return( max_index );
|
||||||
|
} else {
|
||||||
|
FG_LOG( FG_TERRAIN, FG_ALERT, "WHOOPS!!! Dying in next_avail()" );
|
||||||
|
exit( -1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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] );
|
||||||
|
|
Loading…
Reference in a new issue