Fix hanging at application exit

Task-number: QTBUG-75256
Task-number: QTBUG-69627
Change-Id: If4221c8fcf783daf4bf6a38dbf1b9633a20eafb0
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
Tomi Korpipaa 2019-04-29 12:50:14 +03:00 committed by Tomi Korpipää
parent fd902c04b9
commit e4cd15e388
8 changed files with 48 additions and 60 deletions

View File

@ -122,7 +122,6 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
m_funcs_2_1(0),
#endif
m_context(0),
m_dummySurfaceAtDelete(0),
m_isOpenGLES(true)
{
@ -153,6 +152,7 @@ Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
Abstract3DRenderer::~Abstract3DRenderer()
{
contextCleanup();
delete m_drawer;
delete m_cachedScene;
delete m_cachedTheme;
@ -186,18 +186,18 @@ Abstract3DRenderer::~Abstract3DRenderer()
if (m_textureHelper) {
m_textureHelper->deleteTexture(&m_depthTexture);
m_textureHelper->deleteTexture(&m_cursorPositionTexture);
if (QOpenGLContext::currentContext())
m_textureHelper->glDeleteFramebuffers(1, &m_cursorPositionFrameBuffer);
delete m_textureHelper;
}
m_axisCacheX.clearLabels();
m_axisCacheY.clearLabels();
m_axisCacheZ.clearLabels();
}
restoreContextAfterDelete();
void Abstract3DRenderer::contextCleanup()
{
if (QOpenGLContext::currentContext())
m_textureHelper->glDeleteFramebuffers(1, &m_cursorPositionFrameBuffer);
}
void Abstract3DRenderer::initializeOpenGL()
@ -233,6 +233,9 @@ void Abstract3DRenderer::initializeOpenGL()
loadLabelMesh();
loadPositionMapperMesh();
QObject::connect(m_context, &QOpenGLContext::aboutToBeDestroyed,
this, &Abstract3DRenderer::contextCleanup);
}
void Abstract3DRenderer::render(const GLuint defaultFboHandle)
@ -1814,29 +1817,6 @@ void Abstract3DRenderer::queriedGraphPosition(const QMatrix4x4 &projectionViewMa
m_graphPositionQueryPending = false;
}
void Abstract3DRenderer::fixContextBeforeDelete()
{
// Only need to fix context if the current context is null.
// Otherwise we expect it to be our shared context, so we can use it for cleanup.
if (!QOpenGLContext::currentContext() && !m_context.isNull()
&& QThread::currentThread() == this->thread()) {
m_dummySurfaceAtDelete = new QOffscreenSurface();
m_dummySurfaceAtDelete->setFormat(m_context->format());
m_dummySurfaceAtDelete->create();
m_context->makeCurrent(m_dummySurfaceAtDelete);
}
}
void Abstract3DRenderer::restoreContextAfterDelete()
{
if (m_dummySurfaceAtDelete)
m_context->doneCurrent();
delete m_dummySurfaceAtDelete;
m_dummySurfaceAtDelete = 0;
}
void Abstract3DRenderer::calculatePolarXZ(const QVector3D &dataPos, float &x, float &z) const
{
// x is angular, z is radial

View File

@ -191,6 +191,7 @@ Q_SIGNALS:
protected:
Abstract3DRenderer(Abstract3DController *controller);
virtual void contextCleanup();
virtual void initializeOpenGL();
void reInitShaders();
@ -242,9 +243,6 @@ protected:
void queriedGraphPosition(const QMatrix4x4 &projectionViewMatrix, const QVector3D &scaling,
GLuint defaultFboHandle);
void fixContextBeforeDelete();
void restoreContextAfterDelete();
bool m_hasNegativeValues;
Q3DTheme *m_cachedTheme;
Drawer *m_drawer;
@ -339,7 +337,6 @@ protected:
QOpenGLFunctions_2_1 *m_funcs_2_1; // Not owned
#endif
QPointer<QOpenGLContext> m_context; // Not owned
QOffscreenSurface *m_dummySurfaceAtDelete;
bool m_isOpenGLES;
private:

View File

@ -100,8 +100,16 @@ Bars3DRenderer::Bars3DRenderer(Bars3DController *controller)
Bars3DRenderer::~Bars3DRenderer()
{
fixContextBeforeDelete();
contextCleanup();
delete m_barShader;
delete m_barGradientShader;
delete m_depthShader;
delete m_selectionShader;
delete m_backgroundShader;
}
void Bars3DRenderer::contextCleanup()
{
if (QOpenGLContext::currentContext()) {
m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
@ -109,12 +117,6 @@ Bars3DRenderer::~Bars3DRenderer()
m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
m_textureHelper->deleteTexture(&m_bgrTexture);
}
delete m_barShader;
delete m_barGradientShader;
delete m_depthShader;
delete m_selectionShader;
delete m_backgroundShader;
}
void Bars3DRenderer::initializeOpenGL()

View File

@ -134,6 +134,7 @@ public:
void updateMargin(float margin);
protected:
void contextCleanup();
virtual void initializeOpenGL();
virtual void fixCameraTarget(QVector3D &target);
virtual void getVisibleItemBounds(QVector3D &minBounds, QVector3D &maxBounds);

View File

@ -87,15 +87,7 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
Scatter3DRenderer::~Scatter3DRenderer()
{
fixContextBeforeDelete();
if (QOpenGLContext::currentContext()) {
m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
m_textureHelper->deleteTexture(&m_selectionTexture);
m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
m_textureHelper->deleteTexture(&m_bgrTexture);
}
contextCleanup();
delete m_dotShader;
delete m_staticSelectedItemGradientShader;
delete m_staticSelectedItemShader;
@ -106,6 +98,17 @@ Scatter3DRenderer::~Scatter3DRenderer()
delete m_staticGradientPointShader;
}
void Scatter3DRenderer::contextCleanup()
{
if (QOpenGLContext::currentContext()) {
m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
m_textureHelper->deleteTexture(&m_selectionTexture);
m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
m_textureHelper->deleteTexture(&m_bgrTexture);
}
}
void Scatter3DRenderer::initializeOpenGL()
{
Abstract3DRenderer::initializeOpenGL();

View File

@ -120,6 +120,7 @@ public Q_SLOTS:
void updateSelectedItem(int index, QScatter3DSeries *series);
protected:
void contextCleanup();
virtual void initializeOpenGL();
virtual void fixCameraTarget(QVector3D &target);
virtual void getVisibleItemBounds(QVector3D &minBounds, QVector3D &maxBounds);

View File

@ -95,17 +95,7 @@ Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
Surface3DRenderer::~Surface3DRenderer()
{
fixContextBeforeDelete();
if (QOpenGLContext::currentContext()) {
m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
m_textureHelper->deleteTexture(&m_noShadowTexture);
m_textureHelper->deleteTexture(&m_depthTexture);
m_textureHelper->deleteTexture(&m_selectionResultTexture);
}
contextCleanup();
delete m_depthShader;
delete m_backgroundShader;
delete m_selectionShader;
@ -118,6 +108,19 @@ Surface3DRenderer::~Surface3DRenderer()
delete m_surfaceSliceSmoothShader;
}
void Surface3DRenderer::contextCleanup()
{
if (QOpenGLContext::currentContext()) {
m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
m_textureHelper->deleteTexture(&m_noShadowTexture);
m_textureHelper->deleteTexture(&m_depthTexture);
m_textureHelper->deleteTexture(&m_selectionResultTexture);
}
}
void Surface3DRenderer::initializeOpenGL()
{
Abstract3DRenderer::initializeOpenGL();

View File

@ -116,6 +116,7 @@ public:
void render(GLuint defaultFboHandle = 0);
protected:
void contextCleanup();
void initializeOpenGL();
virtual void fixCameraTarget(QVector3D &target);
virtual void getVisibleItemBounds(QVector3D &minBounds, QVector3D &maxBounds);