summaryrefslogtreecommitdiffstats
path: root/src/platformsupport
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport')
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp82
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext_p.h7
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration.cpp11
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration_p.h4
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;