diff options
Diffstat (limited to 'src/platformsupport')
4 files changed, 82 insertions, 22 deletions
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp index eec6463c21..9691d12682 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp @@ -44,6 +44,7 @@ #include "qeglpbuffer_p.h" #include <qpa/qplatformwindow.h> #include <QOpenGLContext> +#include <QtPlatformHeaders/QEGLNativeContext> #include <QDebug> QT_BEGIN_NAMESPACE @@ -108,25 +109,21 @@ QT_BEGIN_NAMESPACE #define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 #endif -QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display) - : m_eglDisplay(display) - , m_eglConfig(q_configFromGLFormat(display, format)) - , m_swapInterval(-1) - , m_swapIntervalEnvChecked(false) - , m_swapIntervalFromEnv(-1) -{ - init(format, share); -} - QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, - EGLConfig config) + EGLConfig *config, const QVariant &nativeHandle) : m_eglDisplay(display) - , m_eglConfig(config) , m_swapInterval(-1) , m_swapIntervalEnvChecked(false) , m_swapIntervalFromEnv(-1) { - init(format, share); + if (nativeHandle.isNull()) { + m_eglConfig = config ? *config : q_configFromGLFormat(display, format); + m_ownsContext = true; + init(format, share); + } else { + m_ownsContext = false; + adopt(nativeHandle, share); + } } void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLContext *share) @@ -198,6 +195,59 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont q_printEglConfig(m_eglDisplay, m_eglConfig); } + updateFormatFromGL(); +} + +void QEGLPlatformContext::adopt(const QVariant &nativeHandle, QPlatformOpenGLContext *share) +{ + if (!nativeHandle.canConvert<QEGLNativeContext>()) { + qWarning("QEGLPlatformContext: Requires a QEGLNativeContext"); + return; + } + QEGLNativeContext handle = nativeHandle.value<QEGLNativeContext>(); + EGLContext context = handle.context(); + if (!context) { + qWarning("QEGLPlatformContext: No EGLContext given"); + return; + } + + // 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; + } + + // Figure out the EGLConfig. + EGLint value = 0; + eglQueryContext(m_eglDisplay, context, EGL_CONFIG_ID, &value); + EGLint n = 0; + EGLConfig cfg; + const EGLint attribs[] = { EGL_CONFIG_ID, value, EGL_NONE }; + if (eglChooseConfig(m_eglDisplay, attribs, &cfg, 1, &n) && n == 1) { + m_eglConfig = cfg; + m_format = q_glFormatFromConfig(m_eglDisplay, m_eglConfig); + } else { + qWarning("QEGLPlatformContext: Failed to get framebuffer configuration for context"); + } + + // Fetch client API type. + value = 0; + eglQueryContext(m_eglDisplay, context, EGL_CONTEXT_CLIENT_TYPE, &value); + if (value == EGL_OPENGL_API || value == EGL_OPENGL_ES_API) { + m_api = value; + eglBindAPI(m_api); + } else { + qWarning("QEGLPlatformContext: Failed to get client API type"); + m_api = EGL_OPENGL_ES_API; + } + + m_eglContext = context; + m_shareContext = share ? static_cast<QEGLPlatformContext *>(share)->m_eglContext : 0; + updateFormatFromGL(); +} + +void QEGLPlatformContext::updateFormatFromGL() +{ #ifndef QT_NO_OPENGL // Make the context current to ensure the GL version query works. This needs a surface too. const EGLint pbufferAttributes[] = { @@ -296,10 +346,10 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface) QEGLPlatformContext::~QEGLPlatformContext() { - if (m_eglContext != EGL_NO_CONTEXT) { + if (m_ownsContext && m_eglContext != EGL_NO_CONTEXT) eglDestroyContext(m_eglDisplay, m_eglContext); - m_eglContext = EGL_NO_CONTEXT; - } + + m_eglContext = EGL_NO_CONTEXT; } void QEGLPlatformContext::doneCurrent() diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h index 714633c3bc..82f062c4a4 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h @@ -44,6 +44,7 @@ #include <qpa/qplatformwindow.h> #include <qpa/qplatformopenglcontext.h> +#include <QtCore/QVariant> #include <EGL/egl.h> QT_BEGIN_NAMESPACE @@ -51,9 +52,8 @@ QT_BEGIN_NAMESPACE class QEGLPlatformContext : public QPlatformOpenGLContext { public: - QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display); QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display, - EGLConfig config); + EGLConfig *config = 0, const QVariant &nativeHandle = QVariant()); ~QEGLPlatformContext(); bool makeCurrent(QPlatformSurface *surface); @@ -74,6 +74,8 @@ protected: private: void init(const QSurfaceFormat &format, QPlatformOpenGLContext *share); + void adopt(const QVariant &nativeHandle, QPlatformOpenGLContext *share); + void updateFormatFromGL(); EGLContext m_eglContext; EGLContext m_shareContext; @@ -84,6 +86,7 @@ private: int m_swapInterval; bool m_swapIntervalEnvChecked; int m_swapIntervalFromEnv; + bool m_ownsContext; }; QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp index 3de0642c93..560ff79ef8 100644 --- a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp @@ -158,9 +158,14 @@ QPlatformOpenGLContext *QEGLPlatformIntegration::createPlatformOpenGLContext(QOp // If there is a "root" window into which raster and QOpenGLWidget content is // composited, all other contexts must share with its context. QOpenGLContext *compositingContext = screen ? screen->compositingContext() : 0; - return createContext(context->format(), - compositingContext ? compositingContext->handle() : context->shareHandle(), - display()); + QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle(); + QVariant nativeHandle = context->nativeHandle(); + QPlatformOpenGLContext *platformContext = createContext(context->format(), + share, + display(), + &nativeHandle); + context->setNativeHandle(nativeHandle); + return platformContext; } QPlatformOffscreenSurface *QEGLPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h index 0de8cc9a33..9d4207e005 100644 --- a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h @@ -44,6 +44,7 @@ #include <qpa/qplatformintegration.h> #include <qpa/qplatformnativeinterface.h> +#include <QtCore/QVariant> #include <EGL/egl.h> QT_BEGIN_NAMESPACE @@ -89,7 +90,8 @@ protected: virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0; virtual QEGLPlatformContext *createContext(const QSurfaceFormat &format, QPlatformOpenGLContext *shareContext, - EGLDisplay display) const = 0; + EGLDisplay display, + QVariant *nativeHandle) const = 0; virtual QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *surface) const = 0; |