From 61d142e9ae65d487718221c8d2c2e70ef081188c Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 13 Dec 2022 12:18:22 +0100 Subject: [PATCH] Sanitize the order of things in QOpenGLContext destroy() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Amends e08fe78b2335046934abae970e59fe0156178b95 (in a way). While touching this function in the other patch, it becomes obvious that the order in which things are cleaned up and invalidated is somewhat odd: the native context is in fact gone _before_ invoking helper callbacks or tearing down the OpenGL API wrappers. This only works because likely nothing relies on the context still being usable when destroying those objects and when the texture/vao helper callbacks run. Reorder this to: 1. emit the about-to signal 2. invoke callbacks and null out helpers 3. destroy the function resolvers 4. only then start tearing down the platform (and so the underlying native) context objects. Change-Id: I9067463b8f6ce1f656129594c347c1428439ca5e Reviewed-by: Qt CI Bot Reviewed-by: Christian Strømme (cherry picked from commit f045ef4ab6f72b2024119d15da8476a26e3b2242) Reviewed-by: Qt Cherry-pick Bot --- src/gui/kernel/qopenglcontext.cpp | 32 ++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 49ba5eea163..4a9d62829f7 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -403,18 +403,13 @@ void QOpenGLContextPrivate::adopt(QPlatformOpenGLContext *context) void QOpenGLContext::destroy() { Q_D(QOpenGLContext); + + // Notify that the native context and the QPlatformOpenGLContext are going + // to go away. if (d->platformGLContext) emit aboutToBeDestroyed(); - if (QOpenGLContext::currentContext() == this) - doneCurrent(); - if (d->shareGroup) - d->shareGroup->d_func()->removeContext(this); - d->shareGroup = nullptr; - delete d->platformGLContext; - d->platformGLContext = nullptr; - delete d->functions; - d->functions = nullptr; + // Invoke callbacks for helpers and invalidate. if (d->textureFunctionsDestroyCallback) { d->textureFunctionsDestroyCallback(); d->textureFunctionsDestroyCallback = nullptr; @@ -427,6 +422,25 @@ void QOpenGLContext::destroy() d->vaoHelperDestroyCallback = nullptr; } d->vaoHelper = nullptr; + + // Tear down function wrappers. + delete d->versionFunctions; + d->versionFunctions = nullptr; + + delete d->functions; + d->functions = nullptr; + + // Clean up and destroy the native context machinery. + if (QOpenGLContext::currentContext() == this) + doneCurrent(); + + if (d->shareGroup) + d->shareGroup->d_func()->removeContext(this); + + d->shareGroup = nullptr; + + delete d->platformGLContext; + d->platformGLContext = nullptr; } /*!