diff options
Diffstat (limited to 'src/particles')
-rw-r--r-- | src/particles/qquickcustomparticle.cpp | 42 | ||||
-rw-r--r-- | src/particles/qquickcustomparticle_p.h | 22 | ||||
-rw-r--r-- | src/particles/qquickimageparticle.cpp | 10 | ||||
-rw-r--r-- | src/particles/qquickparticleemitter_p.h | 2 | ||||
-rw-r--r-- | src/particles/qquickparticlepainter.cpp | 3 | ||||
-rw-r--r-- | src/particles/qquickv4particledata.cpp | 7 |
6 files changed, 52 insertions, 34 deletions
diff --git a/src/particles/qquickcustomparticle.cpp b/src/particles/qquickcustomparticle.cpp index 3cb7f6c2bf..c08ae3d9ff 100644 --- a/src/particles/qquickcustomparticle.cpp +++ b/src/particles/qquickcustomparticle.cpp @@ -94,6 +94,8 @@ struct PlainVertices { QQuickCustomParticle::QQuickCustomParticle(QQuickItem* parent) : QQuickParticlePainter(parent) + , m_common(this, [this](int mappedId){this->propertyChanged(mappedId);}) + , m_myMetaObject(nullptr) , m_dirtyUniforms(true) , m_dirtyUniformValues(true) , m_dirtyTextureProviders(true) @@ -113,7 +115,10 @@ QQuickCustomParticle::~QQuickCustomParticle() void QQuickCustomParticle::componentComplete() { - m_common.updateShader(this, Key::FragmentShader); + if (!m_myMetaObject) + m_myMetaObject = metaObject(); + + m_common.updateShader(this, m_myMetaObject, Key::FragmentShader); updateVertexShader(); reset(); QQuickParticlePainter::componentComplete(); @@ -137,7 +142,7 @@ void QQuickCustomParticle::setFragmentShader(const QByteArray &code) m_common.source.sourceCode[Key::FragmentShader] = code; m_dirtyProgram = true; if (isComponentComplete()) { - m_common.updateShader(this, Key::FragmentShader); + m_common.updateShader(this, m_myMetaObject, Key::FragmentShader); reset(); } emit fragmentShaderChanged(); @@ -201,9 +206,8 @@ void QQuickCustomParticle::setVertexShader(const QByteArray &code) void QQuickCustomParticle::updateVertexShader() { m_common.disconnectPropertySignals(this, Key::VertexShader); - qDeleteAll(m_common.signalMappers[Key::VertexShader]); m_common.uniformData[Key::VertexShader].clear(); - m_common.signalMappers[Key::VertexShader].clear(); + m_common.clearSignalMappers(Key::VertexShader); m_common.attributes.clear(); m_common.attributes.append("qt_ParticlePos"); m_common.attributes.append("qt_ParticleTex"); @@ -224,9 +228,9 @@ void QQuickCustomParticle::updateVertexShader() const QByteArray &code = m_common.source.sourceCode[Key::VertexShader]; if (!code.isEmpty()) - m_common.lookThroughShaderCode(this, Key::VertexShader, code); + m_common.lookThroughShaderCode(this, m_myMetaObject, Key::VertexShader, code); - m_common.connectPropertySignals(this, Key::VertexShader); + m_common.connectPropertySignals(this, m_myMetaObject, Key::VertexShader); } void QQuickCustomParticle::reset() @@ -237,7 +241,7 @@ void QQuickCustomParticle::reset() QSGNode *QQuickCustomParticle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { - QQuickShaderEffectNode *rootNode = static_cast<QQuickShaderEffectNode *>(oldNode); + QQuickOpenGLShaderEffectNode *rootNode = static_cast<QQuickOpenGLShaderEffectNode *>(oldNode); if (m_pleaseReset){ delete rootNode;//Automatically deletes children rootNode = 0; @@ -258,7 +262,7 @@ QSGNode *QQuickCustomParticle::updatePaintNode(QSGNode *oldNode, UpdatePaintNode return rootNode; } -QQuickShaderEffectNode *QQuickCustomParticle::prepareNextFrame(QQuickShaderEffectNode *rootNode) +QQuickOpenGLShaderEffectNode *QQuickCustomParticle::prepareNextFrame(QQuickOpenGLShaderEffectNode *rootNode) { if (!rootNode) rootNode = buildCustomNodes(); @@ -269,7 +273,7 @@ QQuickShaderEffectNode *QQuickCustomParticle::prepareNextFrame(QQuickShaderEffec if (m_dirtyProgram) { const bool isES = QOpenGLContext::currentContext()->isOpenGLES(); - QQuickShaderEffectMaterial *material = static_cast<QQuickShaderEffectMaterial *>(rootNode->material()); + QQuickOpenGLShaderEffectMaterial *material = static_cast<QQuickOpenGLShaderEffectMaterial *>(rootNode->material()); Q_ASSERT(material); Key s = m_common.source; @@ -292,7 +296,7 @@ QQuickShaderEffectNode *QQuickCustomParticle::prepareNextFrame(QQuickShaderEffec material->setProgramSource(s); material->attributes = m_common.attributes; - foreach (QQuickShaderEffectNode* node, m_nodes) + foreach (QQuickOpenGLShaderEffectNode* node, m_nodes) node->markDirty(QSGNode::DirtyMaterial); m_dirtyProgram = false; @@ -305,9 +309,9 @@ QQuickShaderEffectNode *QQuickCustomParticle::prepareNextFrame(QQuickShaderEffec return rootNode; } -QQuickShaderEffectNode* QQuickCustomParticle::buildCustomNodes() +QQuickOpenGLShaderEffectNode* QQuickCustomParticle::buildCustomNodes() { - typedef QHash<int, QQuickShaderEffectNode*>::const_iterator NodeHashConstIt; + typedef QHash<int, QQuickOpenGLShaderEffectNode*>::const_iterator NodeHashConstIt; if (!QOpenGLContext::currentContext()) return 0; @@ -325,14 +329,14 @@ QQuickShaderEffectNode* QQuickCustomParticle::buildCustomNodes() if (groups().isEmpty()) return 0; - QQuickShaderEffectNode *rootNode = 0; - QQuickShaderEffectMaterial *material = new QQuickShaderEffectMaterial; + QQuickOpenGLShaderEffectNode *rootNode = 0; + QQuickOpenGLShaderEffectMaterial *material = new QQuickOpenGLShaderEffectMaterial; m_dirtyProgram = true; for (auto groupId : groupIds()) { int count = m_system->groupData[groupId]->size(); - QQuickShaderEffectNode* node = new QQuickShaderEffectNode(); + QQuickOpenGLShaderEffectNode* node = new QQuickOpenGLShaderEffectNode(); m_nodes.insert(groupId, node); node->setMaterial(material); @@ -391,14 +395,14 @@ void QQuickCustomParticle::sourceDestroyed(QObject *object) void QQuickCustomParticle::propertyChanged(int mappedId) { bool textureProviderChanged; - m_common.propertyChanged(this, mappedId, &textureProviderChanged); + m_common.propertyChanged(this, m_myMetaObject, mappedId, &textureProviderChanged); m_dirtyTextureProviders |= textureProviderChanged; m_dirtyUniformValues = true; update(); } -void QQuickCustomParticle::buildData(QQuickShaderEffectNode *rootNode) +void QQuickCustomParticle::buildData(QQuickOpenGLShaderEffectNode *rootNode) { if (!rootNode) return; @@ -408,9 +412,9 @@ void QQuickCustomParticle::buildData(QQuickShaderEffectNode *rootNode) m_common.uniformData[shaderType][i].value = qVariantFromValue(m_lastTime); } } - m_common.updateMaterial(rootNode, static_cast<QQuickShaderEffectMaterial *>(rootNode->material()), + m_common.updateMaterial(rootNode, static_cast<QQuickOpenGLShaderEffectMaterial *>(rootNode->material()), m_dirtyUniforms, true, m_dirtyTextureProviders); - foreach (QQuickShaderEffectNode* node, m_nodes) + foreach (QQuickOpenGLShaderEffectNode* node, m_nodes) node->markDirty(QSGNode::DirtyMaterial); m_dirtyUniforms = m_dirtyUniformValues = m_dirtyTextureProviders = false; } diff --git a/src/particles/qquickcustomparticle_p.h b/src/particles/qquickcustomparticle_p.h index 25a3a1197c..e9d68cbe5c 100644 --- a/src/particles/qquickcustomparticle_p.h +++ b/src/particles/qquickcustomparticle_p.h @@ -51,8 +51,8 @@ // We mean it. // #include "qquickparticlepainter_p.h" -#include <private/qquickshadereffectnode_p.h> -#include <private/qquickshadereffect_p.h> +#include <private/qquickopenglshadereffectnode_p.h> +#include <private/qquickopenglshadereffect_p.h> #include <QSignalMapper> QT_BEGIN_NAMESPACE @@ -88,29 +88,31 @@ protected: virtual void commit(int gIdx, int pIdx); QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - QQuickShaderEffectNode *prepareNextFrame(QQuickShaderEffectNode *rootNode); + QQuickOpenGLShaderEffectNode *prepareNextFrame(QQuickOpenGLShaderEffectNode *rootNode); void reset(); void resize(int oldCount, int newCount); virtual void componentComplete(); - QQuickShaderEffectNode *buildCustomNodes(); + QQuickOpenGLShaderEffectNode *buildCustomNodes(); void sceneGraphInvalidated(); void itemChange(ItemChange change, const ItemChangeData &value); private Q_SLOTS: void sourceDestroyed(QObject *object); - void propertyChanged(int mappedId); private: - typedef QQuickShaderEffectMaterialKey Key; - typedef QQuickShaderEffectMaterial::UniformData UniformData; + void propertyChanged(int mappedId); + + typedef QQuickOpenGLShaderEffectMaterialKey Key; + typedef QQuickOpenGLShaderEffectMaterial::UniformData UniformData; - void buildData(QQuickShaderEffectNode *rootNode); + void buildData(QQuickOpenGLShaderEffectNode *rootNode); void updateVertexShader(); - QQuickShaderEffectCommon m_common; + QQuickOpenGLShaderEffectCommon m_common; + const QMetaObject *m_myMetaObject; - QHash<int, QQuickShaderEffectNode*> m_nodes; + QHash<int, QQuickOpenGLShaderEffectNode*> m_nodes; qreal m_lastTime; uint m_dirtyUniforms : 1; diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index 84536183ec..e6b921792f 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -49,6 +49,7 @@ #include <private/qquicksprite_p.h> #include <private/qquickspriteengine_p.h> #include <QOpenGLFunctions> +#include <QSGRendererInterface> #include <QtQuick/private/qsgshadersourcebuilder_p.h> #include <QtQuick/private/qsgtexture_p.h> #include <private/qqmlglobal_p.h> @@ -1471,8 +1472,17 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node) update(); } +static inline bool isOpenGL(QSGRenderContext *rc) +{ + QSGRendererInterface *rif = rc->sceneGraphContext()->rendererInterface(rc); + return !rif || rif->graphicsApi() == QSGRendererInterface::OpenGL; +} + QSGNode *QQuickImageParticle::updatePaintNode(QSGNode *node, UpdatePaintNodeData *) { + if (!node && !isOpenGL(QQuickItemPrivate::get(this)->sceneGraphRenderContext())) + return 0; + if (m_pleaseReset){ if (node) delete node; diff --git a/src/particles/qquickparticleemitter_p.h b/src/particles/qquickparticleemitter_p.h index dd55fdc7a6..b3f96ae3e6 100644 --- a/src/particles/qquickparticleemitter_p.h +++ b/src/particles/qquickparticleemitter_p.h @@ -62,7 +62,7 @@ #include <QPointF> QT_BEGIN_NAMESPACE -class QQuickParticleEmitter : public QQuickItem +class Q_QUICKPARTICLES_PRIVATE_EXPORT QQuickParticleEmitter : public QQuickItem { Q_OBJECT Q_PROPERTY(QQuickParticleSystem* system READ system WRITE setSystem NOTIFY systemChanged) diff --git a/src/particles/qquickparticlepainter.cpp b/src/particles/qquickparticlepainter.cpp index d6303eb219..0c2521cd9e 100644 --- a/src/particles/qquickparticlepainter.cpp +++ b/src/particles/qquickparticlepainter.cpp @@ -103,7 +103,8 @@ void QQuickParticlePainter::recalculateGroupIds() const m_groupIdsNeedRecalculation = false; m_groupIds.clear(); - for (const QString &str : groups()) { + const auto groupList = groups(); + for (const QString &str : groupList) { QQuickParticleGroupData::ID groupId = m_system->groupIds.value(str, QQuickParticleGroupData::InvalidID); if (groupId == QQuickParticleGroupData::InvalidID) { // invalid data, not finished setting up, or whatever. Fallback: do not cache. diff --git a/src/particles/qquickv4particledata.cpp b/src/particles/qquickv4particledata.cpp index 99451057ce..bd43d45c38 100644 --- a/src/particles/qquickv4particledata.cpp +++ b/src/particles/qquickv4particledata.cpp @@ -273,10 +273,11 @@ QT_BEGIN_NAMESPACE struct QV4ParticleData : public QV4::Object { struct Data : QV4::Object::Data { - Data(QQuickParticleData *datum, QQuickParticleSystem* particleSystem) - : datum(datum) - , particleSystem(particleSystem) + void init(QQuickParticleData *datum, QQuickParticleSystem* particleSystem) { + Object::init(); + this->datum = datum; + this->particleSystem = particleSystem; } QQuickParticleData* datum;//TODO: Guard needed? QQuickParticleSystem* particleSystem; |