Introduce platform API abstraction for QOpenGLContext

The API is available by including qopenglcontext.h as usual,
but scoped in the QPlatformInterface namespace. The namespace
exposes platform specific type-safe interfaces that provide:

 a) Factory functions for adopting native contexts, e.g.

    QCocoaGLContext::fromNative(nsContext, shareContext);

 b) Access to underlying native handles, e.g.

    openGLContext->platformInterface<QCocoaGLContext>->nativeContext()

 c) Platform specific functionality, e.g.

    static QWGLContext::openGLModuleHandle()

    openGLContext->platformInterface<QEGLContext>->doSomething();

The platform interfaces live close to the classes they extend,
removing the need for complex indirection and plumbing, and
avoids kitchen-sink modules and APIs such as the extras modules,
QPlatformFunctions, or QPlatformNativeInterface.

In the case of QOpenGLContext these platform APIs are backed
by the platform plugin, so dynamic_cast is used to ensure the
platform plugin supports the requested interface, but this is
and implementation detail. The interface APIs are agnostic
to where the implementation lives, while still being available
to the user as part of the APIs they extend/augment.

The documentation will be restored when the dust settles.

Task-number: QTBUG-80233
Change-Id: Iac612403383991c4b24064332542a6e4bcbb3293
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
This commit is contained in:
Tor Arne Vestbø 2020-06-08 20:00:36 +02:00
parent 037dce81fc
commit 6ff79478a4
65 changed files with 638 additions and 978 deletions

View File

@ -381,8 +381,11 @@ void Widget::renderWindowReady()
const char *gltype[] = { "Desktop", "GLES 2", "GLES 1" };
m_output->append(tr("Qt OpenGL configuration: %1")
.arg(QString::fromLatin1(gltype[QOpenGLContext::openGLModuleType()])));
#if defined(Q_OS_WIN)
using namespace QPlatformInterface;
m_output->append(tr("Qt OpenGL library handle: %1")
.arg(QString::number(qintptr(QOpenGLContext::openGLModuleHandle()), 16)));
.arg(QString::number(qintptr(QWGLContext::openGLModuleHandle()), 16)));
#endif
QList<QByteArray> extensionList = context->extensions().values();
std::sort(extensionList.begin(), extensionList.end());

View File

@ -1292,6 +1292,32 @@ template <bool B, typename T = void> struct QEnableIf;
template <typename T> struct QEnableIf<true, T> { typedef T Type; };
}
#define QT_VA_ARGS_CHOOSE(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
#define QT_VA_ARGS_EXPAND(...) __VA_ARGS__ // Needed for MSVC
#define QT_VA_ARGS_COUNT(...) QT_VA_ARGS_EXPAND(QT_VA_ARGS_CHOOSE(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1))
#define QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) MACRO##ARGC
#define QT_OVERLOADED_MACRO_IMP(MACRO, ARGC) QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC)
#define QT_OVERLOADED_MACRO(MACRO, ...) QT_VA_ARGS_EXPAND(QT_OVERLOADED_MACRO_IMP(MACRO, QT_VA_ARGS_COUNT(__VA_ARGS__))(__VA_ARGS__))
// Ensures that the interface's typeinfo is exported so that
// dynamic casts work reliably, and protects the destructor
// so that pointers to the interface can't be deleted.
#define QT_DECLARE_PLATFORM_INTERFACE(InterfaceClass) \
protected: virtual ~InterfaceClass(); public:
// Provides a definition for the interface destructor
#define QT_DEFINE_PLATFORM_INTERFACE2(Namespace, InterfaceClass) \
QT_PREPEND_NAMESPACE(Namespace)::InterfaceClass::~InterfaceClass() = default
// Provides a definition for the destructor, and an explicit
// template instantiation of the platform interface accessor.
#define QT_DEFINE_PLATFORM_INTERFACE3(Namespace, InterfaceClass, PublicClass) \
QT_DEFINE_PLATFORM_INTERFACE2(Namespace, InterfaceClass); \
template Q_DECL_EXPORT QT_PREPEND_NAMESPACE(Namespace)::InterfaceClass *PublicClass::platformInterface() const
#define QT_DEFINE_PLATFORM_INTERFACE(...) QT_OVERLOADED_MACRO(QT_DEFINE_PLATFORM_INTERFACE, QPlatformInterface, __VA_ARGS__)
#define QT_DEFINE_PRIVATE_PLATFORM_INTERFACE(...) QT_OVERLOADED_MACRO(QT_DEFINE_PLATFORM_INTERFACE, QPlatformInterface::Private, __VA_ARGS__)
QT_END_NAMESPACE
// We need to keep QTypeInfo, QSysInfo, QFlags, qDebug & family in qglobal.h for compatibility with Qt 4.

View File

@ -303,13 +303,6 @@ private:
return QAppleLogActivity(os_activity_create(description, parent, OS_ACTIVITY_FLAG_DEFAULT)); \
}()
#define QT_VA_ARGS_CHOOSE(_1, _2, _3, _4, _5, _6, _7, _8, _9, N, ...) N
#define QT_VA_ARGS_COUNT(...) QT_VA_ARGS_CHOOSE(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define QT_OVERLOADED_MACRO(MACRO, ...) _QT_OVERLOADED_MACRO(MACRO, QT_VA_ARGS_COUNT(__VA_ARGS__))(__VA_ARGS__)
#define _QT_OVERLOADED_MACRO(MACRO, ARGC) _QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC)
#define _QT_OVERLOADED_MACRO_EXPAND(MACRO, ARGC) MACRO##ARGC
#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(condition, description, parent) QT_APPLE_LOG_ACTIVITY_CREATE(condition, description, parent)
#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT2(description, parent) QT_APPLE_LOG_ACTIVITY_WITH_PARENT3(true, description, parent)
#define QT_APPLE_LOG_ACTIVITY_WITH_PARENT(...) QT_OVERLOADED_MACRO(QT_APPLE_LOG_ACTIVITY_WITH_PARENT, __VA_ARGS__)

View File

