summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2021-11-12 16:10:05 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-11-17 13:28:20 +0000
commit6ac061f57031bdc12167c7c89501eb03f3a2527b (patch)
tree01848b87bcf759ab456688cccff6493efe8033be
parentf9ea9e9b0a57e4b7db929a2b179ba0f3f622431c (diff)
macOS: Clear NSOpenGLContext drawable when QNSView is about to go away
Calling doneCurrent() on a QCocoaGLContext only clears the current context, but doesns't reset the drawable (view) of the context. In most cases this is fine, but it has been observed to cause issues when using the software GL renderer on Big Sur and above. To be a good citizen we clear the drawable of any of our contexts that are tied to the NSView this about to be go away. Change-Id: I8c845727c50871f30fbebc2ed62a7d0485651ecf Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> (cherry picked from commit 99bb78f6c2a748070d1354f9e13951b1e3344b19) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm9
3 files changed, 20 insertions, 0 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index 40a7a6ef5e..026a99a152 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -422,6 +422,15 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface)
m_updateObservers.append(QMacNotificationObserver([NSApplication sharedApplication],
NSApplicationDidChangeScreenParametersNotification, updateCallback));
+ m_updateObservers.append(QMacNotificationObserver(view,
+ QCocoaWindowWillReleaseQNSViewNotification, [this, view] {
+ if (QT_IGNORE_DEPRECATIONS(m_context.view) != view)
+ return;
+ qCDebug(lcQpaOpenGLContext) << view << "about to be released."
+ << "Clearing current drawable for" << m_context;
+ [m_context clearDrawable];
+ }));
+
// If any of the observers fire at this point it's fine. We check the
// view association (atomically) in the update callback, and skip the
// update if we haven't associated yet. Setting the drawable below will
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 8d7be34695..eeafc2d48d 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -299,6 +299,8 @@ public: // for QNSView
#endif
};
+extern const NSNotificationName QCocoaWindowWillReleaseQNSViewNotification;
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QCocoaWindow *window);
#endif
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index e88372c106..8077c6707c 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -187,6 +187,8 @@ void QCocoaWindow::initialize()
m_initialized = true;
}
+const NSNotificationName QCocoaWindowWillReleaseQNSViewNotification = @"QCocoaWindowWillReleaseQNSViewNotification";
+
QCocoaWindow::~QCocoaWindow()
{
qCDebug(lcQpaWindow) << "QCocoaWindow::~QCocoaWindow" << window();
@@ -216,6 +218,13 @@ QCocoaWindow::~QCocoaWindow()
#endif
}
+ // Must send notification before calling release, as doing it from
+ // [QNSView dealloc] would mean that any weak references to the view
+ // would already return nil.
+ [NSNotificationCenter.defaultCenter
+ postNotificationName:QCocoaWindowWillReleaseQNSViewNotification
+ object:m_view];
+
[m_view release];
[m_nsWindow close];
[m_nsWindow release];