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

Reply via email to