From 4fe9798db3e32aae45d79bef7c1c82e50933658a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 5 Mar 2015 11:46:27 +0100 Subject: Optimize egl cursor update events Avoid invokeMethod on every cursor movement and use an event instead. This is more lightweight and efficient. Also, there is no need to have a separate QObject just for this. Change-Id: I65ae202943eeb1e30cf22926576f84198f2487f8 Reviewed-by: Andy Nichols --- .../eglconvenience/qeglplatformcursor.cpp | 51 ++++++++++++++-------- .../eglconvenience/qeglplatformcursor_p.h | 21 +-------- 2 files changed, 34 insertions(+), 38 deletions(-) (limited to 'src/platformsupport') diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp index fc6e4bad8d..bf23d52465 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp @@ -62,7 +62,7 @@ QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen) m_textureCoordEntry(0), m_textureEntry(0), m_deviceListener(0), - m_updater(screen) + m_updateRequested(false) { QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); if (!hideCursorVal.isEmpty()) @@ -246,30 +246,43 @@ bool QEGLPlatformCursor::setCurrentCursor(QCursor *cursor) } #endif -void QEGLPlatformCursorUpdater::update(const QPoint &pos, const QRegion &rgn) +class CursorUpdateEvent : public QEvent { - m_active = false; - QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(pos), rgn); - QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); -} - -void QEGLPlatformCursorUpdater::scheduleUpdate(const QPoint &pos, const QRegion &rgn) +public: + CursorUpdateEvent(const QPoint &pos, const QRegion &rgn) + : QEvent(QEvent::Type(QEvent::User + 1)), + m_pos(pos), + m_region(rgn) + { } + QPoint pos() const { return m_pos; } + QRegion region() const { return m_region; } + +private: + QPoint m_pos; + QRegion m_region; +}; + +bool QEGLPlatformCursor::event(QEvent *e) { - if (m_active) - return; - - m_active = true; - - // Must not flush the window system events directly from here since we are likely to - // be a called directly from QGuiApplication's processMouseEvents. Flushing events - // could cause reentering by dispatching more queued mouse events. - QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection, - Q_ARG(QPoint, pos), Q_ARG(QRegion, rgn)); + if (e->type() == QEvent::User + 1) { + CursorUpdateEvent *ev = static_cast(e); + m_updateRequested = false; + QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(ev->pos()), ev->region()); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); + return true; + } + return QPlatformCursor::event(e); } void QEGLPlatformCursor::update(const QRegion &rgn) { - m_updater.scheduleUpdate(m_cursor.pos, rgn); + if (!m_updateRequested) { + // Must not flush the window system events directly from here since we are likely to + // be a called directly from QGuiApplication's processMouseEvents. Flushing events + // could cause reentering by dispatching more queued mouse events. + m_updateRequested = true; + QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rgn)); + } } QRect QEGLPlatformCursor::cursorRect() const diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h index 1c05a06b63..481bb3c74c 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h @@ -70,24 +70,6 @@ private: QEGLPlatformCursor *m_cursor; }; -class QEGLPlatformCursorUpdater : public QObject -{ - Q_OBJECT - -public: - QEGLPlatformCursorUpdater(QPlatformScreen *screen) - : m_screen(screen), m_active(false) { } - - void scheduleUpdate(const QPoint &pos, const QRegion &rgn); - -private slots: - void update(const QPoint &pos, const QRegion &rgn); - -private: - QPlatformScreen *m_screen; - bool m_active; -}; - class QEGLPlatformCursor : public QPlatformCursor, protected QOpenGLFunctions { Q_OBJECT @@ -109,6 +91,7 @@ public: void updateMouseStatus(); private: + bool event(QEvent *e) Q_DECL_OVERRIDE; #ifndef QT_NO_CURSOR bool setCurrentCursor(QCursor *cursor); #endif @@ -150,7 +133,7 @@ private: int m_textureCoordEntry; int m_textureEntry; QEGLPlatformCursorDeviceListener *m_deviceListener; - QEGLPlatformCursorUpdater m_updater; + bool m_updateRequested; }; QT_END_NAMESPACE -- cgit v1.2.3