osgEarth 2.1.1
|
Public Member Functions | |
StreamingTerrain (const MapFrame &update_mapf, const MapFrame &cull_mapf, OSGTileFactory *factory, bool quickReleaseGLObjects) | |
virtual const char * | libraryName () const |
virtual const char * | className () const |
virtual Tile * | createTile (const TileKey &key, GeoLocator *locator) const |
TaskService * | getImageryTaskService (int layerId) |
TaskService * | getElevationTaskService () |
TaskService * | getTileGenerationTaskService () |
void | updateTaskServiceThreads (const MapFrame &mapf) |
const LoadingPolicy & | getLoadingPolicy () const |
Protected Member Functions | |
virtual | ~StreamingTerrain () |
virtual unsigned | getNumActiveTasks () const |
virtual void | updateTraversal (osg::NodeVisitor &nv) |
Private Types | |
typedef std::map< int, osg::ref_ptr< TaskService > > | TaskServiceMap |
Private Member Functions | |
TaskService * | createTaskService (const std::string &name, int id, int numThreads) |
TaskService * | getTaskService (int id) |
void | refreshFamily (const MapInfo &info, const TileKey &key, StreamingTile::Relative *family, bool tileTableLocked) |
Private Attributes | |
TaskServiceMap | _taskServices |
OpenThreads::Mutex | _taskServiceMutex |
int | _numLoadingThreads |
LoadingPolicy | _loadingPolicy |
UID | _elevationTaskServiceUID |
Terrain implementation that supports the SEQUENTIAL and PREEMPTIVE loading policies.
Definition at line 31 of file StreamingTerrain.
typedef std::map< int, osg::ref_ptr< TaskService > > StreamingTerrain::TaskServiceMap [private] |
Definition at line 78 of file StreamingTerrain.
StreamingTerrain::StreamingTerrain | ( | const MapFrame & | update_mapf, |
const MapFrame & | cull_mapf, | ||
OSGTileFactory * | factory, | ||
bool | quickReleaseGLObjects | ||
) |
Definition at line 41 of file StreamingTerrain.cpp.
: Terrain( update_mapf, cull_mapf, tileFactory, quickReleaseGLObjects ), _numLoadingThreads( 0 ) { _loadingPolicy = tileFactory->getTerrainOptions().loadingPolicy().get(); setNumChildrenRequiringUpdateTraversal( 1 ); _alwaysUpdate = true; _numLoadingThreads = computeLoadingThreads(_loadingPolicy); OE_INFO << LC << "Using a total of " << _numLoadingThreads << " loading threads " << std::endl; }
StreamingTerrain::~StreamingTerrain | ( | ) | [protected, virtual] |
Definition at line 58 of file StreamingTerrain.cpp.
{
//nop
}
virtual const char* StreamingTerrain::className | ( | ) | const [inline, virtual] |
Reimplemented from Terrain.
Definition at line 41 of file StreamingTerrain.
{ return "StreamingTerrain"; }
TaskService * StreamingTerrain::createTaskService | ( | const std::string & | name, |
int | id, | ||
int | numThreads | ||
) | [private] |
Definition at line 244 of file StreamingTerrain.cpp.
{ ScopedLock<Mutex> lock( _taskServiceMutex ); // first, double-check that the service wasn't created during the locking process: TaskServiceMap::iterator itr = _taskServices.find(id); if (itr != _taskServices.end()) return itr->second.get(); // ok, make a new one TaskService* service = new TaskService( name, numThreads ); _taskServices[id] = service; return service; }
Tile * StreamingTerrain::createTile | ( | const TileKey & | key, |
GeoLocator * | locator | ||
) | const [virtual] |
Reimplemented from Terrain.
Definition at line 64 of file StreamingTerrain.cpp.
{ return new StreamingTile( key, locator, this->getQuickReleaseGLObjects() ); }
TaskService * StreamingTerrain::getElevationTaskService | ( | ) |
Definition at line 275 of file StreamingTerrain.cpp.
{ TaskService* service = getTaskService( ELEVATION_TASK_SERVICE_ID ); if (!service) { service = createTaskService( "elevation", ELEVATION_TASK_SERVICE_ID, 1 ); } return service; }
TaskService * StreamingTerrain::getImageryTaskService | ( | int | layerId | ) |
Definition at line 287 of file StreamingTerrain.cpp.
{ TaskService* service = getTaskService( layerId ); if (!service) { std::stringstream buf; buf << "layer " << layerId; std::string bufStr = buf.str(); service = createTaskService( bufStr, layerId, 1 ); } return service; }
const LoadingPolicy& StreamingTerrain::getLoadingPolicy | ( | ) | const [inline] |
Definition at line 59 of file StreamingTerrain.
{ return _loadingPolicy; }
unsigned StreamingTerrain::getNumActiveTasks | ( | ) | const [protected, virtual] |
Reimplemented from Terrain.
Definition at line 196 of file StreamingTerrain.cpp.
{ ScopedLock<Mutex> lock(const_cast<StreamingTerrain*>(this)->_taskServiceMutex ); unsigned int total = 0; for (TaskServiceMap::const_iterator itr = _taskServices.begin(); itr != _taskServices.end(); ++itr) { total += itr->second->getNumRequests(); } return total; }
TaskService * StreamingTerrain::getTaskService | ( | int | id | ) | [private] |
Definition at line 260 of file StreamingTerrain.cpp.
{ ScopedLock<Mutex> lock( _taskServiceMutex ); TaskServiceMap::iterator itr = _taskServices.find(id); if (itr != _taskServices.end()) { return itr->second.get(); } return NULL; }
TaskService * StreamingTerrain::getTileGenerationTaskService | ( | ) |
Definition at line 301 of file StreamingTerrain.cpp.
{ TaskService* service = getTaskService( TILE_GENERATION_TASK_SERVICE_ID ); if (!service) { int numCompileThreads = _loadingPolicy.numCompileThreads().isSet() ? osg::maximum( 1, _loadingPolicy.numCompileThreads().value() ) : (int)osg::maximum( 1.0f, _loadingPolicy.numCompileThreadsPerCore().value() * (float)GetNumberOfProcessors() ); service = createTaskService( "tilegen", TILE_GENERATION_TASK_SERVICE_ID, numCompileThreads ); } return service; }
virtual const char* StreamingTerrain::libraryName | ( | ) | const [inline, virtual] |
void StreamingTerrain::refreshFamily | ( | const MapInfo & | info, |
const TileKey & | key, | ||
StreamingTile::Relative * | family, | ||
bool | tileTableLocked | ||
) | [private] |
Definition at line 71 of file StreamingTerrain.cpp.
{ osgTerrain::TileID tileId = key.getTileId(); // geocentric maps wrap around in the X dimension. bool wrapX = mapInfo.isGeocentric(); unsigned int tileCountX, tileCountY; mapInfo.getProfile()->getNumTiles( tileId.level, tileCountX, tileCountY ); // Relative::PARENT { family[StreamingTile::Relative::PARENT].expected = true; // TODO: is this always correct? family[StreamingTile::Relative::PARENT].elevLOD = -1; family[StreamingTile::Relative::PARENT].imageLODs.clear(); family[StreamingTile::Relative::PARENT].tileID = osgTerrain::TileID( tileId.level-1, tileId.x/2, tileId.y/2 ); osg::ref_ptr<StreamingTile> parent; getTile( family[StreamingTile::Relative::PARENT].tileID, parent, !tileTableLocked ); if ( parent.valid() ) { family[StreamingTile::Relative::PARENT].elevLOD = parent->getElevationLOD(); ColorLayersByUID relLayers; parent->getCustomColorLayers( relLayers ); for( ColorLayersByUID::const_iterator i = relLayers.begin(); i != relLayers.end(); ++i ) { family[StreamingTile::Relative::PARENT].imageLODs[i->first] = i->second.getLevelOfDetail(); } } } // Relative::WEST { family[StreamingTile::Relative::WEST].expected = tileId.x > 0 || wrapX; family[StreamingTile::Relative::WEST].elevLOD = -1; family[StreamingTile::Relative::WEST].imageLODs.clear(); family[StreamingTile::Relative::WEST].tileID = osgTerrain::TileID( tileId.level, tileId.x > 0? tileId.x-1 : tileCountX-1, tileId.y ); osg::ref_ptr<StreamingTile> west; getTile( family[StreamingTile::Relative::WEST].tileID, west, !tileTableLocked ); if ( west.valid() ) { family[StreamingTile::Relative::WEST].elevLOD = west->getElevationLOD(); ColorLayersByUID relLayers; west->getCustomColorLayers( relLayers ); for( ColorLayersByUID::const_iterator i = relLayers.begin(); i != relLayers.end(); ++i ) { family[StreamingTile::Relative::WEST].imageLODs[i->first] = i->second.getLevelOfDetail(); } } } // Relative::NORTH { family[StreamingTile::Relative::NORTH].expected = tileId.y < (int)tileCountY-1; family[StreamingTile::Relative::NORTH].elevLOD = -1; family[StreamingTile::Relative::NORTH].imageLODs.clear(); family[StreamingTile::Relative::NORTH].tileID = osgTerrain::TileID( tileId.level, tileId.x, tileId.y < (int)tileCountY-1 ? tileId.y+1 : 0 ); osg::ref_ptr<StreamingTile> north; getTile( family[StreamingTile::Relative::NORTH].tileID, north, !tileTableLocked ); if ( north.valid() ) { family[StreamingTile::Relative::NORTH].elevLOD = north->getElevationLOD(); ColorLayersByUID relLayers; north->getCustomColorLayers( relLayers ); for( ColorLayersByUID::const_iterator i = relLayers.begin(); i != relLayers.end(); ++i ) { family[StreamingTile::Relative::NORTH].imageLODs[i->first] = i->second.getLevelOfDetail(); } } } // Relative::EAST { family[StreamingTile::Relative::EAST].expected = tileId.x < (int)tileCountX-1 || wrapX; family[StreamingTile::Relative::EAST].elevLOD = -1; family[StreamingTile::Relative::EAST].imageLODs.clear(); family[StreamingTile::Relative::EAST].tileID = osgTerrain::TileID( tileId.level, tileId.x < (int)tileCountX-1 ? tileId.x+1 : 0, tileId.y ); osg::ref_ptr<StreamingTile> east; getTile( family[StreamingTile::Relative::EAST].tileID, east, !tileTableLocked ); if ( east.valid() ) { family[StreamingTile::Relative::EAST].elevLOD = east->getElevationLOD(); ColorLayersByUID relLayers; east->getCustomColorLayers( relLayers ); for( ColorLayersByUID::const_iterator i = relLayers.begin(); i != relLayers.end(); ++i ) { family[StreamingTile::Relative::EAST].imageLODs[i->first] = i->second.getLevelOfDetail(); } } } // Relative::SOUTH { family[StreamingTile::Relative::SOUTH].expected = tileId.y > 0; family[StreamingTile::Relative::SOUTH].elevLOD = -1; family[StreamingTile::Relative::SOUTH].imageLODs.clear(); family[StreamingTile::Relative::SOUTH].tileID = osgTerrain::TileID( tileId.level, tileId.x, tileId.y > 0 ? tileId.y-1 : tileCountY-1 ); osg::ref_ptr<StreamingTile> south; getTile( family[StreamingTile::Relative::SOUTH].tileID, south, !tileTableLocked ); if ( south.valid() ) { family[StreamingTile::Relative::SOUTH].elevLOD = south->getElevationLOD(); ColorLayersByUID relLayers; south->getCustomColorLayers( relLayers ); for( ColorLayersByUID::const_iterator i = relLayers.begin(); i != relLayers.end(); ++i ) { family[StreamingTile::Relative::SOUTH].imageLODs[i->first] = i->second.getLevelOfDetail(); } } } }
void StreamingTerrain::updateTaskServiceThreads | ( | const MapFrame & | mapf | ) |
Updates the catalog of task service threads - this gets called by the OSGTerrainEngine in response to a change in the Map's data model. The map frame is that of the terrain engine.
Definition at line 316 of file StreamingTerrain.cpp.
{ //Get the maximum elevation weight float elevationWeight = 0.0f; for (ElevationLayerVector::const_iterator itr = mapf.elevationLayers().begin(); itr != mapf.elevationLayers().end(); ++itr) { ElevationLayer* layer = itr->get(); float w = layer->getTerrainLayerOptions().loadingWeight().value(); if (w > elevationWeight) elevationWeight = w; } float totalImageWeight = 0.0f; for (ImageLayerVector::const_iterator itr = mapf.imageLayers().begin(); itr != mapf.imageLayers().end(); ++itr) { totalImageWeight += itr->get()->getTerrainLayerOptions().loadingWeight().value(); } float totalWeight = elevationWeight + totalImageWeight; if (elevationWeight > 0.0f) { //Determine how many threads each layer gets int numElevationThreads = (int)osg::round((float)_numLoadingThreads * (elevationWeight / totalWeight )); OE_INFO << LC << "Elevation Threads = " << numElevationThreads << std::endl; getElevationTaskService()->setNumThreads( numElevationThreads ); } for (ImageLayerVector::const_iterator itr = mapf.imageLayers().begin(); itr != mapf.imageLayers().end(); ++itr) { const TerrainLayerOptions& opt = itr->get()->getTerrainLayerOptions(); int imageThreads = (int)osg::round((float)_numLoadingThreads * (opt.loadingWeight().value() / totalWeight )); OE_INFO << LC << "Image Threads for " << itr->get()->getName() << " = " << imageThreads << std::endl; getImageryTaskService( itr->get()->getUID() )->setNumThreads( imageThreads ); } }
void StreamingTerrain::updateTraversal | ( | osg::NodeVisitor & | nv | ) | [protected, virtual] |
Reimplemented from Terrain.
Definition at line 209 of file StreamingTerrain.cpp.
{ // this stamp keeps track of when requests are dispatched. If a request's stamp gets too // old, it is considered "expired" and subject to cancelation int stamp = nv.getFrameStamp()->getFrameNumber(); // update the frame stamp on the task services. This is necessary to support // automatic request cancelation for image requests. { ScopedLock<Mutex> lock( _taskServiceMutex ); for (TaskServiceMap::iterator i = _taskServices.begin(); i != _taskServices.end(); ++i) { i->second->setStamp( stamp ); } } // next, go through the live tiles and process update-traversal requests. This // requires a read-lock on the master tiles table. { Threading::ScopedReadLock tileTableReadLock( _tilesMutex ); for( TileTable::const_iterator i = _tiles.begin(); i != _tiles.end(); ++i ) { StreamingTile* tile = static_cast<StreamingTile*>( i->second.get() ); // update the neighbor list for each tile. refreshFamily( _update_mapf.getMapInfo(), tile->getKey(), tile->getFamily(), true ); tile->servicePendingElevationRequests( _update_mapf, stamp, true ); tile->serviceCompletedRequests( _update_mapf, true ); } } }
Definition at line 84 of file StreamingTerrain.
Definition at line 83 of file StreamingTerrain.
int StreamingTerrain::_numLoadingThreads [private] |
Definition at line 82 of file StreamingTerrain.
OpenThreads::Mutex StreamingTerrain::_taskServiceMutex [private] |
Definition at line 81 of file StreamingTerrain.
Definition at line 80 of file StreamingTerrain.