@ -347,7 +347,7 @@ endif()
qt_extend_target(Gui CONDITION QT_FEATURE_opengl
SOURCES
kernel/qopenglcontext.cpp kernel/qopenglcontext.h kernel/qopenglcontext_p.h
kernel/qopenglcontext.cpp kernel/qopenglcontext.h kernel/qopenglcontext_p.h kernel/qopenglcontext_platform.h
kernel/qplatformopenglcontext.cpp kernel/qplatformopenglcontext.h
opengl/qopengl.cpp opengl/qopengl.h opengl/qopengl_p.h
opengl/qopenglextensions_p.h
@ -362,6 +362,8 @@ qt_extend_target(Gui CONDITION QT_FEATURE_opengl
# MODULE_CONFIG = "opengl"
qt_extend_target(Gui CONDITION MACOS
SOURCES
platform/macos/qcocoaplatforminterface.mm
LIBRARIES
${FWAppKit}
PUBLIC_LIBRARIES
@ -395,6 +397,7 @@ qt_extend_target(Gui CONDITION WIN32
image/qpixmap_win.cpp
kernel/qwindowdefs_win.h
platform/windows/qwindowsguieventdispatcher.cpp platform/windows/qwindowsguieventdispatcher_p.h
platform/windows/qwindowsplatforminterface.cpp
rhi/qrhid3d11.cpp rhi/qrhid3d11_p.h
rhi/qrhid3d11_p_p.h
text/windows/qwindowsfontdatabase.cpp text/windows/qwindowsfontdatabase_p.h
@ -851,6 +854,7 @@ qt_extend_target(Gui CONDITION UNIX
platform/unix/qgenericunixeventdispatcher.cpp platform/unix/qgenericunixeventdispatcher_p.h
platform/unix/qunixeventdispatcher.cpp
platform/unix/qunixeventdispatcher_qpa_p.h
platform/unix/qunixplatforminterface.cpp
)
qt_extend_target(Gui CONDITION QT_FEATURE_glib AND UNIX

View File

@ -1225,7 +1225,7 @@
"egl": {
"label": "EGL",
"condition": "(features.opengl || features.openvg) && libs.egl && (features.dlopen || !config.unix || config.integrity)",
"output": [ "privateFeature", "feature" ]
"output": [ "publicFeature", "feature" ]
},
"egl_x11": {
"label": "EGL on X11",

View File

@ -161,7 +161,8 @@ qtConfig(opengl) {
HEADERS += \
kernel/qplatformopenglcontext.h \
kernel/qopenglcontext.h \
kernel/qopenglcontext_p.h
kernel/qopenglcontext_p.h \
kernel/qopenglcontext_platform.h \
SOURCES += \
kernel/qplatformopenglcontext.cpp \

View File

@ -347,63 +347,15 @@ void QOpenGLContextPrivate::_q_screenDestroyed(QObject *object)
}
/*!
Set the native handles for this context. When create() is called and a
native handle is set, configuration settings, like format(), are ignored
since this QOpenGLContext will wrap an already created native context
instead of creating a new one from scratch.
\fn T QOpenGLContext::platformInterface<T>()
On some platforms the native context handle is not sufficient and other
related handles (for example, for a window or display) have to be provided
in addition. Therefore \a handle is variant containing a platform-specific
value type. These classes can be found in the QtPlatformHeaders module.
Returns a platform interface of type T for the context.
When create() is called with native handles set, QOpenGLContext does not
take ownership of the handles, so destroying the QOpenGLContext does not
destroy the native context.
This function provides access to platform specific functionality
of QOpenGLContext, as defined in the QPlatformInterface namespace.
\note Some frameworks track the current context and surfaces internally.
Making the adopted QOpenGLContext current via Qt will have no effect on such
other frameworks' internal state. Therefore a subsequent makeCurrent done
via the other framework may have no effect. It is therefore advisable to
make explicit calls to make no context and surface current to reset the
other frameworks' internal state after performing OpenGL operations via Qt.
\note Using foreign contexts with Qt windows and Qt contexts with windows
and surfaces created by other frameworks may give unexpected results,
depending on the platform, due to potential mismatches in context and window
pixel formats. To make sure this does not happen, avoid making contexts and
surfaces from different frameworks current together. Instead, prefer
approaches based on context sharing where OpenGL resources like textures are
accessible both from Qt's and the foreign framework's contexts.
\since 5.4
\sa nativeHandle()
*/
void QOpenGLContext::setNativeHandle(const QVariant &handle)
{
Q_D(QOpenGLContext);
d->nativeHandle = handle;
}
/*!
Returns the native handle for the context.
This function provides access to the QOpenGLContext's underlying native
context. The returned variant contains a platform-specific value type. These
classes can be found in the module QtPlatformHeaders.
On platforms where retrieving the native handle is not supported, or if
neither create() nor setNativeHandle() was called, a null variant is
returned.
\since 5.4
\sa setNativeHandle()
If the requested interface is not available a \nullptr is returned.
*/
QVariant QOpenGLContext::nativeHandle() const
{
Q_D(const QOpenGLContext);
return d->nativeHandle;
}
/*!
Attempts to create the OpenGL context with the current configuration.
@ -433,18 +385,29 @@ bool QOpenGLContext::create()
if (d->platformGLContext)
destroy();
d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this);
if (!d->platformGLContext)
auto *platformContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this);
if (!platformContext)
return false;
d->platformGLContext->setContext(this);
d->platformGLContext->initialize();
if (!d->platformGLContext->isSharing())
d->shareContext = nullptr;
d->shareGroup = d->shareContext ? d->shareContext->shareGroup() : new QOpenGLContextGroup;
d->shareGroup->d_func()->addContext(this);
d->adopt(platformContext);
return isValid();
}
void QOpenGLContextPrivate::adopt(QPlatformOpenGLContext *context)
{
Q_Q(QOpenGLContext);
platformGLContext = context;
platformGLContext->setContext(q);
platformGLContext->initialize();
if (!platformGLContext->isSharing())
shareContext = nullptr;
shareGroup = shareContext ? shareContext->shareGroup() : new QOpenGLContextGroup;
shareGroup->d_func()->addContext(q);
}
/*!
\internal
@ -490,8 +453,6 @@ void QOpenGLContext::destroy()
d->vaoHelperDestroyCallback = nullptr;
}
d->vaoHelper = nullptr;
d->nativeHandle = QVariant();
}
/*!
@ -914,33 +875,6 @@ QScreen *QOpenGLContext::screen() const
return d->screen;
}
/*!
Returns the platform-specific handle for the OpenGL implementation that
is currently in use. (for example, a HMODULE on Windows)
On platforms that do not use dynamic GL switching, the return value
is \nullptr.
The library might be GL-only, meaning that windowing system interface
functions (for example EGL) may live in another, separate library.
\note This function requires that the QGuiApplication instance is already created.
\sa openGLModuleType()
\since 5.3
*/
void *QOpenGLContext::openGLModuleHandle()
{
#ifdef QT_OPENGL_DYNAMIC
QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface();
Q_ASSERT(ni);
return ni->nativeResourceForIntegration(QByteArrayLiteral("glhandle"));
#else
return nullptr;
#endif
}
/*!
\enum QOpenGLContext::OpenGLModuleType
This enum defines the type of the underlying OpenGL implementation.
@ -1350,8 +1284,7 @@ QDebug operator<<(QDebug debug, const QOpenGLContext *ctx)
if (ctx) {
debug << static_cast<const void *>(ctx);
if (ctx->isValid()) {
debug << ", nativeHandle=" << ctx->nativeHandle()
<< ", format=" << ctx->format();
debug << ", format=" << ctx->format();
if (const QSurface *sf = ctx->surface())
debug << ", surface=" << sf;
if (const QScreen *s = ctx->screen())

View File

@ -88,6 +88,7 @@ private:
QOpenGLContextGroup();
friend class QOpenGLContext;
friend class QOpenGLContextPrivate;
friend class QOpenGLContextGroupResourceBase;
friend class QOpenGLSharedResource;
friend class QOpenGLMultiGroupSharedResource;
@ -107,7 +108,6 @@ public:
void setFormat(const QSurfaceFormat &format);
void setShareContext(QOpenGLContext *shareContext);
void setScreen(QScreen *screen);
void setNativeHandle(const QVariant &handle);
bool create();
bool isValid() const;
@ -116,7 +116,6 @@ public:
QOpenGLContext *shareContext() const;
QOpenGLContextGroup *shareGroup() const;
QScreen *screen() const;
QVariant nativeHandle() const;
GLuint defaultFramebufferObject() const;
@ -141,8 +140,6 @@ public:
QSet<QByteArray> extensions() const;
bool hasExtension(const QByteArray &extension) const;
static void *openGLModuleHandle();
enum OpenGLModuleType {
LibGL,
LibGLES
@ -155,6 +152,9 @@ public:
static bool supportsThreadedOpenGL();
static QOpenGLContext *globalShareContext();
template <typename T>
T *platformInterface() const;
Q_SIGNALS:
void aboutToBeDestroyed();
@ -188,6 +188,8 @@ Q_GUI_EXPORT QDebug operator<<(QDebug debug, const QOpenGLContextGroup *cg);
QT_END_NAMESPACE
#include <QtGui/qopenglcontext_platform.h>
#endif // QT_NO_OPENGL
#endif // QOPENGLCONTEXT_H

View File

@ -234,6 +234,8 @@ public:
delete versionFunctions;
}
void adopt(QPlatformOpenGLContext *);
QSurfaceFormat requestedFormat;
QPlatformOpenGLContext *platformGLContext;
QOpenGLContext *shareContext;
@ -264,7 +266,6 @@ public:
// Saves us from querying the driver for the current FBO in most paths.
QOpenGLFramebufferObject *qgl_current_fbo;
QVariant nativeHandle;
GLuint defaultFboRedirect;
static QOpenGLContext *setCurrentContext(QOpenGLContext *context);

View File

@ -0,0 +1,109 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QOPENGLCONTEXT_PLATFORM_H
#define QOPENGLCONTEXT_PLATFORM_H
#ifndef QT_NO_OPENGL
#include <QtGui/qtguiglobal.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/qwindowdefs.h>
#if defined(Q_OS_MACOS)
Q_FORWARD_DECLARE_OBJC_CLASS(NSOpenGLContext);
#endif
#if defined(Q_OS_LINUX)
struct __GLXcontextRec; typedef struct __GLXcontextRec *GLXContext;
#endif
#if QT_CONFIG(egl)
typedef void *EGLContext;
typedef void *EGLDisplay;
#endif
QT_BEGIN_NAMESPACE
namespace QPlatformInterface {
#if defined(Q_OS_MACOS)
struct Q_GUI_EXPORT QCocoaGLContext
{
QT_DECLARE_PLATFORM_INTERFACE(QCocoaGLContext)
static QOpenGLContext *fromNative(QT_IGNORE_DEPRECATIONS(NSOpenGLContext) *, QOpenGLContext *shareContext = nullptr);
virtual QT_IGNORE_DEPRECATIONS(NSOpenGLContext) *nativeContext() const = 0;
};
#endif
#if defined(Q_OS_WIN)
struct Q_GUI_EXPORT QWGLContext
{
QT_DECLARE_PLATFORM_INTERFACE(QWGLContext)
static HMODULE openGLModuleHandle();
static QOpenGLContext *fromNative(HGLRC context, HWND window, QOpenGLContext *shareContext = nullptr);
virtual HGLRC nativeContext() const = 0;
};
#endif
#if defined(Q_OS_LINUX)
struct Q_GUI_EXPORT QGLXContext
{
QT_DECLARE_PLATFORM_INTERFACE(QGLXContext)
static QOpenGLContext *fromNative(GLXContext configBasedContext, QOpenGLContext *shareContext = nullptr);
static QOpenGLContext *fromNative(GLXContext visualBasedContext, void *visualInfo, QOpenGLContext *shareContext = nullptr);
virtual GLXContext nativeContext() const = 0;
};
#endif
#if QT_CONFIG(egl)
struct Q_GUI_EXPORT QEGLContext
{
QT_DECLARE_PLATFORM_INTERFACE(QEGLContext)
static QOpenGLContext *fromNative(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext = nullptr);
virtual EGLContext nativeContext() const = 0;
};
#endif
} // QPlatformInterface
QT_END_NAMESPACE
#endif // QT_NO_OPENGL
#endif // QOPENGLCONTEXT_PLATFORM_H

View File

@ -81,6 +81,30 @@ class QOffscreenSurface;
class QPlatformVulkanInstance;
class QVulkanInstance;
namespace QPlatformInterface::Private {
template <typename R, typename I, auto func, typename... Args>
struct QInterfaceProxyImp
{
template <typename T>
static R apply(T *obj, Args... args)
{
if (auto *iface = dynamic_cast<I*>(obj))
return (iface->*func)(args...);
else
return R();
}
};
template <auto func>
struct QInterfaceProxy;
template <typename R, typename I, typename... Args, R(I::*func)(Args...)>
struct QInterfaceProxy<func> : public QInterfaceProxyImp<R, I, func, Args...> {};
template <typename R, typename I, typename... Args, R(I::*func)(Args...) const>
struct QInterfaceProxy<func> : public QInterfaceProxyImp<R, I, func, Args...> {};
} // QPlatformInterface::Private
class Q_GUI_EXPORT QPlatformIntegration
{
public:
@ -200,6 +224,13 @@ public:
virtual QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const;
#endif
template <auto func, typename... Args>
auto call(Args... args)
{
using namespace QPlatformInterface::Private;
return QInterfaceProxy<func>::apply(this, args...);
}
protected:
QPlatformIntegration() = default;
};

View File

@ -57,6 +57,7 @@
#include <QtGui/qsurfaceformat.h>
#include <QtGui/qwindow.h>
#include <QtGui/qopengl.h>
#include <QtGui/qopenglcontext.h>
QT_BEGIN_NAMESPACE
@ -92,6 +93,7 @@ public:
private:
friend class QOpenGLContext;
friend class QOpenGLContextPrivate;
QScopedPointer<QPlatformOpenGLContextPrivate> d_ptr;
@ -100,6 +102,49 @@ private:
Q_DISABLE_COPY(QPlatformOpenGLContext)
};
template <typename T>
T *QOpenGLContext::platformInterface() const
{
return dynamic_cast<T*>(handle());
}
namespace QPlatformInterface::Private {
#if defined(Q_OS_MACOS)
struct Q_GUI_EXPORT QCocoaGLIntegration
{
QT_DECLARE_PLATFORM_INTERFACE(QCocoaGLIntegration)
virtual QOpenGLContext *createOpenGLContext(NSOpenGLContext *, QOpenGLContext *shareContext) const = 0;
};
#endif
#if defined(Q_OS_WIN)
struct Q_GUI_EXPORT QWindowsGLIntegration
{
QT_DECLARE_PLATFORM_INTERFACE(QWindowsGLIntegration)
virtual HMODULE openGLModuleHandle() const = 0;
virtual QOpenGLContext *createOpenGLContext(HGLRC context, HWND window, QOpenGLContext *shareContext) const = 0;
};
#endif
#if defined(Q_OS_LINUX)
struct Q_GUI_EXPORT QGLXIntegration
{
QT_DECLARE_PLATFORM_INTERFACE(QGLXIntegration)
virtual QOpenGLContext *createOpenGLContext(GLXContext context, void *visualInfo, QOpenGLContext *shareContext) const = 0;
};
#endif
#if QT_CONFIG(egl)
struct Q_GUI_EXPORT QEGLIntegration
{
QT_DECLARE_PLATFORM_INTERFACE(QEGLIntegration)
virtual QOpenGLContext *createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const = 0;
};
#endif
} // QPlatformInterface::Private
QT_END_NAMESPACE
#endif // QT_NO_OPENGL

View File

@ -72,6 +72,9 @@ QT_END_NAMESPACE
#ifndef HINSTANCE
Q_DECLARE_HANDLE(HINSTANCE);
#endif
#ifndef HMODULE
typedef HINSTANCE HMODULE;
#endif
#ifndef HDC
Q_DECLARE_HANDLE(HDC);
#endif
@ -105,6 +108,9 @@ Q_DECLARE_HANDLE(HRGN);
#ifndef HMONITOR
Q_DECLARE_HANDLE(HMONITOR);
#endif
#ifndef HGLRC
Q_DECLARE_HANDLE(HGLRC);
#endif
#ifndef _HRESULT_DEFINED
typedef long HRESULT;
#endif

View File

@ -0,0 +1,4 @@
SOURCES += \
$$PWD/qcocoaplatforminterface.mm
LIBS_PRIVATE += -framework AppKit

View File

@ -1,9 +1,9 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@ -37,43 +37,24 @@
**
****************************************************************************/
#ifndef QWGLNATIVECONTEXT_H
#define QWGLNATIVECONTEXT_H
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformopenglcontext.h>
#include <qpa/qplatformintegration.h>
#include <QtCore/QMetaType>
#include <wingdi.h>
#include <GL/gl.h>
#include <AppKit/AppKit.h>
QT_BEGIN_NAMESPACE
#if defined(Q_CLANG_QDOC)
typedef int HGLRC;
typedef int HWND;
#endif
using namespace QPlatformInterface::Private;
class QWGLNativeContext
QT_DEFINE_PLATFORM_INTERFACE(QCocoaGLContext, QOpenGLContext);
QT_DEFINE_PRIVATE_PLATFORM_INTERFACE(QCocoaGLIntegration);
QOpenGLContext *QPlatformInterface::QCocoaGLContext::fromNative(NSOpenGLContext *nativeContext, QOpenGLContext *shareContext)
{
public:
QWGLNativeContext()
: m_context(0),
m_window(0)
{ }
QWGLNativeContext(HGLRC ctx, HWND wnd)
: m_context(ctx),
m_window(wnd)
{ }
HGLRC context() const { return m_context; }
HWND window() const { return m_window; }
private:
HGLRC m_context;
HWND m_window;
};
return QGuiApplicationPrivate::platformIntegration()->call<
&QCocoaGLIntegration::createOpenGLContext>(nativeContext, shareContext);
}
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QWGLNativeContext)
#endif // QWGLNATIVECONTEXT_H

View File

@ -2,3 +2,4 @@ wasm:include(wasm/wasm.pri)
darwin:include(darwin/darwin.pri)
win32:include(windows/windows.pri)
unix:include(unix/unix.pri)
macos:include(macos/macos.pri)

View File

@ -1,9 +1,9 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@ -37,52 +37,44 @@
**
****************************************************************************/
#ifndef QGLXNATIVECONTEXT_H
#define QGLXNATIVECONTEXT_H
#include <QtGui/private/qtguiglobal_p.h>
#include <QtCore/QMetaType>
#include <X11/Xlib.h>
#include <GL/glx.h>
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformopenglcontext.h>
#include <qpa/qplatformintegration.h>
QT_BEGIN_NAMESPACE
#if defined(Q_CLANG_QDOC)
typedef int GLXContext;
typedef void Display;
typedef int Window;
typedef int VisualID;
using namespace QPlatformInterface::Private;
#if defined(Q_OS_LINUX)
QT_DEFINE_PLATFORM_INTERFACE(QGLXContext, QOpenGLContext);
QT_DEFINE_PRIVATE_PLATFORM_INTERFACE(QGLXIntegration);
QOpenGLContext *QPlatformInterface::QGLXContext::fromNative(GLXContext configBasedContext, QOpenGLContext *shareContext)
{
return QGuiApplicationPrivate::platformIntegration()->call<
&QGLXIntegration::createOpenGLContext>(configBasedContext, nullptr, shareContext);
}
QOpenGLContext *QPlatformInterface::QGLXContext::fromNative(GLXContext visualBasedContext, void *visualInfo, QOpenGLContext *shareContext)
{
return QGuiApplicationPrivate::platformIntegration()->call<
&QGLXIntegration::createOpenGLContext>(visualBasedContext, visualInfo, shareContext);
}
#endif
struct QGLXNativeContext
#if QT_CONFIG(egl)
QT_DEFINE_PLATFORM_INTERFACE(QEGLContext, QOpenGLContext);
QT_DEFINE_PRIVATE_PLATFORM_INTERFACE(QEGLIntegration);
QOpenGLContext *QPlatformInterface::QEGLContext::fromNative(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext)
{
QGLXNativeContext()
: m_context(nullptr),
m_display(nullptr),
m_window(0),
m_visualId(0)
{ }
QGLXNativeContext(GLXContext ctx, Display *dpy = nullptr, Window wnd = 0, VisualID vid = 0)
: m_context(ctx),
m_display(dpy),
m_window(wnd),
m_visualId(vid)
{ }
GLXContext context() const { return m_context; }
Display *display() const { return m_display; }
Window window() const { return m_window; }
VisualID visualId() const { return m_visualId; }
private:
GLXContext m_context;
Display *m_display;
Window m_window;
VisualID m_visualId;
};
return QGuiApplicationPrivate::platformIntegration()->call<
&QEGLIntegration::createOpenGLContext>(context, display, shareContext);
}
#endif
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QGLXNativeContext)
#endif // QGLXNATIVECONTEXT_H

View File

@ -1,6 +1,7 @@
SOURCES += \
platform/unix/qunixeventdispatcher.cpp \
platform/unix/qgenericunixeventdispatcher.cpp
platform/unix/qgenericunixeventdispatcher.cpp \
platform/unix/qunixplatforminterface.cpp
HEADERS += \
platform/unix/qunixeventdispatcher_qpa_p.h \

View File

@ -1,9 +1,9 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@ -37,42 +37,28 @@
**
****************************************************************************/
#ifndef QEGLNATIVECONTEXT_H
#define QEGLNATIVECONTEXT_H
#include <QtCore/QMetaType>
// Leave including egl.h with the appropriate defines to the client.
#include <QtGui/qopenglcontext.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformopenglcontext.h>
#include <qpa/qplatformintegration.h>
QT_BEGIN_NAMESPACE
#if defined(Q_CLANG_QDOC)
typedef int EGLContext;
typedef int EGLDisplay;
#endif
using namespace QPlatformInterface::Private;
struct QEGLNativeContext
QT_DEFINE_PLATFORM_INTERFACE(QWGLContext, QOpenGLContext);
QT_DEFINE_PRIVATE_PLATFORM_INTERFACE(QWindowsGLIntegration);
HMODULE QPlatformInterface::QWGLContext::openGLModuleHandle()
{
QEGLNativeContext()
: m_context(nullptr),
m_display(nullptr)
{ }
return QGuiApplicationPrivate::platformIntegration()->call<
&QWindowsGLIntegration::openGLModuleHandle>();
}
QEGLNativeContext(EGLContext ctx, EGLDisplay dpy)
: m_context(ctx),
m_display(dpy)
{ }
EGLContext context() const { return m_context; }
EGLDisplay display() const { return m_display; }
private:
EGLContext m_context;
EGLDisplay m_display;
};
QOpenGLContext *QPlatformInterface::QWGLContext::fromNative(HGLRC context, HWND window, QOpenGLContext *shareContext)
{
return QGuiApplicationPrivate::platformIntegration()->call<
&QWindowsGLIntegration::createOpenGLContext>(context, window, shareContext);
}
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QEGLNativeContext)
#endif // QEGLNATIVECONTEXT_H

