Added include/osg/GLObjects + .cpp which provide osg::flush*DeletedGLObjects() methods.

Added and cleaned up DeleteHandler calls in osgViewer to help avoid crashes on exit.

Changed DatabasePager across to dynamically checcking osg::getCompileContext(..)

Updated wrappers.
This commit is contained in:
Robert Osfield 2007-07-06 13:08:51 +00:00
parent a484b95d3c
commit 6931ae4878
13 changed files with 147 additions and 108 deletions

View File

@ -157,8 +157,6 @@ int main(int argc, char** argv)
int numProcessors = OpenThreads::GetNumberOfProcessors();
int processNum = 0;
osgDB::DatabasePager* dp = viewer.getScene()->getDatabasePager();
for(unsigned int i=0; i<osg::GraphicsContext::getMaxContextID(); ++i)
{
osg::GraphicsContext* gc = osg::GraphicsContext::getOrCreateCompileContext(i);
@ -171,8 +169,6 @@ int main(int argc, char** argv)
++processNum;
}
dp->addCompileGraphicsContext(gc);
}
}

View File

@ -332,7 +332,7 @@ osg::Geode* createTeapot()
int main(int , char **)
{
#if 1
#if 1
// create viewer on heap as a test, this looks to be causing problems
// on init on some platforms, and seg fault on exit when multi-threading on linux.
@ -344,7 +344,6 @@ int main(int , char **)
// add model to viewer.
viewer->setSceneData( createTeapot() );
// create the windows and run the threads.
return viewer->run();
#else
@ -357,7 +356,6 @@ int main(int , char **)
// create the windows and run the threads.
return viewer.run();
#endif
}

32
include/osg/GLObjects Normal file
View File

@ -0,0 +1,32 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSG_GLOBJECTS
#define OSG_GLOBJECTS 1
#include <osg/Export>
namespace osg {
/** Flush all deleted OpenGL objects within the specified availableTime.
* Note, must be called from a thread which has current the graphics context associated with contextID. */
extern OSG_EXPORT void flushDeletedGLObjects(unsigned int contextID, double currentTime, double& availableTime);
/** Flush all deleted OpenGL objects.
* Note, must be called from a thread which has current the graphics context associated with contextID. */
extern OSG_EXPORT void flushAllDeletedGLObjects(unsigned int contextID);
}
#endif

View File

