qt5-qtdeclarative/qtdeclarative-cleaup-image-and-shadereffectsource-properly.patch
2014-10-29 10:37:53 +01:00

202 lines
6.1 KiB
Diff

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();