diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2016-03-03 14:54:31 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2016-03-04 13:54:50 +0000 |
commit | 5a9734c0d071b7490b3ef7edf5f080786dc89f79 (patch) | |
tree | ef8d18707d2f65df718ea785745d079ff3558fb8 /src/particles/qquickimageparticle.cpp | |
parent | 554566788f585caaef14d929cee6557ad929e06e (diff) |
Particles: reduce excessive hash accesses to a more passable level.
By caching the group id in the particle emitter, and groups in the
painter.
Test case: samegame, 1 player, click 1 set of 3 stones, quit.
QQuickParticleSystem::emittersChanged(), before patch:
- 64M instr. inclusive
- 145,880 calls to findNode (29M instr.)
after:
- 21M instr. inclusive
- 0 calls to findNode
- 25 calls to QQuickParticlePainter::recalculateGroupIds (9800 instr.
inclusive).
Change-Id: I4aba9d50100513c6b7cdd230e30b3aecaf84485a
Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
Diffstat (limited to 'src/particles/qquickimageparticle.cpp')
-rw-r--r-- | src/particles/qquickimageparticle.cpp | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index c88a0b002b..5f2d1db663 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -1020,10 +1020,13 @@ void QQuickImageParticle::setEntryEffect(EntryEffect arg) void QQuickImageParticle::resetColor() { m_explicitColor = false; - foreach (const QString &str, m_groups) - foreach (QQuickParticleData* d, m_system->groupData[m_system->groupIds[str]]->data) - if (d->colorOwner == this) + for (auto groupId : groupIds()) { + for (QQuickParticleData* d : qAsConst(m_system->groupData[groupId]->data)) { + if (d->colorOwner == this) { d->colorOwner = 0; + } + } + } m_color = QColor(); m_color_variation = 0.0f; m_redVariation = 0.0f; @@ -1036,10 +1039,13 @@ void QQuickImageParticle::resetColor() void QQuickImageParticle::resetRotation() { m_explicitRotation = false; - foreach (const QString &str, m_groups) - foreach (QQuickParticleData* d, m_system->groupData[m_system->groupIds[str]]->data) - if (d->rotationOwner == this) + for (auto groupId : groupIds()) { + for (QQuickParticleData* d : qAsConst(m_system->groupData[groupId]->data)) { + if (d->rotationOwner == this) { d->rotationOwner = 0; + } + } + } m_rotation = 0; m_rotationVariation = 0; m_rotationVelocity = 0; @@ -1050,10 +1056,13 @@ void QQuickImageParticle::resetRotation() void QQuickImageParticle::resetDeformation() { m_explicitDeformation = false; - foreach (const QString &str, m_groups) - foreach (QQuickParticleData* d, m_system->groupData[m_system->groupIds[str]]->data) - if (d->deformationOwner == this) + for (auto groupId : groupIds()) { + for (QQuickParticleData* d : qAsConst(m_system->groupData[groupId]->data)) { + if (d->deformationOwner == this) { d->deformationOwner = 0; + } + } + } if (m_xVector) delete m_xVector; if (m_yVector) @@ -1255,9 +1264,9 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node) perfLevel = Simple; } - foreach (const QString &str, m_groups){//For sharing higher levels, need to have highest used so it renders - int gIdx = m_system->groupIds[str]; - foreach (QQuickParticlePainter* p, m_system->groupData[gIdx]->painters){ + for (auto groupId : groupIds()) { + //For sharing higher levels, need to have highest used so it renders + for (QQuickParticlePainter* p : qAsConst(m_system->groupData[groupId]->painters)) { QQuickImageParticle* other = qobject_cast<QQuickImageParticle*>(p); if (other){ if (other->perfLevel > perfLevel) { @@ -1382,16 +1391,15 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node) } m_nodes.clear(); - foreach (const QString &str, m_groups){ - int gIdx = m_system->groupIds[str]; - int count = m_system->groupData[gIdx]->size(); + for (auto groupId : groupIds()) { + int count = m_system->groupData[groupId]->size(); QSGGeometryNode* node = new QSGGeometryNode(); node->setMaterial(m_material); node->markDirty(QSGNode::DirtyMaterial); - m_nodes.insert(gIdx, node); - m_idxStarts.insert(gIdx, m_lastIdxStart); - m_startsIdx.append(qMakePair<int,int>(m_lastIdxStart, gIdx)); + m_nodes.insert(groupId, node); + m_idxStarts.insert(groupId, m_lastIdxStart); + m_startsIdx.append(qMakePair<int,int>(m_lastIdxStart, groupId)); m_lastIdxStart += count; //Create Particle Geometry @@ -1423,7 +1431,7 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node) g->setDrawingMode(GL_TRIANGLES); for (int p=0; p < count; ++p) - commit(gIdx, p);//commit sets geometry for the node, has its own perfLevel switch + commit(groupId, p);//commit sets geometry for the node, has its own perfLevel switch if (perfLevel == Sprites) initTexCoords<SpriteVertex>((SpriteVertex*)g->vertexData(), vCount); @@ -1538,10 +1546,9 @@ void QQuickImageParticle::prepareNextFrame(QSGNode **node) void QQuickImageParticle::spritesUpdate(qreal time) { // Sprite progression handled CPU side, so as to have per-frame control. - foreach (const QString &str, m_groups) { - int gIdx = m_system->groupIds[str]; - foreach (QQuickParticleData* mainDatum, m_system->groupData[gIdx]->data) { - QSGGeometryNode *node = m_nodes[gIdx]; + for (auto groupId : groupIds()) { + for (QQuickParticleData* mainDatum : qAsConst(m_system->groupData[groupId]->data)) { + QSGGeometryNode *node = m_nodes[groupId]; if (!node) continue; //TODO: Interpolate between two different animations if it's going to transition next frame @@ -1549,7 +1556,7 @@ void QQuickImageParticle::spritesUpdate(qreal time) QQuickParticleData* datum = (mainDatum->animationOwner == this ? mainDatum : getShadowDatum(mainDatum)); int spriteIdx = 0; for (int i = 0; i<m_startsIdx.count(); i++) { - if (m_startsIdx[i].second == gIdx){ + if (m_startsIdx[i].second == groupId){ spriteIdx = m_startsIdx[i].first + datum->index; break; } |