Added support for managing a CompileContext. Rearranged the DeleteHandler::flushAll call.

This commit is contained in:
Robert Osfield
2007-07-05 18:33:20 +00:00
parent 7a98691704
commit d1fa520349
8 changed files with 255 additions and 56 deletions

View File

@@ -150,7 +150,7 @@ int main(int argc, char** argv)
viewer.setSceneData( loadedModel.get() );
viewer.realize();
if (createBackgroundContextForCompiling)
{
@@ -158,37 +158,12 @@ int main(int argc, char** argv)
int processNum = 0;
osgDB::DatabasePager* dp = viewer.getScene()->getDatabasePager();
typedef std::vector< osg::ref_ptr<osg::GraphicsContext> > CompileContexts;
CompileContexts compileContexts;
osgViewer::Viewer::Windows windows;
viewer.getWindows(windows);
for(osgViewer::Viewer::Windows::iterator itr = windows.begin();
itr != windows.end();
++itr)
for(unsigned int i=0; i<osg::GraphicsContext::getMaxContextID(); ++i)
{
const osg::GraphicsContext::Traits* src_traits = (*itr)->getTraits();
osg::GraphicsContext* gc = osg::GraphicsContext::getOrCreateCompileContext(i);
osg::GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
traits->screenNum = src_traits->screenNum;
traits->displayNum = src_traits->displayNum;
traits->hostName = src_traits->hostName;
traits->width = 100;
traits->height = 100;
traits->red = src_traits->red;
traits->green = src_traits->green;
traits->blue = src_traits->blue;
traits->alpha = src_traits->alpha;
traits->depth = src_traits->depth;
traits->sharedContext = (*itr);
traits->pbuffer = true;
osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits);
gc->realize();
if (createBackgroundThreadsForCompiling)
if (gc && createBackgroundThreadsForCompiling)
{
gc->createGraphicsThread();
gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors);
@@ -198,11 +173,9 @@ int main(int argc, char** argv)
}
dp->addCompileGraphicsContext(gc);
compileContexts.push_back(gc);
}
}
return viewer.run();
viewer.run();
}

View File

@@ -37,7 +37,7 @@ class OSG_EXPORT DeleteHandler
DeleteHandler(int numberOfFramesToRetainObjects=0);
virtual ~DeleteHandler() { flushAll(); }
virtual ~DeleteHandler();
/** Set the number of frames to retain objects that are have been requested for deletion.
* When set to zero objects are deleted immediately, by set to 1 there are kept around for an extra frame etc.

View File

@@ -165,12 +165,32 @@ class OSG_EXPORT GraphicsContext : public Object
* Automatically increments the usage count of the contextID to 1.*/
static unsigned int createNewContextID();
/** Get the current max ContextID.*/
static unsigned int getMaxContextID();
/** Increment the usage count associate with a contextID. The usage count speficies how many graphics contexts a specific contextID is shared between.*/
static void incrementContextIDUsageCount(unsigned int contextID);
/** Decrement the usage count associate with a contextID. Once the contextID goes to 0 the contextID is then free to be reused.*/
static void decrementContextIDUsageCount(unsigned int contextID);
typedef std::vector<GraphicsContext*> GraphicsContexts;
/** Get all the registered graphics contexts.*/
static GraphicsContexts getAllRegisteredGraphicsContexts();
/** Get all the registered graphics contexts associated with a specific contextID.*/
static GraphicsContexts getRegisteredGraphicsContexts(unsigned int contextID);
/** Get the GraphicsContext for doing background compilation for GraphicsContexts associated with specified contextID.*/
static void setCompileContext(unsigned int contextID, GraphicsContext* gc);
/** Get existing or create a new GraphicsContext to do background compilation for GraphicsContexts associated with specified contextID.*/
static GraphicsContext* getOrCreateCompileContext(unsigned int contextID);
/** Get the GraphicsContext for doing background compilation for GraphicsContexts associated with specified contextID.*/
static GraphicsContext* getCompileContext(unsigned int contextID);
public:
/** Add operation to end of OperationQueue.*/
@@ -376,6 +396,13 @@ class OSG_EXPORT GraphicsContext : public Object
virtual Object* cloneType() const { return 0; }
virtual Object* clone(const CopyOp&) const { return 0; }
/** Register a GraphicsContext.*/
static void registerGraphicsContext(GraphicsContext* gc);
/** Unregister a GraphicsContext.*/
static void unregisterGraphicsContext(GraphicsContext* gc);
void addCamera(osg::Camera* camera);
void removeCamera(osg::Camera* camera);

View File

@@ -67,6 +67,11 @@ DeleteHandler::DeleteHandler(int numberOfFramesToRetainObjects):
{
}
DeleteHandler::~DeleteHandler()
{
// flushAll();
}
void DeleteHandler::flush()
{
typedef std::list<const osg::Referenced*> DeletionList;
@@ -105,12 +110,37 @@ void DeleteHandler::flush()
void DeleteHandler::flushAll()
{
int temp = _numFramesToRetainObjects;
int temp_numFramesToRetainObjects = _numFramesToRetainObjects;
_numFramesToRetainObjects = 0;
flush();
typedef std::list<const osg::Referenced*> DeletionList;
DeletionList deletionList;
_numFramesToRetainObjects = temp;
{
// gather all the objects to delete whilst holding the mutex to the _objectsToDelete
// list, but delete the objects outside this scoped lock so that if any objects deleted
// unref their children then no deadlock happens.
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
ObjectsToDeleteList::iterator itr;
for(itr = _objectsToDelete.begin();
itr != _objectsToDelete.end();
++itr)
{
deletionList.push_back(itr->second);
itr->second = 0;
}
_objectsToDelete.erase( _objectsToDelete.begin(), _objectsToDelete.end());
}
for(DeletionList::iterator ditr = deletionList.begin();
ditr != deletionList.end();
++ditr)
{
doDelete(*ditr);
}
_numFramesToRetainObjects = temp_numFramesToRetainObjects;
}
void DeleteHandler::requestDelete(const osg::Referenced* object)

View File

@@ -22,6 +22,8 @@
#include <osg/FragmentProgram>
#include <osg/VertexProgram>
#include <OpenThreads/ReentrantMutex>
#include <osg/Notify>
#include <map>
@@ -29,6 +31,11 @@
using namespace osg;
/////////////////////////////////////////////////////////////////////////////
//
// GraphicsContext static method implementations
//
static ref_ptr<GraphicsContext::WindowingSystemInterface> s_WindowingSystemInterface;
void GraphicsContext::setWindowingSystemInterface(WindowingSystemInterface* callback)
@@ -60,9 +67,41 @@ std::string GraphicsContext::ScreenIdentifier::displayName() const
}
typedef std::map<unsigned int, unsigned int> ContextIDMap;
class ContextData
{
public:
ContextData():
_numContexts(0) {}
unsigned int _numContexts;
void incrementUsageCount() { ++_numContexts; }
void decrementUsageCount()
{
--_numContexts;
osg::notify(osg::INFO)<<"decrementUsageCount()"<<_numContexts<<std::endl;
if (_numContexts <= 1 && _compileContext.valid())
{
osg::notify(osg::INFO)<<"resetting compileContext "<<_compileContext.get()<<" refCount "<<_compileContext->referenceCount()<<std::endl;
GraphicsContext* gc = _compileContext.get();
_compileContext = 0;
}
}
osg::ref_ptr<osg::GraphicsContext> _compileContext;
};
typedef std::map<unsigned int, ContextData> ContextIDMap;
static ContextIDMap s_contextIDMap;
static OpenThreads::Mutex s_contextIDMapMutex;
static OpenThreads::ReentrantMutex s_contextIDMapMutex;
static GraphicsContext::GraphicsContexts s_registeredContexts;
unsigned int GraphicsContext::createNewContextID()
{
@@ -73,11 +112,11 @@ unsigned int GraphicsContext::createNewContextID()
itr != s_contextIDMap.end();
++itr)
{
if (itr->second == 0)
if (itr->second._numContexts == 0)
{
// reuse contextID;
itr->second = 1;
itr->second._numContexts = 1;
osg::notify(osg::INFO)<<"GraphicsContext::createNewContextID() reusing contextID="<<itr->first<<std::endl;
@@ -86,7 +125,7 @@ unsigned int GraphicsContext::createNewContextID()
}
unsigned int contextID = s_contextIDMap.size();
s_contextIDMap[contextID] = 1;
s_contextIDMap[contextID]._numContexts = 1;
osg::notify(osg::INFO)<<"GraphicsContext::createNewContextID() creating contextID="<<contextID<<std::endl;
@@ -104,35 +143,152 @@ unsigned int GraphicsContext::createNewContextID()
return contextID;
}
unsigned int GraphicsContext::getMaxContextID()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
return s_contextIDMap.size();
}
void GraphicsContext::incrementContextIDUsageCount(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
osg::notify(osg::INFO)<<"GraphicsContext::incrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]<<std::endl;
osg::notify(osg::INFO)<<"GraphicsContext::incrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]._numContexts<<std::endl;
++s_contextIDMap[contextID];
s_contextIDMap[contextID].incrementUsageCount();
}
void GraphicsContext::decrementContextIDUsageCount(unsigned int contextID)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
if (s_contextIDMap[contextID]!=0)
if (s_contextIDMap[contextID]._numContexts!=0)
{
--s_contextIDMap[contextID];
s_contextIDMap[contextID].decrementUsageCount();
}
else
{
osg::notify(osg::NOTICE)<<"Warning: decrementContextIDUsageCount("<<contextID<<") called on expired contextID."<<std::endl;
}
osg::notify(osg::INFO)<<"GraphicsContext::decrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]<<std::endl;
osg::notify(osg::INFO)<<"GraphicsContext::decrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]._numContexts<<std::endl;
}
void GraphicsContext::registerGraphicsContext(GraphicsContext* gc)
{
osg::notify(osg::INFO)<<"GraphicsContext::registerGraphicsContext "<<gc<<std::endl;
if (!gc) return;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
GraphicsContexts::iterator itr = std::find(s_registeredContexts.begin(), s_registeredContexts.end(), gc);
if (itr != s_registeredContexts.end()) s_registeredContexts.erase(itr);
s_registeredContexts.push_back(gc);
}
void GraphicsContext::unregisterGraphicsContext(GraphicsContext* gc)
{
osg::notify(osg::INFO)<<"GraphicsContext::unregisterGraphicsContext "<<gc<<std::endl;
if (!gc) return;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
GraphicsContexts::iterator itr = std::find(s_registeredContexts.begin(), s_registeredContexts.end(), gc);
if (itr != s_registeredContexts.end()) s_registeredContexts.erase(itr);
}
GraphicsContext::GraphicsContexts GraphicsContext::getAllRegisteredGraphicsContexts()
{
osg::notify(osg::INFO)<<"GraphicsContext::getAllRegisteredGraphicsContexts s_registeredContexts.size()="<<s_registeredContexts.size()<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
return s_registeredContexts;
}
GraphicsContext::GraphicsContexts GraphicsContext::getRegisteredGraphicsContexts(unsigned int contextID)
{
GraphicsContexts contexts;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
for(GraphicsContexts::iterator itr = s_registeredContexts.begin();
itr != s_registeredContexts.end();
++itr)
{
GraphicsContext* gc = *itr;
if (gc->getState() && gc->getState()->getContextID()==contextID) contexts.push_back(gc);
}
osg::notify(osg::INFO)<<"GraphicsContext::getRegisteredGraphicsContexts "<<contextID<<" contexts.size()="<<contexts.size()<<std::endl;
return contexts;
}
GraphicsContext* GraphicsContext::getOrCreateCompileContext(unsigned int contextID)
{
osg::notify(osg::INFO)<<"GraphicsContext::createCompileContext."<<std::endl;
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
if (s_contextIDMap[contextID]._compileContext.valid()) return s_contextIDMap[contextID]._compileContext.get();
}
GraphicsContext::GraphicsContexts contexts = GraphicsContext::getRegisteredGraphicsContexts(contextID);
if (contexts.empty()) return 0;
GraphicsContext* src_gc = contexts.front();
const osg::GraphicsContext::Traits* src_traits = src_gc->getTraits();
osg::GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
traits->screenNum = src_traits->screenNum;
traits->displayNum = src_traits->displayNum;
traits->hostName = src_traits->hostName;
traits->width = 100;
traits->height = 100;
traits->red = src_traits->red;
traits->green = src_traits->green;
traits->blue = src_traits->blue;
traits->alpha = src_traits->alpha;
traits->depth = src_traits->depth;
traits->sharedContext = src_gc;
traits->pbuffer = true;
osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits);
gc->realize();
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
s_contextIDMap[contextID]._compileContext = gc;
}
osg::notify(osg::INFO)<<" succeded GraphicsContext::createCompileContext."<<std::endl;
return gc;
}
void GraphicsContext::setCompileContext(unsigned int contextID, GraphicsContext* gc)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
s_contextIDMap[contextID]._compileContext = gc;
}
GraphicsContext* GraphicsContext::getCompileContext(unsigned int contextID)
{
osg::notify(osg::NOTICE)<<"GraphicsContext::getCompileContext "<<contextID<<std::endl;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
return s_contextIDMap[contextID]._compileContext.get();
}
/////////////////////////////////////////////////////////////////////////////
//
// GraphicsContext standard method implementations
//
GraphicsContext::GraphicsContext():
_clearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f)),
_clearMask(0),
@@ -140,6 +296,8 @@ GraphicsContext::GraphicsContext():
{
setThreadSafeRefUnref(true);
_operationsBlock = new RefBlock;
registerGraphicsContext(this);
}
GraphicsContext::GraphicsContext(const GraphicsContext&, const osg::CopyOp&):
@@ -149,11 +307,15 @@ GraphicsContext::GraphicsContext(const GraphicsContext&, const osg::CopyOp&):
{
setThreadSafeRefUnref(true);
_operationsBlock = new RefBlock;
registerGraphicsContext(this);
}
GraphicsContext::~GraphicsContext()
{
close(false);
unregisterGraphicsContext(this);
}
void GraphicsContext::clear()
@@ -193,7 +355,7 @@ void GraphicsContext::close(bool callCloseImplementation)
if (_state.valid())
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
if (s_contextIDMap[_state->getContextID()]>1) sharedContextExists = true;
if (s_contextIDMap[_state->getContextID()]._numContexts>1) sharedContextExists = true;
}
// release all the OpenGL objects in the scene graphs associted with this

View File

@@ -13,6 +13,7 @@
#include <osg/View>
#include <osg/Notify>
#include <osg/TexEnv>
#include <osg/DeleteHandler>
using namespace osg;
@@ -72,6 +73,17 @@ View::~View()
cd._camera->setCullCallback(0);
}
_camera = 0;
_slaves.clear();
_light = 0;
if (osg::Referenced::getDeleteHandler())
{
// osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
osg::Referenced::getDeleteHandler()->flushAll();
}
osg::notify(osg::INFO)<<"Done destructing osg::View"<<std::endl;
}

View File

@@ -1178,7 +1178,7 @@ struct X11WindowingSystemInterface : public osg::GraphicsContext::WindowingSyste
~X11WindowingSystemInterface()
{
osg::notify(osg::INFO)<<"~X11WindowingSystemInterface()"<<std::endl;
//osg::notify(osg::NOTICE)<<"~X11WindowingSystemInterface()"<<std::endl;
XSetErrorHandler(0);
}

View File

@@ -692,12 +692,7 @@ Viewer::~Viewer()
{
(*citr)->close();
}
if (osg::Referenced::getDeleteHandler())
{
osg::Referenced::getDeleteHandler()->setNumFramesToRetainObjects(0);
osg::Referenced::getDeleteHandler()->flushAll();
}
//osg::notify(osg::NOTICE)<<"finish Viewer::~Viewer()"<<std::endl;
getAllThreads(threads);