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>
This commit is contained in:
parent
d017baac89
commit
ecd11e498f
@ -232,4 +232,6 @@ void QOffscreenBackingStore::clearHash()
|
|||||||
|
|
||||||
QHash<WId, QOffscreenBackingStore *> QOffscreenBackingStore::m_backingStoreForWinIdHash;
|
QHash<WId, QOffscreenBackingStore *> QOffscreenBackingStore::m_backingStoreForWinIdHash;
|
||||||
|
|
||||||
|
QOffscreenPlatformNativeInterface::~QOffscreenPlatformNativeInterface() = default;
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include <qpa/qplatformdrag.h>
|
#include <qpa/qplatformdrag.h>
|
||||||
#endif
|
#endif
|
||||||
#include <qpa/qplatformintegration.h>
|
#include <qpa/qplatformintegration.h>
|
||||||
|
#include <qpa/qplatformnativeinterface.h>
|
||||||
#include <qpa/qplatformscreen.h>
|
#include <qpa/qplatformscreen.h>
|
||||||
#include <qpa/qplatformwindow.h>
|
#include <qpa/qplatformwindow.h>
|
||||||
|
|
||||||
@ -116,6 +117,12 @@ private:
|
|||||||
static QHash<WId, QOffscreenBackingStore *> m_backingStoreForWinIdHash;
|
static QHash<WId, QOffscreenBackingStore *> m_backingStoreForWinIdHash;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QOffscreenPlatformNativeInterface : public QPlatformNativeInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~QOffscreenPlatformNativeInterface();
|
||||||
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -244,6 +244,13 @@ QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPlatformNativeInterface *QOffscreenIntegration::nativeInterface() const
|
||||||
|
{
|
||||||
|
if (!m_nativeInterface)
|
||||||
|
m_nativeInterface.reset(new QOffscreenPlatformNativeInterface);
|
||||||
|
return m_nativeInterface.get();
|
||||||
|
}
|
||||||
|
|
||||||
static QString themeName() { return QStringLiteral("offscreen"); }
|
static QString themeName() { return QStringLiteral("offscreen"); }
|
||||||
|
|
||||||
QStringList QOffscreenIntegration::themeNames() const
|
QStringList QOffscreenIntegration::themeNames() const
|
||||||
|
@ -71,19 +71,22 @@ public:
|
|||||||
QPlatformFontDatabase *fontDatabase() const override;
|
QPlatformFontDatabase *fontDatabase() const override;
|
||||||
QAbstractEventDispatcher *createEventDispatcher() const override;
|
QAbstractEventDispatcher *createEventDispatcher() const override;
|
||||||
|
|
||||||
|
QPlatformNativeInterface *nativeInterface() const override;
|
||||||
|
|
||||||
QStringList themeNames() const override;
|
QStringList themeNames() const override;
|
||||||
QPlatformTheme *createPlatformTheme(const QString &name) const override;
|
QPlatformTheme *createPlatformTheme(const QString &name) const override;
|
||||||
|
|
||||||
static QOffscreenIntegration *createOffscreenIntegration(const QStringList& paramList);
|
static QOffscreenIntegration *createOffscreenIntegration(const QStringList& paramList);
|
||||||
|
|
||||||
QList<QPlatformScreen *> screens() const;
|
QList<QPlatformScreen *> screens() const;
|
||||||
private:
|
protected:
|
||||||
QScopedPointer<QPlatformFontDatabase> m_fontDatabase;
|
QScopedPointer<QPlatformFontDatabase> m_fontDatabase;
|
||||||
#if QT_CONFIG(draganddrop)
|
#if QT_CONFIG(draganddrop)
|
||||||
QScopedPointer<QPlatformDrag> m_drag;
|
QScopedPointer<QPlatformDrag> m_drag;
|
||||||
#endif
|
#endif
|
||||||
QScopedPointer<QPlatformInputContext> m_inputContext;
|
QScopedPointer<QPlatformInputContext> m_inputContext;
|
||||||
QScopedPointer<QPlatformServices> m_services;
|
QScopedPointer<QPlatformServices> m_services;
|
||||||
|
mutable QScopedPointer<QPlatformNativeInterface> m_nativeInterface;
|
||||||
QList<QPlatformScreen *> m_screens;
|
QList<QPlatformScreen *> m_screens;
|
||||||
bool m_windowFrameMarginsEnabled = true;
|
bool m_windowFrameMarginsEnabled = true;
|
||||||
};
|
};
|
||||||
|
@ -76,6 +76,8 @@ private:
|
|||||||
QOffscreenX11Connection *m_connection;
|
QOffscreenX11Connection *m_connection;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
QOffscreenX11Integration::~QOffscreenX11Integration() = default;
|
||||||
|
|
||||||
bool QOffscreenX11Integration::hasCapability(QPlatformIntegration::Capability cap) const
|
bool QOffscreenX11Integration::hasCapability(QPlatformIntegration::Capability cap) const
|
||||||
{
|
{
|
||||||
switch (cap) {
|
switch (cap) {
|
||||||
@ -88,21 +90,27 @@ bool QOffscreenX11Integration::hasCapability(QPlatformIntegration::Capability ca
|
|||||||
|
|
||||||
QPlatformOpenGLContext *QOffscreenX11Integration::createPlatformOpenGLContext(QOpenGLContext *context) const
|
QPlatformOpenGLContext *QOffscreenX11Integration::createPlatformOpenGLContext(QOpenGLContext *context) const
|
||||||
{
|
{
|
||||||
if (!m_connection)
|
auto &connection = nativeInterface()->m_connection;
|
||||||
m_connection.reset(new QOffscreenX11Connection);
|
|
||||||
|
|
||||||
if (!m_connection->display())
|
if (!connection)
|
||||||
|
connection.reset(new QOffscreenX11Connection);
|
||||||
|
|
||||||
|
if (!connection->display())
|
||||||
return nullptr;
|
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);
|
Q_UNUSED(screen);
|
||||||
if (resource.toLower() == QByteArrayLiteral("display") ) {
|
if (resource.toLower() == QByteArrayLiteral("display") ) {
|
||||||
@ -114,7 +122,7 @@ void *QOffscreenX11Integration::nativeResourceForScreen(const QByteArray &resour
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef QT_NO_OPENGL
|
#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 (resource.toLower() == QByteArrayLiteral("glxconfig") ) {
|
||||||
if (context) {
|
if (context) {
|
||||||
QOffscreenX11GLXContext *glxPlatformContext = static_cast<QOffscreenX11GLXContext *>(context->handle());
|
QOffscreenX11GLXContext *glxPlatformContext = static_cast<QOffscreenX11GLXContext *>(context->handle());
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#define QOFFSCREENINTEGRATION_X11_H
|
#define QOFFSCREENINTEGRATION_X11_H
|
||||||
|
|
||||||
#include "qoffscreenintegration.h"
|
#include "qoffscreenintegration.h"
|
||||||
|
#include "qoffscreencommon.h"
|
||||||
|
|
||||||
#include <qglobal.h>
|
#include <qglobal.h>
|
||||||
#include <qscopedpointer.h>
|
#include <qscopedpointer.h>
|
||||||
@ -52,22 +53,27 @@ QT_BEGIN_NAMESPACE
|
|||||||
class QOffscreenX11Connection;
|
class QOffscreenX11Connection;
|
||||||
class QOffscreenX11Info;
|
class QOffscreenX11Info;
|
||||||
|
|
||||||
class QOffscreenX11Integration : public QOffscreenIntegration, public QPlatformNativeInterface
|
class QOffscreenX11PlatformNativeInterface : public QOffscreenPlatformNativeInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool hasCapability(QPlatformIntegration::Capability cap) const override;
|
~QOffscreenX11PlatformNativeInterface();
|
||||||
|
|
||||||
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
|
|
||||||
QPlatformNativeInterface *nativeInterface()const override;
|
|
||||||
|
|
||||||
// QPlatformNativeInterface
|
|
||||||
void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) override;
|
void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) override;
|
||||||
#ifndef QT_NO_OPENGL
|
#ifndef QT_NO_OPENGL
|
||||||
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override;
|
void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
QScopedPointer<QOffscreenX11Connection> m_connection;
|
||||||
mutable 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 {
|
class QOffscreenX11Connection {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user