View File

@ -1,2 +1,4 @@
HEADERS += platform/windows/qwindowsguieventdispatcher_p.h
SOURCES += platform/windows/qwindowsguieventdispatcher.cpp
SOURCES += \
platform/windows/qwindowsguieventdispatcher.cpp \
platform/windows/qwindowsplatforminterface.cpp

View File

@ -1,4 +0,0 @@
HEADERS += $$PWD/qglxnativecontext.h \
$$PWD/qeglnativecontext.h \
$$PWD/qcocoanativecontext.h \
$$PWD/qwglnativecontext.h

View File

@ -1,72 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QCOCOANATIVECONTEXT_H
#define QCOCOANATIVECONTEXT_H
#include <QtCore/QMetaType>
#include <AppKit/NSOpenGL.h>
QT_BEGIN_NAMESPACE
#if defined(Q_CLANG_QDOC)
typedef void NSOpenGLContext;
#endif
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

View File

@ -1,58 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\class QCocoaNativeContext
\inmodule QtPlatformHeaders
\since 5.4
\brief A class encapsulating a Cocoa NSOpenGLContext.
\note There is no binary compatibility guarantee for this class, meaning
that an application using it is only guaranteed to work with the Qt version it was
developed against.
\sa QOpenGLContext::setNativeHandle(), QOpenGLContext::nativeHandle()
*/
/*!
\fn NSOpenGLContext *QCocoaNativeContext::context() const
\return the context.
*/
/*!
\fn QCocoaNativeContext::QCocoaNativeContext()
Construct a new instance with no handles.
*/
/*!
\fn QCocoaNativeContext::QCocoaNativeContext(NSOpenGLContext *ctx)
Constructs a new instance with the provided \a ctx handle.
*/

View File

