From a22053ad9ee145bb312beaa673c9d1efa9ccf2a3 Mon Sep 17 00:00:00 2001 From: Alan Alpert Date: Thu, 9 Jun 2011 19:00:33 +1000 Subject: [PATCH] Do delegate management outside the render thread Very simple implementation, there's probably a better way to do it. --- src/declarative/particles/qsgmodelparticle.cpp | 43 ++++++++++++++++------- src/declarative/particles/qsgmodelparticle_p.h | 4 ++- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/declarative/particles/qsgmodelparticle.cpp b/src/declarative/particles/qsgmodelparticle.cpp index 94ce082..704b9a2 100644 --- a/src/declarative/particles/qsgmodelparticle.cpp +++ b/src/declarative/particles/qsgmodelparticle.cpp @@ -42,6 +42,7 @@ #include "qsgmodelparticle_p.h" #include #include +#include #include 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(qmlAttachedPropertiesObject(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(qmlAttachedPropertiesObject(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; diff --git a/src/declarative/particles/qsgmodelparticle_p.h b/src/declarative/particles/qsgmodelparticle_p.h index 4dd8bfa..04533a7 100644 --- a/src/declarative/particles/qsgmodelparticle_p.h +++ b/src/declarative/particles/qsgmodelparticle_p.h @@ -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 > m_deletables; + QList m_deletables; + QList< int > m_requests; int m_particleCount; bool m_fade; -- 1.7.2.5