osgEarth 2.1.1
Public Member Functions | Protected Member Functions | Private Types | Private Member Functions | Private Attributes

StreamingTerrain Class Reference

Inheritance diagram for StreamingTerrain:
Collaboration diagram for StreamingTerrain:

List of all members.

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 TilecreateTile (const TileKey &key, GeoLocator *locator) const
TaskServicegetImageryTaskService (int layerId)
TaskServicegetElevationTaskService ()
TaskServicegetTileGenerationTaskService ()
void updateTaskServiceThreads (const MapFrame &mapf)
const LoadingPolicygetLoadingPolicy () 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

TaskServicecreateTaskService (const std::string &name, int id, int numThreads)
TaskServicegetTaskService (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

Detailed Description

Terrain implementation that supports the SEQUENTIAL and PREEMPTIVE loading policies.

Definition at line 31 of file StreamingTerrain.


Member Typedef Documentation

typedef std::map< int, osg::ref_ptr< TaskService > > StreamingTerrain::TaskServiceMap [private]

Definition at line 78 of file StreamingTerrain.


Constructor & Destructor Documentation

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

Here is the call graph for this function:

StreamingTerrain::~StreamingTerrain ( ) [protected, virtual]

Definition at line 58 of file StreamingTerrain.cpp.

{
    //nop
}

Member Function Documentation

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

Here is the caller graph for this function:

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

Here is the call graph for this function:

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

Here is the call graph for this function:

Here is the caller graph for this function:

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

Here is the call graph for this function:

Here is the caller graph for this function:

const LoadingPolicy& StreamingTerrain::getLoadingPolicy ( ) const [inline]

Definition at line 59 of file StreamingTerrain.

{ return _loadingPolicy; }

Here is the caller graph for this function:

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

Here is the caller graph for this function:

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

Here is the call graph for this function:

Here is the caller graph for this function:

virtual const char* StreamingTerrain::libraryName ( ) const [inline, virtual]

Reimplemented from Terrain.

Definition at line 40 of file StreamingTerrain.

{ return "osgEarth"; }
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();
            }
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

Here is the call graph for this function:

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

Here is the call graph for this function:


Member Data Documentation

Definition at line 84 of file StreamingTerrain.

Definition at line 83 of file StreamingTerrain.

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.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines