]> git.mxchange.org Git - flightgear.git/commitdiff
Modified FlightGear/src/Scenery. The tile loader thread no longer adds
authorcurt <curt>
Mon, 16 Apr 2001 20:03:52 +0000 (20:03 +0000)
committercurt <curt>
Mon, 16 Apr 2001 20:03:52 +0000 (20:03 +0000)
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
src/Scenery/FGTileLoader.cxx
src/Scenery/FGTileLoader.hxx
src/Scenery/tileentry.cxx
src/Scenery/tileentry.hxx
src/Scenery/tilemgr.cxx
src/Scenery/tilemgr.hxx

diff --git a/Thanks b/Thanks
index 7ff985ad4b22e6fb3250d898de457f8be6c08b06..af89d5a0c84b0ca06df6134ee06626fcbafb0919 100644 (file)
--- a/Thanks
+++ b/Thanks
@@ -48,6 +48,7 @@ Bernie Bright <bbright@c031.aone.net.au>
   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 <buckel@mail.uni-wuerzburg.de>
index 3465e0f2bf110daa9e0040ae705d36bc73a5bf7b..6a787926fba57af17dd65a125091d6b39285e61a 100644 (file)
@@ -27,6 +27,7 @@
 #include <Main/globals.hxx>
 #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);
 }
index 912475abe44bcdf004c5438c3516507fae3ac1c1..b5fb759c7474655836bc85b7e958e586507f5b38 100644 (file)
 #ifndef FG_TILE_LOADER_HXX
 #define FG_TILE_LOADER_HXX
 
-#include <queue>
-#include <pthread.h>
-
 #include <simgear/bucket/newbucket.hxx>
 #include <simgear/misc/sg_path.hxx>
 
 #ifdef ENABLE_THREADS
 #  include <simgear/threads/SGThread.hxx>
+#  include <simgear/threads/SGQueue.hxx>
 #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;
 
     /**
index f7c2a5e057c4939d2b5cfb3d51163668b1448d7d..1aad249ae8d410f62ba4779c99463daa7fac9b7b 100644 (file)
@@ -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;
 }
index f9f88d08c83b9d5bb842cb6e6b5ce9339a05a05e..a34426b3a4497e46104013e4afe4adfdf23f4b89 100644 (file)
@@ -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 );
 };
 
 
index 44b05269548cee5a8505c559df4ddfb766165a54..b47e6246d60cd8ef61d61177ceb36ae7f26fdf64 100644 (file)
@@ -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<FGTileEntry*> 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;
index 0bd450fd7a13a56e30f5d038659fbf16ea10c5e1..2503f50d78cb8b0562ababd9e802db215d0213ca 100644 (file)
@@ -34,6 +34,9 @@
 #include <plib/ssg.h>
 
 #include <simgear/bucket/newbucket.hxx>
+#ifdef ENABLE_THREADS
+#  include <simgear/threads/SGQueue.hxx>
+#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<FGTileEntry*> 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