From Cory Slep and Robert Osfield, "When using Open Scene Graph and Qt on Android, the resulting thread that an application developer’s Q*Application is run on is different than what Qt considers the “main” thread, which can cause subtle problems. This is because Qt loads native libraries in one thread, and later runs the application in a different thread. They delay running in the second thread as long as possible as they have a nontrivial bootstrapping process. The motivation for Qt having this second thread is to allow them to remain responsive to both Java and native events, and capture events that would otherwise be “missed”.

This gives arise to the requirement that a static initialization of a QObject cannot occur for the Android platform, as Qt incorrectly considers that first thread the “main” one before a client application has even begun executing in its second thread.

 

The HeartBeat in GraphicsWindowQt.cpp is a QObject static global initialized at load time, causing the above issue. This changeset changes it to be a singleton that is constructed upon first access to its “instance” method.

 

I have:

- added the static method “instance”,

- moved its constructor to be private, and

- changed the one place it is accessed to access it through the “instance” method.

"

Changes by Robert are to adopt QPointer<HeartBeat> rather than use a C pointer to ensure that the HeartBeat object will be cleaned up automatically rather than leaked.



git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14963 16af8721-9629-0410-8352-f15c8da7e697
This commit is contained in:
Robert Osfield
2015-07-16 15:49:32 +00:00
parent b908ced20c
commit 0f918ee5c9

View File

@@ -15,6 +15,7 @@
#include <osgQt/GraphicsWindowQt>
#include <osgViewer/ViewerBase>
#include <QInputEvent>
#include <QPointer>
#if (QT_VERSION>=QT_VERSION_CHECK(4, 6, 0))
# define USE_GESTURES
@@ -119,18 +120,24 @@ static QtKeyboardMap s_QtKeyboardMap;
/// The object responsible for the scene re-rendering.
class HeartBeat : public QObject {
public:
int _timerId;
osg::Timer _lastFrameStartTime;
osg::observer_ptr< osgViewer::ViewerBase > _viewer;
int _timerId;
osg::Timer _lastFrameStartTime;
osg::observer_ptr< osgViewer::ViewerBase > _viewer;
HeartBeat();
virtual ~HeartBeat();
void init( osgViewer::ViewerBase *viewer );
void stopTimer();
void timerEvent( QTimerEvent *event );
virtual ~HeartBeat();
void init( osgViewer::ViewerBase *viewer );
void stopTimer();
void timerEvent( QTimerEvent *event );
static HeartBeat* instance();
private:
HeartBeat();
static QPointer<HeartBeat> heartBeat;
};
static HeartBeat heartBeat;
QPointer<HeartBeat> HeartBeat::heartBeat;
#if (QT_VERSION < QT_VERSION_CHECK(5, 2, 0))
#define GETDEVICEPIXELRATIO() 1.0
@@ -955,7 +962,7 @@ void osgQt::initQtWindowingSystem()
void osgQt::setViewer( osgViewer::ViewerBase *viewer )
{
heartBeat.init( viewer );
HeartBeat::instance()->init( viewer );
}
@@ -971,6 +978,14 @@ HeartBeat::~HeartBeat()
stopTimer();
}
HeartBeat* HeartBeat::instance()
{
if (!heartBeat)
{
heartBeat = new HeartBeat();
}
return heartBeat;
}
void HeartBeat::stopTimer()
{