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>bb10
parent
fc1092cfad
commit
0b6adbcd23
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -40,8 +40,31 @@
|
|||
#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)
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue