osgEarth 2.1.1
|
00001 /* -*-c++-*- */ 00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph 00003 * Copyright 2008-2010 Pelican Mapping 00004 * http://osgearth.org 00005 * 00006 * osgEarth is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> 00018 */ 00019 #include "ParallelKeyNodeFactory" 00020 #include <osgEarth/Registry> 00021 #include <osg/PagedLOD> 00022 00023 using namespace osgEarth; 00024 using namespace OpenThreads; 00025 00026 #define LC "[ParallelKeyNodeFactory] " 00027 00028 //-------------------------------------------------------------------------- 00029 00030 ParallelKeyNodeFactory::ParallelKeyNodeFactory(TileBuilder* builder, 00031 const OSGTerrainOptions& options, 00032 const MapInfo& mapInfo, 00033 Terrain* terrain, 00034 UID engineUID ) : 00035 00036 SerialKeyNodeFactory( builder, options, mapInfo, terrain, engineUID ) 00037 { 00038 //NOP 00039 } 00040 00041 osg::Node* 00042 ParallelKeyNodeFactory::createNode( const TileKey& key ) 00043 { 00044 // An event for synchronizing the completion of all requests: 00045 Threading::MultiEvent semaphore; 00046 00047 // Collect all the jobs that can run in parallel (from all 4 subtiles) 00048 osg::ref_ptr<TileBuilder::Job> jobs[4]; 00049 unsigned numTasks = 0; 00050 for( unsigned i=0; i<4; ++i ) 00051 { 00052 jobs[i] = _builder->createJob( key.createChildKey(i), semaphore ); 00053 if ( jobs[i].valid() ) 00054 numTasks += jobs[i]->_tasks.size(); 00055 } 00056 00057 // Set up the sempahore to block for the correct number of tasks: 00058 semaphore.reset( numTasks ); 00059 00060 // Run all the tasks in parallel: 00061 for( unsigned i=0; i<4; ++i ) 00062 if ( jobs[i].valid() ) 00063 _builder->runJob( jobs[i].get() ); 00064 00065 // Wait for them to complete: 00066 semaphore.wait(); 00067 00068 // Now postprocess them and assemble into a tile group. 00069 osg::Group* root = new osg::Group(); 00070 00071 for( unsigned i=0; i<4; ++i ) 00072 { 00073 if ( jobs[i].valid() ) 00074 { 00075 osg::ref_ptr<Tile> tile; 00076 bool hasRealData; 00077 bool hasLodBlending; 00078 _builder->finalizeJob( jobs[i].get(), tile, hasRealData, hasLodBlending ); 00079 if ( tile.valid() ) 00080 addTile( tile.get(), hasRealData, hasLodBlending, root ); 00081 } 00082 } 00083 00084 //TODO: need to check to see if the group is empty, and do something different. 00085 return root; 00086 }