From 461baef128b01cd1996e3491637ef046713674bf Mon Sep 17 00:00:00 2001 From: curt Date: Tue, 30 Dec 2003 15:12:04 +0000 Subject: [PATCH] Add a small optimization to reduce the amount of vasi computation that is done every frame. --- src/Scenery/newcache.cxx | 14 ++++++++++++++ src/Scenery/newcache.hxx | 7 ++++--- src/Scenery/tileentry.cxx | 7 +++++-- src/Scenery/tileentry.hxx | 18 +++++++++++++++--- src/Scenery/tilemgr.cxx | 17 ++++++++++++----- src/Scenery/tilemgr.hxx | 5 +---- 6 files changed, 51 insertions(+), 17 deletions(-) diff --git a/src/Scenery/newcache.cxx b/src/Scenery/newcache.cxx index 0ba6176f8..e55e2d655 100644 --- a/src/Scenery/newcache.cxx +++ b/src/Scenery/newcache.cxx @@ -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 // and this does not free the object which is pointed to. void FGNewCache::clear_entry( long cache_index ) { diff --git a/src/Scenery/newcache.hxx b/src/Scenery/newcache.hxx index eaf2c1541..dfbfcf190 100644 --- a/src/Scenery/newcache.hxx +++ b/src/Scenery/newcache.hxx @@ -85,6 +85,10 @@ public: // nothing available to be removed. 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 // and this does not free the object which is pointed to. void clear_entry( long cache_entry ); @@ -92,9 +96,6 @@ public: // Clear all completely loaded tiles (ignores partially loaded tiles) 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 inline FGTileEntry *get_tile( const long tile_index ) { tile_map_iterator it = tile_cache.find( tile_index ); diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index a160ecac3..793694dcf 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -72,6 +72,7 @@ FGTileEntry::FGTileEntry ( const SGBucket& b ) taxi_lights_selector( new ssgSelector ), loaded(false), pending_models(0), + is_inner_ring(false), free_tracker(0) { // 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 - // 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 ) { // cout << "vasi root = " << i << endl; ssgBranch *v = (ssgBranch *)vasi_lights_transform->getKid(i); diff --git a/src/Scenery/tileentry.hxx b/src/Scenery/tileentry.hxx index 0d61677fd..2bf8130b9 100644 --- a/src/Scenery/tileentry.hxx +++ b/src/Scenery/tileentry.hxx @@ -168,8 +168,19 @@ private: 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 { NODES = 0x01, VEC_PTRS = 0x02, @@ -260,10 +271,11 @@ public: */ 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 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; } }; diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 0747c4ea6..313c67fab 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -114,7 +114,7 @@ int FGTileMgr::init() { // 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 FGTileEntry *t = tile_cache.get_tile( b ); @@ -145,6 +145,8 @@ void FGTileMgr::sched_tile( const SGBucket& b ) { // delete.) Try again later 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) tile_cache.set_max_cache_size( (2*xrange + 2) * (2*yrange + 2) * 2 ); - /* cout << "xrange = " << xrange << " yrange = " << yrange << endl; cout << "max cache size = " << tile_cache.get_max_cache_size() << " 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; // schedule center tile first so it can be loaded first b = sgBucketOffset( longitude, latitude, 0, 0 ); - sched_tile( b ); + sched_tile( b, true ); int x, y; @@ -200,7 +207,7 @@ void FGTileMgr::schedule_needed( double vis, SGBucket curr_bucket) { for ( y = -1; y <= 1; ++y ) { if ( x != 0 || y != 0 ) { 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 ) { if ( x < -1 || x > 1 || y < -1 || y > 1 ) { SGBucket b = sgBucketOffset( longitude, latitude, x, y ); - sched_tile( b ); + sched_tile( b, false ); } } } diff --git a/src/Scenery/tilemgr.hxx b/src/Scenery/tilemgr.hxx index ab4c422a9..f0d3969cb 100644 --- a/src/Scenery/tilemgr.hxx +++ b/src/Scenery/tilemgr.hxx @@ -77,14 +77,11 @@ private: void initialize_queue(); // 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 void schedule_needed(double visibility_meters, SGBucket curr_bucket); - // see comment at prep_ssg_nodes() - void prep_ssg_node( int idx ); - FGHitList hit_list; SGBucket previous_bucket;