Added handling of automatic setting up of the contextID.
This commit is contained in:
parent
3c23a42f17
commit
384830d37e
@ -19,10 +19,12 @@
|
||||
|
||||
namespace osg {
|
||||
|
||||
/** Base class for providing Windowing API agnostic access to creating and managing graphics context.*/
|
||||
class OSG_EXPORT GraphicsContext : public Referenced
|
||||
{
|
||||
public:
|
||||
|
||||
/** GraphicsContext Traits object provides the specification of what type of graphics context is required.*/
|
||||
struct Traits : public osg::Referenced
|
||||
{
|
||||
Traits():
|
||||
@ -87,6 +89,7 @@ class OSG_EXPORT GraphicsContext : public Referenced
|
||||
};
|
||||
|
||||
|
||||
/** Callback to be implemented to provide access to Windowing API's ability to create Windows/pbuffers.*/
|
||||
struct CreateGraphicContexCallback : public osg::Referenced
|
||||
{
|
||||
virtual GraphicsContext* createGraphicsContext(Traits* traits) = 0;
|
||||
@ -95,11 +98,24 @@ class OSG_EXPORT GraphicsContext : public Referenced
|
||||
};
|
||||
|
||||
|
||||
/** Set the create graphics context callback - this callback should be supplied by the windows toolkit. */
|
||||
static void setCreateGraphicsContextCallback(CreateGraphicContexCallback* callback);
|
||||
|
||||
/** Get the create graphics context callback*/
|
||||
static CreateGraphicContexCallback* getCreateGraphicsContextCallback();
|
||||
|
||||
/** Create a graphics context for a specified set of traits.*/
|
||||
static GraphicsContext* createGraphicsContext(Traits* traits);
|
||||
|
||||
/** Create a contextID for a new graphics context, this contextID is used to set up the osg::State associate with context.
|
||||
* Automatically increments the usage count of the contextID to 1.*/
|
||||
static unsigned int createNewContextID();
|
||||
|
||||
/** 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);
|
||||
|
||||
public:
|
||||
|
||||
@ -139,7 +155,7 @@ class OSG_EXPORT GraphicsContext : public Referenced
|
||||
|
||||
GraphicsContext();
|
||||
|
||||
virtual ~GraphicsContext() {}
|
||||
virtual ~GraphicsContext();
|
||||
|
||||
ref_ptr<Traits> _traits;
|
||||
ref_ptr<State> _state;
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
|
||||
#include <osg/GraphicsContext>
|
||||
#include <osg/Notify>
|
||||
#include <map>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
@ -36,8 +38,90 @@ GraphicsContext* GraphicsContext::createGraphicsContext(Traits* traits)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
typedef std::map<unsigned int, unsigned int> ContextIDMap;
|
||||
static ContextIDMap s_contextIDMap;
|
||||
static OpenThreads::Mutex s_contextIDMapMutex;
|
||||
|
||||
unsigned int GraphicsContext::createNewContextID()
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
|
||||
|
||||
// first check to see if we can reuse contextID;
|
||||
for(ContextIDMap::iterator itr = s_contextIDMap.begin();
|
||||
itr != s_contextIDMap.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->second == 0)
|
||||
{
|
||||
|
||||
// reuse contextID;
|
||||
itr->second = 1;
|
||||
|
||||
osg::notify(osg::NOTICE)<<"GraphicsContext::createNewContextID() reusing contextID="<<itr->first<<std::endl;
|
||||
|
||||
return itr->first;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int contextID = s_contextIDMap.size();
|
||||
s_contextIDMap[contextID] = 1;
|
||||
|
||||
osg::notify(osg::INFO)<<"GraphicsContext::createNewContextID() creating contextID="<<contextID<<std::endl;
|
||||
|
||||
|
||||
if ( (contextID+1) > osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts() )
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Updating the MaxNumberOfGraphicsContexts to "<<contextID+1<<std::endl;
|
||||
|
||||
// update the the maximum number of graphics contexts,
|
||||
// to ensure that texture objects and display buffers are configured to the correct size.
|
||||
osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts( contextID + 1 );
|
||||
}
|
||||
|
||||
|
||||
return contextID;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
++s_contextIDMap[contextID];
|
||||
}
|
||||
|
||||
void GraphicsContext::decrementContextIDUsageCount(unsigned int contextID)
|
||||
{
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
|
||||
|
||||
|
||||
if (s_contextIDMap[contextID]!=0)
|
||||
{
|
||||
--s_contextIDMap[contextID];
|
||||
}
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
GraphicsContext::GraphicsContext():
|
||||
_threadOfLastMakeCurrent(0)
|
||||
{
|
||||
}
|
||||
|
||||
GraphicsContext::~GraphicsContext()
|
||||
{
|
||||
if (_state.valid())
|
||||
{
|
||||
decrementContextIDUsageCount(_state->getContextID());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,18 +99,26 @@ GraphicsContextImplementation::GraphicsContextImplementation(Traits* traits)
|
||||
// different graphics context so we have our own state.
|
||||
setState(new osg::State);
|
||||
|
||||
if (sharedContext->getState())
|
||||
{
|
||||
getState()->setContextID( sharedContext->getState()->getContextID() );
|
||||
incrementContextIDUsageCount( sharedContext->getState()->getContextID() );
|
||||
}
|
||||
else
|
||||
{
|
||||
getState()->setContextID( GraphicsContext::createNewContextID() );
|
||||
}
|
||||
|
||||
// but we share texture objects etc. so we also share the same contextID
|
||||
getState()->setContextID( sharedContext->getState() ? sharedContext->getState()->getContextID() : 1 );
|
||||
|
||||
_rs->realize(0, sharedContext->_rs->getGLContext());
|
||||
_rs->realize( 0, sharedContext->_rs->getGLContext() );
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
static int count = 1;
|
||||
|
||||
// need to do something here....
|
||||
setState(new osg::State);
|
||||
getState()->setContextID(count++);
|
||||
setState( new osg::State );
|
||||
getState()->setContextID( GraphicsContext::createNewContextID() );
|
||||
|
||||
_rs->realize();
|
||||
}
|
||||
|
@ -239,10 +239,6 @@ void OsgCameraGroup::_init()
|
||||
_start_tick = _timer.tick();
|
||||
|
||||
if (!_frameStamp) _frameStamp = new osg::FrameStamp;
|
||||
|
||||
// set up the maximum number of graphics contexts, before loading the scene graph
|
||||
// to ensure that texture objects and display buffers are configured to the correct size.
|
||||
osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts( getNumberOfCameras() );
|
||||
|
||||
_applicationUsage = osg::ApplicationUsage::instance();
|
||||
|
||||
@ -410,8 +406,6 @@ bool OsgCameraGroup::realize()
|
||||
|
||||
if (!_ds) _ds = osg::DisplaySettings::instance();
|
||||
|
||||
_ds->setMaxNumberOfGraphicsContexts( _cfg->getNumberOfCameras() );
|
||||
|
||||
_shvec.clear();
|
||||
|
||||
osg::Node* node = getTopMostSceneData();
|
||||
@ -440,6 +434,8 @@ bool OsgCameraGroup::realize()
|
||||
// use a std::map to keep track of what render surfaces are associated with what state.
|
||||
typedef std::map<Producer::RenderSurface*,osg::State*> RenderSurfaceStateMap;
|
||||
RenderSurfaceStateMap _renderSurfaceStateMap;
|
||||
|
||||
bool needToCreatedNewContextID = true;
|
||||
unsigned int contextID = 0;
|
||||
|
||||
for(unsigned int i = 0; i < _cfg->getNumberOfCameras(); i++ )
|
||||
@ -461,11 +457,21 @@ bool OsgCameraGroup::realize()
|
||||
if (_renderSurfaceStateMap.count(rs)==0)
|
||||
{
|
||||
_renderSurfaceStateMap[rs] = sv->getState();
|
||||
|
||||
if (needToCreatedNewContextID)
|
||||
{
|
||||
// create a unique contextID for this graphics context.
|
||||
contextID = osg::GraphicsContext::createNewContextID();
|
||||
|
||||
// if we are sharing our graphics context then when needn't create any more.
|
||||
needToCreatedNewContextID = !Producer::RenderSurface::allGLContextsAreShared();
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::GraphicsContext::incrementContextIDUsageCount(contextID);
|
||||
}
|
||||
|
||||
sv->getState()->setContextID(contextID);
|
||||
|
||||
// if we aren't share OpenGL objects between graphics contexts then need to increment the contextID
|
||||
// to ensure that the OSG generates seperate objects for each graphics context.
|
||||
if (!Producer::RenderSurface::allGLContextsAreShared()) ++contextID;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1272,6 +1272,12 @@ void CullVisitor::apply(osg::CameraNode& camera)
|
||||
traits->_blue = 8;
|
||||
traits->_alpha = 0; // ???
|
||||
}
|
||||
|
||||
// share OpenGL objects if possible...
|
||||
if (_state.valid() && _state->getGraphicsContext())
|
||||
{
|
||||
traits->_sharedContext = _state->getGraphicsContext();
|
||||
}
|
||||
|
||||
// create the graphics context according to these traits.
|
||||
context = osg::GraphicsContext::createGraphicsContext(traits.get());
|
||||
|
Loading…
Reference in New Issue
Block a user