From 4a609646b66215ed31d4fb11207b89d0c4b54d8d Mon Sep 17 00:00:00 2001 From: curt Date: Mon, 16 Apr 2001 20:03:52 +0000 Subject: [PATCH] Modified FlightGear/src/Scenery. The tile loader thread no longer adds a newly loaded tile to the scene graph. Instead it puts it in a queue for the tile manager. I've used your counter_hack to check the loaded queue and add any tiles to the scene graph. I was playing around with the counter_hack so there might be some commented out code, etc. I also changed some SG_DEBUGs to SG_INFOs so I could track the tile loading. --- Thanks | 1 + src/Scenery/FGTileLoader.cxx | 33 ++++++++------------------------- src/Scenery/FGTileLoader.hxx | 11 ++++------- src/Scenery/tileentry.cxx | 24 ++++++++++++++---------- src/Scenery/tileentry.hxx | 9 +++++++-- src/Scenery/tilemgr.cxx | 19 +++++++++++++++++-- src/Scenery/tilemgr.hxx | 17 +++++++++++++++++ 7 files changed, 68 insertions(+), 46 deletions(-) diff --git a/Thanks b/Thanks index 7ff985ad4..af89d5a0c 100644 --- a/Thanks +++ b/Thanks @@ -48,6 +48,7 @@ Bernie Bright STL portability, tons o' stuff. :-) Currently trying to get a BeOS port together but life keeps getting in the way! + Threading support and threaded tile pager. Bernhard H. Buckel diff --git a/src/Scenery/FGTileLoader.cxx b/src/Scenery/FGTileLoader.cxx index 3465e0f2b..6a787926f 100644 --- a/src/Scenery/FGTileLoader.cxx +++ b/src/Scenery/FGTileLoader.cxx @@ -27,6 +27,7 @@ #include
#include "FGTileLoader.hxx" #include "tileentry.hxx" +#include "tilemgr.hxx" /** * @@ -50,7 +51,7 @@ FGTileLoader::~FGTileLoader() { #ifdef ENABLE_THREADS // Wake up its time to die. - queue_cond.broadcast(); + // queue_cond.broadcast(); for (int i = 0; i < MAX_THREADS; ++i) { @@ -83,11 +84,7 @@ FGTileLoader::add( FGTileEntry* tile ) } #ifdef ENABLE_THREADS - mutex.lock(); tile_queue.push( tile ); - // Signal waiting working threads. - queue_cond.signal(); - mutex.unlock(); #else tile->load( tile_path, true ); #endif // ENABLE_THREADS @@ -117,32 +114,18 @@ FGTileLoader::LoaderThread::run() pthread_cleanup_push( cleanup_handler, loader ); while ( true ) { // Wait for a load request to be placed in the queue. - loader->mutex.lock(); - while (loader->empty()) - { - loader->queue_cond.wait( loader->mutex ); - } - - // Have we been canceled - exits if yes. - //pthread_testcancel(); - if (loader->empty()) - { - loader->mutex.unlock(); - pthread_exit( PTHREAD_CANCELED ); - } + FGTileEntry* tile = loader->tile_queue.pop(); // Wait for the next frame signal before we load a tile from the queue - // Note that loader->mutex is already locked at this point. - loader->frame_cond.wait( loader->mutex ); - - // Grab the tile to load and release the mutex. - FGTileEntry* tile = loader->tile_queue.front(); - loader->tile_queue.pop(); - loader->mutex.unlock(); + // loader->mutex.lock(); + // loader->frame_cond.wait( loader->mutex ); + // loader->mutex.unlock(); set_cancel( SGThread::CANCEL_DISABLE ); tile->load( loader->tile_path, true ); set_cancel( SGThread::CANCEL_DEFERRED ); + + FGTileMgr::loaded( tile ); } pthread_cleanup_pop(1); } diff --git a/src/Scenery/FGTileLoader.hxx b/src/Scenery/FGTileLoader.hxx index 912475abe..b5fb759c7 100644 --- a/src/Scenery/FGTileLoader.hxx +++ b/src/Scenery/FGTileLoader.hxx @@ -24,14 +24,12 @@ #ifndef FG_TILE_LOADER_HXX #define FG_TILE_LOADER_HXX -#include -#include - #include #include #ifdef ENABLE_THREADS # include +# include #endif // Forward reference. @@ -73,7 +71,7 @@ public: * Returns whether the load queue is empty (contains no elements). * @return true if load queue is empty otherwise returns false. */ - bool empty() const { return tile_queue.empty(); } + // bool empty() const { return tile_queue.empty(); } private: @@ -82,8 +80,8 @@ private: /** * FIFO queue of tiles to load from data files. */ - std::queue< FGTileEntry* > tile_queue; - + SGBlockingQueue< FGTileEntry* > tile_queue; + /** * Base name of directory containing tile data file. */ @@ -131,7 +129,6 @@ private: * Lock and synchronize access to tile queue. */ SGMutex mutex; - SGCondition queue_cond; SGCondition frame_cond; /** diff --git a/src/Scenery/tileentry.cxx b/src/Scenery/tileentry.cxx index f7c2a5e05..1aad249ae 100644 --- a/src/Scenery/tileentry.cxx +++ b/src/Scenery/tileentry.cxx @@ -102,7 +102,7 @@ static void my_remove_branch( ssgBranch * branch ) { // ssg as well as the whole ssg branch void FGTileEntry::free_tile() { int i; - SG_LOG( SG_TERRAIN, SG_DEBUG, + SG_LOG( SG_TERRAIN, SG_INFO, "FREEING TILE = (" << tile_bucket << ")" ); SG_LOG( SG_TERRAIN, SG_DEBUG, @@ -115,12 +115,12 @@ void FGTileEntry::free_tile() { << " texture coordinate arrays" ); for ( i = 0; i < (int)vec3_ptrs.size(); ++i ) { - delete [] vec3_ptrs[i]; //that's the correct version + delete [] vec3_ptrs[i]; } vec3_ptrs.clear(); for ( i = 0; i < (int)vec2_ptrs.size(); ++i ) { - delete [] vec2_ptrs[i]; //that's the correct version + delete [] vec2_ptrs[i]; } vec2_ptrs.clear(); @@ -326,10 +326,6 @@ FGTileEntry::obj_load( const std::string& path, void FGTileEntry::load( const SGPath& base, bool is_base ) { - // a cheesy hack (to be fixed later) - extern ssgBranch *terrain; - extern ssgBranch *ground; - string index_str = tile_bucket.gen_index_str(); SGPath tile_path = base; @@ -339,7 +335,7 @@ FGTileEntry::load( const SGPath& base, bool is_base ) basename.append( index_str ); string path = basename.str(); - SG_LOG( SG_TERRAIN, SG_DEBUG, "Loading tile " << path ); + SG_LOG( SG_TERRAIN, SG_INFO, "Loading tile " << path ); // fgObjLoad will generate ground lighting for us ... ssgVertexArray *light_pts = new ssgVertexArray( 100 ); @@ -386,7 +382,7 @@ FGTileEntry::load( const SGPath& base, bool is_base ) offset.x(), offset.y(), offset.z(), 0.0, 0.0, 0.0 ); terra_transform->setTransform( &sgcoord ); - terrain->addKid( terra_transform ); + // terrain->addKid( terra_transform ); lights_transform = NULL; lights_range = NULL; @@ -410,9 +406,17 @@ FGTileEntry::load( const SGPath& base, bool is_base ) lights_range->addKid( lights_brightness ); lights_transform->addKid( lights_range ); lights_transform->setTransform( &sgcoord ); - ground->addKid( lights_transform ); + // ground->addKid( lights_transform ); } /* end of ground light section */ +} + +void +FGTileEntry::add_ssg_nodes( ssgBranch* terrain, ssgBranch* ground ) +{ + terrain->addKid( terra_transform ); + if (lights_transform != 0) + ground->addKid( lights_transform ); loaded = true; } diff --git a/src/Scenery/tileentry.hxx b/src/Scenery/tileentry.hxx index f9f88d08c..a34426b3a 100644 --- a/src/Scenery/tileentry.hxx +++ b/src/Scenery/tileentry.hxx @@ -118,8 +118,9 @@ private: ssgSelector *lights_brightness; /** - * Indicates this tile has been loaded from a file. - * Note that this may be set asynchronously by another thread. + * Indicates this tile has been loaded from a file and connected + * into the scene graph. Note that this may be set asynchronously + * by another thread. */ volatile bool loaded; @@ -172,6 +173,10 @@ public: */ inline SGBucket get_tile_bucket() const { return tile_bucket; } + /** + * Add terrain mesh and ground lighting to scene graph. + */ + void add_ssg_nodes( ssgBranch* terrain, ssgBranch* ground ); }; diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 44b052695..b47e6246d 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -57,6 +57,7 @@ extern ssgRoot *scene; extern ssgBranch *terrain; +extern ssgBranch *ground; // the tile manager FGTileMgr global_tile_mgr; @@ -68,11 +69,15 @@ static inline Point3D operator + (const Point3D& a, const sgdVec3 b) return Point3D(a.x()+b[0], a.y()+b[1], a.z()+b[2]); } +#ifdef ENABLE_THREADS +SGLockedQueue FGTileMgr::loaded_queue; +#endif // ENABLE_THREADS // Constructor FGTileMgr::FGTileMgr(): state( Start ), - vis( 16000 ) + vis( 16000 ), + counter_hack(0) { } @@ -411,7 +416,17 @@ int FGTileMgr::update( double lon, double lat ) { counter_hack = (counter_hack + 1) % 5; if ( !counter_hack ) { // Notify the tile loader that it can load another tile - loader.update(); + // loader.update(); + +#ifdef ENABLE_THREADS + if (!loaded_queue.empty()) + { + FGTileEntry* e = loaded_queue.pop(); + e->add_ssg_nodes( terrain, ground ); + //std::cout << "Adding ssg nodes for " + //<< e->get_tile_bucket() << "\n"; + } +#endif // ENABLE_THREADS } return 1; diff --git a/src/Scenery/tilemgr.hxx b/src/Scenery/tilemgr.hxx index 0bd450fd7..2503f50d7 100644 --- a/src/Scenery/tilemgr.hxx +++ b/src/Scenery/tilemgr.hxx @@ -34,6 +34,9 @@ #include #include +#ifdef ENABLE_THREADS +# include +#endif // ENABLE_THREADS #include "FGTileLoader.hxx" #include "hitlist.hxx" @@ -113,6 +116,20 @@ private: FGTileLoader loader; int counter_hack; +#ifdef ENABLE_THREADS + /** + * Tiles to add to scene graph. + */ + static SGLockedQueue loaded_queue; + +public: + + /** + * Add a loaded tile to the scene graph queue. + */ + static void loaded( FGTileEntry* t ) { loaded_queue.push(t); } +#endif // ENABLE_THREADS + public: // Constructor -- 2.39.5