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:
parent
a29cb28e93
commit
4a609646b6
7 changed files with 68 additions and 46 deletions
1
Thanks
1
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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue