Added support for managing a CompileContext. Rearranged the DeleteHandler::flushAll call.
This commit is contained in:
@@ -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();
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user