summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2016-06-01 13:29:28 +0200
committerTor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>2016-06-17 13:18:11 +0000
commit0b6adbcd234724edef747df4d17aa7a5bcf4381b (patch)
treebb090f3efee678dc71b20bcf5c7875bb9c555e01 /src/plugins
parentfc1092cfad06a843c24b64afeb0d928e4e318372 (diff)
uikit: Deliver update requests via CADisplayLink callback
Improves performance over the default timer-implementation, and allows us to control the rate and paused state of the display link. Change-Id: I05761b6eb48f5e91af35735e2faa477427cd8440 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/ios/qiosscreen.h5
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm58
-rw-r--r--src/plugins/platforms/ios/qioswindow.h2
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm5
4 files changed, 70 insertions, 0 deletions
diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h
index d6627c78cb..87e1cfb23f 100644
--- a/src/plugins/platforms/ios/qiosscreen.h
+++ b/src/plugins/platforms/ios/qiosscreen.h
@@ -65,9 +65,13 @@ public:
UIScreen *uiScreen() const;
UIWindow *uiWindow() const;
+ void setUpdatesPaused(bool);
+
void updateProperties();
private:
+ void deliverUpdateRequests() const;
+
UIScreen *m_uiScreen;
UIWindow *m_uiWindow;
QRect m_geometry;
@@ -76,6 +80,7 @@ private:
uint m_physicalDpi;
QSizeF m_physicalSize;
QIOSOrientationListener *m_orientationListener;
+ CADisplayLink *m_displayLink;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index d9ec7008d3..4018a02f8d 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -40,10 +40,33 @@
#include "qiosviewcontroller.h"
#include "quiview.h"
+#include <QtGui/private/qwindow_p.h>
+
#include <sys/sysctl.h>
// -------------------------------------------------------------------------
+typedef void (^DisplayLinkBlock)(CADisplayLink *displayLink);
+
+@implementation UIScreen (DisplayLinkBlock)
+- (CADisplayLink*)displayLinkWithBlock:(DisplayLinkBlock)block
+{
+ return [self displayLinkWithTarget:[[block copy] autorelease]
+ selector:@selector(invokeDisplayLinkBlock:)];
+}
+@end
+
+@implementation NSObject (DisplayLinkBlock)
+- (void)invokeDisplayLinkBlock:(CADisplayLink *)sender
+{
+ DisplayLinkBlock block = static_cast<id>(self);
+ block(sender);
+}
+@end
+
+
+// -------------------------------------------------------------------------
+
static QIOSScreen* qtPlatformScreenFor(UIScreen *uiScreen)
{
foreach (QScreen *screen, QGuiApplication::screens()) {
@@ -208,10 +231,16 @@ QIOSScreen::QIOSScreen(UIScreen *screen)
}
updateProperties();
+
+ m_displayLink = [m_uiScreen displayLinkWithBlock:^(CADisplayLink *) { deliverUpdateRequests(); }];
+ m_displayLink.paused = YES; // Enabled when clients call QWindow::requestUpdate()
+ [m_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}
QIOSScreen::~QIOSScreen()
{
+ [m_displayLink invalidate];
+
[m_orientationListener release];
[m_uiWindow release];
}
@@ -291,6 +320,35 @@ void QIOSScreen::updateProperties()
QWindowSystemInterface::handleScreenGeometryChange(screen(), m_geometry, m_availableGeometry);
}
+void QIOSScreen::setUpdatesPaused(bool paused)
+{
+ m_displayLink.paused = paused;
+}
+
+void QIOSScreen::deliverUpdateRequests() const
+{
+ bool pauseUpdates = true;
+
+ QList<QWindow*> windows = QGuiApplication::allWindows();
+ for (int i = 0; i < windows.size(); ++i) {
+ if (platformScreenForWindow(windows.at(i)) != this)
+ continue;
+
+ QWindowPrivate *wp = static_cast<QWindowPrivate *>(QObjectPrivate::get(windows.at(i)));
+ if (!wp->updateRequestPending)
+ continue;
+
+ wp->deliverUpdateRequest();
+
+ // Another update request was triggered, keep the display link running
+ if (wp->updateRequestPending)
+ pauseUpdates = false;
+ }
+
+ // Pause the display link if there are no pending update requests
+ m_displayLink.paused = pauseUpdates;
+}
+
QRect QIOSScreen::geometry() const
{
return m_geometry;
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index 0c65cf8aa5..c1c4cad01a 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -82,6 +82,8 @@ public:
QSurfaceFormat format() const Q_DECL_OVERRIDE;
+ void requestUpdate() Q_DECL_OVERRIDE;
+
private:
void applicationStateChanged(Qt::ApplicationState state);
void applyGeometry(const QRect &rect);
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 3045a15380..42609fd983 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -371,6 +371,11 @@ void QIOSWindow::clearAccessibleCache()
[m_view clearAccessibleCache];
}
+void QIOSWindow::requestUpdate()
+{
+ static_cast<QIOSScreen *>(screen())->setUpdatesPaused(false);
+}
+
#include "moc_qioswindow.cpp"
QT_END_NAMESPACE