From 16d1c00a3da31a5df4e8755d2cb58b9e87e0f57b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 8 Jan 2007 19:29:59 +0000 Subject: [PATCH] Changed the return types of makeCurrent to bool, and added a bool GraphicsContext::releaseContext method along with implementations in osgViewer. --- examples/osgcamera/osgcamera.cpp | 4 +- include/osg/GraphicsContext | 25 ++-- include/osgGA/EventQueue | 14 +++ include/osgGA/GUIEventAdapter | 4 +- .../osgProducer/GraphicsContextImplementation | 7 +- include/osgViewer/GraphicsWindow | 9 +- include/osgViewer/GraphicsWindowCocoa | 5 +- include/osgViewer/GraphicsWindowWin32 | 5 +- include/osgViewer/GraphicsWindowX11 | 5 +- src/osg/GraphicsContext.cpp | 112 ++++++++---------- src/osg/Texture.cpp | 9 +- src/osg/View.cpp | 4 +- src/osgGA/EventQueue.cpp | 19 +++ .../GraphicsContextImplementation.cpp | 14 ++- src/osgViewer/GraphicsWindowCocoa.cpp | 16 ++- src/osgViewer/GraphicsWindowWin32.cpp | 17 ++- src/osgViewer/GraphicsWindowX11.cpp | 46 +++---- src/osgViewer/Viewer.cpp | 32 ++++- 18 files changed, 221 insertions(+), 126 deletions(-) diff --git a/examples/osgcamera/osgcamera.cpp b/examples/osgcamera/osgcamera.cpp index 5e6810fa1..29d1af0fb 100644 --- a/examples/osgcamera/osgcamera.cpp +++ b/examples/osgcamera/osgcamera.cpp @@ -70,13 +70,13 @@ void multipleWindowMultipleCameras(osgViewer::Viewer& viewer) wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height); - unsigned int numCameras = 4; + unsigned int numCameras = 6; double aspectRatioScale = (double)numCameras; double translate_x = double(numCameras)-1; for(unsigned int i=0; i traits = new osg::GraphicsContext::Traits; - traits->screenNum = i / 2; + traits->screenNum = i / 3; traits->x = (i*width)/numCameras; traits->y = 0; traits->width = width/numCameras-1; diff --git a/include/osg/GraphicsContext b/include/osg/GraphicsContext index 84c15ab79..df455d0e4 100644 --- a/include/osg/GraphicsContext +++ b/include/osg/GraphicsContext @@ -219,15 +219,18 @@ class OSG_EXPORT GraphicsContext : public Referenced /** Make this graphics context current. - * Implementated by first aquiring a lock of the GraphicsContext mutex, and then doing a call to makeCurrentImplementation(). */ - void makeCurrent(); + * Implementated by calling makeCurrentImplementation(). + * Returns true on success. */ + bool makeCurrent(); /** Make this graphics context current with specified read context. - * Implementated by first aquiring a lock of the GraphicsContext mutex, and then doing a call to makeContextCurrentImplementation(). */ - void makeContextCurrent(GraphicsContext* readContext); + * Implementated by calling makeContextCurrentImplementation(). + * Returns true on success. */ + bool makeContextCurrent(GraphicsContext* readContext); - /** Release the graphics context by unlocking the GraphicsContext mutex.*/ - void releaseContext(); + /** Release the graphics context. + * Returns true on success. */ + bool releaseContext(); /** Return true if the current thread has this OpenGL graphics context.*/ inline bool isCurrent() const { return _threadOfLastMakeCurrent == OpenThreads::Thread::CurrentThread(); } @@ -264,11 +267,14 @@ class OSG_EXPORT GraphicsContext : public Referenced /** Make this graphics context current implementation. * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */ - virtual void makeCurrentImplementation() = 0; + virtual bool makeCurrentImplementation() = 0; /** Make this graphics context current with specified read context implementation. * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */ - virtual void makeContextCurrentImplementation(GraphicsContext* readContext) = 0; + virtual bool makeContextCurrentImplementation(GraphicsContext* readContext) = 0; + + /** Release the graphics context implementation.*/ + virtual bool releaseContextImplementation() = 0; /** Pure virtual, Bind the graphics context to associated texture implementation. * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */ @@ -278,6 +284,8 @@ class OSG_EXPORT GraphicsContext : public Referenced * Pure virtual - must be implemented by Concrate implementations of GraphicsContext. */ virtual void swapBuffersImplementation() = 0; + + /** resized method should be called when the underlying window has been resized and the GraphicsWindow and associated Cameras must be updated to keep in sync with the new size. */ void resized(int x, int y, int width, int height) @@ -332,7 +340,6 @@ class OSG_EXPORT GraphicsContext : public Referenced Vec4 _clearColor; GLbitfield _clearMask; - OpenThreads::Mutex _mutex; OpenThreads::Thread* _threadOfLastMakeCurrent; typedef std::list< ref_ptr > OperationQueue; diff --git a/include/osgGA/EventQueue b/include/osgGA/EventQueue index 50165c67f..32a88acf6 100644 --- a/include/osgGA/EventQueue +++ b/include/osgGA/EventQueue @@ -150,6 +150,20 @@ class OSGGA_EXPORT EventQueue : public osg::Referenced void keyRelease(int key, double time); + /** Method for adapting close window events.*/ + void closeWindow() { closeWindow(getTime()); } + + /** Method for adapting close window event with specified event time.*/ + void closeWindow(double time); + + + /** Method for adapting application quit events.*/ + void quitApplication() { quitApplication(getTime()); } + + /** Method for adapting application quit events with specified event time.*/ + void quitApplication(double time); + + /** Method for adapting frame events.*/ void frame(double time); diff --git a/include/osgGA/GUIEventAdapter b/include/osgGA/GUIEventAdapter index c15ee3a61..539bcade4 100644 --- a/include/osgGA/GUIEventAdapter +++ b/include/osgGA/GUIEventAdapter @@ -53,7 +53,9 @@ public: SCROLL, PEN_PRESSURE, PEN_PROXIMITY_ENTER, - PEN_PROXIMITY_LEAVE + PEN_PROXIMITY_LEAVE, + CLOSE_WINDOW, + QUIT_APPLICATION }; enum KeySymbol diff --git a/include/osgProducer/GraphicsContextImplementation b/include/osgProducer/GraphicsContextImplementation index 49031154c..358ae4b4e 100644 --- a/include/osgProducer/GraphicsContextImplementation +++ b/include/osgProducer/GraphicsContextImplementation @@ -56,10 +56,13 @@ class OSGPRODUCER_EXPORT GraphicsContextImplementation : public osg::GraphicsCon virtual void closeImplementation(); /** Make this graphics context current.*/ - virtual void makeCurrentImplementation(); + virtual bool makeCurrentImplementation(); /** Make this graphics context current with specified read context.*/ - virtual void makeContextCurrentImplementation(osg::GraphicsContext* readContext); + virtual bool makeContextCurrentImplementation(osg::GraphicsContext* readContext); + + /** Release the graphics context.*/ + virtual bool releaseContextImplementation(); /** Bind the graphics context to associated texture.*/ virtual void bindPBufferToTextureImplementation(GLenum buffer); diff --git a/include/osgViewer/GraphicsWindow b/include/osgViewer/GraphicsWindow index 6db864d7c..fa49212be 100644 --- a/include/osgViewer/GraphicsWindow +++ b/include/osgViewer/GraphicsWindow @@ -74,15 +74,18 @@ class OSGVIEWER_EXPORT GraphicsWindow : public osg::GraphicsContext, public osgG /** Make this graphics context current implementation. * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */ - virtual void makeCurrentImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow::makeCurrentImplementation() not implemented."< lock(s_contextIDMapMutex); + if (s_contextIDMap[_state->getContextID()]>1) sharedContextExists = true; + } + + // release all the OpenGL objects in the scene graphs associted 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="<getContextID()="<<_state->getContextID()< lock(s_contextIDMapMutex); - if (s_contextIDMap[_state->getContextID()]>1) sharedContextExists = true; - } - - osg::notify(osg::NOTICE)<<"Closing still viable window "<getContextID()="<<_state->getContextID()<releaseGLObjects(_state.get()); -#else - camera->releaseGLObjects(0); -#endif - } - } -#endif - -#if 1 - osg::notify(osg::NOTICE)<<"Doing makeCurrent "<getContextID(),currentTime,availableTime); osg::Shader::flushDeletedGlShaders(_state->getContextID(),currentTime,availableTime); - osg::notify(osg::NOTICE)<<"Done Flush "<reset(); releaseContext(); @@ -247,46 +239,37 @@ void GraphicsContext::close(bool callCloseImplementation) } -void GraphicsContext::makeCurrent() +bool GraphicsContext::makeCurrent() { - ReleaseContext_Block_MakeCurrentOperation* rcbmco = 0; - - if (_graphicsThread.valid() && - _threadOfLastMakeCurrent == _graphicsThread.get() && - _threadOfLastMakeCurrent != OpenThreads::Thread::CurrentThread()) - { - // create a relase contex, block and make current operation to stop the graphics thread while we use the graphics context for ourselves - rcbmco = new ReleaseContext_Block_MakeCurrentOperation; - _graphicsThread->add(rcbmco); - } - - if (!isCurrent()) _mutex.lock(); - - makeCurrentImplementation(); + bool result = makeCurrentImplementation(); - _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread(); - - if (rcbmco) + if (result) { - // Let the "relase contex, block and make current operation" proceed, which will now move on to trying to aquire the graphics - // contex itself with a makeCurrent(), this will then block on the GraphicsContext mutex till releaseContext() releases it. - rcbmco->release(); + _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread(); } + + return result; } -void GraphicsContext::makeContextCurrent(GraphicsContext* readContext) +bool GraphicsContext::makeContextCurrent(GraphicsContext* readContext) { - if (!isCurrent()) _mutex.lock(); + bool result = makeContextCurrentImplementation(readContext); - makeContextCurrentImplementation(readContext); - - _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread(); + if (result) + { + _threadOfLastMakeCurrent = OpenThreads::Thread::CurrentThread(); + } + + return result; } -void GraphicsContext::releaseContext() +bool GraphicsContext::releaseContext() { - _mutex.unlock(); - _threadOfLastMakeCurrent = reinterpret_cast(0xffff); + bool result = releaseContextImplementation(); + + _threadOfLastMakeCurrent = (OpenThreads::Thread*)(-1); + + return result; } void GraphicsContext::swapBuffers() @@ -306,7 +289,6 @@ void GraphicsContext::swapBuffers() makeCurrent(); swapBuffersImplementation(); clear(); - releaseContext(); } } diff --git a/src/osg/Texture.cpp b/src/osg/Texture.cpp index 811045688..52faa0270 100644 --- a/src/osg/Texture.cpp +++ b/src/osg/Texture.cpp @@ -218,13 +218,14 @@ void TextureObjectManager::flushAllTextureObjects(unsigned int contextID) OpenThreads::ScopedLock lock(_mutex); Texture::TextureObjectList& tol = _textureObjectListMap[contextID]; - osg::notify(osg::NOTICE)<<"Flushing texture objects num="<_id<_id<_id)); } tol.clear(); @@ -1304,8 +1305,8 @@ void Texture::resizeGLObjectBuffers(unsigned int maxSize) void Texture::releaseGLObjects(State* state) const { - if (state) osg::notify(osg::NOTICE)<<"Texture::releaseGLObjects contextID="<getContextID()<(this)->dirtyTextureObject(); else diff --git a/src/osg/View.cpp b/src/osg/View.cpp index 9266effdf..63dd18783 100644 --- a/src/osg/View.cpp +++ b/src/osg/View.cpp @@ -26,7 +26,7 @@ View::View() View::~View() { - osg::notify(osg::NOTICE)<<"Destructing osg::View"<setCullCallback(0); } - osg::notify(osg::NOTICE)<<"Done destructing osg::View"<setEventType(GUIEventAdapter::CLOSE_WINDOW); + event->setTime(time); + + addEvent(event); +} + +void EventQueue::quitApplication(double time) +{ + GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState); + event->setEventType(GUIEventAdapter::QUIT_APPLICATION); + event->setTime(time); + + addEvent(event); +} + + void EventQueue::frame(double time) { GUIEventAdapter* event = new GUIEventAdapter(*_accumulateEventState); diff --git a/src/osgProducer/GraphicsContextImplementation.cpp b/src/osgProducer/GraphicsContextImplementation.cpp index 50ae28dc1..489b8be4e 100644 --- a/src/osgProducer/GraphicsContextImplementation.cpp +++ b/src/osgProducer/GraphicsContextImplementation.cpp @@ -218,18 +218,18 @@ bool GraphicsContextImplementation::realizeImplementation() } } -void GraphicsContextImplementation::makeCurrentImplementation() +bool GraphicsContextImplementation::makeCurrentImplementation() { if (!_rs) { osg::notify(osg::NOTICE)<<"Error: GraphicsContextImplementation::makeCurrentImplementation() no RenderSurface."<makeCurrent(); + + return true; } -void GraphicsContextImplementation::makeContextCurrentImplementation(osg::GraphicsContext* readContext) +bool GraphicsContextImplementation::makeContextCurrentImplementation(osg::GraphicsContext* readContext) { - if (!_rs) return; + if (!_rs) return false; GraphicsContextImplementation* readContextImplemention = dynamic_cast(readContext); @@ -257,6 +259,8 @@ void GraphicsContextImplementation::makeContextCurrentImplementation(osg::Graphi // comment out right now, as Producer's setReadDrawable() is doing a call for us. // _rs->makeCurrent(); + + return true; } void GraphicsContextImplementation::closeImplementation() diff --git a/src/osgViewer/GraphicsWindowCocoa.cpp b/src/osgViewer/GraphicsWindowCocoa.cpp index 95f64065d..261e8d6c4 100644 --- a/src/osgViewer/GraphicsWindowCocoa.cpp +++ b/src/osgViewer/GraphicsWindowCocoa.cpp @@ -46,11 +46,14 @@ class GraphicsContextCocoa : public osg::GraphicsContext /** Make this graphics context current implementation. * Pure virtual - must be implemented by concrate implementations of GraphicsContext. */ - virtual void makeCurrentImplementation() { osg::notify(osg::NOTICE)<<"GraphicsWindow::makeCurrentImplementation() not implemented."<closeWindow(eventTime); } } case Expose : @@ -859,12 +858,13 @@ void GraphicsWindowX11::checkEvents() resized(windowX, windowY, windowWidth, windowHeight); getEventQueue()->windowResize(windowX, windowY, windowWidth, windowHeight, resizeTime); } - + +#if 0 if (destroyWindowRequested) { close(); } - +#endif } void GraphicsWindowX11::grabFocus() diff --git a/src/osgViewer/Viewer.cpp b/src/osgViewer/Viewer.cpp index 48669f8f7..9f6807f75 100644 --- a/src/osgViewer/Viewer.cpp +++ b/src/osgViewer/Viewer.cpp @@ -605,7 +605,8 @@ void Viewer::eventTraversal() osgGA::EventQueue::Events gw_events; gw->getEventQueue()->takeEvents(gw_events); - for(osgGA::EventQueue::Events::iterator itr = gw_events.begin(); + osgGA::EventQueue::Events::iterator itr; + for(itr = gw_events.begin(); itr != gw_events.end(); ++itr) { @@ -692,6 +693,32 @@ void Viewer::eventTraversal() // osg::notify(osg::NOTICE)<<" mouse Xmin = "<getXmin()<<" Ymin="<getYmin()<<" xMax="<getXmax()<<" Ymax="<getYmax()<get(); + switch(event->getEventType()) + { + case(osgGA::GUIEventAdapter::CLOSE_WINDOW): + { + stopThreading(); + + gw->close(); + + // setThreadingModel(ThreadPerCamera); + + setThreadingModel(SingleThreaded); + + startThreading(); + + break; + } + default: + break; + } + } + events.insert(events.end(), gw_events.begin(), gw_events.end()); } @@ -792,6 +819,9 @@ void Viewer::eventTraversal() { case(osgGA::GUIEventAdapter::KEYUP): if (event->getKey()==_keySetsDone) _done = true; + else if (event->getKey()=='s') { setThreadingModel(SingleThreaded); } + else if (event->getKey()=='c') { setThreadingModel(ThreadPerCamera); } + else if (event->getKey()=='w') { setThreadingModel(ThreadPerContext); } break; default: break;