Blob Blame History Raw
diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp
index d752774..ffc1e92 100644
--- a/src/quick/items/qquickimage.cpp
+++ b/src/quick/items/qquickimage.cpp
@@ -49,6 +49,7 @@
 
 #include <QtGui/qpainter.h>
 #include <qmath.h>
+#include <QtCore/QRunnable>
 
 QT_BEGIN_NAMESPACE
 
@@ -100,6 +101,14 @@ QQuickImagePrivate::QQuickImagePrivate()
 {
 }
 
+class QQuickImageCleanup : public QRunnable
+{
+public:
+    QQuickImageCleanup(QQuickImageTextureProvider *p) : provider(p) { }
+    void run() Q_DECL_OVERRIDE { delete provider; }
+    QQuickImageTextureProvider *provider;
+};
+
 /*!
     \qmltype Image
     \instantiates QQuickImage
@@ -159,18 +168,24 @@ QQuickImagePrivate::QQuickImagePrivate()
 QQuickImage::QQuickImage(QQuickItem *parent)
     : QQuickImageBase(*(new QQuickImagePrivate), parent)
 {
+    connect(this, SIGNAL(sceneGraphInvalidated()), this, SLOT(invalidateSG()));
 }
 
 QQuickImage::QQuickImage(QQuickImagePrivate &dd, QQuickItem *parent)
     : QQuickImageBase(dd, parent)
 {
+    connect(this, SIGNAL(sceneGraphInvalidated()), this, SLOT(invalidateSG()));
 }
 
 QQuickImage::~QQuickImage()
 {
     Q_D(QQuickImage);
-    if (d->provider)
-        d->provider->deleteLater();
+    if (QQuickWindow *w = window()) {
+        w->scheduleRenderJob(new QQuickImageCleanup(d->provider), QQuickWindow::AfterSynchronizingStage);
+    } else {
+        // Should have been released already in releaseResources or in invalidateSG.
+        Q_ASSERT(!d->provider);
+    }
 }
 
 void QQuickImagePrivate::setImage(const QImage &image)
@@ -560,6 +575,22 @@ QSGTextureProvider *QQuickImage::textureProvider() const
     return d->provider;
 }
 
+void QQuickImage::invalidateSG()
+{
+    Q_D(QQuickImage);
+    delete d->provider;
+    d->provider = 0;
+}
+
+void QQuickImage::releaseResources()
+{
+    Q_D(QQuickImage);
+    if (d->provider) {
+        window()->scheduleRenderJob(new QQuickImageCleanup(d->provider), QQuickWindow::AfterSynchronizingStage);
+        d->provider = 0;
+    }
+}
+
 QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
 {
     Q_D(QQuickImage);
diff --git a/src/quick/items/qquickimage_p.h b/src/quick/items/qquickimage_p.h
index 56b064f..82ac776 100644
--- a/src/quick/items/qquickimage_p.h
+++ b/src/quick/items/qquickimage_p.h
@@ -102,10 +102,14 @@ Q_SIGNALS:
     void verticalAlignmentChanged(VAlignment alignment);
     Q_REVISION(1) void mipmapChanged(bool);
 
+private Q_SLOTS:
+    void invalidateSG();
+
 protected:
     QQuickImage(QQuickImagePrivate &dd, QQuickItem *parent);
     void pixmapChange();
     void updatePaintedGeometry();
+    void releaseResources() Q_DECL_OVERRIDE;
 
     virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
     virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp
index ebeff59..6158bbb 100644
--- a/src/quick/items/qquickshadereffectsource.cpp
+++ b/src/quick/items/qquickshadereffectsource.cpp
@@ -50,6 +50,7 @@
 #include "qopenglframebufferobject.h"
 #include "qmath.h"
 #include <QtQuick/private/qsgtexture_p.h>
+#include <QtCore/QRunnable>
 
 QT_BEGIN_NAMESPACE
 
@@ -485,6 +486,21 @@ QImage QQuickShaderEffectTexture::toImage() const
     return QImage();
 }
 
+class QQuickShaderEffectSourceCleanup : public QRunnable
+{
+public:
+    QQuickShaderEffectSourceCleanup(QQuickShaderEffectTexture *t, QQuickShaderEffectSourceTextureProvider *p)
+        : texture(t)
+        , provider(p)
+    {}
+    void run() Q_DECL_OVERRIDE {
+        delete texture;
+        delete provider;
+    }
+    QQuickShaderEffectTexture *texture;
+    QQuickShaderEffectSourceTextureProvider *provider;
+};
+
 /*!
     \qmltype ShaderEffectSource
     \instantiates QQuickShaderEffectSource
@@ -586,15 +602,20 @@ QQuickShaderEffectSource::QQuickShaderEffectSource(QQuickItem *parent)
     , m_grab(true)
 {
     setFlag(ItemHasContents);
+    connect(this, SIGNAL(sceneGraphInvalidated()), this, SLOT(invalidateSG()));
 }
 
 QQuickShaderEffectSource::~QQuickShaderEffectSource()
 {
-    if (m_texture)
-        m_texture->deleteLater();
-
-    if (m_provider)
-        m_provider->deleteLater();
+    if (window()) {
+        window()->scheduleRenderJob(new QQuickShaderEffectSourceCleanup(m_texture, m_provider),
+                                    QQuickWindow::AfterSynchronizingStage);
+    } else {
+        // If we don't have a window, these should already have been
+        // released in invalidateSG or in releaseResrouces()
+        Q_ASSERT(!m_texture);
+        Q_ASSERT(!m_provider);
+    }
 
     if (m_sourceItem) {
         QQuickItemPrivate *sd = QQuickItemPrivate::get(m_sourceItem);
@@ -961,12 +982,10 @@ static void get_wrap_mode(QQuickShaderEffectSource::WrapMode mode, QSGTexture::W
 
 void QQuickShaderEffectSource::releaseResources()
 {
-    if (m_texture) {
-        m_texture->deleteLater();
+    if (m_texture || m_provider) {
+        window()->scheduleRenderJob(new QQuickShaderEffectSourceCleanup(m_texture, m_provider),
+                                    QQuickWindow::AfterSynchronizingStage);
         m_texture = 0;
-    }
-    if (m_provider) {
-        m_provider->deleteLater();
         m_provider = 0;
     }
 }
@@ -1058,6 +1077,16 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint
     return node;
 }
 
+void QQuickShaderEffectSource::invalidateSG()
+{
+    if (m_texture)
+        delete m_texture;
+    if (m_provider)
+        delete m_provider;
+    m_texture = 0;
+    m_provider = 0;
+}
+
 void QQuickShaderEffectSource::itemChange(ItemChange change, const ItemChangeData &value)
 {
     if (change == QQuickItem::ItemSceneChange && m_sourceItem) {
diff --git a/src/quick/items/qquickshadereffectsource_p.h b/src/quick/items/qquickshadereffectsource_p.h
index efa963f..13b81ce 100644
--- a/src/quick/items/qquickshadereffectsource_p.h
+++ b/src/quick/items/qquickshadereffectsource_p.h
@@ -235,6 +235,7 @@ Q_SIGNALS:
 
 private Q_SLOTS:
     void sourceItemDestroyed(QObject *item);
+    void invalidateSG();
 
 protected:
     virtual void releaseResources();