Do delegate management outside the render thread
authorAlan Alpert <alan.alpert@nokia.com>
Thu, 9 Jun 2011 09:00:33 +0000 (19:00 +1000)
committerAlan Alpert <alan.alpert@nokia.com>
Thu, 9 Jun 2011 09:00:33 +0000 (19:00 +1000)
Very simple implementation, there's probably a better way to do it.

src/declarative/particles/qsgmodelparticle.cpp
src/declarative/particles/qsgmodelparticle_p.h

index 94ce082..704b9a2 100644 (file)
@@ -42,6 +42,7 @@
 #include "qsgmodelparticle_p.h"
 #include <QtDeclarative/private/qsgvisualitemmodel_p.h>
 #include <qsgnode.h>
+#include <QTimer>
 #include <QDebug>
 
 QT_BEGIN_NAMESPACE
@@ -50,6 +51,12 @@ QSGModelParticle::QSGModelParticle(QSGItem *parent) :
     QSGParticlePainter(parent), m_ownModel(false), m_comp(0), m_model(0), m_fade(true), m_modelCount(0)
 {
     setFlag(QSGItem::ItemHasContents);
+    QTimer* manageDelegates = new QTimer(this);//TODO: don't leak
+    connect(manageDelegates, SIGNAL(timeout()),
+            this, SLOT(processPending()));
+    manageDelegates->setInterval(16);
+    manageDelegates->setSingleShot(false);
+    manageDelegates->start();
 }
 
 QVariant QSGModelParticle::model() const
@@ -153,27 +160,38 @@ void QSGModelParticle::load(QSGParticleData* d)
         if(m_stasis.contains(m_items[pos]))
             qWarning() << "Current model particles prefers overwrite:false";
         //remove old item from the particle that is dying to make room for this one
-        m_items[pos]->setOpacity(0.);
+        m_deletables << m_items[pos];
         m_available << m_idx[pos];
-        m_model->release(m_items[pos]);
         m_idx[pos] = -1;
         m_items[pos] = 0;
         m_data[pos] = 0;
         m_activeCount--;
     }
-    m_items[pos] = m_model->item(m_available.first());
-    m_idx[pos] = m_available.first();
-    m_available.pop_front();
-    QSGModelParticleAttached* mpa = qobject_cast<QSGModelParticleAttached*>(qmlAttachedPropertiesObject<QSGModelParticle>(m_items[pos]));
-    if(mpa){
-        mpa->m_mp = this;
-        mpa->attach();
-    }
-    m_items[pos]->setParentItem(this);
+    m_requests << pos;
     m_data[pos] = d;
     m_activeCount++;
 }
 
+void QSGModelParticle::processPending()
+{//can't create/delete arbitrary items in the render thread
+    foreach(QSGItem* item, m_deletables){
+        item->setOpacity(0.);
+        m_model->release(item);
+    }
+
+    foreach(int pos, m_requests){
+        m_items[pos] = m_model->item(m_available.first());
+        m_idx[pos] = m_available.first();
+        m_available.pop_front();
+        QSGModelParticleAttached* mpa = qobject_cast<QSGModelParticleAttached*>(qmlAttachedPropertiesObject<QSGModelParticle>(m_items[pos]));
+        if(mpa){
+            mpa->m_mp = this;
+            mpa->attach();
+        }
+        m_items[pos]->setParentItem(this);
+    }
+}
+
 void QSGModelParticle::reload(QSGParticleData* d)
 {
     //No-op unless we start copying the data.
@@ -242,9 +260,8 @@ void QSGModelParticle::prepareNextFrame()
             continue;
         }
         if(t >= 1.0){//Usually happens from load
-            item->setOpacity(0.);
             m_available << m_idx[i];
-            m_model->release(m_items[i]);
+            m_deletables << item;
             m_idx[i] = -1;
             m_items[i] = 0;
             m_data[i] = 0;
index 4dd8bfa..04533a7 100644 (file)
@@ -96,12 +96,14 @@ protected:
     void prepareNextFrame();
 private slots:
     void updateCount();
+    void processPending();
 private:
     bool m_ownModel;
     QDeclarativeComponent* m_comp;
     QSGVisualDataModel *m_model;
     QVariant m_dataSource;
-    QList<QPointer<QSGItem> > m_deletables;
+    QList<QSGItem*> m_deletables;
+    QList< int > m_requests;
     int m_particleCount;
     bool m_fade;