From 6e03533f9432eb1695e3c3bbe65667974b5415b4 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 12 Dec 2017 15:19:30 +0100 Subject: Fix image particle flickering due to broken state machine logic A null QSGNode cannot be returned since that leads to not showing anything in the next frame. That is unacceptable in case there are already particles displayed and we are merely regenerating due to the increased number of particles. Task-number: QTBUG-54673 Change-Id: If610c56f6d82d35a8de6b435fd8b18ceb7adf2e7 Reviewed-by: Laszlo Agocs --- src/particles/qquickimageparticle.cpp | 18 ++++++++++++++++-- src/particles/qquickimageparticle_p.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'src/particles') diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index 0b1de08ea3..9f87297b22 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -701,6 +701,7 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size) QQuickImageParticle::QQuickImageParticle(QQuickItem* parent) : QQuickParticlePainter(parent) , m_color_variation(0.0) + , m_outgoingNode(nullptr) , m_material(nullptr) , m_alphaVariation(0.0) , m_alpha(1.0) @@ -744,6 +745,8 @@ void QQuickImageParticle::sceneGraphInvalidated() { m_nodes.clear(); m_material = nullptr; + delete m_outgoingNode; + m_outgoingNode = nullptr; } void QQuickImageParticle::setImage(const QUrl &image) @@ -1476,8 +1479,11 @@ QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData return nullptr; if (m_pleaseReset){ - if (node) - delete node; + // Cannot just destroy the node and then return null (in case image + // loading is still in progress). Rather, keep track of the old node + // until we have a new one. + delete m_outgoingNode; + m_outgoingNode = node; node = nullptr; m_lastLevel = perfLevel; @@ -1491,6 +1497,9 @@ QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData m_pleaseReset = false; m_startedImageLoading = 0;//Cancel a part-way build (may still have a pending load) + } else if (!m_material) { + delete node; + node = nullptr; } if (m_system && m_system->isRunning() && !m_system->isPaused()){ @@ -1504,6 +1513,11 @@ QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData } } + if (!node) { + node = m_outgoingNode; + m_outgoingNode = nullptr; + } + return node; } diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h index 95323c25a6..e9ac56d64e 100644 --- a/src/particles/qquickimageparticle_p.h +++ b/src/particles/qquickimageparticle_p.h @@ -379,6 +379,7 @@ private: QColor m_color; qreal m_color_variation; + QSGNode *m_outgoingNode; QHash m_nodes; QHash m_idxStarts;//TODO: Proper resizing will lead to needing a spriteEngine per particle - do this after sprite engine gains transparent sharing? QList > m_startsIdx;//Same data, optimized for alternate retrieval -- cgit v1.2.3