Hello community, here is the log from the commit of package libqt5-qtdeclarative for openSUSE:Factory checked in at 2016-02-16 09:27:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libqt5-qtdeclarative (Old) and /work/SRC/openSUSE:Factory/.libqt5-qtdeclarative.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libqt5-qtdeclarative" Changes: -------- --- /work/SRC/openSUSE:Factory/libqt5-qtdeclarative/libqt5-qtdeclarative.changes 2015-10-19 22:44:56.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.libqt5-qtdeclarative.new/libqt5-qtdeclarative.changes 2016-02-16 09:27:42.000000000 +0100 @@ -1,0 +2,13 @@ +Sat Feb 13 01:54:31 UTC 2016 - m...@suse.com + +- Add 0001-scene-graph-fixed-memory-leak-in-qsgbatchrenderer-re.patch + fixing a memory leak, QTBUG#48799. + +------------------------------------------------------------------- +Mon Feb 1 17:00:44 UTC 2016 - hrvoje.sen...@gmail.com + +- Added sanitize-visibleItems-list-after-model-insertions.patch + and Refactor-FxViewItem-releasing-code.patch to help in resolving + kde#352055 and qtbug#48870 + +------------------------------------------------------------------- @@ -4 +17 @@ -- Update to 5.5.1 +- Update to 5.5.1 (boo#954149) New: ---- 0001-scene-graph-fixed-memory-leak-in-qsgbatchrenderer-re.patch Refactor-FxViewItem-releasing-code.patch sanitize-visibleItems-list-after-model-insertions.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libqt5-qtdeclarative.spec ++++++ --- /var/tmp/diff_new_pack.ncgEhi/_old 2016-02-16 09:27:43.000000000 +0100 +++ /var/tmp/diff_new_pack.ncgEhi/_new 2016-02-16 09:27:43.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package libqt5-qtdeclarative # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -35,6 +35,12 @@ Source1: baselibs.conf # PATCH-FIX-OPENSUSE sse2_nojit.patch -- enable JIT and sse2 only on sse2 case Patch100: sse2_nojit.patch +# PATCH-FIX-UPSTREAM Refactor-FxViewItem-releasing-code.patch +Patch101: Refactor-FxViewItem-releasing-code.patch +# PATCH-FIX-UPSTREAM sanitize-visibleItems-list-after-model-insertions.patch +Patch102: sanitize-visibleItems-list-after-model-insertions.patch +# PATCH-FIX-UPSTREAM QTBUG-48799 +Patch103: 0001-scene-graph-fixed-memory-leak-in-qsgbatchrenderer-re.patch BuildRequires: fdupes BuildRequires: libQt5Core-private-headers-devel >= %{version} BuildRequires: libQt5Gui-private-headers-devel >= %{version} @@ -72,6 +78,9 @@ %prep %setup -q -n qtdeclarative-opensource-src-%{real_version} %patch100 -p1 +%patch101 -p1 +%patch102 -p1 +%patch103 -p1 %package -n %libname Summary: Qt 5 Declarative Library ++++++ 0001-scene-graph-fixed-memory-leak-in-qsgbatchrenderer-re.patch ++++++ >From 19f54b2d2539171f682bcf32cdc7983294355e02 Mon Sep 17 00:00:00 2001 From: Martin Banky <martin.ba...@gmail.com> Date: Thu, 15 Oct 2015 23:07:32 -0700 Subject: [PATCH] Scene Graph: Fixed memory leak in QSGBatchRenderer::Renderer::map() In the uncommon case (m_context->hasBrokenIndexBufferObjects() || m_visualizeMode != VisualizeNothing) of mapping a buffer, malloc is called without first freeing the previous malloc. Regression was introduced with: qt5 commit: 9347499e78f03710eaf24af3c1e7ac650d0ef81d qtdeclarative commit: a371bac3fba73f92aaa63a68d8ab1ae81a1d1031 [ChangeLog][QtQuick][Scene Graph] Fixed memory leak in QSGBatchRenderer::Renderer::map() Task-number: QTBUG-48799 Change-Id: I5ef4b7301d390463845aeb192851f86655962499 --- src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 60ada14..75923d7 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -902,7 +902,11 @@ void Renderer::map(Buffer *buffer, int byteSize, bool isIndexBuf) pool.resize(byteSize); buffer->data = pool.data(); } else { - buffer->data = (char *) malloc(byteSize); + if (buffer->size != byteSize) { + if (buffer->data) + free(buffer->data); + buffer->data = (char *) malloc(byteSize); + } } buffer->size = byteSize; -- 2.6.0 ++++++ Refactor-FxViewItem-releasing-code.patch ++++++ diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 20b6dd5..96759b1 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -81,6 +81,8 @@ public: bool removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) Q_DECL_OVERRIDE; void visibleItemsChanged() Q_DECL_OVERRIDE; + void removeItem(FxViewItem *item); + FxViewItem *newViewItem(int index, QQuickItem *item) Q_DECL_OVERRIDE; void initializeViewItem(FxViewItem *item) Q_DECL_OVERRIDE; bool releaseItem(FxViewItem *item) Q_DECL_OVERRIDE; @@ -686,6 +688,18 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal return changed; } +void QQuickListViewPrivate::removeItem(FxViewItem *item) +{ + if (item->transitionScheduledOrRunning()) { + qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item" << item->index << item->item->objectName(); + item->releaseAfterTransition = true; + releasePendingTransition.append(item); + } else { + qCDebug(lcItemViewDelegateLifecycle) << "\treleasing stationary item" << item->index << item->item->objectName(); + releaseItem(item); + } +} + bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal bufferTo) { FxViewItem *item = 0; @@ -708,13 +722,7 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer if (item->index != -1) visibleIndex++; visibleItems.removeAt(index); - if (item->transitionScheduledOrRunning()) { - qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item" << item->index << item->item->objectName(); - item->releaseAfterTransition = true; - releasePendingTransition.append(item); - } else { - releaseItem(item); - } + removeItem(item); if (index == 0) break; item = visibleItems.at(--index); @@ -730,13 +738,7 @@ bool QQuickListViewPrivate::removeNonVisibleItems(qreal bufferFrom, qreal buffer break; qCDebug(lcItemViewDelegateLifecycle) << "refill: remove last" << visibleIndex+visibleItems.count()-1 << item->position() << item->item->objectName(); visibleItems.removeLast(); - if (item->transitionScheduledOrRunning()) { - qCDebug(lcItemViewDelegateLifecycle) << "\tnot releasing animating item" << item->index << item->item->objectName(); - item->releaseAfterTransition = true; - releasePendingTransition.append(item); - } else { - releaseItem(item); - } + removeItem(item); changed = true; } ++++++ sanitize-visibleItems-list-after-model-insertions.patch ++++++ >From be1ef858f44e1523ba264520a0361981cf9b37c6 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich <gabriel.dedietr...@theqtcompany.com> Date: Wed, 25 Nov 2015 12:14:52 -0800 Subject: [PATCH] ListView: Sanitize visibleItems list after model insertions In QQuickListViewPrivate::applyInsertionChange(), we update the visibleItems list by first shifting the currently visible items and then we add as many items as the model was added and at the right position. We do this in such a way that we won't create items that will not be visible right away (and may be deleted right after by removeNonVisibleItems()). However, this may leave gaps in the item index sequence, and QQuickListView doesn't always recover gracefully from it. The purpose of this patch is to make sure those gaps are cleared right after inserting the new items. Since the insertions can happen in two different places (either before or after the first visible item) we need to update the visibleItems list accordingly. The way we sanitize visibleItems is by removing those items that lie beyond a possible index gap. If insertion happens before the first visible item, we'll remove all those items before the insertion point. If the insertion happens after the first visible item, we'll remove the items after the insertion point. Besides that, the logic for inserting before the visible position was wrong. As items are inserted bottom-up in that case, the insertion would start by just accounting for the item's size until the condition pos > from && insertionIdx < visibleIndex would become false only because 'pos' would be small enough. After that, the next loop run would start adding items before the 'from' position, which is wrong. Our fix is to move the condition outside the loop if the insertion index will be before the visible index and just account for the items' size in that case. Otherwise, the insertion happens as usual until pos < from. Change-Id: I35767cf6e9737bea1fe7677e580245fc7172710c Task-number: QTBUG-48870 --- src/quick/items/qquicklistview.cpp | 59 ++++++++++++++++++---- 1 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index c7df855..9f53586 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -3097,12 +3097,13 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch int i = 0; qreal from = tempPos - displayMarginBeginning - buffer; - for (i = count-1; i >= 0; --i) { - if (pos > from && insertionIdx < visibleIndex) { - // item won't be visible, just note the size for repositioning - insertResult->sizeChangesBeforeVisiblePos += averageSize + spacing; - pos -= averageSize + spacing; - } else { + if (insertionIdx < visibleIndex) { + if (pos >= from) { + // items won't be visible, just note the size for repositioning + insertResult->sizeChangesBeforeVisiblePos += count * (averageSize + spacing); + } + } else { + for (i = count-1; i >= 0 && pos >= from; --i) { // item is before first visible e.g. in cache buffer FxViewItem *item = 0; if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) @@ -3117,17 +3118,33 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch insertResult->changedFirstItem = true; if (!change.isMove()) { addedItems->append(item); - item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); + if (transitioner) + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); + else + static_cast<FxListItemSG *>(item)->setPosition(pos, true); } insertResult->sizeChangesBeforeVisiblePos += item->size() + spacing; pos -= item->size() + spacing; + index++; + } + } + + int firstOkIdx = -1; + for (int i = 0; i <= insertionIdx && i < visibleItems.count() - 1; i++) { + if (visibleItems.at(i)->index + 1 != visibleItems.at(i + 1)->index) { + firstOkIdx = i + 1; + break; } - index++; } + for (int i = 0; i < firstOkIdx; i++) { + FxViewItem *nvItem = visibleItems.takeFirst(); + addedItems->removeOne(nvItem); + removeItem(nvItem); + } + } else { - int i = 0; qreal to = buffer + displayMarginEnd + tempPos + size(); - for (i = 0; i < count && pos <= to; ++i) { + for (int i = 0; i < count && pos <= to; ++i) { FxViewItem *item = 0; if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i)))) item->index = modelIndex + i; @@ -3147,12 +3164,32 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch movingIntoView->append(MovedItem(item, change.moveKey(item->index))); } else { addedItems->append(item); - item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); + if (transitioner) + item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::AddTransition, true); + else + static_cast<FxListItemSG *>(item)->setPosition(pos, true); } insertResult->sizeChangesAfterVisiblePos += item->size() + spacing; pos += item->size() + spacing; ++index; } + + if (0 < index && index < visibleItems.count()) { + FxViewItem *prevItem = visibleItems.at(index - 1); + FxViewItem *item = visibleItems.at(index); + if (prevItem->index != item->index - 1) { + int i = index; + qreal prevPos = prevItem->position(); + while (i < visibleItems.count()) { + FxListItemSG *nvItem = static_cast<FxListItemSG *>(visibleItems.takeLast()); + insertResult->sizeChangesAfterVisiblePos -= nvItem->size() + spacing; + addedItems->removeOne(nvItem); + if (nvItem->transitionScheduledOrRunning()) + nvItem->setPosition(prevPos + (nvItem->index - prevItem->index) * averageSize); + removeItem(nvItem); + } + } + } } updateVisibleIndex(); -- 2.6.2.2.g1b5ffa3