aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/context2d/qquickcontext2dtexture.cpp
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@jollamobile.com>2014-08-01 11:22:31 +0200
committerGunnar Sletta <gunnar.sletta@jollamobile.com>2014-08-01 23:17:44 +0200
commit76859e50d4b986fb88c2f193a70fd9b40963c59a (patch)
tree510d5553d472017e343fc1ca755ea7e313313d39 /src/quick/items/context2d/qquickcontext2dtexture.cpp
parent557d73575978b873bb01ea791ae237fa6067fa7f (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.cpp50
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)