@ -218,21 +218,12 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
addLoadedDataToSceneGraph(currentFrameTime);
}
/** 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;
@ -375,7 +366,7 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl
double _expiryDelay;
ActiveGraphicsContexts _activeGraphicsContexts;
CompileGraphicsContexts _compileGraphicsContexts;
// CompileGraphicsContexts _compileGraphicsContexts;
bool _doPreCompile;
double _targetFrameRate;

View File

@ -59,6 +59,7 @@ SET(LIB_PUBLIC_HEADERS
${HEADER_PATH}/GL
${HEADER_PATH}/GL2Extensions
${HEADER_PATH}/GLExtensions
${HEADER_PATH}/GLObjects
${HEADER_PATH}/GLU
${HEADER_PATH}/Geode
${HEADER_PATH}/Geometry
@ -212,6 +213,7 @@ ADD_LIBRARY(${LIB_NAME}
FrameStamp.cpp
FrontFace.cpp
GLExtensions.cpp
GLObjects.cpp
Geode.cpp
Geometry.cpp
GraphicsContext.cpp

52
src/osg/GLObjects.cpp Normal file
View File

@ -0,0 +1,52 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osg/GLObjects>
#include <osg/Texture>
#include <osg/VertexProgram>
#include <osg/FragmentProgram>
#include <osg/Shader>
#include <osg/BufferObject>
#include <osg/FrameBufferObject>
#include <osg/Drawable>
void osg::flushDeletedGLObjects(unsigned int contextID, double currentTime, double& availableTime)
{
osg::FrameBufferObject::flushDeletedFrameBufferObjects(contextID,currentTime,availableTime);
osg::RenderBuffer::flushDeletedRenderBuffers(contextID,currentTime,availableTime);
osg::Texture::flushDeletedTextureObjects(contextID,currentTime,availableTime);
osg::Drawable::flushDeletedDisplayLists(contextID,availableTime);
osg::Drawable::flushDeletedVertexBufferObjects(contextID,currentTime,availableTime);
osg::VertexProgram::flushDeletedVertexProgramObjects(contextID,currentTime,availableTime);
osg::FragmentProgram::flushDeletedFragmentProgramObjects(contextID,currentTime,availableTime);
osg::Program::flushDeletedGlPrograms(contextID,currentTime,availableTime);
osg::Shader::flushDeletedGlShaders(contextID,currentTime,availableTime);
osg::BufferObject::flushDeletedBufferObjects(contextID,currentTime,availableTime);
}
void osg::flushAllDeletedGLObjects(unsigned int contextID)
{
double currentTime = DBL_MAX;
double availableTime = DBL_MAX;
osg::FrameBufferObject::flushDeletedFrameBufferObjects(contextID,currentTime,availableTime);
osg::RenderBuffer::flushDeletedRenderBuffers(contextID,currentTime,availableTime);
osg::Texture::flushAllDeletedTextureObjects(contextID);
osg::Drawable::flushAllDeletedDisplayLists(contextID);
osg::Drawable::flushDeletedVertexBufferObjects(contextID,currentTime,availableTime);
osg::VertexProgram::flushDeletedVertexProgramObjects(contextID,currentTime,availableTime);
osg::FragmentProgram::flushDeletedFragmentProgramObjects(contextID,currentTime,availableTime);
osg::Program::flushDeletedGlPrograms(contextID,currentTime,availableTime);
osg::Shader::flushDeletedGlShaders(contextID,currentTime,availableTime);
osg::BufferObject::flushDeletedBufferObjects(contextID,currentTime,availableTime);
}

View File

@ -280,7 +280,7 @@ void GraphicsContext::setCompileContext(unsigned int contextID, GraphicsContext*
GraphicsContext* GraphicsContext::getCompileContext(unsigned int contextID)
{
osg::notify(osg::NOTICE)<<"GraphicsContext::getCompileContext "<<contextID<<std::endl;
//osg::notify(osg::NOTICE)<<"GraphicsContext::getCompileContext "<<contextID<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
return s_contextIDMap[contextID]._compileContext.get();
}

View File

@ -292,7 +292,6 @@ void DatabasePager::requestNodeFile(const std::string& fileName,osg::Group* grou
setSchedulePriority(_threadPriorityDuringFrame);
startThread();
}
}
}
@ -594,29 +593,31 @@ void DatabasePager::run()
updateDatabasePagerThreadBlock();
}
if (loadedObjectsNeedToBeCompiled && !_compileGraphicsContexts.empty())
if (loadedObjectsNeedToBeCompiled)
{
for(CompileGraphicsContexts::iterator citr = _compileGraphicsContexts.begin();
citr != _compileGraphicsContexts.end();
++citr)
for(ActiveGraphicsContexts::iterator itr = _activeGraphicsContexts.begin();
itr != _activeGraphicsContexts.end();
++itr)
{
osg::GraphicsContext* gc = citr->get();
osg::GraphicsContext* gc = osg::GraphicsContext::getCompileContext(*itr);
if (gc)
{
osg::OperationsThread* gt = gc->getGraphicsThread();
if (gt) gt->add(new DatabasePager::CompileOperation(this));
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;
}
@ -883,37 +884,6 @@ 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)
@ -951,16 +921,8 @@ void DatabasePager::CompileOperation::operator () (osg::Object* object)
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;
return osg::GraphicsContext::getCompileContext(contextID)==0;
}
void DatabasePager::compileAllGLObjects(osg::State& state)

View File

@ -16,17 +16,14 @@
#include <osg/Timer>
#include <osg/GLExtensions>
#include <osg/GLObjects>
#include <osg/Notify>
#include <osg/Texture>
#include <osg/VertexProgram>
#include <osg/FragmentProgram>
#include <osg/AlphaFunc>
#include <osg/TexEnv>
#include <osg/ColorMatrix>
#include <osg/LightModel>
#include <osg/CollectOccludersVisitor>
#include <osg/Shader>
#include <osg/BufferObject>
#include <osg/GLU>
@ -835,19 +832,7 @@ void SceneView::flushAllDeletedGLObjects()
_requiresFlush = false;
double availableTime = 100.0f;
double currentTime = state->getFrameStamp()?state->getFrameStamp()->getReferenceTime():0.0;
osg::FrameBufferObject::flushDeletedFrameBufferObjects(state->getContextID(),currentTime,availableTime);
osg::RenderBuffer::flushDeletedRenderBuffers(state->getContextID(),currentTime,availableTime);
osg::Texture::flushAllDeletedTextureObjects(state->getContextID());
osg::Drawable::flushAllDeletedDisplayLists(state->getContextID());
osg::Drawable::flushDeletedVertexBufferObjects(state->getContextID(),currentTime,availableTime);
osg::VertexProgram::flushDeletedVertexProgramObjects(state->getContextID(),currentTime,availableTime);
osg::FragmentProgram::flushDeletedFragmentProgramObjects(state->getContextID(),currentTime,availableTime);
osg::Program::flushDeletedGlPrograms(state->getContextID(),currentTime,availableTime);
osg::Shader::flushDeletedGlShaders(state->getContextID(),currentTime,availableTime);
osg::BufferObject::flushDeletedBufferObjects(state->getContextID(),currentTime,availableTime);
osg::flushAllDeletedGLObjects(getState()->getContextID());
}
void SceneView::flushDeletedGLObjects(double& availableTime)
@ -858,16 +843,7 @@ void SceneView::flushDeletedGLObjects(double& availableTime)
double currentTime = state->getFrameStamp()?state->getFrameStamp()->getReferenceTime():0.0;
osg::FrameBufferObject::flushDeletedFrameBufferObjects(state->getContextID(),currentTime,availableTime);
osg::RenderBuffer::flushDeletedRenderBuffers(state->getContextID(),currentTime,availableTime);
osg::Texture::flushDeletedTextureObjects(state->getContextID(),currentTime,availableTime);
osg::Drawable::flushDeletedDisplayLists(state->getContextID(),availableTime);
osg::Drawable::flushDeletedVertexBufferObjects(state->getContextID(),currentTime,availableTime);
osg::VertexProgram::flushDeletedVertexProgramObjects(state->getContextID(),currentTime,availableTime);
osg::FragmentProgram::flushDeletedFragmentProgramObjects(state->getContextID(),currentTime,availableTime);
osg::Program::flushDeletedGlPrograms(state->getContextID(),currentTime,availableTime);
osg::Shader::flushDeletedGlShaders(state->getContextID(),currentTime,availableTime);
osg::BufferObject::flushDeletedBufferObjects(state->getContextID(),currentTime,availableTime);
osg::flushDeletedGLObjects(getState()->getContextID(), currentTime, availableTime);
}
void SceneView::draw()

View File

@ -343,9 +343,15 @@ struct OSXCarbonWindowingSystemInterface : public osg::GraphicsContext::Windowin
}
/** dtor */
~OSXCarbonWindowingSystemInterface() {
if (_displayIds)
delete[] _displayIds;
~OSXCarbonWindowingSystemInterface()
{
if (osg::Referenced::getDeleteHandler())
{
osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
osg::Referenced::getDeleteHandler()->flushAll();
}
if (_displayIds) delete[] _displayIds;
_displayIds = NULL;
}
@ -1134,6 +1140,12 @@ struct RegisterWindowingSystemInterfaceProxy
~RegisterWindowingSystemInterfaceProxy()
{
if (osg::Referenced::getDeleteHandler())
{
osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
osg::Referenced::getDeleteHandler()->flushAll();
}
osg::GraphicsContext::setWindowingSystemInterface(0);
}
};

