Add a small optimization to reduce the amount of vasi computation that is
done every frame.
This commit is contained in:
parent
a80b033104
commit
461baef128
6 changed files with 51 additions and 17 deletions
|
@ -207,6 +207,20 @@ long FGNewCache::get_oldest_tile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Clear the inner ring flag for all tiles in the cache so that the
|
||||||
|
// external tile scheduler can flag the inner ring correctly.
|
||||||
|
void FGNewCache::clear_inner_ring_flags() {
|
||||||
|
tile_map_iterator current = tile_cache.begin();
|
||||||
|
tile_map_iterator end = tile_cache.end();
|
||||||
|
|
||||||
|
for ( ; current != end; ++current ) {
|
||||||
|
FGTileEntry *e = current->second;
|
||||||
|
if ( e->is_loaded() && (e->get_pending_models() == 0) ) {
|
||||||
|
e->set_inner_ring( false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Clear a cache entry, note that the cache only holds pointers
|
// Clear a cache entry, note that the cache only holds pointers
|
||||||
// and this does not free the object which is pointed to.
|
// and this does not free the object which is pointed to.
|
||||||
void FGNewCache::clear_entry( long cache_index ) {
|
void FGNewCache::clear_entry( long cache_index ) {
|
||||||
|
|
|
@ -85,6 +85,10 @@ public:
|
||||||
// nothing available to be removed.
|
// nothing available to be removed.
|
||||||
long get_oldest_tile();
|
long get_oldest_tile();
|
||||||
|
|
||||||
|
// Clear the inner ring flag for all tiles in the cache so that
|
||||||
|
// the external tile scheduler can flag the inner ring correctly.
|
||||||
|
void clear_inner_ring_flags();
|
||||||
|
|
||||||
// Clear a cache entry, note that the cache only holds pointers
|
// Clear a cache entry, note that the cache only holds pointers
|
||||||
// and this does not free the object which is pointed to.
|
// and this does not free the object which is pointed to.
|
||||||
void clear_entry( long cache_entry );
|
void clear_entry( long cache_entry );
|
||||||
|
@ -92,9 +96,6 @@ public:
|
||||||
// Clear all completely loaded tiles (ignores partially loaded tiles)
|
// Clear all completely loaded tiles (ignores partially loaded tiles)
|
||||||
void clear_cache();
|
void clear_cache();
|
||||||
|
|
||||||
// Fill in a tile cache entry with real data for the specified bucket
|
|
||||||
// void fill_in( const SGBucket& b );
|
|
||||||
|
|
||||||
// Return a pointer to the specified tile cache entry
|
// Return a pointer to the specified tile cache entry
|
||||||
inline FGTileEntry *get_tile( const long tile_index ) {
|
inline FGTileEntry *get_tile( const long tile_index ) {
|
||||||
tile_map_iterator it = tile_cache.find( tile_index );
|
tile_map_iterator it = tile_cache.find( tile_index );
|
||||||
|
|
|
@ -72,6 +72,7 @@ FGTileEntry::FGTileEntry ( const SGBucket& b )
|
||||||
taxi_lights_selector( new ssgSelector ),
|
taxi_lights_selector( new ssgSelector ),
|
||||||
loaded(false),
|
loaded(false),
|
||||||
pending_models(0),
|
pending_models(0),
|
||||||
|
is_inner_ring(false),
|
||||||
free_tracker(0)
|
free_tracker(0)
|
||||||
{
|
{
|
||||||
// update the contents
|
// update the contents
|
||||||
|
@ -493,9 +494,11 @@ void FGTileEntry::prep_ssg_node( const Point3D& p, sgVec3 up, float vis) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( vasi_lights_transform ) {
|
if ( vasi_lights_transform && is_inner_ring ) {
|
||||||
// now we need to traverse the list of vasi lights and update
|
// now we need to traverse the list of vasi lights and update
|
||||||
// their coloring
|
// their coloring (but only for the inner ring, no point in
|
||||||
|
// doing this extra work for tiles that are relatively far
|
||||||
|
// away.)
|
||||||
for ( int i = 0; i < vasi_lights_transform->getNumKids(); ++i ) {
|
for ( int i = 0; i < vasi_lights_transform->getNumKids(); ++i ) {
|
||||||
// cout << "vasi root = " << i << endl;
|
// cout << "vasi root = " << i << endl;
|
||||||
ssgBranch *v = (ssgBranch *)vasi_lights_transform->getKid(i);
|
ssgBranch *v = (ssgBranch *)vasi_lights_transform->getKid(i);
|
||||||
|
|
|
@ -168,8 +168,19 @@ private:
|
||||||
|
|
||||||
double timestamp;
|
double timestamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this value is used by the tile scheduler/loader to mark which
|
||||||
|
* tiles are in the primary ring (i.e. the current tile or the
|
||||||
|
* surrounding eight.) Other routines then can use this as an
|
||||||
|
* optimization and not do some operation to tiles outside of this
|
||||||
|
* inner ring. (For instance vasi color updating)
|
||||||
|
*/
|
||||||
|
bool is_inner_ring;
|
||||||
|
|
||||||
// this variable tracks the status of the incremental memory freeing.
|
/**
|
||||||
|
* this variable tracks the status of the incremental memory
|
||||||
|
* freeing.
|
||||||
|
*/
|
||||||
enum {
|
enum {
|
||||||
NODES = 0x01,
|
NODES = 0x01,
|
||||||
VEC_PTRS = 0x02,
|
VEC_PTRS = 0x02,
|
||||||
|
@ -260,10 +271,11 @@ public:
|
||||||
*/
|
*/
|
||||||
inline ssgTransform *get_terra_transform() { return terra_transform; }
|
inline ssgTransform *get_terra_transform() { return terra_transform; }
|
||||||
|
|
||||||
void set_timestamp(double time_ms) { timestamp = time_ms; }
|
|
||||||
|
|
||||||
inline double get_timestamp() const { return timestamp; }
|
inline double get_timestamp() const { return timestamp; }
|
||||||
|
inline void set_timestamp( double time_ms ) { timestamp = time_ms; }
|
||||||
|
|
||||||
|
inline bool get_inner_ring() const { return is_inner_ring; }
|
||||||
|
inline void set_inner_ring( bool val ) { is_inner_ring = val; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ int FGTileMgr::init() {
|
||||||
|
|
||||||
|
|
||||||
// schedule a tile for loading
|
// schedule a tile for loading
|
||||||
void FGTileMgr::sched_tile( const SGBucket& b ) {
|
void FGTileMgr::sched_tile( const SGBucket& b, const bool is_inner_ring ) {
|
||||||
// see if tile already exists in the cache
|
// see if tile already exists in the cache
|
||||||
FGTileEntry *t = tile_cache.get_tile( b );
|
FGTileEntry *t = tile_cache.get_tile( b );
|
||||||
|
|
||||||
|
@ -145,6 +145,8 @@ void FGTileMgr::sched_tile( const SGBucket& b ) {
|
||||||
// delete.) Try again later
|
// delete.) Try again later
|
||||||
delete e;
|
delete e;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
t->set_inner_ring( is_inner_ring );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,18 +182,23 @@ void FGTileMgr::schedule_needed( double vis, SGBucket curr_bucket) {
|
||||||
|
|
||||||
// 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 );
|
tile_cache.set_max_cache_size( (2*xrange + 2) * (2*yrange + 2) * 2 );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
cout << "xrange = " << xrange << " yrange = " << yrange << endl;
|
cout << "xrange = " << xrange << " yrange = " << yrange << endl;
|
||||||
cout << "max cache size = " << tile_cache.get_max_cache_size()
|
cout << "max cache size = " << tile_cache.get_max_cache_size()
|
||||||
<< " current cache size = " << tile_cache.get_size() << endl;
|
<< " current cache size = " << tile_cache.get_size() << endl;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// clear the inner ring flags so we can set them below. This
|
||||||
|
// prevents us from having "true" entries we aren't able to find
|
||||||
|
// to get rid of if we teleport a long ways away from the current
|
||||||
|
// location.
|
||||||
|
tile_cache.clear_inner_ring_flags();
|
||||||
|
|
||||||
SGBucket b;
|
SGBucket b;
|
||||||
|
|
||||||
// schedule center tile first so it can be loaded first
|
// schedule center tile first so it can be loaded first
|
||||||
b = sgBucketOffset( longitude, latitude, 0, 0 );
|
b = sgBucketOffset( longitude, latitude, 0, 0 );
|
||||||
sched_tile( b );
|
sched_tile( b, true );
|
||||||
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
|
@ -200,7 +207,7 @@ void FGTileMgr::schedule_needed( double vis, SGBucket curr_bucket) {
|
||||||
for ( y = -1; y <= 1; ++y ) {
|
for ( y = -1; y <= 1; ++y ) {
|
||||||
if ( x != 0 || y != 0 ) {
|
if ( x != 0 || y != 0 ) {
|
||||||
b = sgBucketOffset( longitude, latitude, x, y );
|
b = sgBucketOffset( longitude, latitude, x, y );
|
||||||
sched_tile( b );
|
sched_tile( b, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,7 +217,7 @@ void FGTileMgr::schedule_needed( double vis, SGBucket curr_bucket) {
|
||||||
for ( y = -yrange; y <= yrange; ++y ) {
|
for ( y = -yrange; y <= yrange; ++y ) {
|
||||||
if ( x < -1 || x > 1 || y < -1 || y > 1 ) {
|
if ( x < -1 || x > 1 || y < -1 || y > 1 ) {
|
||||||
SGBucket b = sgBucketOffset( longitude, latitude, x, y );
|
SGBucket b = sgBucketOffset( longitude, latitude, x, y );
|
||||||
sched_tile( b );
|
sched_tile( b, false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,14 +77,11 @@ private:
|
||||||
void initialize_queue();
|
void initialize_queue();
|
||||||
|
|
||||||
// schedule a tile for loading
|
// schedule a tile for loading
|
||||||
void sched_tile( const SGBucket& b );
|
void sched_tile( const SGBucket& b, const bool is_inner_ring );
|
||||||
|
|
||||||
// schedule a needed buckets for loading
|
// schedule a needed buckets for loading
|
||||||
void schedule_needed(double visibility_meters, SGBucket curr_bucket);
|
void schedule_needed(double visibility_meters, SGBucket curr_bucket);
|
||||||
|
|
||||||
// see comment at prep_ssg_nodes()
|
|
||||||
void prep_ssg_node( int idx );
|
|
||||||
|
|
||||||
FGHitList hit_list;
|
FGHitList hit_list;
|
||||||
|
|
||||||
SGBucket previous_bucket;
|
SGBucket previous_bucket;
|
||||||
|
|
Loading…
Reference in a new issue