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

View File

@ -84,6 +84,11 @@ QPlatformOpenGLContext *QWaylandBrcmEglIntegration::createPlatformOpenGLContext(
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
{
return m_eglDisplay;

View File

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

View File

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

View File

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

View File

@ -129,6 +129,11 @@ QPlatformOpenGLContext *QWaylandEglClientBufferIntegration::createPlatformOpenGL
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)
{
switch (resource) {

View File

@ -40,6 +40,7 @@ public:
QWaylandWindow *createEglWindow(QWindow *window) 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 *nativeResourceForContext(NativeResource resource, QPlatformOpenGLContext *context) override;

View File

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

View File

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

View File

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

View File

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