1
0
Fork 0

Initial stab at a threaded tile loader contributed by Bernie Bright.

He writes:

Here are the final changes to add threads to the tile loading.  All the
thread related code is in the new FGTileLoader class.

./configure.in
./acconfig.h
Added --with-threads option and corresponding ENABLE_THREADS
definition.  The default is no threads.

./src/Scenery/tilemgr
Removed load_queue and associated references.  This has been replaced by
a new class FGTileLoader in FGNewCache.
Made the global variable global_tile_cache a member.
schedule_needed(): removed global_tile_cache.exists() tests since
sched_tile() effectively repeats the test.
initialize_queue(): removed code that loads tiles since this is now
performed by FGTileLoader.
update(): ditto

./src/Scenery/newcache
Added new class FGTileLoader to manage tile queuing and loading.
tile_map typedefs are private.
exists() is a const member function.
fill_in(): deleted
load_tile(): added.

./src/Scenery/FGTileLoader
The new threaded tile loader.  Maintains a queue of tiles waiting to be
loaded and an array of one or more threads to load the tiles.  Currently
only a single thread is created.  The queue is guarded by a mutex to
synchronize access.  A condition variable signals the thread when the
queue is non-empty.

CLO: I made a few tweaks to address a couple issues, hopefully what we
have is solid, but now we kick it out to the general public to see. :-)
This commit is contained in:
curt 2001-04-11 02:47:15 +00:00
parent a2049b110f
commit b0b6c34249
17 changed files with 430 additions and 101 deletions

View file

@ -322,6 +322,9 @@
/* Define if lex declares yytext as a char * by default, not a char[]. */
#undef YYTEXT_POINTER
/* Define to use tile loading threads */
#undef ENABLE_THREADS
/* Leave that blank line there!! Autoheader needs it.
If you're adding to this file, keep in mind:

View file

@ -453,8 +453,8 @@ public:
virtual void unbind ();
virtual void update ();
virtual bool update( int multi_loop );
virtual bool ToggleDataLogging(bool state) {};
virtual bool ToggleDataLogging(void) {};
virtual bool ToggleDataLogging(bool state) { return false; }
virtual bool ToggleDataLogging(void) { return false; }
// Define the various supported flight models (many not yet implemented)
enum {

View file

@ -103,6 +103,9 @@
/* Define if the X Window System is missing or not being used. */
#undef X_DISPLAY_MISSING
/* Define to use tile loading threads */
#undef ENABLE_THREADS
/* Define if you have the GetLocalTime function. */
#undef HAVE_GETLOCALTIME

View file

@ -19,6 +19,12 @@ NETWORK_LIBS = \
$(top_builddir)/src/Network/libNetwork.a
endif
if WITH_THREADS
THREAD_LIBS = -lsgthreads
else
THREAD_LIBS =
endif
if OLD_AUTOMAKE
# nothing CXXFLAGS += -DPKGLIBDIR=\"$(pkglibdir)\"
else
@ -73,6 +79,7 @@ fgfs_LDADD = \
-lsgroute -lsgsky -lsgephem -lsgtiming -lsgio -lsgscreen \
-lsgmath -lsgbucket -lsgdebug -lsgmagvar -lsgmisc -lsgxml \
$(SERIAL_LIBS) \
$(THREAD_LIBS) \
-lplibpu -lplibfnt -lplibssg -lplibsg \
-lmk4 -lz \
$(opengl_LIBS) \

View file

