diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2020-10-29 16:23:10 +0100 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2020-10-30 16:32:57 +0000 |
commit | ecd11e498f18a18a79a062c39c0917439479ae4d (patch) | |
tree | 87b0b918aaf6c05385e1035dcd2fc1dd519bd181 | |
parent | d017baac8993757c035d5ba2829e88e946c169cc (diff) | |
download | qtbase-ecd11e498f18a18a79a062c39c0917439479ae4d.tar.gz |
Offscreen QPA: implement a native interface
Many code paths simply expect to have a native interface
available, and won't check if a plugin is returning nullptr
for it. This leads to crashes or local workarounds
(e.g. 3197932e6fb03fb9c0ff669af858cb94e3836d79). Instead,
have offscreen implement a dummy native interface.
This requires shuffling some code for the X11 integration.
Pick-to: 5.15
Change-Id: I2bdceee379e4ded9b085ebbb4d03d1e074f60726
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
6 files changed, 50 insertions, 17 deletions
diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.cpp b/src/plugins/platforms/offscreen/qoffscreencommon.cpp index 3d02721869..33b98cfa1b 100644 --- a/src/plugins/platforms/offscreen/qoffscreencommon.cpp +++ b/src/plugins/platforms/offscreen/qoffscreencommon.cpp @@ -232,4 +232,6 @@ void QOffscreenBackingStore::clearHash() QHash<WId, QOffscreenBackingStore *> QOffscreenBackingStore::m_backingStoreForWinIdHash; +QOffscreenPlatformNativeInterface::~QOffscreenPlatformNativeInterface() = default; + QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.h b/src/plugins/platforms/offscreen/qoffscreencommon.h index abb641fbbc..7f92c5b4d9 100644 --- a/src/plugins/platforms/offscreen/qoffscreencommon.h +++ b/src/plugins/platforms/offscreen/qoffscreencommon.h @@ -45,6 +45,7 @@ #include <qpa/qplatformdrag.h> #endif #include <qpa/qplatformintegration.h> +#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformscreen.h> #include <qpa/qplatformwindow.h> @@ -116,6 +117,12 @@ private: static QHash<WId, QOffscreenBackingStore *> m_backingStoreForWinIdHash; }; +class QOffscreenPlatformNativeInterface : public QPlatformNativeInterface +{ +public: + ~QOffscreenPlatformNativeInterface(); +}; + QT_END_NAMESPACE #endif diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp index c9f97ce46a..cc45776397 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp @@ -244,6 +244,13 @@ QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const #endif } +QPlatformNativeInterface *QOffscreenIntegration::nativeInterface() const +{ + if (!m_nativeInterface) + m_nativeInterface.reset(new QOffscreenPlatformNativeInterface); + return m_nativeInterface.get(); +} + static QString themeName() { return QStringLiteral("offscreen"); } QStringList QOffscreenIntegration::themeNames() const diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.h b/src/plugins/platforms/offscreen/qoffscreenintegration.h index be47313913..38d145eee3 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.h @@ -71,19 +71,22 @@ public: QPlatformFontDatabase *fontDatabase() const override; QAbstractEventDispatcher *createEventDispatcher() const override; + QPlatformNativeInterface *nativeInterface() const override; + QStringList themeNames() const override; QPlatformTheme *createPlatformTheme(const QString &name) const override; static QOffscreenIntegration *createOffscreenIntegration(const QStringList& paramList); QList<QPlatformScreen *> screens() const; -private: +protected: QScopedPointer<QPlatformFontDatabase> m_fontDatabase; #if QT_CONFIG(draganddrop) QScopedPointer<QPlatformDrag> m_drag; #endif QScopedPointer<QPlatformInputContext> m_inputContext; QScopedPointer<QPlatformServices> m_services; + mutable QScopedPointer<QPlatformNativeInterface> m_nativeInterface; QList<QPlatformScreen *> m_screens; bool m_windowFrameMarginsEnabled = true; }; diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp index bb4d8aeaa1..a11da2d543 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.cpp @@ -76,6 +76,8 @@ private: QOffscreenX11Connection *m_connection; }; +QOffscreenX11Integration::~QOffscreenX11Integration() = default; + bool QOffscreenX11Integration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { @@ -88,21 +90,27 @@ bool QOffscreenX11Integration::hasCapability(QPlatformIntegration::Capability ca QPlatformOpenGLContext *QOffscreenX11Integration::createPlatformOpenGLContext(QOpenGLContext *context) const { - if (!m_connection) - m_connection.reset(new QOffscreenX11Connection); + auto &connection = nativeInterface()->m_connection; + + if (!connection) + connection.reset(new QOffscreenX11Connection); - if (!m_connection->display()) + if (!connection->display()) return nullptr; - return new QOffscreenX11GLXContext(m_connection->x11Info(), context); + return new QOffscreenX11GLXContext(connection->x11Info(), context); } -QPlatformNativeInterface *QOffscreenX11Integration::nativeInterface() const +QOffscreenX11PlatformNativeInterface *QOffscreenX11Integration::nativeInterface() const { - return const_cast<QOffscreenX11Integration *>(this); + if (!m_nativeInterface) + m_nativeInterface.reset(new QOffscreenX11PlatformNativeInterface); + return static_cast<QOffscreenX11PlatformNativeInterface *>(m_nativeInterface.data()); } -void *QOffscreenX11Integration::nativeResourceForScreen(const QByteArray &resource, QScreen *screen) +QOffscreenX11PlatformNativeInterface::~QOffscreenX11PlatformNativeInterface() = default; + +void *QOffscreenX11PlatformNativeInterface::nativeResourceForScreen(const QByteArray &resource, QScreen *screen) { Q_UNUSED(screen); if (resource.toLower() == QByteArrayLiteral("display") ) { @@ -114,7 +122,7 @@ void *QOffscreenX11Integration::nativeResourceForScreen(const QByteArray &resour } #ifndef QT_NO_OPENGL -void *QOffscreenX11Integration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) { +void *QOffscreenX11PlatformNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) { if (resource.toLower() == QByteArrayLiteral("glxconfig") ) { if (context) { QOffscreenX11GLXContext *glxPlatformContext = static_cast<QOffscreenX11GLXContext *>(context->handle()); diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h index 01a75510fb..ed4b83c0a4 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h +++ b/src/plugins/platforms/offscreen/qoffscreenintegration_x11.h @@ -41,6 +41,7 @@ #define QOFFSCREENINTEGRATION_X11_H #include "qoffscreenintegration.h" +#include "qoffscreencommon.h" #include <qglobal.h> #include <qscopedpointer.h> @@ -52,22 +53,27 @@ QT_BEGIN_NAMESPACE class QOffscreenX11Connection; class QOffscreenX11Info; -class QOffscreenX11Integration : public QOffscreenIntegration, public QPlatformNativeInterface +class QOffscreenX11PlatformNativeInterface : public QOffscreenPlatformNativeInterface { public: - bool hasCapability(QPlatformIntegration::Capability cap) const override; - - QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; - QPlatformNativeInterface *nativeInterface()const override; + ~QOffscreenX11PlatformNativeInterface(); - // QPlatformNativeInterface void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) override; #ifndef QT_NO_OPENGL void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override; #endif -private: - mutable QScopedPointer<QOffscreenX11Connection> m_connection; + QScopedPointer<QOffscreenX11Connection> m_connection; +}; + +class QOffscreenX11Integration : public QOffscreenIntegration +{ +public: + ~QOffscreenX11Integration(); + bool hasCapability(QPlatformIntegration::Capability cap) const override; + + QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override; + QOffscreenX11PlatformNativeInterface *nativeInterface() const override; }; class QOffscreenX11Connection { |