From 8c257264c1873dcf11115d738f9510c1b65da844 Mon Sep 17 00:00:00 2001 From: Andy Nichols Date: Tue, 14 Oct 2014 15:31:05 +0200 Subject: QQuickCustomParticle: Check for current OpenGL Context before use QQuickCustomParticle::buildCustomNodes() assumes there is a valid OpenGL context, but when there is not it will simply crash. Instead we check for a valid current OpenGL context first, and return 0 if it is not availalbe. This needed for the Qt Quick 2d Renderer. Change-Id: I6bfcfc8fa9581bfd27015f719fc527c36492eade Reviewed-by: aavit Reviewed-by: Gunnar Sletta --- src/particles/qquickcustomparticle.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/particles') diff --git a/src/particles/qquickcustomparticle.cpp b/src/particles/qquickcustomparticle.cpp index e03acd693a..2ab24175a3 100644 --- a/src/particles/qquickcustomparticle.cpp +++ b/src/particles/qquickcustomparticle.cpp @@ -303,6 +303,9 @@ QQuickShaderEffectNode *QQuickCustomParticle::prepareNextFrame(QQuickShaderEffec QQuickShaderEffectNode* QQuickCustomParticle::buildCustomNodes() { + if (!QOpenGLContext::currentContext()) + return 0; + if (QOpenGLContext::currentContext()->isOpenGLES() && m_count * 4 > 0xffff) { printf("CustomParticle: Too many particles... \n"); return 0; -- cgit v1.2.3 From 32af8055985c1f978574eec62512638f472e8290 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Thu, 23 Oct 2014 16:01:57 +0200 Subject: Fix leaks in QQuickImageParticle Make sure that ImageData instances, m_shadowData as well as the QSGGeometry of particle nodes are destroyed together with their QQuickImageParticle. Also implement the assignment operator for QQuickParticleData to avoid its v8Datum pointer to be copied over to the shadow datum in getShadowDatum. This would cause a double delete of the QQuickV4ParticleData when trying to call clearShadows() in the destructor. Task-number: QTBUG-36782 Change-Id: Ie03f2be0415daeb7f4f6e5f92295a3ab26a62155 Reviewed-by: Joerg Bornemann --- src/particles/qquickimageparticle.cpp | 23 ++++++++++------------- src/particles/qquickimageparticle_p.h | 9 ++++----- src/particles/qquickparticlesystem.cpp | 20 ++++++++++++++++++++ src/particles/qquickparticlesystem_p.h | 3 +++ 4 files changed, 37 insertions(+), 18 deletions(-) (limited to 'src/particles') diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index 60a67d55a6..50fa9dbc64 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -706,10 +706,6 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size) QQuickImageParticle::QQuickImageParticle(QQuickItem* parent) : QQuickParticlePainter(parent) - , m_image(0) - , m_colorTable(0) - , m_sizeTable(0) - , m_opacityTable(0) , m_color_variation(0.0) , m_material(0) , m_alphaVariation(0.0) @@ -742,6 +738,7 @@ QQuickImageParticle::QQuickImageParticle(QQuickItem* parent) QQuickImageParticle::~QQuickImageParticle() { + clearShadows(); } QQmlListProperty QQuickImageParticle::sprites() @@ -759,15 +756,14 @@ void QQuickImageParticle::setImage(const QUrl &image) { if (image.isEmpty()){ if (m_image) { - delete m_image; - m_image = 0; + m_image.reset(); emit imageChanged(); } return; } if (!m_image) - m_image = new ImageData; + m_image.reset(new ImageData); if (image == m_image->source) return; m_image->source = image; @@ -780,14 +776,14 @@ void QQuickImageParticle::setColortable(const QUrl &table) { if (table.isEmpty()){ if (m_colorTable) { - delete m_colorTable; + m_colorTable.reset(); emit colortableChanged(); } return; } if (!m_colorTable) - m_colorTable = new ImageData; + m_colorTable.reset(new ImageData); if (table == m_colorTable->source) return; m_colorTable->source = table; @@ -799,14 +795,14 @@ void QQuickImageParticle::setSizetable(const QUrl &table) { if (table.isEmpty()){ if (m_sizeTable) { - delete m_sizeTable; + m_sizeTable.reset(); emit sizetableChanged(); } return; } if (!m_sizeTable) - m_sizeTable = new ImageData; + m_sizeTable.reset(new ImageData); if (table == m_sizeTable->source) return; m_sizeTable->source = table; @@ -818,14 +814,14 @@ void QQuickImageParticle::setOpacitytable(const QUrl &table) { if (table.isEmpty()){ if (m_opacityTable) { - delete m_opacityTable; + m_opacityTable.reset(); emit opacitytableChanged(); } return; } if (!m_opacityTable) - m_opacityTable = new ImageData; + m_opacityTable.reset(new ImageData); if (table == m_opacityTable->source) return; m_opacityTable->source = table; @@ -1406,6 +1402,7 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node) else //Simple g = new QSGGeometry(SimpleParticle_AttributeSet, count, 0); + node->setFlag(QSGNode::OwnsGeometry); node->setGeometry(g); if (perfLevel <= Colored){ g->setDrawingMode(GL_POINTS); diff --git a/src/particles/qquickimageparticle_p.h b/src/particles/qquickimageparticle_p.h index ac61ceeb10..657d945bca 100644 --- a/src/particles/qquickimageparticle_p.h +++ b/src/particles/qquickimageparticle_p.h @@ -352,17 +352,16 @@ private: QUrl source; QQuickPixmap pix; }; - ImageData *m_image; - ImageData *m_colorTable; - ImageData *m_sizeTable; - ImageData *m_opacityTable; + QScopedPointer m_image; + QScopedPointer m_colorTable; + QScopedPointer m_sizeTable; + QScopedPointer m_opacityTable; bool loadingSomething(); QColor m_color; qreal m_color_variation; - QSGGeometryNode *m_rootNode; 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 diff --git a/src/particles/qquickparticlesystem.cpp b/src/particles/qquickparticlesystem.cpp index 79d88ee601..db5d607922 100644 --- a/src/particles/qquickparticlesystem.cpp +++ b/src/particles/qquickparticlesystem.cpp @@ -478,6 +478,26 @@ QQuickParticleData::~QQuickParticleData() delete v8Datum; } +QQuickParticleData::QQuickParticleData(const QQuickParticleData &other) +{ + *this = other; +} + +QQuickParticleData &QQuickParticleData::operator=(const QQuickParticleData &other) +{ + clone(other); + + group = other.group; + e = other.e; + system = other.system; + index = other.index; + systemIndex = other.systemIndex; + // Lazily initialized + v8Datum = 0; + + return *this; +} + void QQuickParticleData::clone(const QQuickParticleData& other) { x = other.x; diff --git a/src/particles/qquickparticlesystem_p.h b/src/particles/qquickparticlesystem_p.h index 81d78de8ac..4d6c153282 100644 --- a/src/particles/qquickparticlesystem_p.h +++ b/src/particles/qquickparticlesystem_p.h @@ -137,6 +137,9 @@ public: QQuickParticleData(QQuickParticleSystem* sys); ~QQuickParticleData(); + QQuickParticleData(const QQuickParticleData &other); + QQuickParticleData &operator=(const QQuickParticleData &other); + //Convenience functions for working backwards, because parameters are from the start of particle life //If setting multiple parameters at once, doing the conversion yourself will be faster. -- cgit v1.2.3