From 152a35b027258188bb57db2bafebe5b46d88eb43 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 15 Dec 2011 13:29:48 +1000 Subject: [PATCH] Fix sprite-less sprite mode Sprite performance mode is supposed to work even without sprites, mostly for testing purposes. Also renamed the testing variable from bloat to bypassOptimizations, and removed it from the QML API (although it previously was hidden). Change-Id: I436554d4ee2ed3a1770839b28aba8d8ef843469a Reviewed-by: Martin Jones --- src/quick/particles/qquickimageparticle.cpp | 54 ++++++++++++++++------------ src/quick/particles/qquickimageparticle_p.h | 9 +++-- src/quick/particles/qquickparticlesystem.cpp | 2 +- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/quick/particles/qquickimageparticle.cpp b/src/quick/particles/qquickimageparticle.cpp index 81afce4..1566e7e 100644 --- a/src/quick/particles/qquickimageparticle.cpp +++ b/src/quick/particles/qquickimageparticle.cpp @@ -818,7 +818,7 @@ QQuickImageParticle::QQuickImageParticle(QQuickItem* parent) , m_explicitRotation(false) , m_explicitDeformation(false) , m_explicitAnimation(false) - , m_bloat(false) + , m_bypassOptimizations(false) , perfLevel(Unknown) , m_lastLevel(Unknown) , m_debugMode(false) @@ -1036,11 +1036,11 @@ void QQuickImageParticle::setSpritesInterpolate(bool arg) } } -void QQuickImageParticle::setBloat(bool arg) +void QQuickImageParticle::setBypassOptimizations(bool arg) { - if (m_bloat != arg) { - m_bloat = arg; - emit bloatChanged(arg); + if (m_bypassOptimizations != arg) { + m_bypassOptimizations = arg; + emit bypassOptimizationsChanged(arg); } if (perfLevel < 9999) reset(); @@ -1222,7 +1222,7 @@ QSGGeometryNode* QQuickImageParticle::buildParticleNodes() if (count() <= 0) return 0; - if (m_sprites.count() || m_bloat) { + if (m_sprites.count() || m_bypassOptimizations) { perfLevel = Sprites; } else if (!m_colortable_name.isEmpty() || !m_sizetable_name.isEmpty() || !m_opacitytable_name.isEmpty()) { @@ -1264,12 +1264,16 @@ QSGGeometryNode* QQuickImageParticle::buildParticleNodes() if (perfLevel >= Sprites){ if (!m_spriteEngine) { qWarning() << "ImageParticle: No sprite engine..."; - return 0; + //Sprite performance mode with static image is supported, but not advised + //Note that in this case it always uses shadow data + } else { + image = m_spriteEngine->assembledImage(); + if (image.isNull())//Warning is printed in engine + return 0; } - image = m_spriteEngine->assembledImage(); - if (image.isNull())//Warning is printed in engine - return 0; - } else { + } + + if ( image.isNull() ) { image = QImage(m_image_name.toLocalFile()); if (image.isNull()) { printf("ImageParticle: loading image failed '%s'\n", qPrintable(m_image_name.toLocalFile())); @@ -1289,7 +1293,8 @@ QSGGeometryNode* QQuickImageParticle::buildParticleNodes() case Sprites: m_material = SpriteMaterial::createMaterial(); getState(m_material)->animSheetSize = QSizeF(image.size()); - m_spriteEngine->setCount(m_count); + if (m_spriteEngine) + m_spriteEngine->setCount(m_count); case Tabled: if (!m_material) m_material = TabledMaterial::createMaterial(); @@ -1319,6 +1324,7 @@ QSGGeometryNode* QQuickImageParticle::buildParticleNodes() m_material->setFlag(QSGMaterial::Blending); } + m_nodes.clear(); foreach (const QString &str, m_groups){ int gIdx = m_system->groupIds[str]; int count = m_system->groupData[gIdx]->size(); @@ -1448,7 +1454,8 @@ void QQuickImageParticle::prepareNextFrame() switch (perfLevel){//Fall-through intended case Sprites: //Advance State - m_spriteEngine->updateSprites(timeStamp); + if (m_spriteEngine) + m_spriteEngine->updateSprites(timeStamp); case Tabled: case Deformable: case Colored: @@ -1457,7 +1464,6 @@ void QQuickImageParticle::prepareNextFrame() getState(m_material)->timestamp = time; break; } - foreach (QSGGeometryNode* node, m_nodes) node->markDirty(QSGNode::DirtyMaterial); } @@ -1520,7 +1526,7 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx) switch (perfLevel){//Fall-through is intended on all of them case Sprites: // Initial Sprite State - if (m_explicitAnimation){ + if (m_explicitAnimation && m_spriteEngine){ if (!datum->animationOwner) datum->animationOwner = this; QQuickParticleData* writeTo = (datum->animationOwner == this ? datum : getShadowDatum(datum)); @@ -1534,12 +1540,16 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx) writeTo->animY = m_spriteEngine->spriteY(spriteIdx); writeTo->animWidth = m_spriteEngine->spriteWidth(spriteIdx); writeTo->animHeight = m_spriteEngine->spriteHeight(spriteIdx); - }else{ - writeTo->frameCount = 1; - writeTo->frameDuration = 9999; - writeTo->animX = writeTo->animY = 0; - writeTo->animWidth = writeTo->animHeight = 1; } + } else { + QQuickParticleData* writeTo = getShadowDatum(datum); + writeTo->animT = datum->t; + writeTo->frameCount = 1; + writeTo->frameDuration = 60000000.0; + writeTo->animT = 0; + writeTo->animX = writeTo->animY = 0; + writeTo->animWidth = getState(m_material)->animSheetSize.width(); + writeTo->animHeight = getState(m_material)->animSheetSize.height(); } case Tabled: case Deformable: @@ -1656,8 +1666,8 @@ void QQuickImageParticle::commit(int gIdx, int pIdx) spriteVertices[i].rotationSpeed = datum->rotationSpeed; spriteVertices[i].autoRotate = datum->autoRotate; } - spriteVertices[i].animInterpolate = m_spritesInterpolate ? 1.0 : 0.0;//### Shadow? In particleData? Or uniform? - if (m_explicitAnimation && datum->animationOwner != this) { + spriteVertices[i].animInterpolate = m_spriteEngine ? (m_spritesInterpolate ? 1.0 : 0.0) : 0.0;//### Shadow? In particleData? Or uniform? + if (!m_spriteEngine || (m_explicitAnimation && datum->animationOwner != this)) { QQuickParticleData* shadow = getShadowDatum(datum); spriteVertices[i].frameDuration = shadow->frameDuration; spriteVertices[i].frameCount = shadow->frameCount; diff --git a/src/quick/particles/qquickimageparticle_p.h b/src/quick/particles/qquickimageparticle_p.h index 61c24ed..d8ba26b 100644 --- a/src/quick/particles/qquickimageparticle_p.h +++ b/src/quick/particles/qquickimageparticle_p.h @@ -182,7 +182,6 @@ class QQuickImageParticle : public QQuickParticlePainter Q_PROPERTY(bool spritesInterpolate READ spritesInterpolate WRITE setSpritesInterpolate NOTIFY spritesInterpolateChanged) Q_PROPERTY(EntryEffect entryEffect READ entryEffect WRITE setEntryEffect NOTIFY entryEffectChanged) - Q_PROPERTY(bool bloat READ bloat WRITE setBloat NOTIFY bloatChanged)//Just a debugging property to bypass optimizations Q_ENUMS(EntryEffect) public: explicit QQuickImageParticle(QQuickItem *parent = 0); @@ -251,7 +250,7 @@ public: bool spritesInterpolate() const { return m_spritesInterpolate; } - bool bloat() const { return m_bloat; } + bool bypassOptimizations() const { return m_bypassOptimizations; } EntryEffect entryEffect() const { return m_entryEffect; } @@ -295,7 +294,7 @@ signals: void spritesInterpolateChanged(bool arg); - void bloatChanged(bool arg); + void bypassOptimizationsChanged(bool arg); void entryEffectChanged(EntryEffect arg); @@ -327,7 +326,7 @@ public slots: void setSpritesInterpolate(bool arg); - void setBloat(bool arg); + void setBypassOptimizations(bool arg); void setEntryEffect(EntryEffect arg); @@ -389,7 +388,7 @@ private: void clearShadows(); QQuickParticleData* getShadowDatum(QQuickParticleData* datum); - bool m_bloat; + bool m_bypassOptimizations; PerformanceLevel perfLevel; PerformanceLevel m_lastLevel; diff --git a/src/quick/particles/qquickparticlesystem.cpp b/src/quick/particles/qquickparticlesystem.cpp index 676f191..cbb2605 100644 --- a/src/quick/particles/qquickparticlesystem.cpp +++ b/src/quick/particles/qquickparticlesystem.cpp @@ -835,7 +835,7 @@ void QQuickParticleSystem::reset() void QQuickParticleSystem::loadPainter(QObject *p) { - if (!m_componentComplete) + if (!m_componentComplete || !p) return; QQuickParticlePainter* painter = qobject_cast(p); -- 2.7.4