Accepting request 359195 from KDE:Qt5
1 OBS-URL: https://build.opensuse.org/request/show/359195 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libqt5-qtdeclarative?expand=0&rev=28
This commit is contained in:
parent
bbd98519f1
commit
3dfeb5c7b0
@ -0,0 +1,43 @@
|
|||||||
|
From 19f54b2d2539171f682bcf32cdc7983294355e02 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Martin Banky <Martin.Banky@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
|
||||||
|
|
62
Refactor-FxViewItem-releasing-code.patch
Normal file
62
Refactor-FxViewItem-releasing-code.patch
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,20 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Sat Feb 13 01:54:31 UTC 2016 - matz@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.senjan@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
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Fri Oct 16 20:22:26 UTC 2015 - hrvoje.senjan@gmail.com
|
Fri Oct 16 20:22:26 UTC 2015 - hrvoje.senjan@gmail.com
|
||||||
|
|
||||||
- Update to 5.5.1
|
- Update to 5.5.1 (boo#954149)
|
||||||
* For more details please see:
|
* For more details please see:
|
||||||
http://blog.qt.io/blog/2015/10/15/qt-5-5-1-released/
|
http://blog.qt.io/blog/2015/10/15/qt-5-5-1-released/
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# spec file for package libqt5-qtdeclarative
|
# 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
|
# All modifications and additions to the file contributed by third parties
|
||||||
# remain the property of their copyright owners, unless otherwise agreed
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
@ -35,6 +35,12 @@ Source: %{tar_version}.tar.xz
|
|||||||
Source1: baselibs.conf
|
Source1: baselibs.conf
|
||||||
# PATCH-FIX-OPENSUSE sse2_nojit.patch -- enable JIT and sse2 only on sse2 case
|
# PATCH-FIX-OPENSUSE sse2_nojit.patch -- enable JIT and sse2 only on sse2 case
|
||||||
Patch100: sse2_nojit.patch
|
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: fdupes
|
||||||
BuildRequires: libQt5Core-private-headers-devel >= %{version}
|
BuildRequires: libQt5Core-private-headers-devel >= %{version}
|
||||||
BuildRequires: libQt5Gui-private-headers-devel >= %{version}
|
BuildRequires: libQt5Gui-private-headers-devel >= %{version}
|
||||||
@ -72,6 +78,9 @@ handling.
|
|||||||
%prep
|
%prep
|
||||||
%setup -q -n qtdeclarative-opensource-src-%{real_version}
|
%setup -q -n qtdeclarative-opensource-src-%{real_version}
|
||||||
%patch100 -p1
|
%patch100 -p1
|
||||||
|
%patch101 -p1
|
||||||
|
%patch102 -p1
|
||||||
|
%patch103 -p1
|
||||||
|
|
||||||
%package -n %libname
|
%package -n %libname
|
||||||
Summary: Qt 5 Declarative Library
|
Summary: Qt 5 Declarative Library
|
||||||
|
141
sanitize-visibleItems-list-after-model-insertions.patch
Normal file
141
sanitize-visibleItems-list-after-model-insertions.patch
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
From be1ef858f44e1523ba264520a0361981cf9b37c6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Gabriel de Dietrich <gabriel.dedietrich@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
|
Loading…
Reference in New Issue
Block a user