diff options
author | Gunnar Sletta <gunnar.sletta@jollamobile.com> | 2014-08-01 11:22:31 +0200 |
---|---|---|
committer | Gunnar Sletta <gunnar.sletta@jollamobile.com> | 2014-08-01 23:17:44 +0200 |
commit | 76859e50d4b986fb88c2f193a70fd9b40963c59a (patch) | |
tree | 510d5553d472017e343fc1ca755ea7e313313d39 /src/quick/items/context2d/qquickcontext2dtexture.cpp | |
parent | 557d73575978b873bb01ea791ae237fa6067fa7f (diff) |
More QQuickCanvas cleanup handling.
Avoid calling into QQuickContext2D from QQuickContext2DTexture
after QQuickContext2D has been deleted. We acheive this by
1. Giving the texture a direct pointer to the gl context and
and surface, so that it doesn't need to go through m_context
to get to them (which may have been deleted).
2. Protect access to QQuickContext2DTexture::m_context with
a mutex and make sure it is set to 0 in a safe manner
when the QQuickContext2D object is deleted.
Change-Id: Ie0a30f9fc46f844224838a7cdf2f28a62e8ce322
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
Diffstat (limited to 'src/quick/items/context2d/qquickcontext2dtexture.cpp')
-rw-r--r-- | src/quick/items/context2d/qquickcontext2dtexture.cpp | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index 4007713152..c8bea6f97e 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -90,6 +90,8 @@ struct GLAcquireContext { QQuickContext2DTexture::QQuickContext2DTexture() : m_context(0) + , m_gl(0) + , m_surface(0) , m_item(0) , m_canvasWindowChanged(false) , m_dirtyTexture(false) @@ -146,8 +148,12 @@ void QQuickContext2DTexture::setAntialiasing(bool antialiasing) void QQuickContext2DTexture::setItem(QQuickCanvasItem* item) { m_item = item; - m_context = (QQuickContext2D*)item->rawContext(); // FIXME - m_state = m_context->state; + if (m_item) { + m_context = (QQuickContext2D*) item->rawContext(); // FIXME + m_state = m_context->state; + } else { + m_context = 0; + } } bool QQuickContext2DTexture::setCanvasWindow(const QRect& r) @@ -239,12 +245,15 @@ bool QQuickContext2DTexture::canvasDestroyed() void QQuickContext2DTexture::paint(QQuickContext2DCommandBuffer *ccb) { + QQuickContext2D::mutex.lock(); if (canvasDestroyed()) { delete ccb; + QQuickContext2D::mutex.unlock(); return; } + QQuickContext2D::mutex.unlock(); - GLAcquireContext currentContext(m_context->glContext(), m_context->surface()); + GLAcquireContext currentContext(m_gl, m_surface); if (!m_tiledCanvas) { paintWithoutTiles(ccb); @@ -434,7 +443,7 @@ QSGTexture *QQuickContext2DFBOTexture::textureForNextFrame(QSGTexture *lastTextu } if (m_dirtyTexture) { - if (!m_context->glContext()) { + if (!m_gl) { // on a rendering thread, use the fbo directly... texture->setTextureId(m_fbo->texture()); } else { @@ -492,18 +501,18 @@ bool QQuickContext2DFBOTexture::doMultisampling() const void QQuickContext2DFBOTexture::grabImage(const QRectF& rf) { Q_ASSERT(rf.isValid()); - if (!m_fbo) { - m_context->setGrabbedImage(QImage()); - return; - } - - QImage grabbed; - { - GLAcquireContext ctx(m_context->glContext(), m_context->surface()); - grabbed = m_fbo->toImage().mirrored().copy(rf.toRect()); + QQuickContext2D::mutex.lock(); + if (m_context) { + if (!m_fbo) { + m_context->setGrabbedImage(QImage()); + } else { + QImage grabbed; + GLAcquireContext ctx(m_gl, m_surface); + grabbed = m_fbo->toImage().mirrored().copy(rf.toRect()); + m_context->setGrabbedImage(grabbed); + } } - - m_context->setGrabbedImage(grabbed); + QQuickContext2D::mutex.unlock(); } void QQuickContext2DFBOTexture::compositeTile(QQuickContext2DTile* tile) @@ -586,7 +595,7 @@ void QQuickContext2DFBOTexture::endPainting() if (m_multisampledFbo) QOpenGLFramebufferObject::blitFramebuffer(m_fbo, m_multisampledFbo); - if (m_context->glContext()) { + if (m_gl) { /* When rendering happens on the render thread, the fbo's texture is * used directly for display. If we are on the GUI thread or a * dedicated Canvas render thread, we need to decouple the FBO from @@ -641,9 +650,12 @@ QQuickContext2DTile* QQuickContext2DImageTexture::createTile() const void QQuickContext2DImageTexture::grabImage(const QRectF& rf) { Q_ASSERT(rf.isValid()); - Q_ASSERT(m_context); - QImage grabbed = m_displayImage.copy(rf.toRect()); - m_context->setGrabbedImage(grabbed); + QQuickContext2D::mutex.lock(); + if (m_context) { + QImage grabbed = m_displayImage.copy(rf.toRect()); + m_context->setGrabbedImage(grabbed); + } + QQuickContext2D::mutex.unlock(); } QSGTexture *QQuickContext2DImageTexture::textureForNextFrame(QSGTexture *last) |