Added ability to compile OpenGL objects via pbuffers in the DatabasePager/Viewer
This commit is contained in:
parent
1d78ea2983
commit
1b3468413d
@ -219,12 +219,23 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
}
|
||||
|
||||
|
||||
/** Add a graphics context that should be used to compile/delete OpenGL objects.*/
|
||||
void addCompileGraphicsContext(osg::GraphicsContext* gc);
|
||||
|
||||
/** Removed a graphics context that should be used to compile/delete OpenGL objects.*/
|
||||
void removeCompileGraphicsContext(osg::GraphicsContext* gc);
|
||||
|
||||
|
||||
/** Turn the compilation of rendering objects for specfied graphics context on (true) or off(false). */
|
||||
void setCompileGLObjectsForContextID(unsigned int contextID, bool on);
|
||||
|
||||
/** Get whether the compilation of rendering objects for specfied graphics context on (true) or off(false). */
|
||||
bool getCompileGLObjectsForContextID(unsigned int contextID);
|
||||
|
||||
|
||||
/** Rerturn true if an external draw thread should call compileGLObjects(..) or not.*/
|
||||
bool requiresExternalCompileGLObjects(unsigned int contextID) const;
|
||||
|
||||
/** Return true if there are pending compile operations that are required.
|
||||
* If requiresCompileGLObjects() return true the application should call compileGLObjects() .*/
|
||||
bool requiresCompileGLObjects() const;
|
||||
@ -234,6 +245,11 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
* Note, must only be called from a valid graphics context. */
|
||||
virtual void compileGLObjects(osg::State& state,double& availableTime);
|
||||
|
||||
/** Compile the rendering objects (display lists,texture objects, VBO's) on loaded subgraph.
|
||||
* note, should only be called from the draw thread.
|
||||
* Note, must only be called from a valid graphics context. */
|
||||
virtual void compileAllGLObjects(osg::State& state);
|
||||
|
||||
/** Report how many items are in the _fileRequestList queue */
|
||||
unsigned int getFileRequestListSize() const { return _fileRequestList.size(); }
|
||||
|
||||
@ -241,12 +257,13 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
unsigned int getDataToCompileListSize() const { return _dataToCompileList.size(); }
|
||||
|
||||
|
||||
typedef std::list< osg::ref_ptr<osg::PagedLOD> > PagedLODList;
|
||||
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::map< unsigned int, DataToCompile > DataToCompileMap;
|
||||
typedef std::set<unsigned int> ActiveGraphicsContexts;
|
||||
typedef std::list< osg::ref_ptr<osg::PagedLOD> > PagedLODList;
|
||||
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::map< unsigned int, DataToCompile > DataToCompileMap;
|
||||
typedef std::set<unsigned int> ActiveGraphicsContexts;
|
||||
typedef std::vector< osg::observer_ptr<osg::GraphicsContext> > CompileGraphicsContexts;
|
||||
|
||||
protected:
|
||||
|
||||
@ -358,11 +375,21 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
|
||||
double _expiryDelay;
|
||||
|
||||
ActiveGraphicsContexts _activeGraphicsContexts;
|
||||
CompileGraphicsContexts _compileGraphicsContexts;
|
||||
|
||||
bool _doPreCompile;
|
||||
double _targetFrameRate;
|
||||
double _minimumTimeAvailableForGLCompileAndDeletePerFrame;
|
||||
unsigned int _maximumNumOfObjectsToCompilePerFrame;
|
||||
|
||||
struct CompileOperation : public osg::Operation
|
||||
{
|
||||
CompileOperation(DatabasePager* databasePager);
|
||||
|
||||
virtual void operator () (osg::Object* object);
|
||||
|
||||
osg::observer_ptr<DatabasePager> _databasePager;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -455,14 +455,14 @@ void DatabasePager::run()
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
|
||||
_databasePagerThreadBlock->block();
|
||||
|
||||
if (_useFrameBlock)
|
||||
{
|
||||
_frameBlock->block();
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// delete any children if required.
|
||||
//
|
||||
@ -508,7 +508,7 @@ void DatabasePager::run()
|
||||
|
||||
// load the data, note safe to write to the databaseRequest since once
|
||||
// it is created this thread is the only one to write to the _loadedModel pointer.
|
||||
// osg::notify(osg::NOTICE)<<"In DatabasePager thread readNodeFile("<<databaseRequest->_fileName<<")"<<std::endl;
|
||||
//osg::notify(osg::NOTICE)<<"In DatabasePager thread readNodeFile("<<databaseRequest->_fileName<<")"<<std::endl;
|
||||
//osg::Timer_t before = osg::Timer::instance()->tick();
|
||||
|
||||
|
||||
@ -567,32 +567,59 @@ void DatabasePager::run()
|
||||
}
|
||||
|
||||
// move the databaseRequest from the front of the fileRequest to the end of
|
||||
// dataLoad list.
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_fileRequestListMutex);
|
||||
|
||||
DatabaseRequestList::iterator itr = std::find(_fileRequestList.begin(),_fileRequestList.end(),databaseRequest);
|
||||
if (itr != _fileRequestList.end())
|
||||
// dataToCompile or dataToMerge lists.
|
||||
{
|
||||
if (databaseRequest->_loadedModel.valid())
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_fileRequestListMutex);
|
||||
|
||||
DatabaseRequestList::iterator itr = std::find(_fileRequestList.begin(),_fileRequestList.end(),databaseRequest);
|
||||
if (itr != _fileRequestList.end())
|
||||
{
|
||||
if (loadedObjectsNeedToBeCompiled)
|
||||
if (databaseRequest->_loadedModel.valid())
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
|
||||
_dataToCompileList.push_back(databaseRequest);
|
||||
}
|
||||
else
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToMergeListMutex);
|
||||
_dataToMergeList.push_back(databaseRequest);
|
||||
}
|
||||
}
|
||||
|
||||
_fileRequestList.erase(itr);
|
||||
if (loadedObjectsNeedToBeCompiled)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
|
||||
_dataToCompileList.push_back(databaseRequest);
|
||||
}
|
||||
else
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToMergeListMutex);
|
||||
_dataToMergeList.push_back(databaseRequest);
|
||||
}
|
||||
}
|
||||
|
||||
_fileRequestList.erase(itr);
|
||||
}
|
||||
|
||||
updateDatabasePagerThreadBlock();
|
||||
}
|
||||
|
||||
updateDatabasePagerThreadBlock();
|
||||
|
||||
|
||||
if (loadedObjectsNeedToBeCompiled && !_compileGraphicsContexts.empty())
|
||||
{
|
||||
for(CompileGraphicsContexts::iterator citr = _compileGraphicsContexts.begin();
|
||||
citr != _compileGraphicsContexts.end();
|
||||
++citr)
|
||||
{
|
||||
osg::GraphicsContext* gc = citr->get();
|
||||
if (gc)
|
||||
{
|
||||
osg::OperationsThread* gt = gc->getGraphicsThread();
|
||||
if (gt) gt->add(new DatabasePager::CompileOperation(this));
|
||||
else
|
||||
{
|
||||
gc->makeCurrent();
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"Database pager thread compiling"<<std::endl;
|
||||
|
||||
compileAllGLObjects(*(gc->getState()));
|
||||
|
||||
gc->releaseContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
// osg::notify(osg::NOTICE)<<"Done compiling in paging thread"<<std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -856,6 +883,37 @@ bool DatabasePager::requiresCompileGLObjects() const
|
||||
return !_dataToCompileList.empty();
|
||||
}
|
||||
|
||||
void DatabasePager::addCompileGraphicsContext(osg::GraphicsContext* gc)
|
||||
{
|
||||
for(CompileGraphicsContexts::iterator itr = _compileGraphicsContexts.begin();
|
||||
itr != _compileGraphicsContexts.end();
|
||||
++itr)
|
||||
{
|
||||
if (*itr == gc)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_compileGraphicsContexts.push_back(gc);
|
||||
|
||||
setCompileGLObjectsForContextID(gc->getState()->getContextID(),true);
|
||||
}
|
||||
|
||||
void DatabasePager::removeCompileGraphicsContext(osg::GraphicsContext* gc)
|
||||
{
|
||||
for(CompileGraphicsContexts::iterator itr = _compileGraphicsContexts.begin();
|
||||
itr != _compileGraphicsContexts.end();
|
||||
++itr)
|
||||
{
|
||||
if (*itr == gc)
|
||||
{
|
||||
_compileGraphicsContexts.erase(itr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DatabasePager::setCompileGLObjectsForContextID(unsigned int contextID, bool on)
|
||||
{
|
||||
if (on)
|
||||
@ -874,9 +932,48 @@ bool DatabasePager::getCompileGLObjectsForContextID(unsigned int contextID)
|
||||
}
|
||||
|
||||
|
||||
DatabasePager::CompileOperation::CompileOperation(osgDB::DatabasePager* databasePager):
|
||||
osg::Operation("DatabasePager::CompileOperation",false),
|
||||
_databasePager(databasePager)
|
||||
{
|
||||
}
|
||||
|
||||
void DatabasePager::CompileOperation::operator () (osg::Object* object)
|
||||
{
|
||||
osg::GraphicsContext* context = dynamic_cast<osg::GraphicsContext*>(object);
|
||||
if (!context) return;
|
||||
|
||||
// osg::notify(osg::NOTICE)<<"Background thread compiling"<<std::endl;
|
||||
if (_databasePager.valid()) _databasePager->compileAllGLObjects(*(context->getState()));
|
||||
|
||||
}
|
||||
|
||||
bool DatabasePager::requiresExternalCompileGLObjects(unsigned int contextID) const
|
||||
{
|
||||
if (_activeGraphicsContexts.count(contextID)==0) return false;
|
||||
|
||||
for(CompileGraphicsContexts::const_iterator citr = _compileGraphicsContexts.begin();
|
||||
citr != _compileGraphicsContexts.end();
|
||||
++citr)
|
||||
{
|
||||
const osg::GraphicsContext* gc = citr->get();
|
||||
if (gc && gc->getState()->getContextID()==contextID) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DatabasePager::compileAllGLObjects(osg::State& state)
|
||||
{
|
||||
double availableTime = DBL_MAX;
|
||||
compileGLObjects(state, availableTime);
|
||||
}
|
||||
|
||||
void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
{
|
||||
// osg::notify(osg::NOTICE)<<"DatabasePager::compileGLObjects "<<_frameNumber<<std::endl;
|
||||
// osg::notify(osg::NOTICE)<<"DatabasePager::compileGLObjects "<<_frameNumber<<std::endl;
|
||||
|
||||
bool compileAll = (availableTime==DBL_MAX);
|
||||
|
||||
osg::RenderInfo renderInfo;
|
||||
renderInfo.setState(&state);
|
||||
@ -935,7 +1032,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
|
||||
// while there are valid databaseRequest's in the to compile list and there is
|
||||
// sufficient time left compile each databaseRequest's stateset and drawables.
|
||||
while (databaseRequest.valid() && elapsedTime<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame)
|
||||
while (databaseRequest.valid() && (compileAll || (elapsedTime<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame)) )
|
||||
{
|
||||
DataToCompileMap& dcm = databaseRequest->_dataToCompileMap;
|
||||
DataToCompile& dtc = dcm[state.getContextID()];
|
||||
@ -973,14 +1070,14 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
sslist.erase(sslist.begin(),itr);
|
||||
}
|
||||
|
||||
if (!dtc.second.empty() && (elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame)
|
||||
if (!dtc.second.empty() && (compileAll || ((elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame)))
|
||||
{
|
||||
// we have Drawable's to compile
|
||||
//osg::notify(osg::INFO)<<"Compiling drawables"<<std::endl;
|
||||
DrawableList& dwlist = dtc.second;
|
||||
DrawableList::iterator itr=dwlist.begin();
|
||||
for(;
|
||||
itr!=dwlist.end() && (elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame;
|
||||
itr!=dwlist.end() && (compileAll || ((elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame));
|
||||
++itr)
|
||||
{
|
||||
//osg::notify(osg::INFO)<<" Compiling drawable "<<(*itr).get()<<std::endl;
|
||||
@ -1015,6 +1112,8 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
if (allCompiled)
|
||||
{
|
||||
// we've compile all of the current databaseRequest so we can now pop it off the
|
||||
// osg::notify(osg::NOTICE)<<"All compiled"<<std::endl;
|
||||
|
||||
// to compile list and place it on the merge list.
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
|
||||
|
||||
@ -1035,7 +1134,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
|
||||
}
|
||||
else
|
||||
{
|
||||
//osg::notify(osg::INFO)<<"Not all compiled"<<std::endl;
|
||||
// osg::notify(osg::NOTICE)<<"Not all compiled"<<std::endl;
|
||||
databaseRequest = 0;
|
||||
}
|
||||
|
||||
|
@ -580,12 +580,14 @@ struct CompositeViewerRenderingOperation : public osg::Operation
|
||||
_sceneView->cull();
|
||||
_sceneView->draw();
|
||||
|
||||
if (_databasePager.valid())
|
||||
double availableTime = 0.004; // 4 ms
|
||||
|
||||
if (_databasePager.valid() && _databasePager->requiresExternalCompileGLObjects(_sceneView->getState()->getContextID()))
|
||||
{
|
||||
double availableTime = 0.004; // 4 ms
|
||||
_databasePager->compileGLObjects(*(_sceneView->getState()), availableTime);
|
||||
_sceneView->flushDeletedGLObjects(availableTime);
|
||||
}
|
||||
|
||||
_sceneView->flushDeletedGLObjects(availableTime);
|
||||
}
|
||||
|
||||
osg::observer_ptr<osgUtil::SceneView> _sceneView;
|
||||
|
@ -198,9 +198,9 @@ struct ViewerRenderingOperation : public osg::Operation, public ViewerQuerySuppo
|
||||
_sceneView->draw();
|
||||
|
||||
double availableTime = 0.004; // 4 ms
|
||||
if (_databasePager.valid())
|
||||
if (_databasePager.valid() && _databasePager->requiresExternalCompileGLObjects(_sceneView->getState()->getContextID()))
|
||||
{
|
||||
_databasePager->compileGLObjects(*(_sceneView->getState()), availableTime);
|
||||
_databasePager->compileGLObjects(*(_sceneView->getState()), availableTime);
|
||||
}
|
||||
_sceneView->flushDeletedGLObjects(availableTime);
|
||||
|
||||
@ -422,7 +422,7 @@ struct ViewerDoubleBufferedRenderingOperation : public osg::Operation, public Vi
|
||||
sceneView->draw();
|
||||
|
||||
double availableTime = 0.004; // 4 ms
|
||||
if (_databasePager.valid())
|
||||
if (_databasePager.valid() && _databasePager->requiresExternalCompileGLObjects(sceneView->getState()->getContextID()))
|
||||
{
|
||||
_databasePager->compileGLObjects(*(sceneView->getState()), availableTime);
|
||||
}
|
||||
@ -511,7 +511,7 @@ struct ViewerDoubleBufferedRenderingOperation : public osg::Operation, public Vi
|
||||
sceneView->draw();
|
||||
|
||||
double availableTime = 0.004; // 4 ms
|
||||
if (_databasePager.valid())
|
||||
if (_databasePager.valid() && _databasePager->requiresExternalCompileGLObjects(sceneView->getState()->getContextID()))
|
||||
{
|
||||
_databasePager->compileGLObjects(*(sceneView->getState()), availableTime);
|
||||
}
|
||||
@ -1559,6 +1559,7 @@ void Viewer::setUpRenderingSupport()
|
||||
osg::GraphicsContext* gc = *gcitr;
|
||||
osg::GraphicsContext::Cameras& cameras = gc->getCameras();
|
||||
osg::State* state = gc->getState();
|
||||
|
||||
if (dp) dp->setCompileGLObjectsForContextID(state->getContextID(), true);
|
||||
|
||||
for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();
|
||||
|
Loading…
Reference in New Issue
Block a user