aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/particles/qsgimageparticle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/particles/qsgimageparticle.cpp')
-rw-r--r--src/declarative/particles/qsgimageparticle.cpp255
1 files changed, 165 insertions, 90 deletions
diff --git a/src/declarative/particles/qsgimageparticle.cpp b/src/declarative/particles/qsgimageparticle.cpp
index c9df5f4dbd..15bc88b4c3 100644
--- a/src/declarative/particles/qsgimageparticle.cpp
+++ b/src/declarative/particles/qsgimageparticle.cpp
@@ -305,6 +305,62 @@ QSGImageParticle::QSGImageParticle(QSGItem* parent)
, m_lastLevel(Unknown)
{
setFlag(ItemHasContents);
+ //TODO: Clean up defaults here and in custom
+ m_defaultUltra = new UltraVertices;
+ m_defaultSimple = new SimpleVertices;
+ UltraVertex *vertices = (UltraVertex *) m_defaultUltra;
+ SimpleVertex *vertices2 = (SimpleVertex *) m_defaultSimple;
+ for (int i=0; i<4; ++i) {
+ vertices2[i].x = vertices[i].x = 0;
+ vertices2[i].y = vertices[i].y = 0;
+ vertices2[i].t = vertices[i].t = -1;
+ vertices2[i].lifeSpan = vertices[i].lifeSpan = 0;
+ vertices2[i].size = vertices[i].size = 0;
+ vertices2[i].endSize = vertices[i].endSize = 0;
+ vertices2[i].sx = vertices[i].sx = 0;
+ vertices2[i].sy = vertices[i].sy = 0;
+ vertices2[i].ax = vertices[i].ax = 0;
+ vertices2[i].ay = vertices[i].ay = 0;
+ vertices[i].xx = 1;
+ vertices[i].xy = 0;
+ vertices[i].yx = 0;
+ vertices[i].yy = 1;
+ vertices[i].rotation = 0;
+ vertices[i].rotationSpeed = 0;
+ vertices[i].autoRotate = 0;
+ vertices[i].animIdx = -1;
+ vertices[i].frameDuration = 1;
+ vertices[i].frameCount = 0;
+ vertices[i].animT = -1;
+ vertices[i].color.r = 255;
+ vertices[i].color.g = 255;
+ vertices[i].color.b = 255;
+ vertices[i].color.a = 255;
+ }
+
+ vertices[0].tx = 0;
+ vertices[0].ty = 0;
+
+ vertices[1].tx = 1;
+ vertices[1].ty = 0;
+
+ vertices[2].tx = 0;
+ vertices[2].ty = 1;
+
+ vertices[3].tx = 1;
+ vertices[3].ty = 1;
+
+ vertices2[0].tx = 0;
+ vertices2[0].ty = 0;
+
+ vertices2[1].tx = 1;
+ vertices2[1].ty = 0;
+
+ vertices2[2].tx = 0;
+ vertices2[2].ty = 1;
+
+ vertices2[3].tx = 1;
+ vertices2[3].ty = 1;
}
QDeclarativeListProperty<QSGSprite> QSGImageParticle::sprites()
@@ -498,11 +554,6 @@ void QSGImageParticle::setBloat(bool arg)
if(perfLevel < 9999)
reset();
}
-void QSGImageParticle::setCount(int c)
-{
- QSGParticlePainter::setCount(c);
- m_pleaseReset = true;
-}
void QSGImageParticle::reset()
{
@@ -568,35 +619,9 @@ QSGGeometryNode* QSGImageParticle::buildSimpleParticleNode()
QSGGeometry *g = new QSGGeometry(SimpleParticle_AttributeSet, vCount, iCount);
g->setDrawingMode(GL_TRIANGLES);
- SimpleVertex *vertices = (SimpleVertex *) g->vertexData();
- for (int p=0; p<m_count; ++p) {
- for (int i=0; i<4; ++i) {
- vertices[i].x = 0;
- vertices[i].y = 0;
- vertices[i].t = -1;
- vertices[i].lifeSpan = 0;
- vertices[i].size = 0;
- vertices[i].endSize = 0;
- vertices[i].sx = 0;
- vertices[i].sy = 0;
- vertices[i].ax = 0;
- vertices[i].ay = 0;
- }
-
- vertices[0].tx = 0;
- vertices[0].ty = 0;
-
- vertices[1].tx = 1;
- vertices[1].ty = 0;
-
- vertices[2].tx = 0;
- vertices[2].ty = 1;
-
- vertices[3].tx = 1;
- vertices[3].ty = 1;
-
- vertices += 4;
- }
+ SimpleVertices *vertices = (SimpleVertices *) g->vertexData();
+ for (int p=0; p<m_count; ++p)
+ memcpy(vertices++, m_defaultSimple, sizeof(SimpleVertices));
quint16 *indices = g->indexDataAsUShort();
for (int i=0; i<m_count; ++i) {
@@ -640,6 +665,7 @@ QSGGeometryNode* QSGImageParticle::buildParticleNode()
return 0;
}
+ m_resizePending = false;
if(!m_sprites.count() && !m_bloat
&& m_colortable_name.isEmpty()
&& m_sizetable_name.isEmpty()
@@ -685,8 +711,8 @@ QSGGeometryNode* QSGImageParticle::buildParticleNode()
if(m_lastLevel == 1)
qDebug() << "Theta" << m_lastLevel << oldSimple[0].x << oldSimple[0].y << oldSimple[0].t;
for (int p=0; p<m_count; ++p) {
-
- if (m_lastLevel == 1) {//Transplant/IntermediateVertices?
+ memcpy(vertices, m_defaultUltra, sizeof(UltraVertices));
+ if (m_lastLevel == 1 && m_lastCount > p) {//Transplant/IntermediateVertices?
for (int i=0; i<4; ++i) {
vertices[i].x = oldSimple[i].x;
vertices[i].y = oldSimple[i].y;
@@ -698,64 +724,14 @@ QSGGeometryNode* QSGImageParticle::buildParticleNode()
vertices[i].sy = oldSimple[i].sy;
vertices[i].ax = oldSimple[i].ax;
vertices[i].ay = oldSimple[i].ay;
- vertices[i].xx = 1;
- vertices[i].xy = 0;
- vertices[i].yx = 0;
- vertices[i].yy = 1;
- vertices[i].rotation = 0;
- vertices[i].rotationSpeed = 0;
- vertices[i].autoRotate = 0;
- vertices[i].animIdx = 0;
+ /*
vertices[i].frameDuration = oldSimple[i].lifeSpan;
vertices[i].frameCount = 1;
vertices[i].animT = oldSimple[i].t;
- vertices[i].color.r = 255;
- vertices[i].color.g = 255;
- vertices[i].color.b = 255;
- vertices[i].color.a = 255;
- }
- } else {
- for (int i=0; i<4; ++i) {
- vertices[i].x = 0;
- vertices[i].y = 0;
- vertices[i].t = -1;
- vertices[i].lifeSpan = 0;
- vertices[i].size = 0;
- vertices[i].endSize = 0;
- vertices[i].sx = 0;
- vertices[i].sy = 0;
- vertices[i].ax = 0;
- vertices[i].ay = 0;
- vertices[i].xx = 1;
- vertices[i].xy = 0;
- vertices[i].yx = 0;
- vertices[i].yy = 1;
- vertices[i].rotation = 0;
- vertices[i].rotationSpeed = 0;
- vertices[i].autoRotate = 0;
- vertices[i].animIdx = -1;
- vertices[i].frameDuration = 1;
- vertices[i].frameCount = 0;
- vertices[i].animT = -1;
- vertices[i].color.r = 0;//TODO:Some things never get used uninitialized. Consider dropping them here?
- vertices[i].color.g = 0;
- vertices[i].color.b = 0;
- vertices[i].color.a = 0;
+ */
}
}
- vertices[0].tx = 0;
- vertices[0].ty = 0;
-
- vertices[1].tx = 1;
- vertices[1].ty = 0;
-
- vertices[2].tx = 0;
- vertices[2].ty = 1;
-
- vertices[3].tx = 1;
- vertices[3].ty = 1;
-
vertices += 4;
oldSimple += 4;
}
@@ -813,14 +789,95 @@ QSGGeometryNode* QSGImageParticle::buildParticleNode()
return m_node;
}
+void QSGImageParticle::resize(int oldCount, int newCount)
+{
+ //If perf level changes at the same time as a resize, we reset instead of doing pending resize
+ if(!m_node)
+ return;
+ switch(perfLevel){
+ default:
+ case Sprites:
+ if(m_spriteEngine)
+ reset();//TODO: Handle sprite resizeing (have to shuffle the engine too...)
+ case Coloured:
+ case Deformable:
+ case Tabled:
+ if(!m_resizePending){
+ m_resizePendingUltra.resize(oldCount);
+ UltraVertices *particles = (UltraVertices *) m_node->geometry()->vertexData();
+ for(int i=0; i<oldCount; i++)
+ m_resizePendingUltra[i] = &particles[i];
+ }
+ groupShuffle(m_resizePendingUltra, m_defaultUltra);
+ break;
+ case Simple:
+ if(!m_resizePending){
+ m_resizePendingSimple.resize(oldCount);
+ SimpleVertices *particles = (SimpleVertices *) m_node->geometry()->vertexData();
+ for(int i=0; i<oldCount; i++)
+ m_resizePendingSimple[i] = &particles[i];
+ }
+ groupShuffle(m_resizePendingSimple, m_defaultSimple);
+ break;
+ }
+ m_resizePending = true;
+}
+
+void QSGImageParticle::performPendingResize()
+{
+ m_resizePending = false;
+ if(!m_node)
+ return;
+ UltraVertices tmp1[m_count];//###More vast memcpys that will decrease performance
+ SimpleVertices tmp2[m_count];//###More vast memcpys that will decrease performance
+ switch(perfLevel){
+ case Sprites:
+ case Coloured:
+ case Deformable:
+ case Tabled:
+ Q_ASSERT(m_resizePendingUltra.size() == m_count);//XXX
+ for(int i=0; i<m_count; i++){
+ Q_ASSERT(m_resizePendingUltra[i]);
+ tmp1[i] = *m_resizePendingUltra[i];
+ }
+ m_node->setFlag(QSGNode::OwnsGeometry, false);
+ m_node->geometry()->allocate(m_count*4, m_count*6);
+ memcpy(m_node->geometry()->vertexData(), tmp1, sizeof(UltraVertices) * m_count);
+ m_node->setFlag(QSGNode::OwnsGeometry, true);
+ break;
+ case Simple:
+ Q_ASSERT(m_resizePendingSimple.size() == m_count);//XXX
+ for(int i=0; i<m_count; i++)
+ tmp2[i] = *m_resizePendingSimple[i];
+ m_node->setFlag(QSGNode::OwnsGeometry, false);
+ m_node->geometry()->allocate(m_count*4, m_count*6);
+ memcpy(m_node->geometry()->vertexData(), tmp2, sizeof(SimpleVertices) * m_count);
+ m_node->setFlag(QSGNode::OwnsGeometry, true);
+ break;
+ }
+ quint16 *indices = m_node->geometry()->indexDataAsUShort();
+ for (int i=0; i<m_count; ++i) {
+ int o = i * 4;
+ indices[0] = o;
+ indices[1] = o + 1;
+ indices[2] = o + 2;
+ indices[3] = o + 1;
+ indices[4] = o + 3;
+ indices[5] = o + 2;
+ indices += 6;
+ }
+ m_node->setFlag(QSGNode::OwnsGeometry, true);
+}
+
QSGNode *QSGImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
{
if(m_pleaseReset){
if(m_node){
if(perfLevel == 1){
qDebug() << "Beta";
- m_lastData = qMalloc(m_count*sizeof(SimpleVertices));//TODO: Account for count_changed possibility
- memcpy(m_lastData, m_node->geometry()->vertexData(), m_count * sizeof(SimpleVertices));//TODO: Multiple levels
+ m_lastCount = m_node->geometry()->vertexCount() / 4;
+ m_lastData = qMalloc(m_lastCount*sizeof(SimpleVertices));
+ memcpy(m_lastData, m_node->geometry()->vertexData(), m_lastCount * sizeof(SimpleVertices));//TODO: Multiple levels
}
m_lastLevel = perfLevel;
delete m_node;
@@ -832,6 +889,8 @@ QSGNode *QSGImageParticle::updatePaintNode(QSGNode *, UpdatePaintNodeData *)
m_material = 0;
m_pleaseReset = false;
}
+ if(m_resizePending)
+ performPendingResize();
if(m_system && m_system->isRunning())
prepareNextFrame();
@@ -990,4 +1049,20 @@ void QSGImageParticle::load(QSGParticleData *d)
vertexCopy(*p->v4, d->pv);
}
+/*
+void QSGImageParticle::verticesUpgrade(void *prev, void *next)
+{
+ PerformanceLevel copyLevel = qMin(perfLevel, m_lastLevel);
+ switch(perfLevel){//Intentional fall-through
+ case Sprites:
+ if(copyLevel >= Sprites)
+ case Tabled:
+ case Deformable:
+ case Coloured:
+ }
+
+}
+*/
+
+
QT_END_NAMESPACE