@ -1,70 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\class QEGLNativeContext
\inmodule QtPlatformHeaders
\since 5.4
\brief A class encapsulating an EGL context and display handle.
\note There is no binary compatibility guarantee for this class, meaning
that an application using it is only guaranteed to work with the Qt version it was
developed against.
\note Due to being public while relying on otherwise hidden EGL types, this header
itself does not include \c{EGL/egl.h}. It is the application's responsibility to
include egl.h with any appropriate defines (for example, \c{MESA_EGL_NO_X11_HEADERS}
or other vendor-specific defines controlling the typedefs for EGL's native resources)
before this header.
\sa QOpenGLContext::setNativeHandle(), QOpenGLContext::nativeHandle()
*/
/*!
\fn EGLContext QEGLNativeContext::context() const
\return the EGL context.
*/
/*!
\fn EGLDisplay QEGLNativeContext::display() const
\return the EGL display.
*/
/*!
\fn QEGLNativeContext::QEGLNativeContext()
Construct a new instance with no handles.
*/
/*!
\fn QEGLNativeContext::QEGLNativeContext(EGLContext ctx, EGLDisplay dpy)
Constructs a new instance with the provided \a ctx and \a dpy handles.
*/

View File

@ -1,83 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\class QGLXNativeContext
\inmodule QtPlatformHeaders
\since 5.4
\brief A class encapsulating a GLXContext and related native handles.
\note Only context() is guaranteed to be valid. The other handles may be all \c 0. They are
useful however when QOpenGLContext::setNativeHandle() is used to adopt a legacy context
created by glXCreateContext. To adopt such a context, either the Window or VisualID
that had been used to create the context needs to be known, otherwise the adoption will
fail. For modern contexts created with an FBConfig, these are not necessary, the
GLXContext itself is sufficient. The Display is optional.
\note There is no binary compatibility guarantee for this class, meaning
that an application using it is only guaranteed to work with the Qt version it was
developed against.
\sa QOpenGLContext::setNativeHandle(), QOpenGLContext::nativeHandle()
*/
/*!
\fn GLXContext QGLXNativeContext::context() const
\return the GLXContext.
*/
/*!
\fn Display *QGLXNativeContext::display() const
\return a pointer to the X11 display or \c NULL if not available.
*/
/*!
\fn Window QGLXNativeContext::window() const
\return the X11 Window or \c 0 if not available.
*/
/*!
\fn VisualID QGLXNativeContext::visualId() const
\return the X11 visual ID or \c 0 if not available.
*/
/*!
\fn QGLXNativeContext::QGLXNativeContext()
Construct a new instance with no handles.
*/
/*!
\fn QGLXNativeContext::QGLXNativeContext(GLXContext ctx, Display *dpy, Window wnd, VisualID vid)
Constructs a new instance with the provided \a ctx, \a dpy, \a wnd, \a vid handles.
*/

View File

@ -1,131 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\class QWGLNativeContext
\inmodule QtPlatformHeaders
\since 5.4
\brief A class encapsulating a WGL context on Windows with desktop OpenGL (opengl32.dll).
\note There is no binary compatibility guarantee for this class,
meaning that an application using it is only guaranteed to work with the Qt
version it was developed against.
QWGLNativeContext is a value class that can be passed to
QOpenGLContext::setNativeHandle(). When creating a QOpenGLContext with the
native handle set, no new context will get created. Instead, the provided
handles are used, without taking ownership. This allows wrapping a context
created by an external framework or rendering engine. The typical usage will
be similar to the following snippet:
\code
#include <QtPlatformSupport/QWGLNativeContext>
...create and retrieve the WGL context and the corresponding window...
QOpenGLContext *context = new QOpenGLContext;
QWGLNativeContext nativeContext(hglrc, hwnd);
context->setNativeHandle(QVariant::fromValue(nativeContext));
context->create();
...
\endcode
The window is needed because the its pixel format will be queried. When the
adoption is successful, QOpenGLContext::format() will return a QSurfaceFormat
describing this pixel format.
It is recommended to restrict the usage of QOpenGLContexts created this way.
Various platform-specific behavior and issues may prevent such contexts to be
made current with windows (surfaces) created by Qt due to non-matching pixel
formats for example. A potentially safer solution is to use the wrapped
context only to set up sharing and perform Qt-based rendering offscreen,
using a separate, dedicated QOpenGLContext. The resulting textures are then
accessible in the foreign context too.
\code
...like above...
QOpenGLContext *qtcontext = new QOpenGLContext;
qtcontext->setShareContext(context);
qtcontext->setFormat(context->format());
qtcontext->create();
...use qtcontext for rendering with Qt...
\endcode
In addition to being used with QOpenGLContext::setNativeHandle(), this class
is used also to retrieve the native context handle, that is, a HGLRC value,
from a QOpenGLContext. Calling QOpenGLContext::nativeHandle() returns a
QVariant which, on Windows with opengl32.dll at least, will contain a
QWGLNativeContext:
\code
QVariant nativeHandle = context->nativeHandle();
if (!nativeHandle.isNull() && nativeHandle.canConvert<QWGLNativeContext>()) {
QWGLNativeContext nativeContext = nativeHandle.value<QWGLNativeContext>();
HGLRC hglrc = nativeContext.context();
...
}
\endcode
\sa QOpenGLContext::setNativeHandle(), QOpenGLContext::nativeHandle()
*/
/*!
\fn HGLRC QWGLNativeContext::context() const
\return the WGL context.
*/
/*!
\fn HWND QWGLNativeContext::window() const
\note The window handle is not available when the QWGLNativeContext is
queried from a regular, non-adopted QOpenGLContext using
QOpenGLContext::nativeHandle(). This is because the \e windows platform
plugin creates WGL contexts using a dummy window that is not available
afterwards. Instead, the native window handle (HWND) is queriable from a
QWindow via QPlatformNativeInterface::nativeResourceForWindow() using the \e
"handle" resource key. Note however that the window will not have its pixel
format set until it is first associated with a context via
QOpenGLContext::makeCurrent().
\return handle for the window for which the context was created.
*/
/*!
\fn QWGLNativeContext::QWGLNativeContext()
Construct a new instance with no handles.
*/
/*!
\fn QWGLNativeContext::QWGLNativeContext(HGLRC ctx, HWND wnd)
Constructs a new instance with the provided \a ctx context handle and \a wnd window handle.
\note The window specified by \a wnd must have its pixel format set to a
format compatible with the context's. If no SetPixelFormat() call was made on
any device context belonging to the window, adopting the context will fail.
*/

View File

@ -3,7 +3,6 @@ TEMPLATE = subdirs
VERSION = $$MODULE_VERSION
MODULE_INCNAME = QtPlatformHeaders
include(nativecontexts/nativecontexts.pri)
include(xcbfunctions/xcbfunctions.pri)
include(eglfsfunctions/eglfsfunctions.pri)
include(windowsfunctions/windowsfunctions.pri)

View File

@ -48,6 +48,6 @@ qt_extend_target(EglSupport CONDITION NOT QT_FEATURE_egl_x11
)
qt_extend_target(EglSupport CONDITION QT_FEATURE_dlopen
PUBLIC_LIBRARIES
LIBRARIES
${CMAKE_DL_LIBS}
)

View File

@ -38,6 +38,6 @@ qtConfig(egl_x11) {
}
CONFIG += egl
qtConfig(dlopen): QMAKE_USE += libdl
qtConfig(dlopen): QMAKE_USE_PRIVATE += libdl
load(qt_module)

View File

@ -42,7 +42,6 @@
#include "qeglpbuffer_p.h"
#include <qpa/qplatformwindow.h>
#include <QOpenGLContext>
#include <QtPlatformHeaders/QEGLNativeContext>
#include <QDebug>
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
@ -115,25 +114,13 @@ QT_BEGIN_NAMESPACE
#endif
QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLConfig *config, const QVariant &nativeHandle, Flags flags)
EGLConfig *config, Flags flags)
: m_eglDisplay(display)
, m_swapInterval(-1)
, m_swapIntervalEnvChecked(false)
, m_swapIntervalFromEnv(-1)
, m_flags(flags)
, m_ownsContext(true)
{
if (nativeHandle.isNull()) {
m_eglConfig = config ? *config : q_configFromGLFormat(display, format);
m_ownsContext = true;
init(format, share);
} else {
m_ownsContext = false;
adopt(nativeHandle, share);
}
}
m_eglConfig = config ? *config : q_configFromGLFormat(display, format);
void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLContext *share)
{
m_format = q_glFormatFromConfig(m_eglDisplay, m_eglConfig, format);
// m_format now has the renderableType() resolved (it cannot be Default anymore)
// but does not yet contain version, profile, options.
@ -212,24 +199,11 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
// Cannot just call updateFormatFromGL() since it relies on virtuals. Defer it to initialize().
}
void QEGLPlatformContext::adopt(const QVariant &nativeHandle, QPlatformOpenGLContext *share)
void QEGLPlatformContext::adopt(EGLContext context, EGLDisplay display, QPlatformOpenGLContext *share)
{
if (!nativeHandle.canConvert<QEGLNativeContext>()) {
qWarning("QEGLPlatformContext: Requires a QEGLNativeContext");
return;
}
QEGLNativeContext handle = qvariant_cast<QEGLNativeContext>(nativeHandle);
EGLContext context = handle.context();
if (!context) {
qWarning("QEGLPlatformContext: No EGLContext given");
return;
}
Q_ASSERT(!m_ownsContext);
// A context belonging to a given EGLDisplay cannot be used with another one.
if (handle.display() != m_eglDisplay) {
qWarning("QEGLPlatformContext: Cannot adopt context from different display");
return;
}
m_eglDisplay = display;
// Figure out the EGLConfig.
EGLint value = 0;

View File

@ -56,10 +56,12 @@
#include <qpa/qplatformopenglcontext.h>
#include <QtCore/QVariant>
#include <QtEglSupport/private/qt_egl_p.h>
#include <QtGui/private/qopenglcontext_p.h>
QT_BEGIN_NAMESPACE
class QEGLPlatformContext : public QPlatformOpenGLContext
class QEGLPlatformContext : public QPlatformOpenGLContext,
public QPlatformInterface::QEGLContext
{
public:
enum Flag {
@ -68,8 +70,31 @@ public:
Q_DECLARE_FLAGS(Flags, Flag)
QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLConfig *config = nullptr, const QVariant &nativeHandle = QVariant(),
Flags flags = { });
EGLConfig *config = nullptr, Flags flags = { });
template <typename T>
static QOpenGLContext *createFrom(EGLContext context, EGLDisplay contextDisplay,
EGLDisplay platformDisplay, QOpenGLContext *shareContext)
{
if (!context)
return nullptr;
// A context belonging to a given EGLDisplay cannot be used with another one
if (contextDisplay != platformDisplay) {
qWarning("QEGLPlatformContext: Cannot adopt context from different display");
return nullptr;
}
QPlatformOpenGLContext *shareHandle = shareContext ? shareContext->handle() : nullptr;
auto *resultingContext = new QOpenGLContext;
auto *contextPrivate = QOpenGLContextPrivate::get(resultingContext);
auto *platformContext = new T;
platformContext->adopt(context, contextDisplay, shareHandle);
contextPrivate->adopt(platformContext);
return resultingContext;
}
~QEGLPlatformContext();
void initialize() override;
@ -82,19 +107,21 @@ public:
bool isSharing() const override { return m_shareContext != EGL_NO_CONTEXT; }
bool isValid() const override { return m_eglContext != EGL_NO_CONTEXT; }
EGLContext nativeContext() const override { return eglContext(); }
EGLContext eglContext() const;
EGLDisplay eglDisplay() const;
EGLConfig eglConfig() const;
protected:
QEGLPlatformContext() {} // For adoption
virtual EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) = 0;
virtual EGLSurface createTemporaryOffscreenSurface();
virtual void destroyTemporaryOffscreenSurface(EGLSurface surface);
virtual void runGLChecks();
private:
void init(const QSurfaceFormat &format, QPlatformOpenGLContext *share);
void adopt(const QVariant &nativeHandle, QPlatformOpenGLContext *share);
void adopt(EGLContext context, EGLDisplay display, QPlatformOpenGLContext *shareContext);
void updateFormatFromGL();
EGLContext m_eglContext;
@ -103,11 +130,11 @@ private:
EGLConfig m_eglConfig;
QSurfaceFormat m_format;
EGLenum m_api;
int m_swapInterval;
bool m_swapIntervalEnvChecked;
int m_swapIntervalFromEnv;
int m_swapInterval = -1;
bool m_swapIntervalEnvChecked = false;
int m_swapIntervalFromEnv = -1;
Flags m_flags;
bool m_ownsContext;
bool m_ownsContext = false;
QVector<EGLint> m_contextAttrs;
};

