[osg-submissions] Maximum number of graphics contexts and Texture unref image data after apply

Robert Osfield robert.osfield at gmail.com
Tue Feb 19 02:57:26 PST 2008


Hi Lionel,


On Feb 19, 2008 8:05 AM, Lionel Lagarde <lionel.lagarde at oktal.fr> wrote:
> here is the file non-inlined (Hope so)

The file came though fine this time, thanks.

I have just reviewed the changes and also the default value of the max
number of graphics context in DisplaySettings and it looks like the
this large setting (to 32) is much of the cause of the problem you are
probably seeing with objects not unrefing.  If it were 1 then
GraphicsContext.cpp would work fine.  This large default setting is
required to make sure static arrays are allocted large enough at start
up.

The solution I see are either to accept your change, or to change
change the default number of graphics contexts to 1 and initialize the
statics differently.  The problem with your own change is that the
code will loose any previous setting made by the application to
initialize the max number of graphics contexts required.

> Maybe someone has already say it but if someone wants to send text file
> as non-inlined attachment using a mozilla client, the
>
> mail.content_disposition_type options has to be set to 1 in the
> configuration editor (or the corresponding .js file).

Do the docs on the SubmissionsProtocol about this need updating?

Robert.


>
>
>
>
> Robert Osfield wrote:
> > HI Lionel,
> >
> > The file is still inlined, this is a known bug with outlook and the
> > mozilla email clients, could you zip it.
> >
> > Cheers,
> > Robert.
> >
> > On Feb 18, 2008 3:43 PM, Lionel Lagarde <lionel.lagarde at oktal.fr> wrote:
> >> Sorry ... I missed the reply.
> >>
> >> Here is the file.
> >>
> >> Hi,
> >>
> >> An osg::Texture can unref its image after its apply. A Texture2D unref
> >> its image if areAllTextureObjectsLoaded method returns true.
> >>
> >> This method checks the if a texture object has been allocated for each
> >> graphic context. The number of graphic context is given by the
> >> DisplaySettings::getMaxNumberOfGraphicsContexts method.
> >>
> >>
> >> The 1.2 version of OSG (with Producer) updates the maximum number of
> >> graphic context for each created window.
> >>
> >> The 2.x version of OSG updates the maximum number of graphic context
> >> only if the new context ID is greater than the current number of graphic
> >> context.
> >>
> >> The attached fix updates the DisplaySettings instance for each created
> >> GraphicsContext.
> >>
> >>
> >>
> >> _______________________________________________
> >> osg-submissions mailing list
> >> osg-submissions at lists.openscenegraph.org
> >> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
> >>
> >> /* -*-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 <stdlib.h>
> >>
> >> #include <osg/GraphicsContext>
> >> #include <osg/Camera>
> >> #include <osg/View>
> >> #include <osg/GLObjects>
> >>
> >> #include <osg/FrameBufferObject>
> >> #include <osg/Program>
> >> #include <osg/Drawable>
> >> #include <osg/FragmentProgram>
> >> #include <osg/VertexProgram>
> >>
> >> #include <OpenThreads/ReentrantMutex>
> >>
> >> #include <osg/Notify>
> >>
> >> #include <map>
> >> #include <sstream>
> >> #include <algorithm>
> >>
> >> using namespace osg;
> >>
> >> /////////////////////////////////////////////////////////////////////////////
> >>
> >>
> >> // Use a static reference pointer to hold the window system interface.
> >> // Wrap this within a function, in order to control the order in which
> >> // the static pointer's constructor is executed.
> >>
> >> static ref_ptr<GraphicsContext::WindowingSystemInterface> &windowingSystemInterfaceRef()
> >> {
> >>     static ref_ptr<GraphicsContext::WindowingSystemInterface> s_WindowingSystemInterface;
> >>     return s_WindowingSystemInterface;
> >> }
> >>
> >>
> >> //  GraphicsContext static method implementations
> >>
> >> void GraphicsContext::setWindowingSystemInterface(WindowingSystemInterface* callback)
> >> {
> >>     ref_ptr<GraphicsContext::WindowingSystemInterface> &wsref = windowingSystemInterfaceRef();
> >>     wsref = callback;
> >>     osg::notify(osg::INFO)<<"GraphicsContext::setWindowingSystemInterface() "<<wsref.get()<<"\t"<<&wsref<<std::endl;
> >> }
> >>
> >> GraphicsContext::WindowingSystemInterface* GraphicsContext::getWindowingSystemInterface()
> >> {
> >>     ref_ptr<GraphicsContext::WindowingSystemInterface> &wsref = windowingSystemInterfaceRef();
> >>     osg::notify(osg::INFO)<<"GraphicsContext::getWindowingSystemInterface() "<<wsref.get()<<"\t"<<&wsref<<std::endl;
> >>     return wsref.get();
> >> }
> >>
> >> GraphicsContext* GraphicsContext::createGraphicsContext(Traits* traits)
> >> {
> >>     ref_ptr<GraphicsContext::WindowingSystemInterface> &wsref = windowingSystemInterfaceRef();
> >>     if ( wsref.valid())
> >>     {
> >>         // catch any undefined values.
> >>         if (traits) traits->setUndefinedScreenDetailsToDefaultScreen();
> >>
> >>         return wsref->createGraphicsContext(traits);
> >>     }
> >>     else
> >>         return 0;
> >> }
> >>
> >> GraphicsContext::ScreenIdentifier::ScreenIdentifier():
> >>     displayNum(0),
> >>     screenNum(0) {}
> >>
> >> GraphicsContext::ScreenIdentifier::ScreenIdentifier(int in_screenNum):
> >>     displayNum(0),
> >>     screenNum(in_screenNum) {}
> >>
> >> GraphicsContext::ScreenIdentifier::ScreenIdentifier(const std::string& in_hostName,int in_displayNum, int in_screenNum):
> >>     hostName(in_hostName),
> >>     displayNum(in_displayNum),
> >>     screenNum(in_screenNum) {}
> >>
> >> std::string GraphicsContext::ScreenIdentifier::displayName() const
> >> {
> >>     std::stringstream ostr;
> >>     ostr<<hostName<<":"<<displayNum<<"."<<screenNum;
> >>     return ostr.str();
> >> }
> >>
> >> void GraphicsContext::ScreenIdentifier::readDISPLAY()
> >> {
> >>     const char* ptr = 0;
> >>     if ((ptr=getenv("DISPLAY")) != 0)
> >>     {
> >>         setScreenIdentifier(ptr);
> >>     }
> >> }
> >>
> >> void GraphicsContext::ScreenIdentifier::setScreenIdentifier(const std::string& displayName)
> >> {
> >>     std::string::size_type colon = displayName.find_last_of(':');
> >>     std::string::size_type point = displayName.find_last_of('.');
> >>
> >>     if (point!=std::string::npos &&
> >>         colon==std::string::npos &&
> >>         point < colon) point = std::string::npos;
> >>
> >>     if (colon==std::string::npos)
> >>     {
> >>         hostName = "";
> >>     }
> >>     else
> >>     {
> >>         hostName = displayName.substr(0,colon);
> >>     }
> >>
> >>     std::string::size_type startOfDisplayNum = (colon==std::string::npos) ? 0 : colon+1;
> >>     std::string::size_type endOfDisplayNum = (point==std::string::npos) ?  displayName.size() : point;
> >>
> >>     if (startOfDisplayNum<endOfDisplayNum)
> >>     {
> >>         displayNum = atoi(displayName.substr(startOfDisplayNum,endOfDisplayNum-startOfDisplayNum).c_str());
> >>     }
> >>     else
> >>     {
> >>         displayNum = -1;
> >>     }
> >>
> >>     if (point!=std::string::npos && point+1<displayName.size())
> >>     {
> >>         screenNum = atoi(displayName.substr(point+1,displayName.size()-point-1).c_str());
> >>     }
> >>     else
> >>     {
> >>         screenNum = -1;
> >>     }
> >>
> >> #if 0
> >>     osg::notify(osg::NOTICE)<<"   hostName ["<<hostName<<"]"<<std::endl;
> >>     osg::notify(osg::NOTICE)<<"   displayNum "<<displayNum<<std::endl;
> >>     osg::notify(osg::NOTICE)<<"   screenNum "<<screenNum<<std::endl;
> >> #endif
> >> }
> >>
> >> 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;
> >>
> >>             _compileContext = 0;
> >>         }
> >>     }
> >>
> >>     osg::ref_ptr<osg::GraphicsContext> _compileContext;
> >>
> >> };
> >>
> >>
> >> typedef std::map<unsigned int, ContextData>  ContextIDMap;
> >> static ContextIDMap s_contextIDMap;
> >> static OpenThreads::ReentrantMutex s_contextIDMapMutex;
> >> static GraphicsContext::GraphicsContexts s_registeredContexts;
> >>
> >> 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._numContexts == 0)
> >>         {
> >>
> >>             // reuse contextID;
> >>             itr->second._numContexts = 1;
> >>
> >>             osg::notify(osg::INFO)<<"GraphicsContext::createNewContextID() reusing contextID="<<itr->first<<std::endl;
> >>
> >>             return itr->first;
> >>         }
> >>     }
> >>
> >>     unsigned int contextID = s_contextIDMap.size();
> >>     s_contextIDMap[contextID]._numContexts = 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 );
> >>     }*/
> >>
> >>          // Update the maximum number of graphics contexts
> >>          osg::DisplaySettings::instance()->setMaxNumberOfGraphicsContexts(contextID + 1);
> >>
> >>     return contextID;
> >> }
> >>
> >> unsigned int GraphicsContext::getMaxContextID()
> >> {
> >>     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> >>     unsigned int maxContextID = 0;
> >>     for(ContextIDMap::iterator itr = s_contextIDMap.begin();
> >>         itr != s_contextIDMap.end();
> >>         ++itr)
> >>     {
> >>         if (itr->first > maxContextID) maxContextID = itr->first;
> >>     }
> >>     return maxContextID;
> >> }
> >>
> >>
> >> void GraphicsContext::incrementContextIDUsageCount(unsigned int contextID)
> >> {
> >>     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> >>
> >>     osg::notify(osg::INFO)<<"GraphicsContext::incrementContextIDUsageCount("<<contextID<<") to "<<s_contextIDMap[contextID]._numContexts<<std::endl;
> >>
> >>     s_contextIDMap[contextID].incrementUsageCount();
> >> }
> >>
> >> void GraphicsContext::decrementContextIDUsageCount(unsigned int contextID)
> >> {
> >>
> >>     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> >>
> >>     if (s_contextIDMap[contextID]._numContexts!=0)
> >>     {
> >>         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]._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::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits);
> >>     if (gc.valid() && gc->realize())
> >>     {
> >>         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> >>         s_contextIDMap[contextID]._compileContext = gc;
> >>         osg::notify(osg::INFO)<<"   succeeded GraphicsContext::createCompileContext."<<std::endl;
> >>         return gc.release();
> >>     }
> >>     else
> >>     {
> >>         return 0;
> >>     }
> >>
> >> }
> >>
> >> 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);
> >>     ContextIDMap::iterator itr = s_contextIDMap.find(contextID);
> >>     if (itr != s_contextIDMap.end()) return itr->second._compileContext.get();
> >>     else return 0;
> >> }
> >>
> >>
> >> /////////////////////////////////////////////////////////////////////////////
> >> //
> >> //  GraphicsContext standard method implementations
> >> //
> >> GraphicsContext::GraphicsContext():
> >>     _clearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f)),
> >>     _clearMask(0),
> >>     _threadOfLastMakeCurrent(0)
> >> {
> >>     setThreadSafeRefUnref(true);
> >>     _operationsBlock = new RefBlock;
> >>
> >>     registerGraphicsContext(this);
> >> }
> >>
> >> GraphicsContext::GraphicsContext(const GraphicsContext&, const osg::CopyOp&):
> >>     _clearColor(osg::Vec4(0.0f,0.0f,0.0f,1.0f)),
> >>     _clearMask(0),
> >>     _threadOfLastMakeCurrent(0)
> >> {
> >>     setThreadSafeRefUnref(true);
> >>     _operationsBlock = new RefBlock;
> >>
> >>     registerGraphicsContext(this);
> >> }
> >>
> >> GraphicsContext::~GraphicsContext()
> >> {
> >>     close(false);
> >>
> >>     unregisterGraphicsContext(this);
> >> }
> >>
> >> void GraphicsContext::clear()
> >> {
> >>     if (_clearMask==0 || !_traits) return;
> >>
> >>     glViewport(0, 0, _traits->width, _traits->height);
> >>     glScissor(0, 0, _traits->width, _traits->height);
> >>
> >>     glClearColor( _clearColor[0], _clearColor[1], _clearColor[2], _clearColor[3]);
> >>
> >>     glClear( _clearMask );
> >> }
> >>
> >> bool GraphicsContext::realize()
> >> {
> >>     if (realizeImplementation())
> >>     {
> >>         return true;
> >>     }
> >>     else
> >>     {
> >>         return false;
> >>     }
> >> }
> >>
> >> void GraphicsContext::close(bool callCloseImplementation)
> >> {
> >>     osg::notify(osg::INFO)<<"close("<<callCloseImplementation<<")"<<this<<std::endl;
> >>
> >>     // switch off the graphics thread...
> >>     setGraphicsThread(0);
> >>
> >>
> >>     bool sharedContextExists = false;
> >>
> >>     if (_state.valid())
> >>     {
> >>         OpenThreads::ScopedLock<OpenThreads::Mutex> lock(s_contextIDMapMutex);
> >>         if (s_contextIDMap[_state->getContextID()]._numContexts>1) sharedContextExists = true;
> >>     }
> >>
> >>     // release all the OpenGL objects in the scene graphs associated with this
> >>     for(Cameras::iterator itr = _cameras.begin();
> >>         itr != _cameras.end();
> >>         ++itr)
> >>     {
> >>         Camera* camera = (*itr);
> >>         if (camera)
> >>         {
> >>             osg::notify(osg::INFO)<<"Releasing GL objects for Camera="<<camera<<" _state="<<_state.get()<<std::endl;
> >>             camera->releaseGLObjects(_state.get());
> >>         }
> >>     }
> >>
> >>
> >>     if (callCloseImplementation && _state.valid() && isRealized())
> >>     {
> >>         osg::notify(osg::INFO)<<"Closing still viable window "<<sharedContextExists<<" _state->getContextID()="<<_state->getContextID()<<std::endl;
> >>
> >>         if (makeCurrent())
> >>         {
> >>
> >>             osg::notify(osg::INFO)<<"Doing Flush"<<std::endl;
> >>
> >>             osg::flushAllDeletedGLObjects(_state->getContextID());
> >>
> >>             osg::notify(osg::INFO)<<"Done Flush "<<std::endl;
> >>
> >>             _state->reset();
> >>
> >>             releaseContext();
> >>         }
> >>         else
> >>         {
> >>             osg::notify(osg::INFO)<<"makeCurrent did not succeed, could not do flush/deletion of OpenGL objects."<<std::endl;
> >>         }
> >>     }
> >>
> >>     if (callCloseImplementation) closeImplementation();
> >>
> >>
> >>     // now discard any deleted deleted OpenGL objects that the are still hanging around - such as due to
> >>     // the the flushDelete*() methods not being invoked, such as when using GraphicContextEmbedded where makeCurrent
> >>     // does not work.
> >>     if (_state.valid())
> >>     {
> >>         osg::notify(osg::INFO)<<"Doing discard of deleted OpenGL objects."<<std::endl;
> >>
> >>         osg::discardAllDeletedGLObjects(_state->getContextID());
> >>     }
> >>
> >>     if (_state.valid())
> >>     {
> >>         decrementContextIDUsageCount(_state->getContextID());
> >>
> >>         _state = 0;
> >>     }
> >> }
> >>
> >>
> >> bool GraphicsContext::makeCurrent()
> >> {
> >>     bool result = makeCurrentImplementation();
> >>
> >>     if (result)
> >>     {
> >>         _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread();
> >>
> >>         // initialize extension process, not only initializes on first
> >>         // call, will be a non-op on subsequent calls.
> >>         getState()->initializeExtensionProcs();
> >>     }
> >>
> >>     return result;
> >> }
> >>
> >> bool GraphicsContext::makeContextCurrent(GraphicsContext* readContext)
> >> {
> >>     bool result = makeContextCurrentImplementation(readContext);
> >>
> >>     if (result)
> >>     {
> >>         _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread();
> >>
> >>         // initialize extension process, not only initializes on first
> >>         // call, will be a non-op on subsequent calls.
> >>         getState()->initializeExtensionProcs();
> >>     }
> >>
> >>     return result;
> >> }
> >>
> >> bool GraphicsContext::releaseContext()
> >> {
> >>     bool result = releaseContextImplementation();
> >>
> >>     _threadOfLastMakeCurrent = (OpenThreads::Thread*)(-1);
> >>
> >>     return result;
> >> }
> >>
> >> void GraphicsContext::swapBuffers()
> >> {
> >>     if (isCurrent())
> >>     {
> >>         swapBuffersImplementation();
> >>         clear();
> >>     }
> >>     else if (_graphicsThread.valid() &&
> >>              _threadOfLastMakeCurrent == _graphicsThread.get())
> >>     {
> >>         _graphicsThread->add(new SwapBuffersOperation);
> >>     }
> >>     else
> >>     {
> >>         makeCurrent();
> >>         swapBuffersImplementation();
> >>         clear();
> >>     }
> >> }
> >>
> >>
> >>
> >> void GraphicsContext::createGraphicsThread()
> >> {
> >>     if (!_graphicsThread)
> >>     {
> >>         setGraphicsThread(new GraphicsThread);
> >>     }
> >> }
> >>
> >> void GraphicsContext::setGraphicsThread(GraphicsThread* gt)
> >> {
> >>     if (_graphicsThread==gt) return;
> >>
> >>     if (_graphicsThread.valid())
> >>     {
> >>         // need to kill the thread in some way...
> >>         _graphicsThread->cancel();
> >>         _graphicsThread->setParent(0);
> >>     }
> >>
> >>     _graphicsThread = gt;
> >>
> >>     if (_graphicsThread.valid())
> >>     {
> >>         _graphicsThread->setParent(this);
> >>     }
> >> }
> >>
> >> void GraphicsContext::add(Operation* operation)
> >> {
> >>     osg::notify(osg::INFO)<<"Doing add"<<std::endl;
> >>
> >>     // acquire the lock on the operations queue to prevent anyone else for modifying it at the same time
> >>     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
> >>
> >>     // add the operation to the end of the list
> >>     _operations.push_back(operation);
> >>
> >>     _operationsBlock->set(true);
> >> }
> >>
> >> void GraphicsContext::remove(Operation* operation)
> >> {
> >>     osg::notify(osg::INFO)<<"Doing remove operation"<<std::endl;
> >>
> >>     // acquire the lock on the operations queue to prevent anyone else for modifying it at the same time
> >>     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
> >>
> >>     for(OperationQueue::iterator itr = _operations.begin();
> >>         itr!=_operations.end();)
> >>     {
> >>         if ((*itr)==operation) itr = _operations.erase(itr);
> >>         else ++itr;
> >>     }
> >>
> >>     if (_operations.empty())
> >>     {
> >>         _operationsBlock->set(false);
> >>     }
> >> }
> >>
> >> void GraphicsContext::remove(const std::string& name)
> >> {
> >>     osg::notify(osg::INFO)<<"Doing remove named operation"<<std::endl;
> >>
> >>     // acquire the lock on the operations queue to prevent anyone else for modifying it at the same time
> >>     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
> >>
> >>     // find the remove all operations with specified name
> >>     for(OperationQueue::iterator itr = _operations.begin();
> >>         itr!=_operations.end();)
> >>     {
> >>         if ((*itr)->getName()==name) itr = _operations.erase(itr);
> >>         else ++itr;
> >>     }
> >>
> >>     if (_operations.empty())
> >>     {
> >>         _operationsBlock->set(false);
> >>     }
> >> }
> >>
> >> void GraphicsContext::removeAllOperations()
> >> {
> >>     osg::notify(osg::INFO)<<"Doing remove all operations"<<std::endl;
> >>
> >>     OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
> >>     _operations.clear();
> >>     _operationsBlock->set(false);
> >> }
> >>
> >>
> >> struct CameraRenderOrderSortOp
> >> {
> >>     inline bool operator() (const Camera* lhs,const Camera* rhs) const
> >>     {
> >>         if (lhs->getRenderOrder()<rhs->getRenderOrder()) return true;
> >>         if (rhs->getRenderOrder()<lhs->getRenderOrder()) return false;
> >>         return lhs->getRenderOrderNum()<lhs->getRenderOrderNum();
> >>     }
> >> };
> >>
> >>
> >> void GraphicsContext::runOperations()
> >> {
> >>     // sort the cameras into order
> >>     typedef std::vector<Camera*> CameraVector;
> >>     CameraVector camerasCopy;
> >>     std::copy(_cameras.begin(), _cameras.end(), std::back_inserter(camerasCopy));
> >>     std::sort(camerasCopy.begin(), camerasCopy.end(), CameraRenderOrderSortOp());
> >>
> >>     for(CameraVector::iterator itr = camerasCopy.begin();
> >>         itr != camerasCopy.end();
> >>         ++itr)
> >>     {
> >>         osg::Camera* camera = *itr;
> >>         if (camera->getRenderer()) (*(camera->getRenderer()))(this);
> >>     }
> >>
> >>     for(OperationQueue::iterator itr = _operations.begin();
> >>         itr != _operations.end();
> >>         )
> >>     {
> >>         {
> >>             OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
> >>             _currentOperation = *itr;
> >>
> >>             if (!_currentOperation->getKeep())
> >>             {
> >>                 itr = _operations.erase(itr);
> >>
> >>                 if (_operations.empty())
> >>                 {
> >>                     _operationsBlock->set(false);
> >>                 }
> >>             }
> >>             else
> >>             {
> >>                 ++itr;
> >>             }
> >>         }
> >>
> >>         if (_currentOperation.valid())
> >>         {
> >>             // osg::notify(osg::INFO)<<"Doing op "<<_currentOperation->getName()<<" "<<this<<std::endl;
> >>
> >>             // call the graphics operation.
> >>             (*_currentOperation)(this);
> >>
> >>             {
> >>                 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
> >>                 _currentOperation = 0;
> >>             }
> >>         }
> >>     }
> >> }
> >>
> >> void GraphicsContext::addCamera(osg::Camera* camera)
> >> {
> >>     _cameras.push_back(camera);
> >> }
> >>
> >> void GraphicsContext::removeCamera(osg::Camera* camera)
> >> {
> >>     for(Cameras::iterator itr = _cameras.begin();
> >>         itr != _cameras.end();
> >>         ++itr)
> >>     {
> >>         if (*itr == camera)
> >>         {
> >>             _cameras.erase(itr);
> >>             return;
> >>         }
> >>     }
> >> }
> >>
> >> void GraphicsContext::resizedImplementation(int x, int y, int width, int height)
> >> {
> >>     if (!_traits) return;
> >>
> >>     double widthChangeRatio = double(width) / double(_traits->width);
> >>     double heigtChangeRatio = double(height) / double(_traits->height);
> >>     double aspectRatioChange = widthChangeRatio / heigtChangeRatio;
> >>
> >>     for(Cameras::iterator itr = _cameras.begin();
> >>         itr != _cameras.end();
> >>         ++itr)
> >>     {
> >>         Camera* camera = (*itr);
> >>         Viewport* viewport = camera->getViewport();
> >>         if (viewport)
> >>         {
> >>             if (viewport->x()==0 && viewport->y()==0 &&
> >>                 viewport->width()>=_traits->width && viewport->height()>=_traits->height)
> >>             {
> >>                 viewport->setViewport(0,0,width,height);
> >>             }
> >>             else
> >>             {
> >>                 viewport->x() = static_cast<osg::Viewport::value_type>(double(viewport->x())*widthChangeRatio);
> >>                 viewport->y() = static_cast<osg::Viewport::value_type>(double(viewport->y())*heigtChangeRatio);
> >>                 viewport->width() = static_cast<osg::Viewport::value_type>(double(viewport->width())*widthChangeRatio);
> >>                 viewport->height() = static_cast<osg::Viewport::value_type>(double(viewport->height())*heigtChangeRatio);
> >>             }
> >>         }
> >>
> >>         // if aspect ratio adjusted change the project matrix to suit.
> >>         if (aspectRatioChange != 1.0)
> >>         {
> >>             osg::View* view = camera->getView();
> >>             osg::View::Slave* slave = view ? view->findSlaveForCamera(camera) : 0;
> >>
> >>             if (slave && camera->getReferenceFrame()==osg::Transform::RELATIVE_RF)
> >>             {
> >>                 switch(view->getCamera()->getProjectionResizePolicy())
> >>                 {
> >>                     case(osg::Camera::HORIZONTAL): slave->_projectionOffset *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); break;
> >>                     case(osg::Camera::VERTICAL): slave->_projectionOffset *= osg::Matrix::scale(1.0, aspectRatioChange,1.0); break;
> >>                     default: break;
> >>                 }
> >>             }
> >>             else
> >>             {
> >>                 Camera::ProjectionResizePolicy policy = view ? view->getCamera()->getProjectionResizePolicy() : camera->getProjectionResizePolicy();
> >>                 switch(policy)
> >>                 {
> >>                     case(osg::Camera::HORIZONTAL): camera->getProjectionMatrix() *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0); break;
> >>                     case(osg::Camera::VERTICAL): camera->getProjectionMatrix() *= osg::Matrix::scale(1.0, aspectRatioChange,1.0); break;
> >>                     default: break;
> >>                 }
> >>             }
> >>
> >>         }
> >>
> >>     }
> >>
> >>     _traits->x = x;
> >>     _traits->y = y;
> >>     _traits->width = width;
> >>     _traits->height = height;
> >> }
> >>
> >> _______________________________________________
> >> osg-submissions mailing list
> >> osg-submissions at lists.openscenegraph.org
> >> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
> >>
> >>
> > _______________________________________________
> > osg-submissions mailing list
> > osg-submissions at lists.openscenegraph.org
> > http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
> >
>
> _______________________________________________
> osg-submissions mailing list
> osg-submissions at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
>


More information about the osg-submissions mailing list