aboutsummaryrefslogtreecommitdiffstats
path: root/src/particles/qquickimageparticle.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@digia.com>2016-03-03 14:54:31 +0100
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>2016-03-04 13:54:50 +0000
commit5a9734c0d071b7490b3ef7edf5f080786dc89f79 (patch)
treeef8d18707d2f65df718ea785745d079ff3558fb8 /src/particles/qquickimageparticle.cpp
parent554566788f585caaef14d929cee6557ad929e06e (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.cpp55
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;
}