@ -787,9 +787,9 @@ void fgUpdateTimeDepCalcs() {
cur_fdm_state->update( 0 );
FGSteam::update( 0 );
if ( global_tile_mgr.queue_size() == 0 ) {
//if ( global_tile_mgr.queue_size() == 0 ) {
initial_freeze = false;
}
//}
}
if ( fgGetString("/sim/view-mode") == "pilot" ) {

View file

@ -129,15 +129,16 @@ bool FGMaterialLib::load( const string& mpath ) {
in >> m;
// build the ssgSimpleState
SGPath tex_path( globals->get_fg_root() );
tex_path.append( "Textures.high" );
SGPath tmp_path( globals->get_fg_root() );
tmp_path.append( "Textures.high" );
SGPath tmp_path = tex_path;
tmp_path.append( m.get_texture_name() );
if ( ! local_file_exists(tmp_path.str())
SGPath tex_path = tmp_path;
tex_path.append( m.get_texture_name() );
if ( ! local_file_exists(tex_path.str())
|| general.get_glMaxTexSize() < 512 ) {
tex_path = SGPath( globals->get_fg_root() );
tex_path.append( "Textures" );
tex_path.append( m.get_texture_name() );
}
SG_LOG( SG_TERRAIN, SG_INFO, " Loading material "
@ -150,8 +151,10 @@ bool FGMaterialLib::load( const string& mpath ) {
shade_model = GL_FLAT;
}
m.build_ssg_state( tex_path.str(), shade_model,
fgGetBool("/sim/rendering/textures") );
m.set_texture_name( tex_path.str() );
m.build_ssg_state( shade_model,
fgGetBool("/sim/rendering/textures"),
false );
#if EXTRA_DEBUG
m.dump_info();
@ -201,10 +204,10 @@ bool FGMaterialLib::add_item ( const string &mat_name, const string &full_path )
string tex_name = full_path.substr( pos + 1 );
string tex_path = full_path.substr( 0, pos );
FGNewMat m( mat_name, tex_name );
FGNewMat m( mat_name, full_path );
SG_LOG( SG_TERRAIN, SG_INFO, " Loading material "
<< mat_name << " (" << tex_path << ")");
<< mat_name << " (" << full_path << ")");
#if EXTRA_DEBUG
m.dump_info();
@ -217,8 +220,8 @@ bool FGMaterialLib::add_item ( const string &mat_name, const string &full_path )
shade_model = GL_FLAT;
}
m.build_ssg_state( tex_path, shade_model,
fgGetBool("/sim/rendering/textures") );
m.build_ssg_state( shade_model, fgGetBool("/sim/rendering/textures"),
true );
material_lib.matlib[mat_name] = m;

View file

@ -70,12 +70,9 @@ FGNewMat::FGNewMat ( const string &mat_name, const string &tex_name )
}
void FGNewMat::build_ssg_state( const string& path,
GLenum shade_model, bool texture_default )
void FGNewMat::build_ssg_state( GLenum shade_model, bool texture_default,
bool defer_tex_load )
{
SGPath tex_file( path );
tex_file.append( texture_name );
state = new ssgStateSelector(2);
state->ref();
@ -92,7 +89,12 @@ void FGNewMat::build_ssg_state( const string& path,
textured->enable( GL_TEXTURE_2D );
textured->disable( GL_BLEND );
textured->disable( GL_ALPHA_TEST );
textured->setTexture( (char *)tex_file.c_str(), wrapu, wrapv );
if ( !defer_tex_load ) {
textured->setTexture( (char *)texture_name.c_str(), wrapu, wrapv );
texture_loaded = true;
} else {
texture_loaded = false;
}
// cout << "wrap u = " << wrapu << " wrapv = " << wrapv << endl;
textured->enable( GL_COLOR_MATERIAL );
textured->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );

View file

@ -89,6 +89,9 @@ private:
// material properties
sgVec4 ambient, diffuse, specular, emission;
// true if texture loading deferred, and not yet loaded
bool texture_loaded;
public:
// Constructor
@ -102,8 +105,8 @@ public:
friend istream& operator >> ( istream& in, FGNewMat& m );
// void load_texture( const string& root );
void build_ssg_state( const string& path,
GLenum shade_model, bool texture_default );
void build_ssg_state( GLenum shade_model, bool texture_default,
bool defer_tex_load = false );
void set_ssg_state( ssgSimpleState *s );
inline string get_material_name() const { return material_name; }

View file

@ -0,0 +1,141 @@
// FGTileLoader - Queue scenery tiles for loading.
//
// Written by Bernie Bright, started March 2001.
//
// Copyright (C) 2001 Bernard Bright - bbright@bigpond.net.au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Main/globals.hxx>
#include "FGTileLoader.hxx"
#include "tileentry.hxx"
/**
*
*/
FGTileLoader::FGTileLoader()
{
#ifdef ENABLE_THREADS
// Create and start the loader threads.
for (int i = 0; i < MAX_THREADS; ++i)
{
threads[i] = new LoaderThread(this);
threads[i]->start();
}
#endif // ENABLE_THREADS
}
/**
* Terminate all threads.
*/
FGTileLoader::~FGTileLoader()
{
#ifdef ENABLE_THREADS
// Wake up its time to die.
cond.broadcast();
for (int i = 0; i < MAX_THREADS; ++i)
{
threads[i]->cancel();
threads[i]->join();
}
#endif // ENABLE_THREADS
}
/**
*
*/
void
FGTileLoader::add( FGTileEntry* tile )
{
/**
* Initialise tile_path here and not in ctor to avoid problems
* with the initialastion order of global objects.
*/
static bool beenhere = false;
if (!beenhere)
{
if ( globals->get_fg_scenery() != (string)"" ) {
tile_path.set( globals->get_fg_scenery() );
} else {
tile_path.set( globals->get_fg_root() );
tile_path.append( "Scenery" );
}
beenhere = true;
}
#ifdef ENABLE_THREADS
mutex.lock();
tile_queue.push( tile );
// Signal waiting working threads.
cond.signal();
mutex.unlock();
#else
tile->load( tile_path, true );
#endif // ENABLE_THREADS
}
#ifdef ENABLE_THREADS
/**
*
*/
void
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->cond.wait( loader->mutex );
}
// Have we been canceled - exits if yes.
//pthread_testcancel();
if (loader->empty())
{
loader->mutex.unlock();
pthread_exit( PTHREAD_CANCELED );
}
// Grab the tile to load and release the mutex.
FGTileEntry* tile = loader->tile_queue.front();
loader->tile_queue.pop();
loader->mutex.unlock();
set_cancel( SGThread::CANCEL_DISABLE );
tile->load( loader->tile_path, true );
set_cancel( SGThread::CANCEL_DEFERRED );
}
pthread_cleanup_pop(1);
}
/**
* Ensure mutex is unlocked.
*/
void
cleanup_handler( void* arg )
{
FGTileLoader* loader = (FGTileLoader*) arg;
loader->mutex.unlock();
}
#endif // ENABLE_THREADS

