Tweaks to the tile pager so it waits for a signal from the main thread before
loading the next tile. This allows the main thread to "pace" the tile loader so it consumes fewer resources.
This commit is contained in:
parent
f117bc201f
commit
a29cb28e93
7 changed files with 65 additions and 24 deletions
|
@ -50,7 +50,7 @@ FGTileLoader::~FGTileLoader()
|
|||
{
|
||||
#ifdef ENABLE_THREADS
|
||||
// Wake up its time to die.
|
||||
cond.broadcast();
|
||||
queue_cond.broadcast();
|
||||
|
||||
for (int i = 0; i < MAX_THREADS; ++i)
|
||||
{
|
||||
|
@ -86,13 +86,27 @@ FGTileLoader::add( FGTileEntry* tile )
|
|||
mutex.lock();
|
||||
tile_queue.push( tile );
|
||||
// Signal waiting working threads.
|
||||
cond.signal();
|
||||
queue_cond.signal();
|
||||
mutex.unlock();
|
||||
#else
|
||||
tile->load( tile_path, true );
|
||||
#endif // ENABLE_THREADS
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void
|
||||
FGTileLoader::update()
|
||||
{
|
||||
#ifdef ENABLE_THREADS
|
||||
mutex.lock();
|
||||
frame_cond.signal();
|
||||
mutex.unlock();
|
||||
#endif // ENABLE_THREADS
|
||||
}
|
||||
|
||||
|
||||
#ifdef ENABLE_THREADS
|
||||
/**
|
||||
*
|
||||
|
@ -106,7 +120,7 @@ FGTileLoader::LoaderThread::run()
|
|||
loader->mutex.lock();
|
||||
while (loader->empty())
|
||||
{
|
||||
loader->cond.wait( loader->mutex );
|
||||
loader->queue_cond.wait( loader->mutex );
|
||||
}
|
||||
|
||||
// Have we been canceled - exits if yes.
|
||||
|
@ -117,6 +131,10 @@ FGTileLoader::LoaderThread::run()
|
|||
pthread_exit( PTHREAD_CANCELED );
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
|
|
@ -61,6 +61,14 @@ public:
|
|||
*/
|
||||
void add( FGTileEntry* tile );
|
||||
|
||||
/**
|
||||
* The tile loader thread will only load one tile per call to the
|
||||
* update() method. This is a way to spread out the work of the
|
||||
* tile loader and slow it down so it is less intrusive. For
|
||||
* systems built without thead support this is a no-op.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Returns whether the load queue is empty (contains no elements).
|
||||
* @return true if load queue is empty otherwise returns false.
|
||||
|
@ -123,7 +131,8 @@ private:
|
|||
* Lock and synchronize access to tile queue.
|
||||
*/
|
||||
SGMutex mutex;
|
||||
SGCondition cond;
|
||||
SGCondition queue_cond;
|
||||
SGCondition frame_cond;
|
||||
|
||||
/**
|
||||
* Thread cleanup handler.
|
||||
|
|
|
@ -212,18 +212,13 @@ void FGNewCache::make_space() {
|
|||
* Create a new tile and schedule it for loading.
|
||||
*/
|
||||
void
|
||||
FGNewCache::load_tile( const SGBucket& b )
|
||||
FGNewCache::insert_tile( FGTileEntry *e )
|
||||
{
|
||||
// clear out a distant entry in the cache if needed.
|
||||
make_space();
|
||||
|
||||
// create the entry
|
||||
FGTileEntry *e = new FGTileEntry( b );
|
||||
|
||||
// register it in the cache
|
||||
long tile_index = b.gen_index();
|
||||
long tile_index = e->get_tile_bucket().gen_index();
|
||||
tile_cache[tile_index] = e;
|
||||
|
||||
// Schedule tile for loading
|
||||
loader.add( e );
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include <simgear/math/point3d.hxx>
|
||||
|
||||
#include "tileentry.hxx"
|
||||
#include "FGTileLoader.hxx"
|
||||
|
||||
SG_USING_STD(map);
|
||||
|
||||
|
@ -69,11 +68,6 @@ class FGNewCache {
|
|||
// Free a tile cache entry
|
||||
void entry_free( long cache_index );
|
||||
|
||||
/**
|
||||
* Queue tiles for loading.
|
||||
*/
|
||||
FGTileLoader loader;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
|
@ -128,7 +122,7 @@ public:
|
|||
* Create a new tile and enqueue it for loading.
|
||||
* @param b
|
||||
*/
|
||||
void load_tile( const SGBucket& b );
|
||||
void insert_tile( FGTileEntry* e );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -165,7 +165,13 @@ public:
|
|||
* Return true if the tile entry is loaded, otherwise return false
|
||||
* indicating that the loading thread is still working on this.
|
||||
*/
|
||||
inline bool is_loaded() const { return loaded; }
|
||||
inline bool is_loaded() const { return loaded; }
|
||||
|
||||
/**
|
||||
* Return the "bucket" for this tile
|
||||
*/
|
||||
inline SGBucket get_tile_bucket() const { return tile_bucket; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -116,8 +116,14 @@ void FGTileMgr::sched_tile( const SGBucket& b ) {
|
|||
FGTileEntry *t = tile_cache.get_tile( b );
|
||||
|
||||
if ( t == NULL ) {
|
||||
// register a load request
|
||||
tile_cache.load_tile( b );
|
||||
// create a new entry
|
||||
FGTileEntry *e = new FGTileEntry( b );
|
||||
|
||||
// insert the tile into the cache
|
||||
tile_cache.insert_tile( e );
|
||||
|
||||
// Schedule tile for loading
|
||||
loader.add( e );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,8 +277,6 @@ void FGTileMgr::initialize_queue()
|
|||
SG_LOG( SG_TERRAIN, SG_INFO, "Updating Tile list for " << current_bucket );
|
||||
// cout << "tile cache size = " << tile_cache.get_size() << endl;
|
||||
|
||||
int i;
|
||||
|
||||
// wipe/initialize tile cache
|
||||
// tile_cache.init();
|
||||
previous_bucket.make_bad();
|
||||
|
@ -288,6 +292,7 @@ void FGTileMgr::initialize_queue()
|
|||
#if 0
|
||||
// Now force a load of the center tile and inner ring so we
|
||||
// have something to see in our first frame.
|
||||
int i;
|
||||
for ( i = 0; i < 9; ++i ) {
|
||||
if ( load_queue.size() ) {
|
||||
SG_LOG( SG_TERRAIN, SG_DEBUG,
|
||||
|
@ -402,6 +407,13 @@ int FGTileMgr::update( double lon, double lat ) {
|
|||
last_longitude = longitude;
|
||||
last_latitude = latitude;
|
||||
|
||||
// activate loader thread one out of every 5 frames
|
||||
counter_hack = (counter_hack + 1) % 5;
|
||||
if ( !counter_hack ) {
|
||||
// Notify the tile loader that it can load another tile
|
||||
loader.update();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include <simgear/bucket/newbucket.hxx>
|
||||
|
||||
#include "FGTileLoader.hxx"
|
||||
#include "hitlist.hxx"
|
||||
#include "newcache.hxx"
|
||||
|
||||
|
@ -102,10 +103,16 @@ private:
|
|||
double last_latitude;
|
||||
|
||||
/**
|
||||
*
|
||||
* tile cache
|
||||
*/
|
||||
FGNewCache tile_cache;
|
||||
|
||||
/**
|
||||
* Queue tiles for loading.
|
||||
*/
|
||||
FGTileLoader loader;
|
||||
int counter_hack;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
|
|
Loading…
Reference in a new issue