void
TerrainEngineNode::validateTerrainOptions( TerrainOptions& options )
{
    // make sure all the requested properties are compatible, and fall back as necessary.
    //const Capabilities& caps = Registry::instance()->getCapabilities();

    // warn against mixing multipass technique with preemptive/sequential mode:
    if (options.compositingTechnique() == TerrainOptions::COMPOSITING_MULTIPASS &&
        options.loadingPolicy()->mode() != LoadingPolicy::MODE_STANDARD )
    {
        OE_WARN << LC << "MULTIPASS compositor is incompatible with preemptive/sequential loading policy; "
            << "falling back on STANDARD mode" << std::endl;
        options.loadingPolicy()->mode() = LoadingPolicy::MODE_STANDARD;
    }
}
void
OSGTerrainEngineNode::preInitialize( const Map* map, const TerrainOptions& options )
{
    TerrainEngineNode::preInitialize( map, options );

    _isStreaming =
        options.loadingPolicy()->mode() == LoadingPolicy::MODE_PREEMPTIVE ||
        options.loadingPolicy()->mode() == LoadingPolicy::MODE_SEQUENTIAL;

    // in standard mode, try to set the number of OSG DatabasePager threads to use.
    if ( options.loadingPolicy().isSet() && !_isStreaming )
    {
        int numThreads = -1;

        if ( options.loadingPolicy()->numLoadingThreads().isSet() )
        {
            numThreads = osg::maximum( 1, *options.loadingPolicy()->numLoadingThreads() );
        }
        else if ( options.loadingPolicy()->numLoadingThreadsPerCore().isSet() )
        {
            float numThreadsPerCore = *options.loadingPolicy()->numLoadingThreadsPerCore();
            numThreads = osg::maximum( (int)1, (int)osg::round( 
                numThreadsPerCore * (float)OpenThreads::GetNumberOfProcessors() ) );
        }

        if ( numThreads > 0 )
        {
            OE_INFO << LC << "Requesting " << numThreads << " database pager threads in STANDARD mode" << std::endl;
            osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint( numThreads );
            //osg::DisplaySettings::instance()->setNumOfHttpDatabaseThreadsHint( numThreads );
        }
    }
}
void
OSGTerrainEngineNode::preInitialize( const Map* map, const TerrainOptions& options )
{
    TerrainEngineNode::preInitialize( map, options );

    _isStreaming =
        options.loadingPolicy()->mode() == LoadingPolicy::MODE_PREEMPTIVE ||
        options.loadingPolicy()->mode() == LoadingPolicy::MODE_SEQUENTIAL;

    // in standard mode, try to set the number of OSG DatabasePager threads to use.
    if ( options.loadingPolicy().isSet() && !_isStreaming )
    {
        int numThreads = -1;

        if ( options.loadingPolicy()->numLoadingThreads().isSet() )
        {
            numThreads = osg::maximum( 1, *options.loadingPolicy()->numLoadingThreads() );
        }
        else if ( options.loadingPolicy()->numLoadingThreadsPerCore().isSet() )
        {
            float numThreadsPerCore = *options.loadingPolicy()->numLoadingThreadsPerCore();
            numThreads = osg::maximum( (int)1, (int)osg::round( 
                numThreadsPerCore * (float)OpenThreads::GetNumberOfProcessors() ) );
        }

        if ( numThreads > 0 )
        {
            // NOTE: this doesn't work. the pager gets created before we ever get here.
            numThreads = osg::maximum(numThreads, 2);
            int numHttpThreads = osg::clampBetween( numThreads/2, 1, numThreads-1 );

            //OE_INFO << LC << "Requesting pager threads in STANDARD mode: local=" << numThreads << ", http=" << numHttpThreads << std::endl;
            osg::DisplaySettings::instance()->setNumOfDatabaseThreadsHint( numThreads );
            osg::DisplaySettings::instance()->setNumOfHttpDatabaseThreadsHint( numHttpThreads );
        }
    }
}