View file

@ -0,0 +1,135 @@
// FGTileLoader - Queue scenery tiles for loading.
//
// Written by Bernie Bright, started March 2001.
//
// Copyright (C) 2001 Bernard Bright - bbright@bigpond.net.au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#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>
#endif
// Forward reference.
class FGTileEntry;
/**
* Queues tiles for loading, possibly by a separate thread.
*/
class FGTileLoader
{
public:
/**
* Constructor.
*/
FGTileLoader();
/**
* Destructor.
*/
~FGTileLoader();
/**
* Add a tile to the end of the load queue.
* @param tile The tile to be loaded from disk.
* @param vis Current visibilty (in feet?) (see FGTileMgr::vis).
*/
void add( FGTileEntry* tile );
/**
* 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(); }
private:
private:
/**
* FIFO queue of tiles to load from data files.
*/
std::queue< FGTileEntry* > tile_queue;
/**
* Base name of directory containing tile data file.
*/
SGPath tile_path;
#ifdef ENABLE_THREADS
/**
* Maximum number of threads to create for loading tiles.
*/
enum { MAX_THREADS = 1 };
/**
* This class represents the thread of execution responsible for
* loading a tile.
*/
class LoaderThread : public SGThread
{
public:
LoaderThread( FGTileLoader* l ) : loader(l) {}
~LoaderThread() {}
/**
* Reads the tile from disk.
*/
void run();
private:
FGTileLoader* loader;
private:
// not implemented.
LoaderThread();
LoaderThread( const LoaderThread& );
LoaderThread& operator=( const LoaderThread& );
};
friend class LoaderThread;
/**
* Array of loading threads.
*/
LoaderThread* threads[ MAX_THREADS ];
/**
* Lock and synchronize access to tile queue.
*/
SGMutex mutex;
SGCondition cond;
/**
* Thread cleanup handler.
*/
friend void cleanup_handler( void* );
#endif // ENABLE_THREADS
};
#endif // FG_TILE_LOADER_HXX

View file

@ -1,6 +1,7 @@
noinst_LIBRARIES = libScenery.a
libScenery_a_SOURCES = \
FGTileLoader.cxx FGTileLoader.hxx \
hitlist.cxx hitlist.hxx \
newcache.cxx newcache.hxx \
scenery.cxx scenery.hxx \

View file