View File

@ -71,8 +71,6 @@
#include "qandroidsystemlocale.h"
#include "qandroidplatformoffscreensurface.h"
#include <QtPlatformHeaders/QEGLNativeContext>
#if QT_CONFIG(vulkan)
#include "qandroidplatformvulkanwindow.h"
#include "qandroidplatformvulkaninstance.h"
@ -307,11 +305,15 @@ QPlatformOpenGLContext *QAndroidPlatformIntegration::createPlatformOpenGLContext
format.setRedBufferSize(8);
format.setGreenBufferSize(8);
format.setBlueBufferSize(8);
auto ctx = new QAndroidPlatformOpenGLContext(format, context->shareHandle(), m_eglDisplay, context->nativeHandle());
context->setNativeHandle(QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(ctx->eglContext(), m_eglDisplay)));
auto ctx = new QAndroidPlatformOpenGLContext(format, context->shareHandle(), m_eglDisplay);
return ctx;
}
QOpenGLContext *QAndroidPlatformIntegration::createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const
{
return QEGLPlatformContext::createFrom<QAndroidPlatformOpenGLContext>(context, display, m_eglDisplay, shareContext);
}
QPlatformOffscreenSurface *QAndroidPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{
if (!QtAndroid::activity())

View File

@ -45,6 +45,7 @@
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformmenu.h>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformopenglcontext.h>
#include <EGL/egl.h>
#include <jni.h>
@ -73,6 +74,7 @@ protected:
};
class QAndroidPlatformIntegration : public QPlatformIntegration
, QPlatformInterface::Private::QEGLIntegration
{
friend class QAndroidPlatformScreen;
@ -88,6 +90,7 @@ public:
QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override;
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QOpenGLContext *createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const override;
QAbstractEventDispatcher *createEventDispatcher() const override;
QAndroidPlatformScreen *screen() { return m_primaryScreen; }
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override;

View File

@ -51,9 +51,8 @@
QT_BEGIN_NAMESPACE
QAndroidPlatformOpenGLContext::QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
const QVariant &nativeHandle)
:QEGLPlatformContext(format, share, display, nullptr, nativeHandle)
QAndroidPlatformOpenGLContext::QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display)
: QEGLPlatformContext(format, share, display, nullptr)
{
}

View File

@ -48,13 +48,13 @@ QT_BEGIN_NAMESPACE
class QAndroidPlatformOpenGLContext : public QEGLPlatformContext
{
public:
QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, const QVariant &nativeHandle);
using QEGLPlatformContext::QEGLPlatformContext;
QAndroidPlatformOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display);
void swapBuffers(QPlatformSurface *surface) override;
bool makeCurrent(QPlatformSurface *surface) override;
private:
EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) override;
};
QT_END_NAMESPACE

View File

@ -43,7 +43,8 @@
#include <QtCore/QPointer>
#include <QtCore/private/qcore_mac_p.h>
#include <qpa/qplatformopenglcontext.h>
#include <QtGui/QOpenGLContext>
#include <QtGui/qopenglcontext.h>
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/QWindow>
Q_FORWARD_DECLARE_OBJC_CLASS(NSOpenGLContext);
@ -53,10 +54,11 @@ QT_BEGIN_NAMESPACE
class QCocoaWindow;
class QCocoaGLContext : public QPlatformOpenGLContext
class QCocoaGLContext : public QPlatformOpenGLContext, public QPlatformInterface::QCocoaGLContext
{
public:
QCocoaGLContext(QOpenGLContext *context);
QCocoaGLContext(NSOpenGLContext *context);
~QCocoaGLContext();
void initialize() override;
@ -71,7 +73,7 @@ public:
bool isSharing() const override;
bool isValid() const override;
NSOpenGLContext *nativeContext() const;
NSOpenGLContext *nativeContext() const override;
QFunctionPointer getProcAddress(const char *procName) override;

View File

@ -45,7 +45,6 @@
#include "qcocoascreen.h"
#include <qdebug.h>
#include <QtPlatformHeaders/qcocoanativecontext.h>
#include <dlfcn.h>
static inline QByteArray getGlString(GLenum param)
@ -65,30 +64,23 @@ QCocoaGLContext::QCocoaGLContext(QOpenGLContext *context)
{
}
QCocoaGLContext::QCocoaGLContext(NSOpenGLContext *nativeContext)
: QPlatformOpenGLContext()
{
m_context = [nativeContext retain];
}
void QCocoaGLContext::initialize()
{
QVariant nativeHandle = context()->nativeHandle();
if (!nativeHandle.isNull()) {
if (!nativeHandle.canConvert<QCocoaNativeContext>()) {
qCWarning(lcQpaOpenGLContext, "QOpenGLContext native handle must be a QCocoaNativeContext");
return;
}
m_context = nativeHandle.value<QCocoaNativeContext>().context();
if (!m_context) {
qCWarning(lcQpaOpenGLContext, "QCocoaNativeContext's NSOpenGLContext cannot be null");
return;
}
if (m_context) {
// 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();
[m_context retain];
// 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();
return;
updateSurfaceFormat();
return;
}
// ----------- Default case, we own the NSOpenGLContext -----------
@ -139,9 +131,6 @@ void QCocoaGLContext::initialize()
return;
}
// The native handle should reflect the underlying context, even if we created it
context()->setNativeHandle(QVariant::fromValue<QCocoaNativeContext>(m_context));
// --------------------- Set NSOpenGLContext properties ---------------------
const GLint interval = m_format.swapInterval() >= 0 ? m_format.swapInterval() : 1;

View File

@ -56,12 +56,14 @@
#include <QtCore/QScopedPointer>
#include <qpa/qplatformintegration.h>
#include <QtGui/private/qcoretextfontdatabase_p.h>
#include <QtGui/private/qopenglcontext_p.h>
Q_FORWARD_DECLARE_OBJC_CLASS(NSToolbar);
QT_BEGIN_NAMESPACE
class QCocoaIntegration : public QObject, public QPlatformIntegration
class QCocoaIntegration : public QObject, public QPlatformIntegration,
public QPlatformInterface::Private::QCocoaGLIntegration
{
Q_OBJECT
public:
@ -82,6 +84,7 @@ public:
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override;
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QOpenGLContext *createOpenGLContext(NSOpenGLContext *, QOpenGLContext *shareContext) const override;
#endif
QPlatformBackingStore *createPlatformBackingStore(QWindow *widget) const override;

View File

@ -64,9 +64,8 @@
#include <qpa/qplatformoffscreensurface.h>
#include <QtCore/qcoreapplication.h>
#include <QtPlatformHeaders/qcocoanativecontext.h>
#include <QtGui/private/qcoregraphics_p.h>
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/private/qfontengine_coretext_p.h>
@ -308,6 +307,19 @@ QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLCo
{
return new QCocoaGLContext(context);
}
QOpenGLContext *QCocoaIntegration::createOpenGLContext(NSOpenGLContext *nativeContext, QOpenGLContext *shareContext) const
{
if (!nativeContext)
return nullptr;
auto *context = new QOpenGLContext;
context->setShareContext(shareContext);
auto *contextPrivate = QOpenGLContextPrivate::get(context);
contextPrivate->adopt(new QCocoaGLContext(nativeContext));
return context;
}
#endif
QPlatformBackingStore *QCocoaIntegration::createPlatformBackingStore(QWindow *window) const

View File

@ -59,18 +59,10 @@ class QCocoaNativeInterface : public QPlatformNativeInterface
public:
QCocoaNativeInterface();
#ifndef QT_NO_OPENGL
void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context) override;
#endif
void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) override;
NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource) override;
#ifndef QT_NO_OPENGL
static void *cglContextForContext(QOpenGLContext *context);
static void *nsOpenGLContextForContext(QOpenGLContext* context);
#endif
QFunctionPointer platformFunction(const QByteArray &function) const override;
public Q_SLOTS:

View File

@ -76,20 +76,6 @@ QCocoaNativeInterface::QCocoaNativeInterface()
{
}
#ifndef QT_NO_OPENGL
void *QCocoaNativeInterface::nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context)
{
if (!context)
return nullptr;
if (resourceString.toLower() == "nsopenglcontext")
return nsOpenGLContextForContext(context);
if (resourceString.toLower() == "cglcontextobj")
return cglContextForContext(context);
return nullptr;
}
#endif
void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
if (!window->handle())
@ -182,25 +168,6 @@ void QCocoaNativeInterface::onAppFocusWindowChanged(QWindow *window)
QCocoaMenuBar::updateMenuBarImmediately();
}
#ifndef QT_NO_OPENGL
void *QCocoaNativeInterface::cglContextForContext(QOpenGLContext* context)
{
NSOpenGLContext *nsOpenGLContext = static_cast<NSOpenGLContext*>(nsOpenGLContextForContext(context));
if (nsOpenGLContext)
return [nsOpenGLContext CGLContextObj];
return nullptr;
}
void *QCocoaNativeInterface::nsOpenGLContextForContext(QOpenGLContext* context)
{
if (context) {
if (QCocoaGLContext *cocoaGLContext = static_cast<QCocoaGLContext *>(context->handle()))
return cocoaGLContext->nativeContext();
}
return nullptr;
}
#endif
QFunctionPointer QCocoaNativeInterface::platformFunction(const QByteArray &function) const
{
if (function == QCocoaWindowFunctions::bottomLeftClippedByNSWindowOffsetIdentifier())

View File

@ -50,10 +50,9 @@
QT_BEGIN_NAMESPACE
QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLConfig *config, const QVariant &nativeHandle)
: QEGLPlatformContext(format, share, display, config, nativeHandle,
qt_egl_device_integration()->supportsSurfacelessContexts() ? Flags() : QEGLPlatformContext::NoSurfaceless),
m_tempWindow(0)
EGLConfig *config)
: QEGLPlatformContext(format, share, display, config,
qt_egl_device_integration()->supportsSurfacelessContexts() ? Flags() : QEGLPlatformContext::NoSurfaceless)
{
}

View File

