aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp46
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture.cpp3
-rw-r--r--src/quick/items/context2d/qquickcontext2dtexture_p.h1
3 files changed, 48 insertions, 2 deletions
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index a7d5f7d65f..8858958dbc 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -70,6 +70,8 @@
#include <private/qv4objectproto_p.h>
#include <private/qv4scopedvalue_p.h>
+#include <QtCore/QRunnable>
+
#if defined(Q_OS_QNX) || defined(Q_OS_ANDROID)
#include <ctype.h>
#endif
@@ -4061,6 +4063,27 @@ bool QQuickContext2D::isPointInPath(qreal x, qreal y) const
return contains;
}
+class QQuickContext2DThreadCleanup : public QObject
+{
+public:
+ QQuickContext2DThreadCleanup(QOpenGLContext *gl, QQuickContext2DTexture *t, QOffscreenSurface *s)
+ : context(gl), texture(t), surface(s)
+ { }
+
+ ~QQuickContext2DThreadCleanup()
+ {
+ context->makeCurrent(surface);
+ delete texture;
+ context->doneCurrent();
+ delete context;
+ surface->deleteLater();
+ }
+
+ QOpenGLContext *context;
+ QQuickContext2DTexture *texture;
+ QOffscreenSurface *surface;
+};
+
QQuickContext2D::QQuickContext2D(QObject *parent)
: QQuickCanvasContext(parent)
, m_buffer(new QQuickContext2DCommandBuffer)
@@ -4075,7 +4098,28 @@ QQuickContext2D::QQuickContext2D(QObject *parent)
QQuickContext2D::~QQuickContext2D()
{
delete m_buffer;
- m_texture->deleteLater();
+
+ if (m_renderTarget == QQuickCanvasItem::FramebufferObject) {
+ if (m_renderStrategy == QQuickCanvasItem::Immediate && m_glContext) {
+ Q_ASSERT(QThread::currentThread() == m_glContext->thread());
+ m_glContext->makeCurrent(m_surface.data());
+ delete m_texture;
+ m_glContext->doneCurrent();
+ delete m_glContext;
+ } else if (m_texture->isOnCustomThread()) {
+ Q_ASSERT(m_glContext);
+ QQuickContext2DThreadCleanup *cleaner = new QQuickContext2DThreadCleanup(m_glContext, m_texture, m_surface.take());
+ cleaner->moveToThread(m_texture->thread());
+ cleaner->deleteLater();
+ } else {
+ m_texture->deleteLater();
+ }
+ } else {
+ // Image based does not have GL resources, but must still be deleted
+ // on its designated thread after it has completed whatever it might
+ // currently be doing.
+ m_texture->deleteLater();
+ }
}
QV4::ReturnedValue QQuickContext2D::v4value() const
diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp
index ca66bd7f5a..4007713152 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture.cpp
+++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp
@@ -414,7 +414,8 @@ QQuickContext2DFBOTexture::~QQuickContext2DFBOTexture()
delete m_multisampledFbo;
delete m_paint_device;
- glDeleteTextures(2, m_displayTextures);
+ if (QOpenGLContext::currentContext())
+ glDeleteTextures(2, m_displayTextures);
}
QSGTexture *QQuickContext2DFBOTexture::textureForNextFrame(QSGTexture *lastTexture)
diff --git a/src/quick/items/context2d/qquickcontext2dtexture_p.h b/src/quick/items/context2d/qquickcontext2dtexture_p.h
index cf0e8e3fa9..186863c1aa 100644
--- a/src/quick/items/context2d/qquickcontext2dtexture_p.h
+++ b/src/quick/items/context2d/qquickcontext2dtexture_p.h
@@ -107,6 +107,7 @@ public:
bool setDirtyRect(const QRect &dirtyRect);
bool canvasDestroyed();
void setOnCustomThread(bool is) { m_onCustomThread = is; }
+ bool isOnCustomThread() const { return m_onCustomThread; }
// Called during sync() on the scene graph thread while GUI is blocked.
virtual QSGTexture *textureForNextFrame(QSGTexture *lastFrame) = 0;