From Robert Milharcic, "This will hopefully fix some issues with osgQt, more precisely with GLWidget event handling. There are at least two current GL context braking events, QEvent::Hide and QEvent::ParentChange. When running in a multithreaded mode they both try to change current GL context in a wrong thread (main GUI thread). The QEvent::ParentChange is also problematic when running in a single threaded model because Qt is going to release current contex then delete it, and then it will create new one, and as a result the osg will continue to render to an invalid deleted context. This changes workaround above problems by deferring execution of the problematic evens. These events has to be enqueued and executed later. The enqueued event processing is currently done right after swap in a swapBuffersImplementation of GraphicsWindowQt while code is running in a render thread by calling QGLWidget handler directly. In principle the deferred events queue should be executed while in GUI thread but I couldn't find any reliable way to do this, that is without risking a deadlock. For now it is assumed, Qt is not going to execute any GUI thread only operations inside the QGLWidget handler."
This commit is contained in:
@@ -261,7 +261,7 @@ class OSG_EXPORT GraphicsContext : public Object
|
||||
void removeAllOperations();
|
||||
|
||||
/** Run the operations. */
|
||||
void runOperations();
|
||||
virtual void runOperations();
|
||||
|
||||
typedef std::list< ref_ptr<Operation> > GraphicsOperationQueue;
|
||||
|
||||
|
||||
@@ -14,8 +14,13 @@
|
||||
#ifndef OSGVIEWER_GRAPHICSWINDOWQT
|
||||
#define OSGVIEWER_GRAPHICSWINDOWQT
|
||||
|
||||
#include <osgViewer/GraphicsWindow>
|
||||
#include <QtCore/QMutex>
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtCore/QQueue>
|
||||
#include <QtCore/QSet>
|
||||
#include <QtOpenGL/QGLWidget>
|
||||
|
||||
#include <osgViewer/GraphicsWindow>
|
||||
#include <osgQt/Export>
|
||||
|
||||
class QInputEvent;
|
||||
@@ -46,6 +51,7 @@ void OSGQT_EXPORT setViewer( osgViewer::ViewerBase *viewer );
|
||||
class OSGQT_EXPORT GLWidget : public QGLWidget
|
||||
{
|
||||
typedef QGLWidget inherited;
|
||||
|
||||
public:
|
||||
|
||||
GLWidget( QWidget* parent = NULL, const QGLWidget* shareWidget = NULL, Qt::WindowFlags f = 0, bool forwardKeyEvents = false );
|
||||
@@ -71,9 +77,37 @@ public:
|
||||
virtual void wheelEvent( QWheelEvent* event );
|
||||
|
||||
protected:
|
||||
|
||||
int getNumDeferredEvents()
|
||||
{
|
||||
QMutexLocker lock(&_deferredEventQueueMutex);
|
||||
return _deferredEventQueue.count();
|
||||
}
|
||||
void enqueueDeferredEvent(QEvent::Type eventType, QEvent::Type removeEventType = QEvent::None)
|
||||
{
|
||||
QMutexLocker lock(&_deferredEventQueueMutex);
|
||||
|
||||
if (removeEventType != QEvent::None)
|
||||
{
|
||||
if (_deferredEventQueue.removeOne(removeEventType))
|
||||
_eventCompressor.remove(eventType);
|
||||
}
|
||||
|
||||
if (_eventCompressor.find(eventType) == _eventCompressor.end())
|
||||
{
|
||||
_deferredEventQueue.enqueue(eventType);
|
||||
_eventCompressor.insert(eventType);
|
||||
}
|
||||
}
|
||||
void processDeferredEvents();
|
||||
|
||||
friend class GraphicsWindowQt;
|
||||
GraphicsWindowQt* _gw;
|
||||
|
||||
QMutex _deferredEventQueueMutex;
|
||||
QQueue<QEvent::Type> _deferredEventQueue;
|
||||
QSet<QEvent::Type> _eventCompressor;
|
||||
|
||||
bool _forwardKeyEvents;
|
||||
|
||||
virtual void resizeEvent( QResizeEvent* event );
|
||||
@@ -96,8 +130,8 @@ public:
|
||||
inline GLWidget* getGraphWidget() { return _widget; }
|
||||
/// deprecated
|
||||
inline const GLWidget* getGraphWidget() const { return _widget; }
|
||||
|
||||
struct WindowData : public osg::Referenced
|
||||
|
||||
struct WindowData : public osg::Referenced
|
||||
{
|
||||
WindowData( GLWidget* widget = NULL, GLWidget* parent = NULL ): _widget(widget), _parent(parent) {}
|
||||
GLWidget* _widget;
|
||||
@@ -129,12 +163,13 @@ struct WindowData : public osg::Referenced
|
||||
virtual bool makeCurrentImplementation();
|
||||
virtual bool releaseContextImplementation();
|
||||
virtual void swapBuffersImplementation();
|
||||
|
||||
virtual void runOperations();
|
||||
|
||||
virtual void requestWarpPointer( float x, float y );
|
||||
|
||||
protected:
|
||||
friend class GLWidget;
|
||||
|
||||
friend class GLWidget;
|
||||
GLWidget* _widget;
|
||||
bool _ownsWidget;
|
||||
QCursor _currentCursor;
|
||||
|
||||
Reference in New Issue
Block a user