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.

Pick-to: 6.2 6.2.2
Change-Id: I8c845727c50871f30fbebc2ed62a7d0485651ecf
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Tor Arne Vestbø 2021-11-12 16:10:05 +01:00
parent 550e02b809
commit 99bb78f6c2
3 changed files with 20 additions and 0 deletions

View File

@ -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

View File

@ -295,6 +295,8 @@ public: // for QNSView
#endif
};
extern const NSNotificationName QCocoaWindowWillReleaseQNSViewNotification;
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QCocoaWindow *window);
#endif

View File

@ -186,6 +186,8 @@ void QCocoaWindow::initialize()
m_initialized = true;
}
const NSNotificationName QCocoaWindowWillReleaseQNSViewNotification = @"QCocoaWindowWillReleaseQNSViewNotification";
QCocoaWindow::~QCocoaWindow()
{
qCDebug(lcQpaWindow) << "QCocoaWindow::~QCocoaWindow" << window();
@ -209,6 +211,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];