summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2021-11-26 11:47:23 +0100
committerPaul Lemire <paul.lemire@kdab.com>2021-11-30 10:40:28 +0100
commit559d77cacf7a3f6a29d3debec6d61a2ef8a59dc9 (patch)
treed415e6b382f689e44df1ec7713e1f00da0983e2b
parentc71b73e8bc809cb23c9f66180e57eeef61dbd200 (diff)
OpenGL renderer: restore surface on context when shutting down
When using a QQuickWidget and Qt3D, on shutdown and assert occurs. This is the result of the QQuickWidget expecting the surface on the context to be its own internal surface after the QQuickRenderControl has been invalidated. This conflict with what Qt3D does on shutdown as it makes the context current on its own internal offscreen surface on shutdown. Therefore, to fix this issue, we record the surface in use before Qt3D shuts down and we make the context current on it after Qt3D has shutdown. Arguably, the fix should really go in QQuickWidgetPrivate::invalidateRenderControl where the QQuickWidget should check that the current surface is indeed the one it expects and set it accordingly. Change-Id: I534dc330a30a2ad5d17a6416715d03206ef4b1c9 Pick-to: 6.2 5.15 Reviewed-by: Mike Krus <mike.krus@kdab.com>
-rw-r--r--src/plugins/renderers/opengl/renderer/renderer.cpp66
1 files changed, 39 insertions, 27 deletions
diff --git a/src/plugins/renderers/opengl/renderer/renderer.cpp b/src/plugins/renderers/opengl/renderer/renderer.cpp
index 37a9eafd9..e09423005 100644
--- a/src/plugins/renderers/opengl/renderer/renderer.cpp
+++ b/src/plugins/renderers/opengl/renderer/renderer.cpp
@@ -585,38 +585,50 @@ void Renderer::releaseGraphicsResources()
QOpenGLContext *context = m_submissionContext->openGLContext();
Q_ASSERT(context);
- if (context->thread() == QThread::currentThread() && context->makeCurrent(offscreenSurface)) {
-
- // Clean up the graphics context and any resources
- const std::vector<HGLTexture> &activeTexturesHandles = m_glResourceManagers->glTextureManager()->activeHandles();
- for (const HGLTexture &textureHandle : activeTexturesHandles) {
- GLTexture *tex = m_glResourceManagers->glTextureManager()->data(textureHandle);
- tex->destroy();
- }
+ if (context->thread() == QThread::currentThread()) {
+ QSurface *lastContextSurface = context->surface();
+
+ if (context->makeCurrent(offscreenSurface)) {
+ // Clean up the graphics context and any resources
+ const std::vector<HGLTexture> &activeTexturesHandles = m_glResourceManagers->glTextureManager()->activeHandles();
+ for (const HGLTexture &textureHandle : activeTexturesHandles) {
+ GLTexture *tex = m_glResourceManagers->glTextureManager()->data(textureHandle);
+ tex->destroy();
+ }
- // Do the same thing with buffers
- const std::vector<HGLBuffer> &activeBuffers = m_glResourceManagers->glBufferManager()->activeHandles();
- for (const HGLBuffer &bufferHandle : activeBuffers) {
- GLBuffer *buffer = m_glResourceManagers->glBufferManager()->data(bufferHandle);
- buffer->destroy(m_submissionContext.data());
- }
+ // Do the same thing with buffers
+ const std::vector<HGLBuffer> &activeBuffers = m_glResourceManagers->glBufferManager()->activeHandles();
+ for (const HGLBuffer &bufferHandle : activeBuffers) {
+ GLBuffer *buffer = m_glResourceManagers->glBufferManager()->data(bufferHandle);
+ buffer->destroy(m_submissionContext.data());
+ }
- // Do the same thing with shaders
- const std::vector<GLShader *> shaders = m_glResourceManagers->glShaderManager()->takeActiveResources();
- qDeleteAll(shaders);
+ // Do the same thing with shaders
+ const std::vector<GLShader *> shaders = m_glResourceManagers->glShaderManager()->takeActiveResources();
+ qDeleteAll(shaders);
- // Do the same thing with VAOs
- const std::vector<HVao> &activeVaos = m_glResourceManagers->vaoManager()->activeHandles();
- for (const HVao &vaoHandle : activeVaos) {
- OpenGLVertexArrayObject *vao = m_glResourceManagers->vaoManager()->data(vaoHandle);
- vao->destroy();
- }
+ // Do the same thing with VAOs
+ const std::vector<HVao> &activeVaos = m_glResourceManagers->vaoManager()->activeHandles();
+ for (const HVao &vaoHandle : activeVaos) {
+ OpenGLVertexArrayObject *vao = m_glResourceManagers->vaoManager()->data(vaoHandle);
+ vao->destroy();
+ }
- m_submissionContext->releaseRenderTargets();
+ m_submissionContext->releaseRenderTargets();
- m_frameProfiler.reset();
- if (m_ownedContext)
- context->doneCurrent();
+ m_frameProfiler.reset();
+ if (m_ownedContext) {
+ context->doneCurrent();
+ } else {
+ // Leave the context in the state we found it in by restoring
+ // its last used surface. This satisfies expectations when used
+ // with QQuickWidgets that surface on current context after
+ // QQuickRenderControl cleanup is the same as prior to the
+ // cleanup. Arguably this could also be checked for in
+ // QQuickWidgetPrivate::invalidateRenderControl.
+ context->makeCurrent(lastContextSurface);
+ }
+ }
} else {
qWarning() << "Failed to make context current: OpenGL resources will not be destroyed";
}