Wayland: support adoption of native EGL contexts

QWaylandIntegration does not implement the
QNativeInterface::Private::QEGLIntegration interface. This means that
trying to create a QOpenGLContext from a native EGL context fails,
and QNativeInterface::QEGLContext::fromNative() always returns nullptr.

This commit makes QWaylandIntegration inherit from QEGLIntegration and
implement its interface. This in turn requires adding a new API to the
HW interfaces (implemented by both the EGL and the brcm-egl
integrations) to request adoption of a native context.

Fixes: QTBUG-110758
Change-Id: I81c08fcf1110b5e9e1d8739532df9ce78410d694
Reviewed-by: David Edmundson <davidedmundson@kde.org>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Giuseppe D'Angelo 2025-05-30 12:01:49 +02:00
parent 89ec9276fc
commit 7c0a96785f
11 changed files with 31 additions and 0 deletions

View File

@ -17,10 +17,12 @@
#include <QtCore/private/qglobal_p.h> #include <QtCore/private/qglobal_p.h>
#include <QtWaylandClient/qtwaylandclientglobal.h> #include <QtWaylandClient/qtwaylandclientglobal.h>
#include <QtGui/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QWindow; class QWindow;
class QOpenGLContext;
class QPlatformOpenGLContext; class QPlatformOpenGLContext;
class QSurfaceFormat; class QSurfaceFormat;
@ -44,6 +46,7 @@ public:
virtual QWaylandWindow *createEglWindow(QWindow *window) = 0; virtual QWaylandWindow *createEglWindow(QWindow *window) = 0;
virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0; virtual QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const = 0;
virtual QOpenGLContext *createOpenGLContext(EGLContext context, EGLDisplay contextDisplay, QOpenGLContext *shareContext) const = 0;
enum NativeResource { enum NativeResource {
EglDisplay, EglDisplay,

View File

@ -84,6 +84,11 @@ QPlatformOpenGLContext *QWaylandBrcmEglIntegration::createPlatformOpenGLContext(
return new QWaylandBrcmGLContext(m_eglDisplay, glFormat, share); return new QWaylandBrcmGLContext(m_eglDisplay, glFormat, share);
} }
QOpenGLContext *QWaylandBrcmEglIntegration::createOpenGLContext(EGLContext context, EGLDisplay contextDisplay, QOpenGLContext *shareContext) const
{
return QEGLPlatformContext::createFrom<QWaylandBrcmGLContext>(context, contextDisplay, m_eglDisplay, shareContext);
}
EGLDisplay QWaylandBrcmEglIntegration::eglDisplay() const EGLDisplay QWaylandBrcmEglIntegration::eglDisplay() const
{ {
return m_eglDisplay; return m_eglDisplay;

View File

@ -38,6 +38,7 @@ public:
QWaylandWindow *createEglWindow(QWindow *window); QWaylandWindow *createEglWindow(QWindow *window);
QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const override; QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const override;
QOpenGLContext *createOpenGLContext(EGLContext context, EGLDisplay contextDisplay, QOpenGLContext *shareContext) const override;
EGLDisplay eglDisplay() const; EGLDisplay eglDisplay() const;

View File

@ -20,6 +20,8 @@ namespace QtWaylandClient {
extern QSurfaceFormat brcmFixFormat(const QSurfaceFormat &format); extern QSurfaceFormat brcmFixFormat(const QSurfaceFormat &format);
QWaylandBrcmGLContext::QWaylandBrcmGLContext() = default;
QWaylandBrcmGLContext::QWaylandBrcmGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share) QWaylandBrcmGLContext::QWaylandBrcmGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
: QPlatformOpenGLContext() : QPlatformOpenGLContext()
, m_eglDisplay(eglDisplay) , m_eglDisplay(eglDisplay)

View File

@ -18,6 +18,7 @@ class QWaylandWindow;
class QWaylandBrcmGLContext : public QPlatformOpenGLContext { class QWaylandBrcmGLContext : public QPlatformOpenGLContext {
public: public:
QWaylandBrcmGLContext();
QWaylandBrcmGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share); QWaylandBrcmGLContext(EGLDisplay eglDisplay, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
~QWaylandBrcmGLContext(); ~QWaylandBrcmGLContext();

View File

@ -129,6 +129,11 @@ QPlatformOpenGLContext *QWaylandEglClientBufferIntegration::createPlatformOpenGL
return new QWaylandGLContext(m_eglDisplay, m_display, fmt, share); return new QWaylandGLContext(m_eglDisplay, m_display, fmt, share);
} }
QOpenGLContext *QWaylandEglClientBufferIntegration::createOpenGLContext(EGLContext context, EGLDisplay contextDisplay, QOpenGLContext *shareContext) const
{
return QEGLPlatformContext::createFrom<QWaylandGLContext>(context, contextDisplay, m_eglDisplay, shareContext);
}
void *QWaylandEglClientBufferIntegration::nativeResource(NativeResource resource) void *QWaylandEglClientBufferIntegration::nativeResource(NativeResource resource)
{ {
switch (resource) { switch (resource) {

View File

@ -40,6 +40,7 @@ public:
QWaylandWindow *createEglWindow(QWindow *window) override; QWaylandWindow *createEglWindow(QWindow *window) override;
QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const override; QPlatformOpenGLContext *createPlatformOpenGLContext(const QSurfaceFormat &glFormat, QPlatformOpenGLContext *share) const override;
QOpenGLContext *createOpenGLContext(EGLContext context, EGLDisplay contextDisplay, QOpenGLContext *shareContext) const override;
void *nativeResource(NativeResource resource) override; void *nativeResource(NativeResource resource) override;
void *nativeResourceForContext(NativeResource resource, QPlatformOpenGLContext *context) override; void *nativeResourceForContext(NativeResource resource, QPlatformOpenGLContext *context) override;

View File

@ -191,6 +191,8 @@ public:
int m_textureWrap; int m_textureWrap;
}; };
QWaylandGLContext::QWaylandGLContext() = default;
QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *display, QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *display,
const QSurfaceFormat &fmt, QPlatformOpenGLContext *share) const QSurfaceFormat &fmt, QPlatformOpenGLContext *share)
: QEGLPlatformContext(fmt, share, eglDisplay) : QEGLPlatformContext(fmt, share, eglDisplay)

View File

@ -34,6 +34,7 @@ class DecorationsBlitter;
class Q_WAYLANDCLIENT_EXPORT QWaylandGLContext : public QEGLPlatformContext class Q_WAYLANDCLIENT_EXPORT QWaylandGLContext : public QEGLPlatformContext
{ {
public: public:
QWaylandGLContext();
QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *display, const QSurfaceFormat &format, QPlatformOpenGLContext *share); QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *display, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
~QWaylandGLContext(); ~QWaylandGLContext();
void swapBuffers(QPlatformSurface *surface) override; void swapBuffers(QPlatformSurface *surface) override;

View File

@ -161,6 +161,11 @@ QPlatformOpenGLContext *QWaylandIntegration::createPlatformOpenGLContext(QOpenGL
return mDisplay->clientBufferIntegration()->createPlatformOpenGLContext(context->format(), context->shareHandle()); return mDisplay->clientBufferIntegration()->createPlatformOpenGLContext(context->format(), context->shareHandle());
return nullptr; return nullptr;
} }
QOpenGLContext *QWaylandIntegration::createOpenGLContext(EGLContext context, EGLDisplay contextDisplay, QOpenGLContext *shareContext) const
{
return mClientBufferIntegration->createOpenGLContext(context, contextDisplay, shareContext);
}
#endif // opengl #endif // opengl
QPlatformBackingStore *QWaylandIntegration::createPlatformBackingStore(QWindow *window) const QPlatformBackingStore *QWaylandIntegration::createPlatformBackingStore(QWindow *window) const

View File

@ -17,6 +17,7 @@
#include <QtWaylandClient/qtwaylandclientglobal.h> #include <QtWaylandClient/qtwaylandclientglobal.h>
#include <qpa/qplatformintegration.h> #include <qpa/qplatformintegration.h>
#include <qpa/qplatformopenglcontext.h>
#include <QtCore/QScopedPointer> #include <QtCore/QScopedPointer>
#include <QtCore/QMutex> #include <QtCore/QMutex>
#include <QtCore/private/qglobal_p.h> #include <QtCore/private/qglobal_p.h>
@ -37,6 +38,9 @@ class QWaylandCursor;
class QWaylandPlatformServices; class QWaylandPlatformServices;
class Q_WAYLANDCLIENT_EXPORT QWaylandIntegration : public QPlatformIntegration class Q_WAYLANDCLIENT_EXPORT QWaylandIntegration : public QPlatformIntegration
#if QT_CONFIG(opengl)
, public QNativeInterface::Private::QEGLIntegration
#endif
{ {
public: public:
QWaylandIntegration(const QString &platformName); QWaylandIntegration(const QString &platformName);
@ -50,6 +54,7 @@ public:
QPlatformWindow *createPlatformWindow(QWindow *window) const override; QPlatformWindow *createPlatformWindow(QWindow *window) const override;
#if QT_CONFIG(opengl) #if QT_CONFIG(opengl)
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QOpenGLContext *createOpenGLContext(EGLContext context, EGLDisplay display, QOpenGLContext *shareContext) const override;
#endif #endif
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override; QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override;