From: Gunnar Sletta Date: Wed, 7 Sep 2011 09:46:12 +0000 (+0200) Subject: Fix QSGshaderEffectTexture cleanup X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=40b0b72d7b228929f01c996fa36b1dc617c93a86;p=konrad%2Fqtdeclarative.git Fix QSGshaderEffectTexture cleanup Because we often created it too early it did not have a QSGContext and would thus not clean up properly, causing crashes. Change-Id: I1f5c82c87326254885ec217aaab4f1e79d18a243 Reviewed-on: http://codereview.qt.nokia.com/4329 Reviewed-by: Kim M. Kalland --- diff --git a/src/declarative/items/qsgitem_p.h b/src/declarative/items/qsgitem_p.h index 294edc0..513aba2 100644 --- a/src/declarative/items/qsgitem_p.h +++ b/src/declarative/items/qsgitem_p.h @@ -258,7 +258,7 @@ public: quint32 dummy:1; QSGCanvas *canvas; - QSGContext *sceneGraphContext() const { return static_cast(QObjectPrivate::get(canvas))->context; } + QSGContext *sceneGraphContext() const { Q_ASSERT(canvas); return static_cast(QObjectPrivate::get(canvas))->context; } QSGItem *parentItem; QList childItems; diff --git a/src/declarative/items/qsgshadereffectsource.cpp b/src/declarative/items/qsgshadereffectsource.cpp index bb55af5..3b09838 100644 --- a/src/declarative/items/qsgshadereffectsource.cpp +++ b/src/declarative/items/qsgshadereffectsource.cpp @@ -103,7 +103,7 @@ QSGShaderEffectTexture::QSGShaderEffectTexture(QSGItem *shaderSource) #ifdef QSG_DEBUG_FBO_OVERLAY , m_debugOverlay(0) #endif - , m_context(0) + , m_context(QSGItemPrivate::get(shaderSource)->sceneGraphContext()) , m_mipmap(false) , m_live(true) , m_recursive(false) @@ -124,18 +124,6 @@ QSGShaderEffectTexture::~QSGShaderEffectTexture() #endif } -void QSGShaderEffectTexture::scheduleForCleanup() -{ - if (m_context) - m_context->scheduleTextureForCleanup(this); - else { - // Never really been used, hence we can delete it right away.. - Q_ASSERT(!m_fbo); - delete this; - } -} - - int QSGShaderEffectTexture::textureId() const { return m_fbo ? m_fbo->texture() : 0; @@ -265,10 +253,6 @@ void QSGShaderEffectTexture::grab() return; } - if (!m_context) - m_context = QSGItemPrivate::get(m_shaderSource)->sceneGraphContext(); - Q_ASSERT(QSGItemPrivate::get(m_shaderSource)->sceneGraphContext() == m_context); - if (!m_renderer) { m_renderer = m_context->createRenderer(); connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture()), Qt::DirectConnection); @@ -494,6 +478,7 @@ QImage QSGShaderEffectTexture::toImage() const QSGShaderEffectSource::QSGShaderEffectSource(QSGItem *parent) : QSGItem(parent) , m_provider(0) + , m_texture(0) , m_wrapMode(ClampToEdge) , m_sourceItem(0) , m_textureSize(0, 0) @@ -505,13 +490,12 @@ QSGShaderEffectSource::QSGShaderEffectSource(QSGItem *parent) , m_grab(true) { setFlag(ItemHasContents); - m_texture = new QSGShaderEffectTexture(this); - connect(m_texture, SIGNAL(textureChanged()), this, SLOT(update())); } QSGShaderEffectSource::~QSGShaderEffectSource() { - m_texture->scheduleForCleanup(); + if (m_texture) + m_texture->deleteLater(); if (m_provider) m_provider->deleteLater(); @@ -520,6 +504,21 @@ QSGShaderEffectSource::~QSGShaderEffectSource() QSGItemPrivate::get(m_sourceItem)->derefFromEffectItem(m_hideSource); } +void QSGShaderEffectSource::ensureTexture() +{ + if (m_texture) + return; + + Q_ASSERT_X(QSGItemPrivate::get(this)->canvas + && QSGItemPrivate::get(this)->sceneGraphContext() + && QThread::currentThread() == QSGItemPrivate::get(this)->sceneGraphContext()->thread(), + "QSGShaderEffectSource::ensureTexture", + "Cannot be used outside the rendering thread"); + + m_texture = new QSGShaderEffectTexture(this); + connect(m_texture, SIGNAL(textureChanged()), this, SLOT(update())); +} + QSGTextureProvider *QSGShaderEffectSource::textureProvider() const { if (!m_provider) { @@ -528,8 +527,10 @@ QSGTextureProvider *QSGShaderEffectSource::textureProvider() const && QSGItemPrivate::get(this)->sceneGraphContext() && QThread::currentThread() == QSGItemPrivate::get(this)->sceneGraphContext()->thread(), "QSGShaderEffectSource::textureProvider", - "Cannot be used outside the GUI thread"); + "Cannot be used outside the rendering thread"); const_cast(this)->m_provider = new QSGShaderEffectSourceTextureProvider(); + + const_cast(this)->ensureTexture(); connect(m_texture, SIGNAL(textureChanged()), m_provider, SIGNAL(textureChanged()), Qt::DirectConnection); m_provider->sourceTexture = m_texture; } @@ -829,6 +830,8 @@ QSGNode *QSGShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaintNod return 0; } + ensureTexture(); + QSGShaderEffectTexture *tex = qobject_cast(m_texture); tex->setLive(m_live); tex->setItem(QSGItemPrivate::get(m_sourceItem)->itemNode()); diff --git a/src/declarative/items/qsgshadereffectsource_p.h b/src/declarative/items/qsgshadereffectsource_p.h index 77cb412..6662412 100644 --- a/src/declarative/items/qsgshadereffectsource_p.h +++ b/src/declarative/items/qsgshadereffectsource_p.h @@ -116,7 +116,6 @@ public: void scheduleUpdate(); - void scheduleForCleanup(); QImage toImage() const; Q_SIGNALS: @@ -233,6 +232,8 @@ protected: virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); private: + void ensureTexture(); + QSGShaderEffectSourceTextureProvider *m_provider; QSGShaderEffectTexture *m_texture; WrapMode m_wrapMode;