diff --git a/applications/osgviewer/osgviewer.cpp b/applications/osgviewer/osgviewer.cpp index 61a4583de..bc888df35 100644 --- a/applications/osgviewer/osgviewer.cpp +++ b/applications/osgviewer/osgviewer.cpp @@ -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; iaddCompileGraphicsContext(gc); } } diff --git a/examples/osgteapot/osgteapot.cpp b/examples/osgteapot/osgteapot.cpp index 8cf358ecc..112849cfe 100644 --- a/examples/osgteapot/osgteapot.cpp +++ b/examples/osgteapot/osgteapot.cpp @@ -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 } diff --git a/include/osg/GLObjects b/include/osg/GLObjects new file mode 100644 index 000000000..8ea6caa85 --- /dev/null +++ b/include/osg/GLObjects @@ -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 + +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 diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index 157b729ba..f60a89297 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -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; diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index 275ce3695..c898d9a8e 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -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 diff --git a/src/osg/GLObjects.cpp b/src/osg/GLObjects.cpp new file mode 100644 index 000000000..81f3452ec --- /dev/null +++ b/src/osg/GLObjects.cpp @@ -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 + +#include +#include +#include +#include +#include +#include +#include + +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); +} + diff --git a/src/osg/GraphicsContext.cpp b/src/osg/GraphicsContext.cpp index 29f3ed015..80173983b 100644 --- a/src/osg/GraphicsContext.cpp +++ b/src/osg/GraphicsContext.cpp @@ -280,7 +280,7 @@ void GraphicsContext::setCompileContext(unsigned int contextID, GraphicsContext* GraphicsContext* GraphicsContext::getCompileContext(unsigned int contextID) { - osg::notify(osg::NOTICE)<<"GraphicsContext::getCompileContext "< lock(s_contextIDMapMutex); return s_contextIDMap[contextID]._compileContext.get(); } diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index 08f30d5f4..f20cc40fc 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -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"<getState())); gc->releaseContext(); } } } + // osg::notify(osg::NOTICE)<<"Done compiling in paging thread"<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) diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index edb29e2dd..f136984ce 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -16,17 +16,14 @@ #include #include +#include #include #include -#include -#include #include #include #include #include #include -#include -#include #include @@ -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() diff --git a/src/osgViewer/GraphicsWindowCarbon.cpp b/src/osgViewer/GraphicsWindowCarbon.cpp index 615788717..02b078988 100644 --- a/src/osgViewer/GraphicsWindowCarbon.cpp +++ b/src/osgViewer/GraphicsWindowCarbon.cpp @@ -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); } }; diff --git a/src/osgViewer/GraphicsWindowWin32.cpp b/src/osgViewer/GraphicsWindowWin32.cpp index 0b5f2c84c..da7f5293e 100644 --- a/src/osgViewer/GraphicsWindowWin32.cpp +++ b/src/osgViewer/GraphicsWindowWin32.cpp @@ -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); } }; diff --git a/src/osgViewer/GraphicsWindowX11.cpp b/src/osgViewer/GraphicsWindowX11.cpp index 85f2faf47..b1dcd919c 100644 --- a/src/osgViewer/GraphicsWindowX11.cpp +++ b/src/osgViewer/GraphicsWindowX11.cpp @@ -19,6 +19,8 @@ #include #include +#include + #include #include @@ -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()"<setNumFramesToRetainObjects(0); + osg::Referenced::getDeleteHandler()->flushAll(); + } + osg::GraphicsContext::setWindowingSystemInterface(0); + } }; diff --git a/src/osgWrappers/osgDB/DatabasePager.cpp b/src/osgWrappers/osgDB/DatabasePager.cpp index 851fa9d2a..6c30bdb05 100644 --- a/src/osgWrappers/osgDB/DatabasePager.cpp +++ b/src/osgWrappers/osgDB/DatabasePager.cpp @@ -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,