Added ability to compile OpenGL objects via pbuffers in the DatabasePager/Viewer

This commit is contained in:
Robert Osfield 2007-06-22 14:48:18 +00:00
parent 1d78ea2983
commit 1b3468413d
4 changed files with 172 additions and 43 deletions

View File

@ -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). */ /** Turn the compilation of rendering objects for specfied graphics context on (true) or off(false). */
void setCompileGLObjectsForContextID(unsigned int contextID, bool on); void setCompileGLObjectsForContextID(unsigned int contextID, bool on);
/** Get whether the compilation of rendering objects for specfied graphics context on (true) or off(false). */ /** Get whether the compilation of rendering objects for specfied graphics context on (true) or off(false). */
bool getCompileGLObjectsForContextID(unsigned int contextID); 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. /** Return true if there are pending compile operations that are required.
* If requiresCompileGLObjects() return true the application should call compileGLObjects() .*/ * If requiresCompileGLObjects() return true the application should call compileGLObjects() .*/
bool requiresCompileGLObjects() const; 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. */ * Note, must only be called from a valid graphics context. */
virtual void compileGLObjects(osg::State& state,double& availableTime); 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 */ /** Report how many items are in the _fileRequestList queue */
unsigned int getFileRequestListSize() const { return _fileRequestList.size(); } unsigned int getFileRequestListSize() const { return _fileRequestList.size(); }
@ -247,6 +263,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
typedef std::pair<StateSetList,DrawableList> DataToCompile; typedef std::pair<StateSetList,DrawableList> DataToCompile;
typedef std::map< unsigned int, DataToCompile > DataToCompileMap; typedef std::map< unsigned int, DataToCompile > DataToCompileMap;
typedef std::set<unsigned int> ActiveGraphicsContexts; typedef std::set<unsigned int> ActiveGraphicsContexts;
typedef std::vector< osg::observer_ptr<osg::GraphicsContext> > CompileGraphicsContexts;
protected: protected:
@ -358,11 +375,21 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
double _expiryDelay; double _expiryDelay;
ActiveGraphicsContexts _activeGraphicsContexts; ActiveGraphicsContexts _activeGraphicsContexts;
CompileGraphicsContexts _compileGraphicsContexts;
bool _doPreCompile; bool _doPreCompile;
double _targetFrameRate; double _targetFrameRate;
double _minimumTimeAvailableForGLCompileAndDeletePerFrame; double _minimumTimeAvailableForGLCompileAndDeletePerFrame;
unsigned int _maximumNumOfObjectsToCompilePerFrame; unsigned int _maximumNumOfObjectsToCompilePerFrame;
struct CompileOperation : public osg::Operation
{
CompileOperation(DatabasePager* databasePager);
virtual void operator () (osg::Object* object);
osg::observer_ptr<DatabasePager> _databasePager;
};
}; };
} }

View File