@ -43,15 +43,11 @@
#include "newcache.hxx"
#include "tileentry.hxx"
#include "tilemgr.hxx" // temp, need to delete later
SG_USING_NAMESPACE(std);
// the tile cache
FGNewCache global_tile_cache;
// Constructor
FGNewCache::FGNewCache( void ) {
tile_cache.clear();
@ -68,7 +64,7 @@ void FGNewCache::entry_free( long cache_index ) {
SG_LOG( SG_TERRAIN, SG_DEBUG, "FREEING CACHE ENTRY = " << cache_index );
FGTileEntry *e = tile_cache[cache_index];
e->free_tile();
delete( e );
delete e;
tile_cache.erase( cache_index );
}
@ -107,14 +103,16 @@ void FGNewCache::init( void ) {
// Search for the specified "bucket" in the cache
bool FGNewCache::exists( const SGBucket& b ) {
bool FGNewCache::exists( const SGBucket& b ) const {
long tile_index = b.gen_index();
tile_map_iterator it = tile_cache.find( tile_index );
const_tile_map_iterator it = tile_cache.find( tile_index );
return ( it != tile_cache.end() );
}
// depricated for threading
#if 0
// Fill in a tile cache entry with real data for the specified bucket
void FGNewCache::fill_in( const SGBucket& b ) {
SG_LOG( SG_TERRAIN, SG_DEBUG, "FILL IN CACHE ENTRY = " << b.gen_index() );
@ -140,13 +138,12 @@ void FGNewCache::fill_in( const SGBucket& b ) {
// Load the appropriate data file
e->load( tile_path, true );
}
#endif
// Ensure at least one entry is free in the cache
void FGNewCache::make_space() {
SG_LOG( SG_TERRAIN, SG_DEBUG, "Make space in cache" );
SG_LOG( SG_TERRAIN, SG_DEBUG, "cache entries = " << tile_cache.size() );
SG_LOG( SG_TERRAIN, SG_DEBUG, "max size = " << max_cache_size );
@ -169,26 +166,29 @@ void FGNewCache::make_space() {
long index = current->first;
FGTileEntry *e = current->second;
// calculate approximate distance from view point
sgdCopyVec3( abs_view_pos,
globals->get_current_view()->get_abs_view_pos() );
if ( e->is_loaded() ) {
// calculate approximate distance from view point
sgdCopyVec3( abs_view_pos,
globals->get_current_view()->get_abs_view_pos() );
SG_LOG( SG_TERRAIN, SG_DEBUG, "DIST Abs view pos = "
<< abs_view_pos[0] << ","
<< abs_view_pos[1] << ","
<< abs_view_pos[2] );
SG_LOG( SG_TERRAIN, SG_DEBUG,
" ref point = " << e->center );
SG_LOG( SG_TERRAIN, SG_DEBUG, "DIST Abs view pos = "
<< abs_view_pos[0] << ","
<< abs_view_pos[1] << ","
<< abs_view_pos[2] );
SG_LOG( SG_TERRAIN, SG_DEBUG,
" ref point = " << e->center );
sgdVec3 center;
sgdSetVec3( center, e->center.x(), e->center.y(), e->center.z() );
dist = sgdDistanceVec3( center, abs_view_pos );
sgdVec3 center;
sgdSetVec3( center,
e->center.x(), e->center.y(), e->center.z() );
dist = sgdDistanceVec3( center, abs_view_pos );
SG_LOG( SG_TERRAIN, SG_DEBUG, " distance = " << dist );
SG_LOG( SG_TERRAIN, SG_DEBUG, " distance = " << dist );
if ( dist > max_dist ) {
max_dist = dist;
max_index = index;
if ( dist > max_dist ) {
max_dist = dist;
max_index = index;
}
}
}
@ -206,3 +206,24 @@ void FGNewCache::make_space() {
}
}
}
/**
* Create a new tile and schedule it for loading.
*/
void
FGNewCache::load_tile( const SGBucket& b )
{
// 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();
tile_cache[tile_index] = e;
// Schedule tile for loading
loader.add( e );
}

View file

@ -46,18 +46,17 @@
#include <simgear/math/point3d.hxx>
#include "tileentry.hxx"
#include "FGTileLoader.hxx"
SG_USING_STD(map);
typedef map < long, FGTileEntry * > tile_map;
typedef tile_map::iterator tile_map_iterator;
typedef tile_map::const_iterator const_tile_map_iterator;
// A class to store and manage a pile of tiles
class FGNewCache {
typedef map < long, FGTileEntry * > tile_map;
typedef tile_map::iterator tile_map_iterator;
typedef tile_map::const_iterator const_tile_map_iterator;
// cache storage space
tile_map tile_cache;
@ -70,6 +69,11 @@ class FGNewCache {
// Free a tile cache entry
void entry_free( long cache_index );
/**
* Queue tiles for loading.
*/
FGTileLoader loader;
public:
// Constructor
@ -82,13 +86,13 @@ public:
void init( void );
// Check if the specified "bucket" exists in the cache
bool exists( const SGBucket& b );
bool exists( const SGBucket& b ) const;
// Ensure at least one entry is free in the cache
void make_space();
// Fill in a tile cache entry with real data for the specified bucket
void fill_in( const SGBucket& b );
// void fill_in( const SGBucket& b );
// Return a pointer to the specified tile cache entry
inline FGTileEntry *get_tile( const long tile_index ) {
@ -119,11 +123,13 @@ public:
inline int get_max_cache_size() const { return max_cache_size; }
inline void set_max_cache_size( int m ) { max_cache_size = m; }
/**
* Create a new tile and enqueue it for loading.
* @param b
*/
void load_tile( const SGBucket& b );
};
// the tile cache
extern FGNewCache global_tile_cache;
#endif // _NEWCACHE_HXX

View file

@ -339,7 +339,7 @@ FGTileEntry::load( const SGPath& base, bool is_base )
basename.append( index_str );
string path = basename.str();
SG_LOG( SG_TERRAIN, SG_INFO, "Loading tile " << path );
SG_LOG( SG_TERRAIN, SG_DEBUG, "Loading tile " << path );
// fgObjLoad will generate ground lighting for us ...
ssgVertexArray *light_pts = new ssgVertexArray( 100 );

View file

@ -160,6 +160,12 @@ public:
* random ground light points
*/
void load( const SGPath& base, bool is_base );
/**
* 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; }
};

View file

@ -93,7 +93,7 @@ int FGTileMgr::init() {
} else {
SG_LOG( SG_TERRAIN, SG_INFO,
"... First time through." );
global_tile_cache.init();
tile_cache.init();
}
hit_list.clear();
@ -113,29 +113,32 @@ int FGTileMgr::init() {
// schedule a tile for loading
void FGTileMgr::sched_tile( const SGBucket& b ) {
// see if tile already exists in the cache
FGTileEntry *t = global_tile_cache.get_tile( b );
FGTileEntry *t = tile_cache.get_tile( b );
if ( t == NULL ) {
// register a load request
load_queue.push_back( b );
tile_cache.load_tile( b );
}
}
// depricated for threading
#if 0
// load a tile
void FGTileMgr::load_tile( const SGBucket& b ) {
// see if tile already exists in the cache
FGTileEntry *t = global_tile_cache.get_tile( b );
FGTileEntry *t = tile_cache.get_tile( b );
if ( t == NULL ) {
SG_LOG( SG_TERRAIN, SG_DEBUG, "Loading tile " << b );
global_tile_cache.fill_in( b );
t = global_tile_cache.get_tile( b );
tile_cache.fill_in( b );
t = tile_cache.get_tile( b );
t->prep_ssg_node( scenery.center, vis);
} else {
SG_LOG( SG_TERRAIN, SG_DEBUG, "Tile already in cache " << b );
}
}
#endif
static void CurrentNormalInLocalPlane(sgVec3 dst, sgVec3 src) {
@ -215,20 +218,20 @@ void FGTileMgr::schedule_needed() {
#else
vis = current_weather.get_visibility();
#endif
cout << "visibility = " << vis << endl;
// cout << "visibility = " << vis << endl;
double tile_width = current_bucket.get_width_m();
double tile_height = current_bucket.get_height_m();
cout << "tile width = " << tile_width << " tile_height = " << tile_height
<< endl;
// cout << "tile width = " << tile_width << " tile_height = "
// << tile_height !<< endl;
xrange = (int)(vis / tile_width) + 1;
yrange = (int)(vis / tile_height) + 1;
if ( xrange < 1 ) { xrange = 1; }
if ( yrange < 1 ) { yrange = 1; }
cout << "xrange = " << xrange << " yrange = " << yrange << endl;
// cout << "xrange = " << xrange << " yrange = " << yrange << endl;
global_tile_cache.set_max_cache_size( (2*xrange + 2) * (2*yrange + 2) );
tile_cache.set_max_cache_size( (2*xrange + 2) * (2*yrange + 2) );
SGBucket b;
@ -243,9 +246,7 @@ void FGTileMgr::schedule_needed() {
for ( y = -1; y <= 1; ++y ) {
if ( x != 0 || y != 0 ) {
b = sgBucketOffset( longitude, latitude, x, y );
if ( ! global_tile_cache.exists( b ) ) {
sched_tile( b );
}
sched_tile( b );
}
}
}
@ -255,9 +256,7 @@ void FGTileMgr::schedule_needed() {
for ( y = -yrange; y <= yrange; ++y ) {
if ( x < -1 || x > 1 || y < -1 || y > 1 ) {
SGBucket b = sgBucketOffset( longitude, latitude, x, y );
if ( ! global_tile_cache.exists( b ) ) {
sched_tile( b );
}
sched_tile( b );
}
}
}
@ -270,12 +269,12 @@ void FGTileMgr::initialize_queue()
// system and load all relavant tiles
SG_LOG( SG_TERRAIN, SG_INFO, "Updating Tile list for " << current_bucket );
cout << "tile cache size = " << global_tile_cache.get_size() << endl;
// cout << "tile cache size = " << tile_cache.get_size() << endl;
int i;
// wipe/initialize tile cache
// global_tile_cache.init();
// tile_cache.init();
previous_bucket.make_bad();
// build the local area list and schedule tiles for loading
@ -285,6 +284,8 @@ void FGTileMgr::initialize_queue()
schedule_needed();
// do we really want to lose this? CLO
#if 0
// Now force a load of the center tile and inner ring so we
// have something to see in our first frame.
for ( i = 0; i < 9; ++i ) {
@ -297,6 +298,7 @@ void FGTileMgr::initialize_queue()
load_tile( pending );
}
}
#endif
}
@ -305,7 +307,7 @@ void FGTileMgr::initialize_queue()
// tile_cache -- which actually handles all the
// (de)allocations
void FGTileMgr::destroy_queue() {
load_queue.clear();
// load_queue.clear();
}
@ -328,8 +330,8 @@ int FGTileMgr::update( double lon, double lat ) {
current_bucket.set_bucket( longitude, latitude );
// SG_LOG( SG_TERRAIN, SG_DEBUG, "Updating Tile list for " << current_bucket );
if ( global_tile_cache.exists( current_bucket ) ) {
current_tile = global_tile_cache.get_tile( current_bucket );
if ( tile_cache.exists( current_bucket ) ) {
current_tile = tile_cache.get_tile( current_bucket );
scenery.next_center = current_tile->center;
} else {
SG_LOG( SG_TERRAIN, SG_WARN, "Tile not found (Ok if initializing)" );
@ -346,6 +348,8 @@ int FGTileMgr::update( double lon, double lat ) {
state = Running;
}
// now handled by threaded tile pager
#if 0
if ( load_queue.size() ) {
SG_LOG( SG_TERRAIN, SG_INFO, "Load queue size = " << load_queue.size()
<< " loading a tile" );
@ -354,6 +358,7 @@ int FGTileMgr::update( double lon, double lat ) {
load_queue.pop_front();
load_tile( pending );
}
#endif
if ( scenery.center == Point3D(0.0) ) {
// initializing
@ -419,15 +424,15 @@ void FGTileMgr::prep_ssg_nodes() {
// selector and transform
FGTileEntry *e;
global_tile_cache.reset_traversal();
tile_cache.reset_traversal();
while ( ! global_tile_cache.at_end() ) {
while ( ! tile_cache.at_end() ) {
// cout << "processing a tile" << endl;
if ( (e = global_tile_cache.get_current()) ) {
if ( (e = tile_cache.get_current()) ) {
e->prep_ssg_node( scenery.center, vis);
} else {
cout << "warning ... empty tile in cache" << endl;
}
global_tile_cache.next();
tile_cache.next();
}
}

View file

@ -31,16 +31,12 @@
#include <simgear/compiler.h>
#include <list>
#include <plib/ssg.h>
#include <simgear/bucket/newbucket.hxx>
#include "hitlist.hxx"
SG_USING_STD(list);
#include "newcache.hxx"
#if defined(USE_MEM) || defined(WIN32)
# define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
@ -66,9 +62,6 @@ private:
load_state state;
// pending tile load queue
list < SGBucket > load_queue;
// initialize the cache
void initialize_queue();
@ -80,9 +73,6 @@ private:
// schedule a tile for loading
void sched_tile( const SGBucket& b );
// load a tile
void load_tile( const SGBucket& b );
// schedule a needed buckets for loading
void schedule_needed();
@ -111,6 +101,11 @@ private:
double last_longitude;
double last_latitude;
/**
*
*/
FGNewCache tile_cache;
public:
// Constructor
@ -144,8 +139,6 @@ public:
// transform and update it's range selector based on current
// visibilty
void prep_ssg_nodes();
inline int queue_size() const { return load_queue.size(); }
};