diff options
-rw-r--r-- | src/quick/items/context2d/qquickcontext2d.cpp | 59 | ||||
-rw-r--r-- | src/quick/items/context2d/qquickcontext2dtexture.cpp | 3 | ||||
-rw-r--r-- | src/quick/items/context2d/qquickcontext2dtexture_p.h | 1 |
3 files changed, 61 insertions, 2 deletions
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index ab21c3c9a8..4b70934320 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 @@ -4001,6 +4003,34 @@ 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; +}; + +class QQuickContext2DTextureCleanup : public QRunnable +{ +public: + QQuickContext2DTexture *texture; + void run() Q_DECL_OVERRIDE { delete texture; } +}; + QQuickContext2D::QQuickContext2D(QObject *parent) : QQuickCanvasContext(parent) , m_buffer(new QQuickContext2DCommandBuffer) @@ -4015,7 +4045,34 @@ 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 { + if (m_canvas->window()) { + QQuickContext2DTextureCleanup *c = new QQuickContext2DTextureCleanup; + c->texture = m_texture; + m_canvas->window()->scheduleRenderJob(c, QQuickWindow::AfterSynchronizingStage); + } else { + delete m_texture; + } + } + } 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 0ab76b0ca5..fbfd3df324 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; - QOpenGLContext::currentContext()->functions()->glDeleteTextures(2, m_displayTextures); + if (QOpenGLContext::currentContext()) + QOpenGLContext::currentContext()->functions()->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; |