@ -61,8 +61,9 @@ QT_BEGIN_NAMESPACE
class Q_EGLFS_EXPORT QEglFSContext : public QEGLPlatformContext
{
public:
using QEGLPlatformContext::QEGLPlatformContext;
QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLConfig *config, const QVariant &nativeHandle);
EGLConfig *config);
EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) override;
EGLSurface createTemporaryOffscreenSurface() override;
void destroyTemporaryOffscreenSurface(EGLSurface surface) override;
@ -72,7 +73,7 @@ public:
QEglFSCursorData cursorData;
private:
EGLNativeWindowType m_tempWindow;
EGLNativeWindowType m_tempWindow = 0;
};
QT_END_NAMESPACE

View File

@ -76,8 +76,6 @@
# include <QtOpenGL/private/qopenglcompositorbackingstore_p.h>
#endif
#include <QtPlatformHeaders/QEGLNativeContext>
#if QT_CONFIG(libinput)
#include <QtInputSupport/private/qlibinputhandler_p.h>
#endif
@ -215,22 +213,20 @@ QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLCo
{
EGLDisplay dpy = context->screen() ? static_cast<QEglFSScreen *>(context->screen()->handle())->display() : display();
QPlatformOpenGLContext *share = context->shareHandle();
QVariant nativeHandle = context->nativeHandle();
QEglFSContext *ctx;
QSurfaceFormat adjustedFormat = qt_egl_device_integration()->surfaceFormatFor(context->format());
if (nativeHandle.isNull()) {
EGLConfig config = QEglFSDeviceIntegration::chooseConfig(dpy, adjustedFormat);
ctx = new QEglFSContext(adjustedFormat, share, dpy, &config, QVariant());
} else {
ctx = new QEglFSContext(adjustedFormat, share, dpy, nullptr, nativeHandle);
}
nativeHandle = QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(ctx->eglContext(), dpy));
EGLConfig config = QEglFSDeviceIntegration::chooseConfig(dpy, adjustedFormat);
ctx = new QEglFSContext(adjustedFormat, share, dpy, &config);
context->setNativeHandle(nativeHandle);
return ctx;
}
QOpenGLContext *QEglFSIntegration::createOpenGLContext(EGLContext context, EGLDisplay contextDisplay, QOpenGLContext *shareContext) const
{
return QEGLPlatformContext::createFrom<QEglFSContext>(context, contextDisplay, display(), shareContext);
}
QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{
EGLDisplay dpy = surface->screen() ? static_cast<QEglFSScreen *>(surface->screen()->handle())->display() : display();

View File

@ -57,6 +57,7 @@
#include <QtGui/QWindow>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformopenglcontext.h>
#include <qpa/qplatformscreen.h>
QT_BEGIN_NAMESPACE
@ -67,6 +68,7 @@ class QFbVtHandler;
class QEvdevKeyboardManager;
class Q_EGLFS_EXPORT QEglFSIntegration : public QPlatformIntegration, public QPlatformNativeInterface
, public QPlatformInterface::Private::QEGLIntegration
{
public:
QEglFSIntegration();
@ -86,6 +88,7 @@ public:
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override;
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QOpenGLContext *createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const override;
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override;
#endif
#if QT_CONFIG(vulkan)

View File

@ -41,7 +41,6 @@
#include <QByteArray>
#include <QOpenGLContext>
#include <QtPlatformHeaders/QGLXNativeContext>
#include <X11/Xlib.h>
#include <GL/glx.h>
@ -241,9 +240,6 @@ QOffscreenX11GLXContext::QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGL
d->window = createDummyWindow(x11, visualInfo);
XFree(visualInfo);
}
if (d->context)
context->setNativeHandle(QVariant::fromValue<QGLXNativeContext>(QGLXNativeContext(d->context)));
}
QOffscreenX11GLXContext::~QOffscreenX11GLXContext()
@ -296,7 +292,7 @@ bool QOffscreenX11GLXContext::isValid() const
return d->context && d->window;
}
void *QOffscreenX11GLXContext::glxContext() const
GLXContext QOffscreenX11GLXContext::glxContext() const
{
return d->context;
}

View File

@ -90,6 +90,7 @@ private:
class QOffscreenX11GLXContextData;
class QOffscreenX11GLXContext : public QPlatformOpenGLContext
, public QPlatformInterface::QGLXContext
{
public:
QOffscreenX11GLXContext(QOffscreenX11Info *x11, QOpenGLContext *context);
@ -104,8 +105,10 @@ public:
bool isSharing() const override;
bool isValid() const override;
GLXContext nativeContext() const override { return glxContext(); }
void *glxConfig() const;
void *glxContext() const;
GLXContext glxContext() const;
private:
QScopedPointer<QOffscreenX11GLXContextData> d;

View File

@ -46,7 +46,6 @@
#include <QtCore/qsysinfo.h>
#include <QtGui/qguiapplication.h>
#include <qpa/qplatformnativeinterface.h>
#include <QtPlatformHeaders/qwglnativecontext.h>
#include <algorithm>
@ -225,6 +224,11 @@ QWindowsOpenGLContext *QOpenGLStaticContext::createContext(QOpenGLContext *conte
return new QWindowsGLContext(this, context);
}
QWindowsOpenGLContext *QOpenGLStaticContext::createContext(HGLRC context, HWND window)
{
return new QWindowsGLContext(this, context, window);
}
template <class MaskType, class FlagType> inline bool testFlag(MaskType mask, FlagType flag)
{
return (mask & MaskType(flag)) != 0;
@ -1056,48 +1060,6 @@ QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext,
if (!m_staticContext) // Something went very wrong. Stop here, isValid() will return false.
return;
QVariant nativeHandle = context->nativeHandle();
if (!nativeHandle.isNull()) {
// Adopt and existing context.
if (!nativeHandle.canConvert<QWGLNativeContext>()) {
qWarning("QWindowsGLContext: Requires a QWGLNativeContext");
return;
}
auto handle = nativeHandle.value<QWGLNativeContext>();
HGLRC wglcontext = handle.context();
HWND wnd = handle.window();
if (!wglcontext || !wnd) {
qWarning("QWindowsGLContext: No context and window given");
return;
}
HDC dc = GetDC(wnd);
// A window with an associated pixel format is mandatory.
// When no SetPixelFormat() call has been made, the following will fail.
m_pixelFormat = GetPixelFormat(dc);
bool ok = m_pixelFormat != 0;
if (!ok)
qWarning("QWindowsGLContext: Failed to get pixel format");
ok = DescribePixelFormat(dc, m_pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &m_obtainedPixelFormatDescriptor);
if (!ok) {
qWarning("QWindowsGLContext: Failed to describe pixel format");
} else {
QWindowsOpenGLAdditionalFormat obtainedAdditional;
m_obtainedFormat = GDI::qSurfaceFormatFromPixelFormat(m_obtainedPixelFormatDescriptor, &obtainedAdditional);
m_renderingContext = wglcontext;
ok = updateObtainedParams(dc);
}
ReleaseDC(wnd, dc);
if (ok)
m_ownsContext = false;
else
m_renderingContext = nullptr;
return;
}
QSurfaceFormat format = context->format();
if (format.renderableType() == QSurfaceFormat::DefaultRenderableType)
format.setRenderableType(QSurfaceFormat::OpenGL);
@ -1199,11 +1161,6 @@ QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext,
} while (false);
// Make the HGLRC retrievable via QOpenGLContext::nativeHandle().
// Do not provide the window since it is the dummy one and it is about to disappear.
if (m_renderingContext)
context->setNativeHandle(QVariant::fromValue<QWGLNativeContext>(QWGLNativeContext(m_renderingContext, nullptr)));
if (hdc)
ReleaseDC(dummyWindow, hdc);
if (dummyWindow)
@ -1217,6 +1174,37 @@ QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext,
<< "\n HGLRC=" << m_renderingContext;
}
QWindowsGLContext::QWindowsGLContext(QOpenGLStaticContext *staticContext, HGLRC wglcontext, HWND wnd)
: m_staticContext(staticContext)
{
if (!m_staticContext) // Something went very wrong. Stop here, isValid() will return false.
return;
HDC dc = GetDC(wnd);
// A window with an associated pixel format is mandatory.
// When no SetPixelFormat() call has been made, the following will fail.
m_pixelFormat = GetPixelFormat(dc);
bool ok = m_pixelFormat != 0;
if (!ok)
qWarning("QWindowsGLContext: Failed to get pixel format");
ok = DescribePixelFormat(dc, m_pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &m_obtainedPixelFormatDescriptor);
if (!ok) {
qWarning("QWindowsGLContext: Failed to describe pixel format");
} else {
QWindowsOpenGLAdditionalFormat obtainedAdditional;
m_obtainedFormat = GDI::qSurfaceFormatFromPixelFormat(m_obtainedPixelFormatDescriptor, &obtainedAdditional);
m_renderingContext = wglcontext;
ok = updateObtainedParams(dc);
}
ReleaseDC(wnd, dc);
if (ok)
m_ownsContext = false;
else
m_renderingContext = nullptr;
}
QWindowsGLContext::~QWindowsGLContext()
{
if (m_renderingContext && m_ownsContext)

View File

@ -174,6 +174,7 @@ public:
static QByteArray getGlString(unsigned int which);
QWindowsOpenGLContext *createContext(QOpenGLContext *context) override;
QWindowsOpenGLContext *createContext(HGLRC context, HWND window) override;
void *moduleHandle() const override { return opengl32.moduleHandle(); }
QOpenGLContext::OpenGLModuleType moduleType() const override
{ return QOpenGLContext::LibGL; }
@ -199,10 +200,12 @@ public:
static QWindowsOpengl32DLL opengl32;
};
class QWindowsGLContext : public QWindowsOpenGLContext
class QWindowsGLContext : public QWindowsOpenGLContext, public QPlatformInterface::QWGLContext
{
public:
explicit QWindowsGLContext(QOpenGLStaticContext *staticContext, QOpenGLContext *context);
explicit QWindowsGLContext(QOpenGLStaticContext *staticContext, HGLRC context, HWND window);
~QWindowsGLContext() override;
bool isSharing() const override { return context()->shareHandle(); }
bool isValid() const override { return m_renderingContext && !m_lost; }
@ -219,7 +222,7 @@ public:
HGLRC renderingContext() const { return m_renderingContext; }
void *nativeContext() const override { return m_renderingContext; }
HGLRC nativeContext() const override { return m_renderingContext; }
private:
typedef GLenum (APIENTRY *GlGetGraphicsResetStatusArbType)();

View File

@ -475,6 +475,33 @@ QOpenGLContext::OpenGLModuleType QWindowsIntegration::openGLModuleType()
#endif
}
HMODULE QWindowsIntegration::openGLModuleHandle() const
{
if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
return static_cast<HMODULE>(staticOpenGLContext->moduleHandle());
return nullptr;
}
QOpenGLContext *QWindowsIntegration::createOpenGLContext(HGLRC ctx, HWND window, QOpenGLContext *shareContext) const
{
if (!ctx || !window)
return nullptr;
if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) {
QScopedPointer<QWindowsOpenGLContext> result(staticOpenGLContext->createContext(ctx, window));
if (result->isValid()) {
auto *context = new QOpenGLContext;
context->setShareContext(shareContext);
auto *contextPrivate = QOpenGLContextPrivate::get(context);
contextPrivate->adopt(result.take());
return context;
}
}
return nullptr;
}
QWindowsStaticOpenGLContext *QWindowsIntegration::staticOpenGLContext()
{
QWindowsIntegration *integration = QWindowsIntegration::instance();

View File

@ -44,6 +44,8 @@
#include <qpa/qplatformintegration.h>
#include <QtCore/qscopedpointer.h>
#include <QtGui/private/qwindowsfontdatabase_p.h>
#include <QtGui/private/qopenglcontext_p.h>
#include <qpa/qplatformopenglcontext.h>
QT_BEGIN_NAMESPACE
@ -52,7 +54,7 @@ struct QWindowsWindowData;
class QWindowsWindow;
class QWindowsStaticOpenGLContext;
class QWindowsIntegration : public QPlatformIntegration
class QWindowsIntegration : public QPlatformIntegration, public QPlatformInterface::Private::QWindowsGLIntegration
{
Q_DISABLE_COPY_MOVE(QWindowsIntegration)
public:
@ -87,6 +89,9 @@ public:
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QOpenGLContext::OpenGLModuleType openGLModuleType() override;
static QWindowsStaticOpenGLContext *staticOpenGLContext();
HMODULE openGLModuleHandle() const override;
QOpenGLContext *createOpenGLContext(HGLRC context, HWND window, QOpenGLContext *shareContext) const;
#endif
QAbstractEventDispatcher *createEventDispatcher() const override;
void initialize() override;

View File

@ -57,6 +57,7 @@ public:
virtual ~QWindowsStaticOpenGLContext() = default;
virtual QWindowsOpenGLContext *createContext(QOpenGLContext *context) = 0;
virtual QWindowsOpenGLContext *createContext(HGLRC context, HWND window) = 0;
virtual void *moduleHandle() const = 0;
virtual QOpenGLContext::OpenGLModuleType moduleType() const = 0;
virtual bool supportsThreadedOpenGL() const { return false; }
@ -77,9 +78,6 @@ class QWindowsOpenGLContext : public QPlatformOpenGLContext
{
Q_DISABLE_COPY_MOVE(QWindowsOpenGLContext)
public:
// Returns the native context handle (e.g. HGLRC for WGL).
virtual void *nativeContext() const = 0;
// These should be implemented only for some winsys interfaces, for example EGL.
// For others, like WGL, they are not relevant.
virtual void *nativeDisplay() const { return nullptr; }

View File

@ -43,16 +43,15 @@
#include "qxcbeglwindow.h"
#include <QtEglSupport/private/qeglplatformcontext_p.h>
#include <QtEglSupport/private/qeglpbuffer_p.h>
#include <QtPlatformHeaders/QEGLNativeContext>
QT_BEGIN_NAMESPACE
class QXcbEglContext : public QEGLPlatformContext
{
public:
QXcbEglContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share,
EGLDisplay display, const QVariant &nativeHandle)
: QEGLPlatformContext(glFormat, share, display, nullptr, nativeHandle)
using QEGLPlatformContext::QEGLPlatformContext;
QXcbEglContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share, EGLDisplay display)
: QEGLPlatformContext(glFormat, share, display, nullptr)
{
}
@ -86,10 +85,6 @@ public:
else
return static_cast<QEGLPbuffer *>(surface)->pbuffer();
}
QVariant nativeHandle() const {
return QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(eglContext(), eglDisplay()));
}
};
QT_END_NAMESPACE

