macOS: Simplify and clean up QCocoaGLContext constructor

Change-Id: Ie16256282784926506355012a735511b98118614
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@qt.io>
This commit is contained in:
Tor Arne Vestbø 2018-08-01 12:54:20 +02:00
parent 1d42241d37
commit fa455b4c60
3 changed files with 36 additions and 34 deletions

View File

@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
class QCocoaGLContext : public QPlatformOpenGLContext class QCocoaGLContext : public QPlatformOpenGLContext
{ {
public: public:
QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, const QVariant &nativeHandle); QCocoaGLContext(QOpenGLContext *context);
~QCocoaGLContext(); ~QCocoaGLContext();
bool makeCurrent(QPlatformSurface *surface) override; bool makeCurrent(QPlatformSurface *surface) override;
@ -77,11 +77,11 @@ private:
bool setActiveWindow(QWindow *window); bool setActiveWindow(QWindow *window);
void updateSurfaceFormat(); void updateSurfaceFormat();
NSOpenGLContext *m_context; NSOpenGLContext *m_context = nil;
NSOpenGLContext *m_shareContext; NSOpenGLContext *m_shareContext = nil;
QSurfaceFormat m_format; QSurfaceFormat m_format;
QPointer<QWindow> m_currentWindow; QPointer<QWindow> m_currentWindow;
bool m_didCheckForSoftwareContext; bool m_didCheckForSoftwareContext = false;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -58,40 +58,44 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaOpenGLContext, "qt.qpa.openglcontext", QtWarningMsg); Q_LOGGING_CATEGORY(lcQpaOpenGLContext, "qt.qpa.openglcontext", QtWarningMsg);
QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context)
const QVariant &nativeHandle) : QPlatformOpenGLContext(), m_format(context->format())
: m_context(nil),
m_shareContext(nil),
m_format(format),
m_didCheckForSoftwareContext(false)
{ {
QVariant nativeHandle = context->nativeHandle();
if (!nativeHandle.isNull()) { if (!nativeHandle.isNull()) {
if (!nativeHandle.canConvert<QCocoaNativeContext>()) { if (!nativeHandle.canConvert<QCocoaNativeContext>()) {
qCWarning(lcQpaOpenGLContext, "QOpenGLContext native handle must be a QCocoaNativeContext"); qCWarning(lcQpaOpenGLContext, "QOpenGLContext native handle must be a QCocoaNativeContext");
return; return;
} }
QCocoaNativeContext handle = nativeHandle.value<QCocoaNativeContext>(); m_context = nativeHandle.value<QCocoaNativeContext>().context();
NSOpenGLContext *context = handle.context(); if (!m_context) {
if (!context) {
qCWarning(lcQpaOpenGLContext, "QCocoaNativeContext's NSOpenGLContext can not be null"); qCWarning(lcQpaOpenGLContext, "QCocoaNativeContext's NSOpenGLContext can not be null");
return; return;
} }
m_context = context;
[m_context retain]; [m_context retain];
m_shareContext = share ? static_cast<QCocoaGLContext *>(share)->nativeContext() : nil;
// Note: We have no way of knowing whether the NSOpenGLContext was created with the
// share context as reported by the QOpenGLContext, but we just have to trust that
// it was. It's okey, as the only thing we're using it for is to report isShared().
if (QPlatformOpenGLContext *shareContext = context->shareHandle())
m_shareContext = static_cast<QCocoaGLContext *>(shareContext)->nativeContext();
updateSurfaceFormat(); updateSurfaceFormat();
return; return;
} }
// we only support OpenGL contexts under Cocoa // ----------- Default case, we own the NSOpenGLContext -----------
// We only support OpenGL contexts under Cocoa
if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType) if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType)
m_format.setRenderableType(QSurfaceFormat::OpenGL); m_format.setRenderableType(QSurfaceFormat::OpenGL);
if (m_format.renderableType() != QSurfaceFormat::OpenGL) if (m_format.renderableType() != QSurfaceFormat::OpenGL)
return; return;
m_shareContext = share ? static_cast<QCocoaGLContext *>(share)->nativeContext() : nil; if (QPlatformOpenGLContext *shareContext = context->shareHandle()) {
m_shareContext = static_cast<QCocoaGLContext *>(shareContext)->nativeContext();
if (m_shareContext) {
// Allow sharing between 3.2 Core and 4.1 Core profile versions in // Allow sharing between 3.2 Core and 4.1 Core profile versions in
// cases where NSOpenGLContext creates a 4.1 context where a 3.2 // cases where NSOpenGLContext creates a 4.1 context where a 3.2
// context was requested. Due to the semantics of QSurfaceFormat // context was requested. Due to the semantics of QSurfaceFormat
@ -100,14 +104,13 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo
GLint shareContextRequestedProfile; GLint shareContextRequestedProfile;
[m_shareContext.pixelFormat getValues:&shareContextRequestedProfile [m_shareContext.pixelFormat getValues:&shareContextRequestedProfile
forAttribute:NSOpenGLPFAOpenGLProfile forVirtualScreen:0]; forAttribute:NSOpenGLPFAOpenGLProfile forVirtualScreen:0];
auto shareContextActualProfile = share->format().version(); auto shareContextActualProfile = shareContext->format().version();
if (shareContextRequestedProfile == NSOpenGLProfileVersion3_2Core && if (shareContextRequestedProfile == NSOpenGLProfileVersion3_2Core
shareContextActualProfile >= qMakePair(4, 1)) { && shareContextActualProfile >= qMakePair(4, 1)) {
// There is a mismatch. Downgrade requested format to make the
// There is a mismatch, downgrade requested format to make the // NSOpenGLPFAOpenGLProfile attributes match. (NSOpenGLContext
// NSOpenGLPFAOpenGLProfile attributes match. (NSOpenGLContext will // will fail to create a new context if there is a mismatch).
// fail to create a new context if there is a mismatch).
if (m_format.version() >= qMakePair(4, 1)) if (m_format.version() >= qMakePair(4, 1))
m_format.setVersion(3, 2); m_format.setVersion(3, 2);
} }
@ -118,12 +121,11 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo
NSOpenGLPixelFormat *pixelFormat = [pixelFormatForSurfaceFormat(m_format) autorelease]; NSOpenGLPixelFormat *pixelFormat = [pixelFormatForSurfaceFormat(m_format) autorelease];
m_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:m_shareContext]; m_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:m_shareContext];
// retry without sharing on context creation failure.
if (!m_context && m_shareContext) { if (!m_context && m_shareContext) {
qCWarning(lcQpaOpenGLContext, "Could not create NSOpenGLContext with shared context, " qCWarning(lcQpaOpenGLContext, "Could not create NSOpenGLContext with shared context, "
"falling back to unshared context."); "falling back to unshared context.");
m_shareContext = nil;
m_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; m_context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
m_shareContext = nil;
} }
if (!m_context) { if (!m_context) {
@ -131,16 +133,18 @@ QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLCo
return; return;
} }
const GLint interval = format.swapInterval() >= 0 ? format.swapInterval() : 1; // --------------------- Set NSOpenGLContext properties ---------------------
const GLint interval = m_format.swapInterval() >= 0 ? m_format.swapInterval() : 1;
[m_context setValues:&interval forParameter:NSOpenGLCPSwapInterval]; [m_context setValues:&interval forParameter:NSOpenGLCPSwapInterval];
if (format.alphaBufferSize() > 0) { if (m_format.alphaBufferSize() > 0) {
int zeroOpacity = 0; int zeroOpacity = 0;
[m_context setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity]; [m_context setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
} }
// OpenGL surfaces can be ordered either above(default) or below the NSWindow
// OpenGL surfaces can be ordered either above(default) or below the NSWindow. // FIXME: Promote to QSurfaceFormat option or property
const GLint order = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER"); const GLint order = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER");
[m_context setValues:&order forParameter:NSOpenGLCPSurfaceOrder]; [m_context setValues:&order forParameter:NSOpenGLCPSurfaceOrder];

View File

@ -360,9 +360,7 @@ QPlatformOffscreenSurface *QCocoaIntegration::createPlatformOffscreenSurface(QOf
#ifndef QT_NO_OPENGL #ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{ {
QCocoaGLContext *glContext = new QCocoaGLContext(context->format(), QCocoaGLContext *glContext = new QCocoaGLContext(context);
context->shareHandle(),
context->nativeHandle());
context->setNativeHandle(QVariant::fromValue<QCocoaNativeContext>(glContext->nativeContext())); context->setNativeHandle(QVariant::fromValue<QCocoaNativeContext>(glContext->nativeContext()));
return glContext; return glContext;
} }