@ -567,8 +567,8 @@ void DatabasePager::run()
} }
// move the databaseRequest from the front of the fileRequest to the end of // move the databaseRequest from the front of the fileRequest to the end of
// dataLoad list. // dataToCompile or dataToMerge lists.
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_fileRequestListMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_fileRequestListMutex);
DatabaseRequestList::iterator itr = std::find(_fileRequestList.begin(),_fileRequestList.end(),databaseRequest); DatabaseRequestList::iterator itr = std::find(_fileRequestList.begin(),_fileRequestList.end(),databaseRequest);
@ -592,6 +592,33 @@ void DatabasePager::run()
} }
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 else
@ -856,6 +883,37 @@ bool DatabasePager::requiresCompileGLObjects() const
return !_dataToCompileList.empty(); 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) void DatabasePager::setCompileGLObjectsForContextID(unsigned int contextID, bool on)
{ {
if (on) if (on)
@ -874,10 +932,49 @@ 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) 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; osg::RenderInfo renderInfo;
renderInfo.setState(&state); 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 // while there are valid databaseRequest's in the to compile list and there is
// sufficient time left compile each databaseRequest's stateset and drawables. // 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; DataToCompileMap& dcm = databaseRequest->_dataToCompileMap;
DataToCompile& dtc = dcm[state.getContextID()]; DataToCompile& dtc = dcm[state.getContextID()];
@ -973,14 +1070,14 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
sslist.erase(sslist.begin(),itr); 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 // we have Drawable's to compile
//osg::notify(osg::INFO)<<"Compiling drawables"<<std::endl; //osg::notify(osg::INFO)<<"Compiling drawables"<<std::endl;
DrawableList& dwlist = dtc.second; DrawableList& dwlist = dtc.second;
DrawableList::iterator itr=dwlist.begin(); DrawableList::iterator itr=dwlist.begin();
for(; for(;
itr!=dwlist.end() && (elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame; itr!=dwlist.end() && (compileAll || ((elapsedTime+estimatedDrawableDuration)<availableTime && numObjectsCompiled<_maximumNumOfObjectsToCompilePerFrame));
++itr) ++itr)
{ {
//osg::notify(osg::INFO)<<" Compiling drawable "<<(*itr).get()<<std::endl; //osg::notify(osg::INFO)<<" Compiling drawable "<<(*itr).get()<<std::endl;
@ -1015,6 +1112,8 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
if (allCompiled) if (allCompiled)
{ {
// we've compile all of the current databaseRequest so we can now pop it off the // 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. // to compile list and place it on the merge list.
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_dataToCompileListMutex);
@ -1035,7 +1134,7 @@ void DatabasePager::compileGLObjects(osg::State& state, double& availableTime)
} }
else else
{ {
//osg::notify(osg::INFO)<<"Not all compiled"<<std::endl; // osg::notify(osg::NOTICE)<<"Not all compiled"<<std::endl;
databaseRequest = 0; databaseRequest = 0;
} }

View File

@ -580,12 +580,14 @@ struct CompositeViewerRenderingOperation : public osg::Operation
_sceneView->cull(); _sceneView->cull();
_sceneView->draw(); _sceneView->draw();
if (_databasePager.valid())
{
double availableTime = 0.004; // 4 ms double availableTime = 0.004; // 4 ms
if (_databasePager.valid() && _databasePager->requiresExternalCompileGLObjects(_sceneView->getState()->getContextID()))
{
_databasePager->compileGLObjects(*(_sceneView->getState()), availableTime); _databasePager->compileGLObjects(*(_sceneView->getState()), availableTime);
_sceneView->flushDeletedGLObjects(availableTime);
} }
_sceneView->flushDeletedGLObjects(availableTime);
} }
osg::observer_ptr<osgUtil::SceneView> _sceneView; osg::observer_ptr<osgUtil::SceneView> _sceneView;

View File

@ -198,7 +198,7 @@ struct ViewerRenderingOperation : public osg::Operation, public ViewerQuerySuppo
_sceneView->draw(); _sceneView->draw();
double availableTime = 0.004; // 4 ms 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);
} }
@ -422,7 +422,7 @@ struct ViewerDoubleBufferedRenderingOperation : public osg::Operation, public Vi
sceneView->draw(); sceneView->draw();
double availableTime = 0.004; // 4 ms 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);
} }
@ -511,7 +511,7 @@ struct ViewerDoubleBufferedRenderingOperation : public osg::Operation, public Vi
sceneView->draw(); sceneView->draw();
double availableTime = 0.004; // 4 ms 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);
} }
@ -1559,6 +1559,7 @@ void Viewer::setUpRenderingSupport()
osg::GraphicsContext* gc = *gcitr; osg::GraphicsContext* gc = *gcitr;
osg::GraphicsContext::Cameras& cameras = gc->getCameras(); osg::GraphicsContext::Cameras& cameras = gc->getCameras();
osg::State* state = gc->getState(); osg::State* state = gc->getState();
if (dp) dp->setCompileGLObjectsForContextID(state->getContextID(), true); if (dp) dp->setCompileGLObjectsForContextID(state->getContextID(), true);
for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin(); for(osg::GraphicsContext::Cameras::iterator citr = cameras.begin();