summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorRichard Moe Gustavsen <richard.gustavsen@digia.com>2013-05-30 10:07:29 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-06-05 21:15:26 +0200
commit102bdf35b13f1b60df26052341ebc5a2833518c7 (patch)
treed603ff2116af12f4d3a64a8a8987107b83e0383e /src/plugins
parente8237a3d19e90c31af6d5a6c5e3a2f7815740226 (diff)
iOS: change accelerometer to use QTimer for polling
According to the docs (CMMotionManager class reference) there are two ways of interacting with the accelerometer; Either through the callback API (NSOperationQueue), or peridic sampling (polling). Our first implementation of IOSAcceleometer used the former technique, which turns out to have bad performance when using the sensor together with a fine-grained QTimer. And this case is pretty common when using sensors together with e.g QML. Reading through the docs more carefully, they recommend using the polling technique when creating games instead since the NSOperationQueue introduces some overhead. So this patch does that, change the implementation to use QTimer based polling. And this solves the performance issues found. Change-Id: Ifde0d2292302467afb8db90a954ef45f3238350e Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/sensors/ios/iosaccelerometer.h9
-rw-r--r--src/plugins/sensors/ios/iosaccelerometer.mm52
2 files changed, 24 insertions, 37 deletions
diff --git a/src/plugins/sensors/ios/iosaccelerometer.h b/src/plugins/sensors/ios/iosaccelerometer.h
index 5fcac19f..1a6560b1 100644
--- a/src/plugins/sensors/ios/iosaccelerometer.h
+++ b/src/plugins/sensors/ios/iosaccelerometer.h
@@ -42,29 +42,28 @@
#ifndef IOSACCELEROMETER_H
#define IOSACCELEROMETER_H
-#include <Foundation/Foundation.h>
+#include <CoreMotion/CMMotionManager.h>
#include <qsensorbackend.h>
#include <qaccelerometer.h>
QT_BEGIN_NAMESPACE
-@class QtIoAccelListener;
-
class IOSAccelerometer : public QSensorBackend
{
public:
static char const * const id;
explicit IOSAccelerometer(QSensor *sensor);
- ~IOSAccelerometer();
+ void timerEvent(QTimerEvent *);
void start();
void stop();
private:
- NSOperationQueue *m_updateQueue;
+ CMMotionManager *m_motionManager;
QAccelerometerReading m_reading;
+ int m_timer;
};
QT_END_NAMESPACE
diff --git a/src/plugins/sensors/ios/iosaccelerometer.mm b/src/plugins/sensors/ios/iosaccelerometer.mm
index b657b507..5f9c0f16 100644
--- a/src/plugins/sensors/ios/iosaccelerometer.mm
+++ b/src/plugins/sensors/ios/iosaccelerometer.mm
@@ -40,8 +40,6 @@
****************************************************************************/
#include <UIKit/UIAccelerometer.h>
-#include <CoreMotion/CMMotionManager.h>
-#include <QPointer>
#include "iosaccelerometer.h"
#include "iosmotionmanager.h"
@@ -52,49 +50,39 @@ QT_BEGIN_NAMESPACE
IOSAccelerometer::IOSAccelerometer(QSensor *sensor)
: QSensorBackend(sensor)
- , m_updateQueue([[NSOperationQueue alloc] init])
+ , m_motionManager([QIOSMotionManager sharedManager])
+ , m_timer(0)
{
setReading<QAccelerometerReading>(&m_reading);
addDataRate(1, 100); // 100Hz
addOutputRange(-22.418, 22.418, 0.17651); // 2G
}
-IOSAccelerometer::~IOSAccelerometer()
-{
- [m_updateQueue release];
-}
-
void IOSAccelerometer::start()
{
- CMMotionManager *motionManager = [QIOSMotionManager sharedManager];
- // Convert from Hz to NSTimeInterval:
int hz = sensor()->dataRate();
- motionManager.accelerometerUpdateInterval = (hz == 0) ? 0 : 1. / hz;
-
- QPointer<QObject> self = this;
- [motionManager startAccelerometerUpdatesToQueue:m_updateQueue withHandler:^(CMAccelerometerData *data, NSError *error) {
- // NSOperationQueue is multi-threaded, so we process the data by queuing a callback to
- // the main application queue. By the time the callback executes, IOSAccelerometer might
- // have been deleted, so we need an extra QPointer check for that:
- dispatch_async(dispatch_get_main_queue(), ^{
- if (self) {
- Q_UNUSED(error);
- // Convert from NSTimeInterval to microseconds and G to m/s2, and flip axes:
- CMAcceleration acc = data.acceleration;
- const qreal G = 9.8066;
- m_reading.setTimestamp(quint64(data.timestamp * 1000000));
- m_reading.setX(qreal(acc.x) * G * -1);
- m_reading.setY(qreal(acc.y) * G * -1);
- m_reading.setZ(qreal(acc.z) * G * -1);
- newReadingAvailable();
- }
- });
- }];
+ m_timer = startTimer(1000 / (hz == 0 ? 60 : hz));
+ [m_motionManager startAccelerometerUpdates];
}
void IOSAccelerometer::stop()
{
- [[QIOSMotionManager sharedManager] stopAccelerometerUpdates];
+ [m_motionManager stopAccelerometerUpdates];
+ killTimer(m_timer);
+ m_timer = 0;
+}
+
+void IOSAccelerometer::timerEvent(QTimerEvent *)
+{
+ // Convert from NSTimeInterval to microseconds and G to m/s2, and flip axes:
+ CMAccelerometerData *data = m_motionManager.accelerometerData;
+ CMAcceleration acc = data.acceleration;
+ static const qreal G = 9.8066;
+ m_reading.setTimestamp(quint64(data.timestamp * 1e6));
+ m_reading.setX(qreal(acc.x) * G * -1);
+ m_reading.setY(qreal(acc.y) * G * -1);
+ m_reading.setZ(qreal(acc.z) * G * -1);
+ newReadingAvailable();
}
QT_END_NAMESPACE