summaryrefslogtreecommitdiff
path: root/qt5
diff options
context:
space:
mode:
authorDanny Rawlins <monster.romster@gmail.com>2016-11-22 08:28:42 +1100
committerDanny Rawlins <monster.romster@gmail.com>2016-11-22 08:29:11 +1100
commit7dfa27747e3fe0df06411fcc787001aab7669db7 (patch)
treecb58623ac503a7c67964503a9791cc2e40fcabdc /qt5
parent54661c6f0aa20fc9b35ffa4832e1ccfe09bb3faa (diff)
downloadopt-7dfa27747e3fe0df06411fcc787001aab7669db7.tar.gz
opt-7dfa27747e3fe0df06411fcc787001aab7669db7.tar.xz
qt5: fix memory leak, xcb treat bitmap cursors differently from shaped cursors
Diffstat (limited to 'qt5')
-rw-r--r--qt5/.md5sum1
-rw-r--r--qt5/Pkgfile8
-rw-r--r--qt5/qtbase-memory-leak.patch135
3 files changed, 142 insertions, 2 deletions
diff --git a/qt5/.md5sum b/qt5/.md5sum
index bce791b97..35360b272 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 56994f2a1..97c6b8f22 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 000000000..009b15576
--- /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

Generated by cgit