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:
parent
85917c4b72
commit
c0e94fa0cd
@ -65,8 +65,6 @@ public:
|
|||||||
bool isSharing() const override;
|
bool isSharing() const override;
|
||||||
bool isValid() const override;
|
bool isValid() const override;
|
||||||
|
|
||||||
void windowWasHidden();
|
|
||||||
|
|
||||||
NSOpenGLContext *nativeContext() const;
|
NSOpenGLContext *nativeContext() const;
|
||||||
|
|
||||||
QFunctionPointer getProcAddress(const char *procName) override;
|
QFunctionPointer getProcAddress(const char *procName) override;
|
||||||
@ -80,7 +78,6 @@ private:
|
|||||||
NSOpenGLContext *m_context = nil;
|
NSOpenGLContext *m_context = nil;
|
||||||
NSOpenGLContext *m_shareContext = nil;
|
NSOpenGLContext *m_shareContext = nil;
|
||||||
QSurfaceFormat m_format;
|
QSurfaceFormat m_format;
|
||||||
QPointer<QWindow> m_currentWindow;
|
|
||||||
bool m_didCheckForSoftwareContext = false;
|
bool m_didCheckForSoftwareContext = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -318,9 +318,6 @@ void QCocoaGLContext::updateSurfaceFormat()
|
|||||||
|
|
||||||
QCocoaGLContext::~QCocoaGLContext()
|
QCocoaGLContext::~QCocoaGLContext()
|
||||||
{
|
{
|
||||||
if (m_currentWindow && m_currentWindow.data()->handle())
|
|
||||||
static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(0);
|
|
||||||
|
|
||||||
[m_context release];
|
[m_context release];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,20 +369,15 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface)
|
|||||||
// on the previously set drawable.
|
// on the previously set drawable.
|
||||||
qCDebug(lcQpaOpenGLContext) << "Clearing current drawable" << m_context.view << "for" << m_context;
|
qCDebug(lcQpaOpenGLContext) << "Clearing current drawable" << m_context.view << "for" << m_context;
|
||||||
[m_context clearDrawable];
|
[m_context clearDrawable];
|
||||||
m_currentWindow.clear();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window);
|
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;
|
return true;
|
||||||
|
|
||||||
Q_ASSERT(window->handle());
|
|
||||||
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
|
|
||||||
NSView *view = cocoaWindow->view();
|
|
||||||
|
|
||||||
if ((m_context.view = view) != view) {
|
if ((m_context.view = view) != view) {
|
||||||
qCInfo(lcQpaOpenGLContext) << "Failed to set" << view << "as drawable for" << m_context;
|
qCInfo(lcQpaOpenGLContext) << "Failed to set" << view << "as drawable for" << m_context;
|
||||||
return false;
|
return false;
|
||||||
@ -393,12 +385,6 @@ bool QCocoaGLContext::setDrawable(QPlatformSurface *surface)
|
|||||||
|
|
||||||
qCInfo(lcQpaOpenGLContext) << "Set drawable for" << m_context << "to" << m_context.view;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,24 +421,13 @@ void QCocoaGLContext::doneCurrent()
|
|||||||
qCDebug(lcQpaOpenGLContext) << "Clearing current context"
|
qCDebug(lcQpaOpenGLContext) << "Clearing current context"
|
||||||
<< [NSOpenGLContext currentContext] << "in" << QThread::currentThread();
|
<< [NSOpenGLContext currentContext] << "in" << QThread::currentThread();
|
||||||
|
|
||||||
if (m_currentWindow && m_currentWindow.data()->handle())
|
// Note: We do not need to clear the current drawable here.
|
||||||
static_cast<QCocoaWindow *>(m_currentWindow.data()->handle())->setCurrentContext(nullptr);
|
// As long as there is no current context, GL calls will
|
||||||
|
// do nothing.
|
||||||
m_currentWindow.clear();
|
|
||||||
|
|
||||||
[NSOpenGLContext clearCurrentContext];
|
[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
|
QSurfaceFormat QCocoaGLContext::format() const
|
||||||
{
|
{
|
||||||
return m_format;
|
return m_format;
|
||||||
|
@ -102,10 +102,6 @@ void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceS
|
|||||||
|
|
||||||
if (resourceString == "nsview") {
|
if (resourceString == "nsview") {
|
||||||
return static_cast<QCocoaWindow *>(window->handle())->m_view;
|
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") {
|
} else if (resourceString == "nswindow") {
|
||||||
return static_cast<QCocoaWindow *>(window->handle())->nativeWindow();
|
return static_cast<QCocoaWindow *>(window->handle())->nativeWindow();
|
||||||
#if QT_CONFIG(vulkan)
|
#if QT_CONFIG(vulkan)
|
||||||
|
@ -169,11 +169,6 @@ public:
|
|||||||
NSUInteger windowStyleMask(Qt::WindowFlags flags);
|
NSUInteger windowStyleMask(Qt::WindowFlags flags);
|
||||||
void setWindowZoomButton(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;
|
bool setWindowModified(bool modified) override;
|
||||||
|
|
||||||
void setFrameStrutEventsEnabled(bool enabled) override;
|
void setFrameStrutEventsEnabled(bool enabled) override;
|
||||||
@ -253,9 +248,6 @@ public: // for QNSView
|
|||||||
bool m_inSetVisible;
|
bool m_inSetVisible;
|
||||||
bool m_inSetGeometry;
|
bool m_inSetGeometry;
|
||||||
bool m_inSetStyleMask;
|
bool m_inSetStyleMask;
|
||||||
#ifndef QT_NO_OPENGL
|
|
||||||
QCocoaGLContext *m_glContext;
|
|
||||||
#endif
|
|
||||||
QCocoaMenuBar *m_menubar;
|
QCocoaMenuBar *m_menubar;
|
||||||
|
|
||||||
bool m_needsInvalidateShadow;
|
bool m_needsInvalidateShadow;
|
||||||
|
@ -151,9 +151,6 @@ QCocoaWindow::QCocoaWindow(QWindow *win, WId nativeHandle)
|
|||||||
, m_inSetVisible(false)
|
, m_inSetVisible(false)
|
||||||
, m_inSetGeometry(false)
|
, m_inSetGeometry(false)
|
||||||
, m_inSetStyleMask(false)
|
, m_inSetStyleMask(false)
|
||||||
#ifndef QT_NO_OPENGL
|
|
||||||
, m_glContext(nullptr)
|
|
||||||
#endif
|
|
||||||
, m_menubar(nullptr)
|
, m_menubar(nullptr)
|
||||||
, m_needsInvalidateShadow(false)
|
, m_needsInvalidateShadow(false)
|
||||||
, m_hasModalSession(false)
|
, m_hasModalSession(false)
|
||||||
@ -405,10 +402,6 @@ void QCocoaWindow::setVisible(bool visible)
|
|||||||
[m_view setHidden:NO];
|
[m_view setHidden:NO];
|
||||||
} else {
|
} else {
|
||||||
// qDebug() << "close" << this;
|
// qDebug() << "close" << this;
|
||||||
#ifndef QT_NO_OPENGL
|
|
||||||
if (m_glContext)
|
|
||||||
m_glContext->windowWasHidden();
|
|
||||||
#endif
|
|
||||||
QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
|
QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
|
||||||
QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = nullptr;
|
QCocoaEventDispatcherPrivate *cocoaEventDispatcherPrivate = nullptr;
|
||||||
if (cocoaEventDispatcher)
|
if (cocoaEventDispatcher)
|
||||||
@ -1336,18 +1329,6 @@ bool QCocoaWindow::windowIsPopupType(Qt::WindowType type) const
|
|||||||
return ((type & Qt::Popup) == Qt::Popup);
|
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.
|
Checks if the window is the content view of its immediate NSWindow.
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user