Introduction of IncrementalCompileOperation support to DatabasePager.
This commit is contained in:
@@ -28,10 +28,13 @@
|
||||
#include <OpenThreads/ScopedLock>
|
||||
#include <OpenThreads/Condition>
|
||||
|
||||
#include <osgUtil/IncrementalCompileOperation>
|
||||
|
||||
#include <osgDB/SharedStateManager>
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osgDB/Options>
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <algorithm>
|
||||
@@ -165,6 +168,15 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
* note, should be only be called from the update thread. */
|
||||
virtual void registerPagedLODs(osg::Node* subgraph, int frameNumber = 0);
|
||||
|
||||
/** Set the incremental compile operation.
|
||||
* Used to manage the OpenGL object compilation and merging of subgraphs in a way that avoids overloading
|
||||
* the rendering of frame with too many new objects in one frame. */
|
||||
void setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation* ico);
|
||||
|
||||
/** Get the incremental compile operation. */
|
||||
osgUtil::IncrementalCompileOperation* getIncrementalCompileOperation() { return _incrementalCompileOperation.get(); }
|
||||
|
||||
|
||||
/** Set whether the database pager should pre compile OpenGL objects before allowing
|
||||
* them to be merged into the scene graph.
|
||||
* Pre compilation helps reduce the chances of frame drops, but also slows the
|
||||
@@ -318,7 +330,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
/** Report how many items are in the _dataToCompileList queue */
|
||||
unsigned int getDataToCompileListSize() const { return _dataToCompileList->size(); }
|
||||
|
||||
/** Report how many items are in the _dataToCompileList queue */
|
||||
/** Report how many items are in the _dataToMergeList queue */
|
||||
unsigned int getDataToMergeListSize() const { return _dataToMergeList->size(); }
|
||||
|
||||
/** Report whether any requests are in the pager.*/
|
||||
@@ -338,7 +350,8 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
|
||||
typedef std::set< osg::ref_ptr<osg::StateSet> > StateSetList;
|
||||
typedef std::vector< osg::ref_ptr<osg::Drawable> > DrawableList;
|
||||
typedef std::pair<StateSetList,DrawableList> DataToCompile;
|
||||
//typedef std::pair<StateSetList,DrawableList> DataToCompile;
|
||||
typedef osgUtil::IncrementalCompileOperation::CompileData DataToCompile;
|
||||
typedef std::map< unsigned int, DataToCompile > DataToCompileMap;
|
||||
typedef std::set<unsigned int> ActiveGraphicsContexts;
|
||||
typedef std::vector< osg::observer_ptr<osg::GraphicsContext> > CompileGraphicsContexts;
|
||||
@@ -358,6 +371,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
virtual bool containsPagedLOD(const osg::observer_ptr<osg::PagedLOD>& plod) const = 0;
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~DatabasePager();
|
||||
@@ -407,7 +421,8 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
return _valid && (frameNumber - _frameNumberLastRequest <= 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct RequestQueue : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
@@ -470,7 +485,10 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
// forward declare inner helper classes
|
||||
class FindCompileableGLObjectsVisitor;
|
||||
friend class FindCompileableGLObjectsVisitor;
|
||||
|
||||
|
||||
struct DatabasePagerCompileCompletedCallback;
|
||||
friend struct DatabasePagerCompileCompletedCallback;
|
||||
|
||||
class FindPagedLODsVisitor;
|
||||
friend class FindPagedLODsVisitor;
|
||||
|
||||
@@ -568,7 +586,8 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void compileCompleted(DatabaseRequest* databaseRequest);
|
||||
|
||||
/** Iterate through the active PagedLOD nodes children removing
|
||||
* children which havn't been visited since specified expiryTime.
|
||||
* note, should be only be called from the update thread. */
|
||||
@@ -620,6 +639,8 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
// CompileGraphicsContexts _compileGraphicsContexts;
|
||||
|
||||
bool _doPreCompile;
|
||||
osg::ref_ptr<osgUtil::IncrementalCompileOperation> _incrementalCompileOperation;
|
||||
|
||||
double _targetFrameRate;
|
||||
double _minimumTimeAvailableForGLCompileAndDeletePerFrame;
|
||||
unsigned int _maximumNumOfObjectsToCompilePerFrame;
|
||||
|
||||
@@ -62,10 +62,14 @@ namespace osgDB {
|
||||
|
||||
void apply(osg::Node& node);
|
||||
void apply(osg::Geode& geode);
|
||||
|
||||
// Answers the question "Will this state set be eliminated by
|
||||
// the SharedStateManager because an equivalent one has been
|
||||
// seen already?" Safe to call from the pager thread.
|
||||
bool isShared(osg::StateSet* stateSet);
|
||||
|
||||
bool isShared(osg::Texture* texture);
|
||||
|
||||
protected:
|
||||
|
||||
inline bool shareTexture(osg::Object::DataVariance variance)
|
||||
|
||||
@@ -109,6 +109,8 @@ class OSGUTIL_EXPORT IncrementalCompileOperation : public osg::GraphicsOperation
|
||||
|
||||
struct CompileCompletedCallback : public osg::Referenced
|
||||
{
|
||||
/// return true if the callback assumes responsibility for merging any associated subgraphs with the main scene graph
|
||||
/// return false if callback doesn't handle the merge, and instead requires the IncrementalCompileOperation to handle this for us
|
||||
virtual bool compileCompleted(CompileSet* compileSet) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -151,6 +151,7 @@ ADD_DEFINITIONS(-DOSG_PLUGIN_EXTENSION=${CMAKE_SHARED_MODULE_SUFFIX})
|
||||
|
||||
LINK_INTERNAL(${LIB_NAME}
|
||||
osg
|
||||
osgUtil
|
||||
OpenThreads
|
||||
)
|
||||
LINK_EXTERNAL(${LIB_NAME} ${OSGDB_PLATFORM_SPECIFIC_LIBRARIES} ${DL_LIBRARY})
|
||||
|
||||
@@ -105,6 +105,32 @@ RefPtrAdapter<FuncObj> refPtrAdapt(const FuncObj& func)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CountPagedLODList
|
||||
//
|
||||
struct DatabasePager::DatabasePagerCompileCompletedCallback : public osgUtil::IncrementalCompileOperation::CompileCompletedCallback
|
||||
{
|
||||
DatabasePagerCompileCompletedCallback(osgDB::DatabasePager* pager, osgDB::DatabasePager::DatabaseRequest* databaseRequest):
|
||||
_pager(pager),
|
||||
_databaseRequest(databaseRequest) {}
|
||||
|
||||
virtual bool compileCompleted(osgUtil::IncrementalCompileOperation::CompileSet* compileSet)
|
||||
{
|
||||
_pager->compileCompleted(_databaseRequest.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
osgDB::DatabasePager* _pager;
|
||||
osg::ref_ptr<osgDB::DatabasePager::DatabaseRequest> _databaseRequest;
|
||||
};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CountPagedLODList
|
||||
//
|
||||
class DatabasePager::CountPagedLODsVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
@@ -362,7 +388,6 @@ public:
|
||||
// if texture object attributes exist and need to be
|
||||
// compiled, add the state to the list for later
|
||||
// compilation.
|
||||
bool compileStateSet = false;
|
||||
for(unsigned int i=0;i<stateset->getTextureAttributeList().size();++i)
|
||||
{
|
||||
osg::Texture* texture = dynamic_cast<osg::Texture*>(stateset->getTextureAttribute(i,osg::StateAttribute::TEXTURE));
|
||||
@@ -380,7 +405,8 @@ public:
|
||||
|
||||
if (!_pager->isCompiled(texture))
|
||||
{
|
||||
compileStateSet = true;
|
||||
_dataToCompile->_textures.push_back(texture);
|
||||
|
||||
if (osg::getNotifyLevel() >= osg::DEBUG_INFO)
|
||||
{
|
||||
OSG_INFO <<"Found compilable texture " << texture << " ";
|
||||
@@ -392,10 +418,6 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
if (compileStateSet && _dataToCompile)
|
||||
{
|
||||
_dataToCompile->first.insert(stateset);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -437,7 +459,7 @@ public:
|
||||
// anything for VBOs, does it?
|
||||
if (_dataToCompile && (drawable->getUseVertexBufferObjects() || drawable->getUseDisplayList()) && !_pager->isCompiled(drawable))
|
||||
{
|
||||
_dataToCompile->second.push_back(drawable);
|
||||
_dataToCompile->_drawables.push_back(drawable);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -991,13 +1013,21 @@ void DatabasePager::DatabaseThread::run()
|
||||
|
||||
databaseRequest->_loadedModel->accept(frov);
|
||||
|
||||
if (_pager->_doPreCompile &&
|
||||
!_pager->_activeGraphicsContexts.empty())
|
||||
if (_pager->_doPreCompile && !dtc->empty())
|
||||
{
|
||||
if (!dtc->first.empty() || !dtc->second.empty())
|
||||
if (_pager->_incrementalCompileOperation.valid())
|
||||
{
|
||||
loadedObjectsNeedToBeCompiled = true;
|
||||
OSG_NOTICE<<"Using IncrementalCompileOperation"<<std::endl;
|
||||
|
||||
osgUtil::IncrementalCompileOperation::CompileSet* compileSet = new osgUtil::IncrementalCompileOperation::CompileSet(databaseRequest->_loadedModel.get());
|
||||
compileSet->_compileCompletedCallback = new DatabasePagerCompileCompletedCallback(_pager, databaseRequest);
|
||||
|
||||
_pager->_incrementalCompileOperation->add(compileSet);
|
||||
|
||||
loadedObjectsNeedToBeCompiled = true;
|
||||
}
|
||||
else if (!_pager->_activeGraphicsContexts.empty())
|
||||
{
|
||||
// copy the objects from the compile list to the other graphics context list.
|
||||
for(;
|
||||
itr != _pager->_activeGraphicsContexts.end();
|
||||
@@ -1012,7 +1042,10 @@ void DatabasePager::DatabaseThread::run()
|
||||
// dataToCompile or dataToMerge lists.
|
||||
if (loadedObjectsNeedToBeCompiled)
|
||||
{
|
||||
_pager->_dataToCompileList->add(databaseRequest.get());
|
||||
if (!_pager->_incrementalCompileOperation)
|
||||
{
|
||||
_pager->_dataToCompileList->add(databaseRequest.get());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1314,6 +1347,11 @@ DatabasePager::DatabasePager(const DatabasePager& rhs)
|
||||
}
|
||||
|
||||
|
||||
void DatabasePager::setIncrementalCompileOperation(osgUtil::IncrementalCompileOperation* ico)
|
||||
{
|
||||
_incrementalCompileOperation = ico;
|
||||
}
|
||||
|
||||
DatabasePager::~DatabasePager()
|
||||
{
|
||||
cancel();
|
||||
@@ -2052,6 +2090,12 @@ bool DatabasePager::requiresExternalCompileGLObjects(unsigned int contextID) con
|
||||
return osg::GraphicsContext::getCompileContext(contextID)==0;
|
||||
}
|
||||
|
||||
void DatabasePager::compileCompleted(DatabaseRequest* databaseRequest)
|
||||
{
|
||||
OSG_NOTICE<<"DatabasePager::compileCompleted("<<databaseRequest<<")"<<std::endl;
|
||||
_dataToMergeList->add(databaseRequest);
|
||||
}
|
||||
|
||||
void DatabasePager::compileAllGLObjects(osg::State& state, bool doFlush)
|
||||
{
|
||||
double availableTime = DBL_MAX;
|
||||
@@ -2089,23 +2133,25 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime, b
|
||||
{
|
||||
DataToCompileMap& dcm = databaseRequest->_dataToCompileMap;
|
||||
DataToCompile& dtc = dcm[state.getContextID()];
|
||||
if (!dtc.first.empty() && (elapsedTime+estimatedTextureDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame)
|
||||
if (!dtc._textures.empty() && (elapsedTime+estimatedTextureDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame)
|
||||
{
|
||||
|
||||
#if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE)
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0);
|
||||
#endif
|
||||
|
||||
// we have StateSet's to compile
|
||||
StateSetList& sslist = dtc.first;
|
||||
//OSG_INFO<<"Compiling statesets"<<std::endl;
|
||||
StateSetList::iterator itr=sslist.begin();
|
||||
//OSG_INFO<<"Compiling textures"<<std::endl;
|
||||
|
||||
// we have Textures to compile
|
||||
typedef osgUtil::IncrementalCompileOperation::CompileData::Textures Textures;
|
||||
Textures& textures = dtc._textures;
|
||||
Textures::iterator itr=textures.begin();
|
||||
unsigned int objTemp = numObjectsCompiled;
|
||||
for(;
|
||||
itr!=sslist.end() && (compileAll || ((elapsedTime+estimatedTextureDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame));
|
||||
itr!=textures.end() && (compileAll || ((elapsedTime+estimatedTextureDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame));
|
||||
++itr)
|
||||
{
|
||||
//OSG_INFO<<" Compiling stateset "<<(*itr).get()<<std::endl;
|
||||
OSG_INFO<<" Compiling texture "<<(*itr).get()<<std::endl;
|
||||
if (isCompiled(itr->get(), state.getContextID())
|
||||
|| (sharedManager && sharedManager->isShared(itr->get())))
|
||||
{
|
||||
@@ -2114,7 +2160,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime, b
|
||||
}
|
||||
double startCompileTime = timer.delta_s(start_tick,timer.tick());
|
||||
|
||||
(*itr)->compileGLObjects(state);
|
||||
(*itr)->apply(state);
|
||||
|
||||
#if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GL3_AVAILABLE)
|
||||
GLint p;
|
||||
@@ -2130,19 +2176,20 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime, b
|
||||
}
|
||||
if (osg::getNotifyLevel() >= osg::DEBUG_INFO
|
||||
&& numObjectsCompiled > objTemp)
|
||||
OSG_INFO<< _frameNumber << " compiled "
|
||||
OSG_NOTICE<< _frameNumber << " compiled "
|
||||
<< numObjectsCompiled - objTemp
|
||||
<< " StateSets" << std::endl;
|
||||
// remove the compiled statesets from the list.
|
||||
sslist.erase(sslist.begin(),itr);
|
||||
textures.erase(textures.begin(),itr);
|
||||
}
|
||||
|
||||
if (!dtc.second.empty() && (compileAll || ((elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame)))
|
||||
if (!dtc._drawables.empty() && (compileAll || ((elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame)))
|
||||
{
|
||||
// we have Drawable's to compile
|
||||
//OSG_INFO<<"Compiling drawables"<<std::endl;
|
||||
DrawableList& dwlist = dtc.second;
|
||||
DrawableList::iterator itr=dwlist.begin();
|
||||
typedef osgUtil::IncrementalCompileOperation::CompileData::Drawables Drawables;
|
||||
Drawables& dwlist = dtc._drawables;
|
||||
Drawables::iterator itr = dwlist.begin();
|
||||
unsigned int objTemp = numObjectsCompiled;
|
||||
for(;
|
||||
itr!=dwlist.end() && (compileAll || ((elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame));
|
||||
@@ -2186,12 +2233,11 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime, b
|
||||
itr!=dcm.end() && allCompiled;
|
||||
++itr)
|
||||
{
|
||||
if (!(itr->second.first.empty())) allCompiled=false;
|
||||
if (!(itr->second.second.empty())) allCompiled=false;
|
||||
if (!(itr->second.empty())) allCompiled=false;
|
||||
}
|
||||
|
||||
//if (numObjectsCompiled > 0)
|
||||
//OSG_NOTICE<< _frameNumber << "compiled " << numObjectsCompiled << " objects" << std::endl;
|
||||
if (numObjectsCompiled > 0)
|
||||
OSG_NOTICE<< "Framenumber "<<_frameNumber << ": compiled " << numObjectsCompiled << " objects" << std::endl;
|
||||
|
||||
if (allCompiled)
|
||||
{
|
||||
|
||||
@@ -108,7 +108,7 @@ void SharedStateManager::apply(osg::Geode& geode)
|
||||
}
|
||||
}
|
||||
|
||||
bool SharedStateManager::isShared(osg::StateSet *ss)
|
||||
bool SharedStateManager::isShared(osg::StateSet* ss)
|
||||
{
|
||||
if (shareStateSet(ss->getDataVariance()))
|
||||
{
|
||||
@@ -119,6 +119,17 @@ bool SharedStateManager::isShared(osg::StateSet *ss)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SharedStateManager::isShared(osg::Texture* texture)
|
||||
{
|
||||
if (shareTexture(texture->getDataVariance()))
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_listMutex);
|
||||
return find(texture) != 0;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// SharedStateManager::find
|
||||
//----------------------------------------------------------------
|
||||
|
||||
@@ -1601,6 +1601,11 @@ void View::assignSceneDataToCameras()
|
||||
{
|
||||
// OSG_NOTICE<<"View::assignSceneDataToCameras()"<<std::endl;
|
||||
|
||||
if (_scene.valid() && _scene->getDatabasePager() && getViewerBase())
|
||||
{
|
||||
_scene->getDatabasePager()->setIncrementalCompileOperation(getViewerBase()->getIncrementalCompileOperation());
|
||||
}
|
||||
|
||||
osg::Node* sceneData = _scene.valid() ? _scene->getSceneData() : 0;
|
||||
|
||||
if (_cameraManipulator.valid())
|
||||
|
||||
@@ -66,6 +66,11 @@ Viewer::Viewer(osg::ArgumentParser& arguments)
|
||||
//arguments.getApplicationUsage()->addCommandLineOption("--collar","");
|
||||
//arguments.getApplicationUsage()->addCommandLineOption("--im","");
|
||||
|
||||
if (arguments.read("--ico"))
|
||||
{
|
||||
setIncrementalCompileOperation(new osgUtil::IncrementalCompileOperation());
|
||||
}
|
||||
|
||||
std::string filename;
|
||||
bool readConfig = false;
|
||||
while (arguments.read("-c",filename))
|
||||
|
||||
@@ -563,6 +563,17 @@ void ViewerBase::setIncrementalCompileOperation(osgUtil::IncrementalCompileOpera
|
||||
// assign new operation
|
||||
_incrementalCompileOperation = ico;
|
||||
|
||||
Scenes scenes;
|
||||
getScenes(scenes,false);
|
||||
for(Scenes::iterator itr = scenes.begin();
|
||||
itr != scenes.end();
|
||||
++itr)
|
||||
{
|
||||
osgDB::DatabasePager* dp = (*itr)->getDatabasePager();
|
||||
dp->setIncrementalCompileOperation(ico);
|
||||
}
|
||||
|
||||
|
||||
if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user