ports/opt (3.2): qt5: fix memory leak, xcb treat bitmap cursors differently from shaped cursors
![](https://secure.gravatar.com/avatar/df8330968b6df8cd1c1942c5fb4b720c.jpg?s=120&d=mm&r=g)
commit 7dfa27747e3fe0df06411fcc787001aab7669db7 Author: Danny Rawlins <monster.romster@gmail.com> Date: Tue Nov 22 08:28:42 2016 +1100 qt5: fix memory leak, xcb treat bitmap cursors differently from shaped cursors diff --git a/qt5/.md5sum b/qt5/.md5sum index bce791b..35360b2 100644 --- a/qt5/.md5sum +++ b/qt5/.md5sum @@ -1,5 +1,6 @@ 63ec6b584757eef8cd713e4958297251 qt-everywhere-opensource-src-5.7.0.tar.xz 67165bacd3231b57d7b7db1e6bcb7d89 qt5-logo.png +9842c327b091b360da7a4d90f5fdf4da qtbase-memory-leak.patch 646aea77ca90031c453a65ef61db55f9 qtbug-49452.patch 462f079cd46f869def6858903a718bf5 qtbug-53071.patch da4fd787ea877516397a027412e975e1 qtbug-53071b.patch diff --git a/qt5/Pkgfile b/qt5/Pkgfile index 56994f2..97c6b8f 100644 --- a/qt5/Pkgfile +++ b/qt5/Pkgfile @@ -6,13 +6,14 @@ name=qt5 version=5.7.0 -release=3 +release=4 source=(http://download.qt.io/official_releases/qt/${version::3}/$version/single/qt-everywhere-opensource-src-$version.tar.xz qt5-logo.png qtbug-53071.patch qtbug-53071b.patch qtbug-53237.patch - qtbug-49452.patch) + qtbug-49452.patch + qtbase-memory-leak.patch) build() { cd qt-everywhere-opensource-src-$version @@ -27,6 +28,9 @@ build() { # Fix freetype engine performance patch -p1 -d qtbase -i $SRC/qtbug-49452.patch + # Fix memory leak + patch -p1 -d qtbase -i $SRC/qtbase-memory-leak.patch + # Respect system CXX [ "$CXX" ] || CXX=g++ sed -i "/^QMAKE_CXX\s/s|=.*|= $CXX|" qtbase/mkspecs/common/g++-base.conf diff --git a/qt5/qtbase-memory-leak.patch b/qt5/qtbase-memory-leak.patch new file mode 100644 index 0000000..009b155 --- /dev/null +++ b/qt5/qtbase-memory-leak.patch @@ -0,0 +1,135 @@ +From 422838685c31d9b57133a8711bfd5db92095d96d Mon Sep 17 00:00:00 2001 +From: Robin Burchell <robin.burchell@viroteck.net> +Date: Wed, 7 Sep 2016 14:34:03 +0200 +Subject: [PATCH] xcb: Treat bitmap cursors differently from shaped cursors + +QXcbCursor had a "cache" of cursor handles. Unfortunately, as QXcbCursor has its +lifetime tied to the screen, this cache grew unbounded whenever the cursor was +set: this could be witnessed worst when repeatedly setting the current cursor to +a different pixmap each time. + +We fix this by keeping the cursor cache only for the "regular" shaped cursors +that are often shared between windows, working on the assumption that custom +cursors are generally specific only to a given window. This makes the lifetime +of the bitmap cursors much more clear: they are tied to that window, and when +the window is destroyed (or changes cursor), so too is the bitmap cursor +destroyed (if set). + +Reported-by: Will Thompson <wjt@endlessm.com> +Change-Id: Ia558d858ff49e89cd5220344567203eb0267a133 +Reviewed-by: Uli Schlachter <psychon@znc.in> +Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> +--- + src/plugins/platforms/xcb/qxcbcursor.cpp | 24 +++++++++++++++++------- + src/plugins/platforms/xcb/qxcbwindow.cpp | 22 +++++++++++++++++++--- + src/plugins/platforms/xcb/qxcbwindow.h | 3 ++- + 3 files changed, 38 insertions(+), 11 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp +index b321ed9..4646ced 100644 +--- a/src/plugins/platforms/xcb/qxcbcursor.cpp ++++ b/src/plugins/platforms/xcb/qxcbcursor.cpp +@@ -353,17 +353,27 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) + return; + + xcb_cursor_t c = XCB_CURSOR_NONE; ++ bool isBitmapCursor = false; ++ + if (cursor) { +- const QXcbCursorCacheKey key(*cursor); +- CursorHash::iterator it = m_cursorHash.find(key); +- if (it == m_cursorHash.end()) { +- const Qt::CursorShape shape = cursor->shape(); +- it = m_cursorHash.insert(key, shape == Qt::BitmapCursor ? createBitmapCursor(cursor) : createFontCursor(shape)); ++ const Qt::CursorShape shape = cursor->shape(); ++ isBitmapCursor = shape == Qt::BitmapCursor; ++ ++ if (!isBitmapCursor) { ++ const QXcbCursorCacheKey key(*cursor); ++ CursorHash::iterator it = m_cursorHash.find(key); ++ if (it == m_cursorHash.end()) { ++ it = m_cursorHash.insert(key, createFontCursor(shape)); ++ } ++ c = it.value(); ++ } else { ++ // Do not cache bitmap cursors, as otherwise they have unclear ++ // lifetime (we effectively leak xcb_cursor_t). ++ c = createBitmapCursor(cursor); + } +- c = it.value(); + } + +- w->setCursor(c); ++ w->setCursor(c, isBitmapCursor); + } + + static int cursorIdForShape(int cshape) +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index d46228c..5f402b6 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -302,6 +302,7 @@ QXcbWindow::QXcbWindow(QWindow *window) + , m_lastWindowStateEvent(-1) + , m_syncState(NoSyncNeeded) + , m_pendingSyncRequest(0) ++ , m_currentBitmapCursor(XCB_CURSOR_NONE) + { + setConnection(xcbScreen()->connection()); + } +@@ -620,6 +621,9 @@ void QXcbWindow::create() + + QXcbWindow::~QXcbWindow() + { ++ if (m_currentBitmapCursor != XCB_CURSOR_NONE) { ++ xcb_free_cursor(xcb_connection(), m_currentBitmapCursor); ++ } + if (window()->type() != Qt::ForeignWindow) + destroy(); + else { +@@ -2665,10 +2669,22 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab) + return result; + } + +-void QXcbWindow::setCursor(xcb_cursor_t cursor) ++void QXcbWindow::setCursor(xcb_cursor_t cursor, bool isBitmapCursor) + { +- xcb_change_window_attributes(xcb_connection(), m_window, XCB_CW_CURSOR, &cursor); +- xcb_flush(xcb_connection()); ++ xcb_connection_t *conn = xcb_connection(); ++ ++ xcb_change_window_attributes(conn, m_window, XCB_CW_CURSOR, &cursor); ++ xcb_flush(conn); ++ ++ if (m_currentBitmapCursor != XCB_CURSOR_NONE) { ++ xcb_free_cursor(conn, m_currentBitmapCursor); ++ } ++ ++ if (isBitmapCursor) { ++ m_currentBitmapCursor = cursor; ++ } else { ++ m_currentBitmapCursor = XCB_CURSOR_NONE; ++ } + } + + void QXcbWindow::windowEvent(QEvent *event) +diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h +index b8bcf44..f2b6904 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.h ++++ b/src/plugins/platforms/xcb/qxcbwindow.h +@@ -97,7 +97,7 @@ class Q_XCB_EXPORT QXcbWindow : public QXcbObject, public QXcbWindowEventListene + bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE; + bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE; + +- void setCursor(xcb_cursor_t cursor); ++ void setCursor(xcb_cursor_t cursor, bool isBitmapCursor); + + QSurfaceFormat format() const Q_DECL_OVERRIDE; + +@@ -263,6 +263,7 @@ public Q_SLOTS: + SyncState m_syncState; + + QXcbSyncWindowRequest *m_pendingSyncRequest; ++ xcb_cursor_t m_currentBitmapCursor; + }; + + QT_END_NAMESPACE
participants (1)
-
crux@crux.nu