1
0
Fork 0

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.
This commit is contained in:
curt 2001-04-16 20:03:52 +00:00
parent a29cb28e93
commit 4a609646b6
7 changed files with 68 additions and 46 deletions

1
Thanks
View file

@ -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>

View 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);
}

View file

@ -24,14 +24,12 @@
#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,7 +80,7 @@ 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;
/**

View 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;
}

View 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 );
};

View 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;

View 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