View File

@ -101,12 +101,15 @@ QPlatformOpenGLContext *QXcbEglIntegration::createPlatformOpenGLContext(QOpenGLC
QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
QXcbEglContext *platformContext = new QXcbEglContext(screen->surfaceFormatFor(context->format()),
context->shareHandle(),
eglDisplay(),
context->nativeHandle());
context->setNativeHandle(platformContext->nativeHandle());
eglDisplay());
return platformContext;
}
QOpenGLContext *QXcbEglIntegration::createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const
{
return QEGLPlatformContext::createFrom<QXcbEglContext>(context, display, eglDisplay(), shareContext);
}
QPlatformOffscreenSurface *QXcbEglIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
{
QXcbScreen *screen = static_cast<QXcbScreen *>(surface->screen()->handle());

View File

@ -45,6 +45,7 @@
#include "qxcbeglwindow.h"
#include <QtGui/QOpenGLContext>
#include <qpa/qplatformopenglcontext.h>
#include <QtGui/qpa/qplatformscreen.h>
#include <QtGui/QScreen>
@ -57,6 +58,7 @@ QT_BEGIN_NAMESPACE
class QXcbEglNativeInterfaceHandler;
class QXcbEglIntegration : public QXcbGlIntegration
, public QPlatformInterface::Private::QEGLIntegration
{
public:
QXcbEglIntegration();
@ -66,6 +68,7 @@ public:
QXcbWindow *createWindow(QWindow *window) const override;
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QOpenGLContext *createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const override;
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override;
bool supportsThreadedOpenGL() const override { return true; }

View File

@ -56,7 +56,6 @@
#include "qglxintegration.h"
#include <QtGlxSupport/private/qglxconvenience_p.h>
#include <QtPlatformHeaders/QGLXNativeContext>
#include "qxcbglintegration.h"
@ -219,26 +218,11 @@ static void updateFormatFromContext(QSurfaceFormat &format)
}
}
QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share,
const QVariant &nativeHandle)
QGLXContext::QGLXContext(Display *display, QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
: QPlatformOpenGLContext()
, m_display(static_cast<Display *>(screen->connection()->xlib_display()))
, m_config(nullptr)
, m_context(nullptr)
, m_shareContext(nullptr)
, m_display(display)
, m_format(format)
, m_isPBufferCurrent(false)
, m_ownsContext(nativeHandle.isNull())
, m_getGraphicsResetStatus(nullptr)
, m_lost(false)
{
if (nativeHandle.isNull())
init(screen, share);
else
init(screen, share, nativeHandle);
}
void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
, m_ownsContext(true)
{
if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType)
#if QT_CONFIG(opengles2)
@ -423,49 +407,15 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
XDestroyWindow(m_display, window);
}
void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share, const QVariant &nativeHandle)
QGLXContext::QGLXContext(Display *display, GLXContext context, void *visualInfo, QPlatformOpenGLContext *share)
: QPlatformOpenGLContext()
, m_display(display)
{
if (!nativeHandle.canConvert<QGLXNativeContext>()) {
qWarning("QGLXContext: Requires a QGLXNativeContext");
return;
}
QGLXNativeContext handle = qvariant_cast<QGLXNativeContext>(nativeHandle);
GLXContext context = handle.context();
if (!context) {
qWarning("QGLXContext: No GLXContext given");
return;
}
// Legacy contexts created using glXCreateContext are created using a
// XVisualInfo. If the user passed one we should use that.
XVisualInfo *vinfo = static_cast<XVisualInfo*>(visualInfo);
// Legacy contexts created using glXCreateContext are created using a visual
// and the FBConfig cannot be queried. The only way to adapt these contexts
// is to figure out the visual id.
XVisualInfo *vinfo = nullptr;
// If the VisualID is provided use it.
VisualID vid = handle.visualId();
if (!vid) {
// In the absence of the VisualID figure it out from the window.
Window wnd = handle.window();
if (wnd) {
XWindowAttributes attrs;
XGetWindowAttributes(m_display, wnd, &attrs);
vid = XVisualIDFromVisual(attrs.visual);
}
}
if (vid) {
XVisualInfo v;
v.screen = screen->screenNumber();
v.visualid = vid;
int n = 0;
vinfo = XGetVisualInfo(m_display, VisualScreenMask | VisualIDMask, &v, &n);
if (n < 1) {
XFree(vinfo);
vinfo = nullptr;
}
}
// For contexts created with an FBConfig using the modern functions providing the
// visual or window is not mandatory. Just query the config from the context.
GLXFBConfig config = nullptr;
// Otherwise assume the context was created with an FBConfig using the modern functions
if (!vinfo) {
int configId = 0;
if (glXQueryContext(m_display, context, GLX_FBCONFIG_ID, &configId) != Success) {
@ -490,19 +440,17 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share, const
if (configs && numConfigs > 1) // this is suspicious so warn but let it continue
qWarning("QGLXContext: Multiple configs for FBConfig ID %d", configId);
config = configs[0];
// Store the config.
m_config = config;
m_config = configs[0];
}
Q_ASSERT(vinfo || config);
Q_ASSERT(vinfo || m_config);
int screenNumber = DefaultScreen(m_display);
Window window;
if (vinfo)
window = createDummyWindow(m_display, vinfo, screenNumber, RootWindow(m_display, screenNumber));
else
window = createDummyWindow(m_display, config, screenNumber, RootWindow(m_display, screenNumber));
window = createDummyWindow(m_display, m_config, screenNumber, RootWindow(m_display, screenNumber));
if (!window) {
qWarning("QGLXContext: Failed to create dummy window");
return;
@ -522,7 +470,7 @@ void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share, const
if (vinfo)
qglx_surfaceFormatFromVisualInfo(&m_format, m_display, vinfo);
else
qglx_surfaceFormatFromGLXFBConfig(&m_format, m_display, config);
qglx_surfaceFormatFromGLXFBConfig(&m_format, m_display, m_config);
glXMakeCurrent(m_display, prevDrawable, prevContext);
XDestroyWindow(m_display, window);
@ -553,11 +501,6 @@ static QXcbScreen *screenForPlatformSurface(QPlatformSurface *surface)
return nullptr;
}
QVariant QGLXContext::nativeHandle() const
{
return QVariant::fromValue<QGLXNativeContext>(QGLXNativeContext(m_context));
}
bool QGLXContext::makeCurrent(QPlatformSurface *surface)
{
bool success = false;

View File

@ -53,11 +53,12 @@
QT_BEGIN_NAMESPACE
class QGLXContext : public QPlatformOpenGLContext
class QGLXContext : public QPlatformOpenGLContext,
public QPlatformInterface::QGLXContext
{
public:
QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share,
const QVariant &nativeHandle);
QGLXContext(Display *display, QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
QGLXContext(Display *display, GLXContext context, void *visualInfo, QPlatformOpenGLContext *share);
~QGLXContext();
bool makeCurrent(QPlatformSurface *surface) override;
@ -69,27 +70,24 @@ public:
bool isSharing() const override;
bool isValid() const override;
GLXContext nativeContext() const override { return glxContext(); }
GLXContext glxContext() const { return m_context; }
GLXFBConfig glxConfig() const { return m_config; }
QVariant nativeHandle() const;
static bool supportsThreading();
static void queryDummyContext();
private:
void init(QXcbScreen *screen, QPlatformOpenGLContext *share);
void init(QXcbScreen *screen, QPlatformOpenGLContext *share, const QVariant &nativeHandle);
Display *m_display;
GLXFBConfig m_config;
GLXContext m_context;
GLXContext m_shareContext;
Display *m_display = nullptr;
GLXFBConfig m_config = nullptr;
GLXContext m_context = nullptr;
GLXContext m_shareContext = nullptr;
QSurfaceFormat m_format;
bool m_isPBufferCurrent;
bool m_ownsContext;
GLenum (APIENTRY * m_getGraphicsResetStatus)();
bool m_lost;
bool m_isPBufferCurrent = false;
bool m_ownsContext = false;
GLenum (APIENTRY * m_getGraphicsResetStatus)() = nullptr;
bool m_lost = false;
static bool m_queriedDummyContext;
static bool m_supportsThreading;
};

View File

@ -49,6 +49,7 @@
#include "qglxintegration.h"
#include <QtGui/QOpenGLContext>
#include <QtGui/private/qopenglcontext_p.h>
#include "qxcbglxnativeinterfacehandler.h"
@ -187,10 +188,22 @@ QXcbWindow *QXcbGlxIntegration::createWindow(QWindow *window) const
QPlatformOpenGLContext *QXcbGlxIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
QGLXContext *platformContext = new QGLXContext(screen, screen->surfaceFormatFor(context->format()),
context->shareHandle(), context->nativeHandle());
context->setNativeHandle(platformContext->nativeHandle());
return platformContext;
return new QGLXContext(static_cast<Display *>(m_connection->xlib_display()),
screen, screen->surfaceFormatFor(context->format()), context->shareHandle());
}
QOpenGLContext *QXcbGlxIntegration::createOpenGLContext(GLXContext glxContext, void *visualInfo, QOpenGLContext *shareContext) const
{
if (!glxContext)
return nullptr;
QPlatformOpenGLContext *shareHandle = shareContext ? shareContext->handle() : nullptr;
auto *context = new QOpenGLContext;
auto *contextPrivate = QOpenGLContextPrivate::get(context);
auto *display = static_cast<Display *>(m_connection->xlib_display());
contextPrivate->adopt(new QGLXContext(display, glxContext, visualInfo, shareHandle));
return context;
}
QPlatformOffscreenSurface *QXcbGlxIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const

View File

@ -46,7 +46,8 @@ QT_BEGIN_NAMESPACE
class QXcbNativeInterfaceHandler;
class QXcbGlxIntegration : public QXcbGlIntegration
class QXcbGlxIntegration : public QXcbGlIntegration,
public QPlatformInterface::Private::QGLXIntegration
{
public:
QXcbGlxIntegration();
@ -58,6 +59,7 @@ public:
QXcbWindow *createWindow(QWindow *window) const override;
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override;
QOpenGLContext *createOpenGLContext(GLXContext context, void *visualInfo, QOpenGLContext *shareContext) const override;
bool supportsThreadedOpenGL() const override;
bool supportsSwitchableWidgetComposition() const override;

View File

@ -275,7 +275,26 @@ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLCont
}
return glIntegration->createPlatformOpenGLContext(context);
}
#endif
QOpenGLContext *QXcbIntegration::createOpenGLContext(GLXContext context, void *visualInfo, QOpenGLContext *shareContext) const
{
using namespace QPlatformInterface::Private;
if (auto *glxIntegration = dynamic_cast<QGLXIntegration*>(m_connection->glIntegration()))
return glxIntegration->createOpenGLContext(context, visualInfo, shareContext);
else
return nullptr;
}
QOpenGLContext *QXcbIntegration::createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const
{
using namespace QPlatformInterface::Private;
if (auto *eglIntegration = dynamic_cast<QEGLIntegration*>(m_connection->glIntegration()))
return eglIntegration->createOpenGLContext(context, display, shareContext);
else
return nullptr;
}
#endif // QT_NO_OPENGL
QPlatformBackingStore *QXcbIntegration::createPlatformBackingStore(QWindow *window) const
{

View File

@ -43,6 +43,7 @@
#include <QtGui/private/qtguiglobal_p.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformscreen.h>
#include <qpa/qplatformopenglcontext.h>
#include "qxcbexport.h"
@ -55,6 +56,8 @@ class QAbstractEventDispatcher;
class QXcbNativeInterface;
class Q_XCB_EXPORT QXcbIntegration : public QPlatformIntegration
, public QPlatformInterface::Private::QGLXIntegration
, public QPlatformInterface::Private::QEGLIntegration
{
public:
QXcbIntegration(const QStringList &parameters, int &argc, char **argv);
@ -65,6 +68,8 @@ public:
QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override;
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QOpenGLContext *createOpenGLContext(GLXContext context, void *visualInfo, QOpenGLContext *shareContext) const override;
QOpenGLContext *createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const override;
#endif
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override;

View File

@ -52,15 +52,6 @@
#include <QSignalSpy>
#ifdef USE_GLX
// Must be included last due to the X11 types
#include <QtPlatformHeaders/QGLXNativeContext>
#endif
#if defined(Q_OS_WIN32) && !QT_CONFIG(opengles2)
#include <QtPlatformHeaders/QWGLNativeContext>
#endif
Q_DECLARE_METATYPE(QImage::Format)
class tst_QOpenGL : public QObject
@ -1480,6 +1471,8 @@ void tst_QOpenGL::defaultSurfaceFormat()
QCOMPARE(context->format(), fmt);
}
using namespace QPlatformInterface;
#ifdef USE_GLX
void tst_QOpenGL::glxContextWrap()
{
@ -1496,17 +1489,14 @@ void tst_QOpenGL::glxContextWrap()
QOpenGLContext *ctx0 = new QOpenGLContext;
ctx0->setFormat(window->format());
QVERIFY(ctx0->create());
QVariant v = ctx0->nativeHandle();
QVERIFY(!v.isNull());
QVERIFY(v.canConvert<QGLXNativeContext>());
GLXContext context = v.value<QGLXNativeContext>().context();
auto *glxContextIf = ctx0->platformInterface<QGLXContext>();
QVERIFY(glxContextIf);
GLXContext context = glxContextIf->nativeContext();
QVERIFY(context);
// Then create another QOpenGLContext wrapping it.
QOpenGLContext *ctx = new QOpenGLContext;
ctx->setNativeHandle(QVariant::fromValue<QGLXNativeContext>(QGLXNativeContext(context)));
QVERIFY(ctx->create());
QCOMPARE(ctx->nativeHandle().value<QGLXNativeContext>().context(), context);
QOpenGLContext *ctx = QGLXContext::fromNative(context);
QVERIFY(ctx);
QVERIFY(nativeIf->nativeResourceForContext(QByteArrayLiteral("glxcontext"), ctx) == (void *) context);
QVERIFY(ctx->makeCurrent(window));
@ -1533,11 +1523,9 @@ void tst_QOpenGL::wglContextWrap()
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
QVariant v = ctx->nativeHandle();
QVERIFY(!v.isNull());
QVERIFY(v.canConvert<QWGLNativeContext>());
QWGLNativeContext nativeContext = v.value<QWGLNativeContext>();
QVERIFY(nativeContext.context());
auto *wglContext = ctx->platformInterface<QWGLContext>();
QVERIFY(wglContext);
QVERIFY(wglContext->nativeContext());
// Now do a makeCurrent() do make sure the pixel format on the native
// window (the HWND we are going to retrieve below) is set.
@ -1547,9 +1535,9 @@ void tst_QOpenGL::wglContextWrap()
HWND wnd = (HWND) qGuiApp->platformNativeInterface()->nativeResourceForWindow(QByteArrayLiteral("handle"), window.data());
QVERIFY(wnd);
QScopedPointer<QOpenGLContext> adopted(new QOpenGLContext);
adopted->setNativeHandle(QVariant::fromValue<QWGLNativeContext>(QWGLNativeContext(nativeContext.context(), wnd)));
QVERIFY(adopted->create());
QScopedPointer<QOpenGLContext> adopted(QWGLContext::fromNative(wglContext->nativeContext(), wnd));
QVERIFY(!adopted.isNull());
QVERIFY(adopted->isValid());
// This tests two things: that a regular, non-adopted QOpenGLContext is
// able to return a QSurfaceFormat containing the real values after

View File

@ -1,7 +1,7 @@
TEMPLATE = app
TARGET = qopenglcontext
QT += gui-private egl_support-private
QT += gui-private egl_support-private opengl
HEADERS += $$PWD/qopenglcontextwindow.h

View File

@ -34,7 +34,6 @@
#include <qpa/qplatformnativeinterface.h>
#include <QtEglSupport/private/qeglconvenience_p.h>
#include <QtPlatformHeaders/QEGLNativeContext>
QOpenGLContextWindow::QOpenGLContextWindow()
: m_blitter(0)
@ -98,7 +97,12 @@ void QOpenGLContextWindow::createForeignContext()
// underlying native context. This way the texture, that belongs to the context
// created here, will be accessible from m_context too.
EGLContext shareCtx = m_context->nativeHandle().value<QEGLNativeContext>().context();
using namespace QPlatformInterface;
auto *eglContext = m_context->platformInterface<QEGLContext>();
if (!eglContext)
qFatal("Not running with EGL backend");
EGLContext shareCtx = eglContext->nativeContext();
Q_ASSERT(shareCtx != EGL_NO_CONTEXT);
EGLDisplay dpy = (EGLDisplay) qGuiApp->platformNativeInterface()->nativeResourceForWindow(
@ -127,12 +131,8 @@ void QOpenGLContextWindow::createForeignContext()
Q_ASSERT(ctx != EGL_NO_CONTEXT);
// Wrap ctx into a QOpenGLContext.
QOpenGLContext *ctxWrap = new QOpenGLContext;
ctxWrap->setNativeHandle(QVariant::fromValue<QEGLNativeContext>(QEGLNativeContext(ctx, dpy)));
ctxWrap->setShareContext(m_context); // only needed for correct bookkeeping
if (!ctxWrap->create())
qFatal("Failed to created wrapping context");
Q_ASSERT(ctxWrap->nativeHandle().value<QEGLNativeContext>().context() == ctx);
QOpenGLContext *ctxWrap = QEGLContext::fromNative(ctx, dpy, m_context);
Q_ASSERT(ctxWrap->platformInterface<QEGLContext>()->nativeContext() == ctx);
QOffscreenSurface surface;
surface.setFormat(fmt);

View File

@ -31,7 +31,7 @@
#include <QtGui/QWindow>
#include <QtGui/QOpenGLContext>
#include <QtGui/QOpenGLTextureBlitter>
#include <QtOpenGL/QOpenGLTextureBlitter>
#include <QtGui/QImage>
#include <QtCore/QVariant>