macOS: Use NSOpenGLContext's drawable directly to track active drawable

We don't need a separate QWindow pointer to keep track of the active
window, it's recorded already by the NSOpenGLContext's drawable.

And we don't need to juggle the drawable when the window is hidden,
the drawable is still valid after the window is re-shown, and we
call update on every frame (for now) anyways, which will reconfigure
the drawable if needed.

Change-Id: I199b6c027226dd239c13ecc4aba86986ca09a1eb
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Tor Arne Vestbø 2018-09-05 12:18:59 +02:00
parent 85917c4b72
commit c0e94fa0cd
5 changed files with 5 additions and 64 deletions

View File

@ -65,8 +65,6 @@ public:
bool isSharing() const override;
bool isValid() const override;
void windowWasHidden();
NSOpenGLContext *nativeContext() const;
QFunctionPointer getProcAddress(const char *procName) override;
@ -80,7 +78,6 @@ private:
NSOpenGLContext *m_context = nil;
NSOpenGLContext *m_shareContext = nil;
QSurfaceFormat m_format;
QPointer<QWindow> m_currentWindow;
bool m_didCheckForSoftwareContext = false;
};

View File

@ -318,9 +318,6 @@ void QCocoaGLContext::updateSurfaceFormat()
QCocoaGLContext::~QCocoaGLContext()
{
if (m_currentWindow && m_currentWindow.data()->handle())
static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
[m_context release];
}
@ -372,20 +369,15 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface)
// on the previously set drawable.
qCDebug(lcQpaOpenGLContext) << "Clearing current drawable" << m_context.view << "for" << m_context;
[m_context clearDrawable];
m_currentWindow.clear();
return true;
}
Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window);
QWindow *window = static_cast<QCocoaWindow *>(surface)->window();
QNSView *view = qnsview_cast(static_cast<QCocoaWindow *>(surface)->view());
if (window == m_currentWindow.data())
if (view == m_context.view)
return true;
Q_ASSERT(window->handle());
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
NSView *view = cocoaWindow->view();
if ((m_context.view = view) != view) {
qCInfo(lcQpaOpenGLContext) << "Failed to set" << view << "as drawable for" << m_context;
return false;
@ -393,12 +385,6 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface)
qCInfo(lcQpaOpenGLContext) << "Set drawable for" << m_context << "to" << m_context.view;
if (m_currentWindow && m_currentWindow.data()->handle())
static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
m_currentWindow = window;
cocoaWindow->setCurrentContext(this);
return true;
}
@ -435,24 +421,13 @@ void QCocoaGLContext::doneCurrent()
qCDebug(lcQpaOpenGLContext) << "Clearing current context"
<< [NSOpenGLContext currentContext] << "in" << QThread::currentThread();
if (m_currentWindow && m_currentWindow.data()->handle())
static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(nullptr);
m_currentWindow.clear();
// Note: We do not need to clear the current drawable here.
// As long as there is no current context, GL calls will
// do nothing.
[NSOpenGLContext clearCurrentContext];
}
void QCocoaGLContext::windowWasHidden()
{
// If the window is hidden, we need to unset the m_currentWindow
// variable so that succeeding makeCurrent's will not abort prematurely
// because of the optimization in setDrawable.
// Doing a full doneCurrent here is not preferable, because the GL context
// might be rendering in a different thread at this time.
m_currentWindow.clear();
}
QSurfaceFormat QCocoaGLContext::format() const
{
return m_format;

View File

@ -102,10 +102,6 @@ void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceS
if (resourceString == "nsview") {
return static_cast<QCocoaWindow *>(window->handle())->m_view;
#ifndef QT_NO_OPENGL
} else if (resourceString == "nsopenglcontext") {
return static_cast<QCocoaWindow *>(window->handle())->currentContext()->nativeContext();
#endif
} else if (resourceString == "nswindow") {
return static_cast<QCocoaWindow *>(window->handle())->nativeWindow();
#if QT_CONFIG(vulkan)

View File

@ -169,11 +169,6 @@ public:
NSUInteger windowStyleMask(Qt::WindowFlags flags);
void setWindowZoomButton(Qt::WindowFlags flags);
#ifndef QT_NO_OPENGL
void setCurrentContext(QCocoaGLContext *context);
QCocoaGLContext *currentContext() const;
#endif
bool setWindowModified(bool modified) override;
void setFrameStrutEventsEnabled(bool enabled) override;
@ -253,9 +248,6 @@ public: // for QNSView
bool m_inSetVisible;
bool m_inSetGeometry;
bool m_inSetStyleMask;
#ifndef QT_NO_OPENGL
QCocoaGLContext *m_glContext;
#endif
QCocoaMenuBar *m_menubar;
bool m_needsInvalidateShadow;

View File

@ -151,9 +151,6 @@ QCocoaWindow::QCocoaWindow(QWindow *win, WId nativeHandle)
, m_inSetVisible(false)
, m_inSetGeometry(false)
, m_inSetStyleMask(false)
#ifndef QT_NO_OPENGL
, m_glContext(nullptr)
#endif
, m_menubar(nullptr)
, m_needsInvalidateShadow(false)
, m_hasModalSession(false)
@ -405,10 +402,6 @@ void QCocoaWindow::setVisible(bool visible)
[m_view setHidden:NO];
} else {
// qDebug() << "close" << this;
#ifndef QT_NO_OPENGL
if (m_glContext)
m_glContext->windowWasHidden();
#endif
QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = nullptr;
if (cocoaEventDispatcher)
@ -1336,18 +1329,6 @@ bool QCocoaWindow::windowIsPopupType(Qt::WindowType type) const
return ((type & Qt::Popup) == Qt::Popup);
}
#ifndef QT_NO_OPENGL
void QCocoaWindow::setCurrentContext(QCocoaGLContext *context)
{
m_glContext = context;
}
QCocoaGLContext *QCocoaWindow::currentContext() const
{
return m_glContext;
}
#endif
/*!
Checks if the window is the content view of its immediate NSWindow.