From 27dc07fa050b5f216516debcd11802530a0c2d79 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Sun, 6 Apr 2014 15:53:55 +0200 Subject: [PATCH] Support adapting an existing NSOpenGLContext in cocoa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I61b4055020c82dd5ac40850fe7def91d26ffb6fe Reviewed-by: Morten Johan Sørvig --- .../nativecontexts/nativecontexts.pri | 3 +- .../nativecontexts/qcocoanativecontext.h | 69 +++++++++++++++++++ src/plugins/platforms/cocoa/qcocoaglcontext.h | 4 +- .../platforms/cocoa/qcocoaglcontext.mm | 30 +++++++- .../platforms/cocoa/qcocoaintegration.mm | 6 +- 5 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 src/platformheaders/nativecontexts/qcocoanativecontext.h diff --git a/src/platformheaders/nativecontexts/nativecontexts.pri b/src/platformheaders/nativecontexts/nativecontexts.pri index 3fe62ea6fe..09ad14dd71 100644 --- a/src/platformheaders/nativecontexts/nativecontexts.pri +++ b/src/platformheaders/nativecontexts/nativecontexts.pri @@ -1,2 +1,3 @@ HEADERS += $$PWD/qglxnativecontext.h \ - $$PWD/qeglnativecontext.h + $$PWD/qeglnativecontext.h \ + $$PWD/qcocoanativecontext.h diff --git a/src/platformheaders/nativecontexts/qcocoanativecontext.h b/src/platformheaders/nativecontexts/qcocoanativecontext.h new file mode 100644 index 0000000000..e1cefd24b3 --- /dev/null +++ b/src/platformheaders/nativecontexts/qcocoanativecontext.h @@ -0,0 +1,69 @@ +/**************************************************************************** + ** + ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). + ** Contact: http://www.qt-project.org/legal + ** + ** This file is part of the plugins of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:LGPL$ + ** Commercial License Usage + ** Licensees holding valid commercial Qt licenses may use this file in + ** accordance with the commercial license agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and Digia. For licensing terms and + ** conditions see http://qt.digia.com/licensing. For further information + ** use the contact form at http://qt.digia.com/contact-us. + ** + ** GNU Lesser General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU Lesser + ** General Public License version 2.1 as published by the Free Software + ** Foundation and appearing in the file LICENSE.LGPL included in the + ** packaging of this file. Please review the following information to + ** ensure the GNU Lesser General Public License version 2.1 requirements + ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. + ** + ** In addition, as a special exception, Digia gives you certain additional + ** rights. These rights are described in the Digia Qt LGPL Exception + ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. + ** + ** GNU General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU + ** General Public License version 3.0 as published by the Free Software + ** Foundation and appearing in the file LICENSE.GPL included in the + ** packaging of this file. Please review the following information to + ** ensure the GNU General Public License version 3.0 requirements will be + ** met: http://www.gnu.org/copyleft/gpl.html. + ** + ** + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#ifndef QCOCOANATIVECONTEXT_H +#define QCOCOANATIVECONTEXT_H + +#include + +QT_BEGIN_NAMESPACE + +struct QCocoaNativeContext +{ + QCocoaNativeContext() + : m_context(0) + { } + + QCocoaNativeContext(NSOpenGLContext *ctx) + : m_context(ctx) + { } + + NSOpenGLContext *context() const { return m_context; } + +private: + NSOpenGLContext *m_context; +}; + +QT_END_NAMESPACE + +Q_DECLARE_METATYPE(QCocoaNativeContext) + +#endif // QCOCOANATIVECONTEXT_H diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.h b/src/plugins/platforms/cocoa/qcocoaglcontext.h index 30f1cdc278..2aa22ea759 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.h +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.h @@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE class QCocoaGLContext : public QPlatformOpenGLContext { public: - QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share); + QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, const QVariant &nativeHandle); ~QCocoaGLContext(); QSurfaceFormat format() const; @@ -77,6 +77,8 @@ public: void windowWasHidden(); + QVariant nativeHandle() const; + private: void setActiveWindow(QWindow *window); void updateSurfaceFormat(); diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm index 3f61bd81ee..7b70fbb4bb 100644 --- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm +++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm @@ -46,6 +46,7 @@ #include #include #include +#include #import @@ -117,11 +118,33 @@ static void updateFormatFromContext(QSurfaceFormat *format) format->setProfile(QSurfaceFormat::CompatibilityProfile); } -QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share) +QCocoaGLContext::QCocoaGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, + const QVariant &nativeHandle) : m_context(nil), m_shareContext(nil), m_format(format) { + if (!nativeHandle.isNull()) { + if (!nativeHandle.canConvert()) { + qWarning("QCocoaGLContext: Requires a QCocoaNativeContext"); + return; + } + QCocoaNativeContext handle = nativeHandle.value(); + NSOpenGLContext *context = handle.context(); + if (!context) { + qWarning("QCocoaGLContext: No NSOpenGLContext given"); + return; + } + m_context = context; + [m_context retain]; + m_shareContext = share ? static_cast(share)->nsOpenGLContext() : nil; + // OpenGL surfaces can be ordered either above(default) or below the NSWindow. + const GLint order = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER"); + [m_context setValues:&order forParameter:NSOpenGLCPSurfaceOrder]; + updateSurfaceFormat(); + return; + } + // we only support OpenGL contexts under Cocoa if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType) m_format.setRenderableType(QSurfaceFormat::OpenGL); @@ -168,6 +191,11 @@ QCocoaGLContext::~QCocoaGLContext() [m_context release]; } +QVariant QCocoaGLContext::nativeHandle() const +{ + return QVariant::fromValue(QCocoaNativeContext(m_context)); +} + // Match up with createNSOpenGLPixelFormat! QSurfaceFormat QCocoaGLContext::format() const { diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 8723b20615..b22bc71e30 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -422,7 +422,11 @@ QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWindow *window) const QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { - return new QCocoaGLContext(context->format(), context->shareHandle()); + QCocoaGLContext *glContext = new QCocoaGLContext(context->format(), + context->shareHandle(), + context->nativeHandle()); + context->setNativeHandle(glContext->nativeHandle()); + return glContext; } QPlatformBackingStore *QCocoaIntegration::createPlatformBackingStore(QWindow *window) const