diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2016-06-01 13:29:28 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com> | 2016-06-17 13:18:11 +0000 |
commit | 0b6adbcd234724edef747df4d17aa7a5bcf4381b (patch) | |
tree | bb090f3efee678dc71b20bcf5c7875bb9c555e01 /src/plugins | |
parent | fc1092cfad06a843c24b64afeb0d928e4e318372 (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.h | 5 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qiosscreen.mm | 58 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/ios/qioswindow.mm | 5 |
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 |