View File

@ -567,6 +567,12 @@ Win32WindowingSystem::Win32WindowingSystem()
Win32WindowingSystem::~Win32WindowingSystem()
{
if (osg::Referenced::getDeleteHandler())
{
osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
osg::Referenced::getDeleteHandler()->flushAll();
}
unregisterWindowClasses();
}
@ -2184,6 +2190,12 @@ struct RegisterWindowingSystemInterfaceProxy
~RegisterWindowingSystemInterfaceProxy()
{
if (osg::Referenced::getDeleteHandler())
{
osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
osg::Referenced::getDeleteHandler()->flushAll();
}
osg::GraphicsContext::setWindowingSystemInterface(0);
}
};

View File

@ -19,6 +19,8 @@
#include <osgViewer/api/X11/GraphicsWindowX11>
#include <osgViewer/api/X11/PixelBufferX11>
#include <osg/DeleteHandler>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@ -1178,6 +1180,12 @@ struct X11WindowingSystemInterface : public osg::GraphicsContext::WindowingSyste
~X11WindowingSystemInterface()
{
if (osg::Referenced::getDeleteHandler())
{
osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
osg::Referenced::getDeleteHandler()->flushAll();
}
//osg::notify(osg::NOTICE)<<"~X11WindowingSystemInterface()"<<std::endl;
XSetErrorHandler(0);
}
@ -1251,7 +1259,15 @@ struct RegisterWindowingSystemInterfaceProxy
~RegisterWindowingSystemInterfaceProxy()
{
osg::notify(osg::INFO)<<"~RegisterWindowingSystemInterfaceProxy()"<<std::endl;
if (osg::Referenced::getDeleteHandler())
{
osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
osg::Referenced::getDeleteHandler()->flushAll();
}
osg::GraphicsContext::setWindowingSystemInterface(0);
}
};

View File

@ -259,16 +259,6 @@ BEGIN_OBJECT_REFLECTOR(osgDB::DatabasePager)
__void__updateSceneGraph__double,
"Merge the changes to the scene graph by calling calling removeExpiredSubgraphs then addLoadedDataToSceneGraph. ",
"Note, must only be called from single thread update phase. ");
I_Method1(void, addCompileGraphicsContext, IN, osg::GraphicsContext *, gc,
Properties::NON_VIRTUAL,
__void__addCompileGraphicsContext__osg_GraphicsContext_P1,
"Add a graphics context that should be used to compile/delete OpenGL objects. ",
"");
I_Method1(void, removeCompileGraphicsContext, IN, osg::GraphicsContext *, gc,
Properties::NON_VIRTUAL,
__void__removeCompileGraphicsContext__osg_GraphicsContext_P1,
"Removed a graphics context that should be used to compile/delete OpenGL objects. ",
"");
I_Method2(void, setCompileGLObjectsForContextID, IN, unsigned int, contextID, IN, bool, on,
Properties::NON_VIRTUAL,
__void__setCompileGLObjectsForContextID__unsigned_int__bool,