diff options
Diffstat (limited to 'src/plugins/platforms/eglfs/deviceintegration')
27 files changed, 254 insertions, 116 deletions
diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index 769c248d0d..b46b04d149 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -1,12 +1,12 @@ TEMPLATE = subdirs -contains(QT_CONFIG, egl_x11): SUBDIRS += eglfs_x11 -contains(QT_CONFIG, eglfs_gbm): SUBDIRS += eglfs_kms_support eglfs_kms -contains(QT_CONFIG, eglfs_egldevice): SUBDIRS += eglfs_kms_support eglfs_kms_egldevice -contains(QT_CONFIG, eglfs_brcm): SUBDIRS += eglfs_brcm -contains(QT_CONFIG, eglfs_mali): SUBDIRS += eglfs_mali -contains(QT_CONFIG, eglfs_viv): SUBDIRS += eglfs_viv -contains(QT_CONFIG, eglfs_viv_wl): SUBDIRS += eglfs_viv_wl +qtConfig(egl_x11): SUBDIRS += eglfs_x11 +qtConfig(eglfs_gbm): SUBDIRS += eglfs_kms_support eglfs_kms +qtConfig(eglfs_egldevice): SUBDIRS += eglfs_kms_support eglfs_kms_egldevice +qtConfig(eglfs_brcm): SUBDIRS += eglfs_brcm +qtConfig(eglfs_mali): SUBDIRS += eglfs_mali +qtConfig(eglfs_viv): SUBDIRS += eglfs_viv +qtConfig(eglfs_viv_wl): SUBDIRS += eglfs_viv_wl eglfs_kms_egldevice.depends = eglfs_kms_support eglfs_kms.depends = eglfs_kms_support diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro index cd97c2c5a3..d65e136a96 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro @@ -8,8 +8,8 @@ CONFIG += egl LIBS += -lbcm_host QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 SOURCES += $$PWD/qeglfsbrcmmain.cpp \ $$PWD/qeglfsbrcmintegration.cpp diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp index 363fce2214..4e811a1dfe 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp @@ -93,9 +93,23 @@ void QEglFSBrcmIntegration::platformInit() bcm_host_init(); } +static int getDisplayId() +{ + // As defined in vc_dispmanx_types.h + // DISPMANX_ID_MAIN_LCD 0 + // DISPMANX_ID_AUX_LCD 1 + // DISPMANX_ID_HDMI 2 + // DISPMANX_ID_SDTV 3 + // DISPMANX_ID_FORCE_LCD 4 + // DISPMANX_ID_FORCE_TV 5 + // DISPMANX_ID_FORCE_OTHER 6 /* non-default display */ + static const int dispmanxId = qEnvironmentVariableIntValue("QT_QPA_EGLFS_DISPMANX_ID"); + return (dispmanxId >= 0 && dispmanxId <= 6) ? dispmanxId : 0; +} + EGLNativeDisplayType QEglFSBrcmIntegration::platformDisplay() const { - dispman_display = vc_dispmanx_display_open(0/* LCD */); + dispman_display = vc_dispmanx_display_open(getDisplayId()); return EGL_DEFAULT_DISPLAY; } @@ -107,7 +121,7 @@ void QEglFSBrcmIntegration::platformDestroy() QSize QEglFSBrcmIntegration::screenSize() const { uint32_t width, height; - graphics_get_display_size(0 /* LCD */, &width, &height); + graphics_get_display_size(getDisplayId(), &width, &height); return QSize(width, height); } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro index b0d631a9d1..70ff054172 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro @@ -8,16 +8,10 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS - -CONFIG += link_pkgconfig -!contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += libdrm gbm -} else { - LIBS += -ldrm -lgbm -} +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 +QMAKE_USE += gbm drm CONFIG += egl QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp index 278752bddf..99f6cfb0ca 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp @@ -142,10 +142,10 @@ void QEglFSKmsGbmDevice::handleDrmEvent() drmHandleEvent(fd(), &drmEvent); } -QEglFSKmsScreen *QEglFSKmsGbmDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) +QEglFSKmsScreen *QEglFSKmsGbmDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output) { static bool firstScreen = true; - QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(integration, device, output, position); + QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(integration, device, output); if (firstScreen && integration->hwCursor()) { m_globalCursor = new QEglFSKmsGbmCursor(screen); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h index 6a45f9ffa0..7c0af84422 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h @@ -68,8 +68,7 @@ public: virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position) Q_DECL_OVERRIDE; + QEglFSKmsOutput output) Q_DECL_OVERRIDE; private: Q_DISABLE_COPY(QEglFSKmsGbmDevice) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp index 7a17b60a5e..dde386fc57 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp @@ -93,10 +93,9 @@ QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject( } QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position) - : QEglFSKmsScreen(integration, device, output, position) + QEglFSKmsDevice *device, + QEglFSKmsOutput output) + : QEglFSKmsScreen(integration, device, output) , m_gbm_surface(Q_NULLPTR) , m_gbm_bo_current(Q_NULLPTR) , m_gbm_bo_next(Q_NULLPTR) @@ -130,8 +129,8 @@ gbm_surface *QEglFSKmsGbmScreen::createSurface() if (!m_gbm_surface) { qCDebug(qLcEglfsKmsDebug) << "Creating window for screen" << name(); m_gbm_surface = gbm_surface_create(static_cast<QEglFSKmsGbmDevice *>(device())->gbmDevice(), - geometry().width(), - geometry().height(), + rawGeometry().width(), + rawGeometry().height(), GBM_FORMAT_XRGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h index 3381bbfdbb..d7ad348291 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h @@ -55,9 +55,8 @@ class QEglFSKmsGbmScreen : public QEglFSKmsScreen { public: QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration, - QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position); + QEglFSKmsDevice *device, + QEglFSKmsOutput output); ~QEglFSKmsGbmScreen(); QPlatformCursor *cursor() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro index 8eabd2d4b7..5f47b98369 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro @@ -4,15 +4,10 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr INCLUDEPATH += $$PWD/../.. $$PWD/../eglfs_kms_support -DEFINES += MESA_EGL_NO_X11_HEADERS - -CONFIG += link_pkgconfig -!contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += libdrm -} else { - LIBS += -ldrm -} +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 +QMAKE_USE += drm CONFIG += egl QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp index 743f714cf0..d30963ff96 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp @@ -40,11 +40,15 @@ #include "qeglfskmsegldevice.h" #include "qeglfskmsegldevicescreen.h" #include "qeglfskmsegldeviceintegration.h" +#include "private/qeglfscursor_p.h" #include <QtCore/private/qcore_unix_p.h> +QT_BEGIN_NAMESPACE + QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path) - : QEglFSKmsDevice(integration, path) + : QEglFSKmsDevice(integration, path), + m_globalCursor(nullptr) { } @@ -52,6 +56,8 @@ bool QEglFSKmsEglDevice::open() { Q_ASSERT(fd() == -1); + qCDebug(qLcEglfsKmsDebug, "Opening DRM device %s", qPrintable(devicePath())); + int fd = drmOpen(devicePath().toLocal8Bit().constData(), Q_NULLPTR); if (Q_UNLIKELY(fd < 0)) qFatal("Could not open DRM device"); @@ -63,6 +69,8 @@ bool QEglFSKmsEglDevice::open() void QEglFSKmsEglDevice::close() { + qCDebug(qLcEglfsKmsDebug, "Closing DRM device"); + if (qt_safe_close(fd()) == -1) qErrnoWarning("Could not close DRM device"); @@ -74,7 +82,26 @@ EGLNativeDisplayType QEglFSKmsEglDevice::nativeDisplay() const return static_cast<QEglFSKmsEglDeviceIntegration *>(m_integration)->eglDevice(); } -QEglFSKmsScreen *QEglFSKmsEglDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) +QEglFSKmsScreen *QEglFSKmsEglDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, + QEglFSKmsOutput output) { - return new QEglFSKmsEglDeviceScreen(integration, device, output, position); + QEglFSKmsScreen *screen = new QEglFSKmsEglDeviceScreen(integration, device, output); + + if (!m_globalCursor && !integration->separateScreens()) { + qCDebug(qLcEglfsKmsDebug, "Creating new global mouse cursor"); + m_globalCursor = new QEglFSCursor(screen); + } + + return screen; } + +void QEglFSKmsEglDevice::destroyGlobalCursor() +{ + if (m_globalCursor) { + qCDebug(qLcEglfsKmsDebug, "Destroying global mouse cursor"); + delete m_globalCursor; + m_globalCursor = nullptr; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h index b1c98f3fe6..8c8f79f70c 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h @@ -42,6 +42,10 @@ #include <qeglfskmsdevice.h> +QT_BEGIN_NAMESPACE + +class QPlatformCursor; + class QEglFSKmsEglDevice: public QEglFSKmsDevice { public: @@ -54,8 +58,15 @@ public: virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position) Q_DECL_OVERRIDE; + QEglFSKmsOutput output) Q_DECL_OVERRIDE; + + QPlatformCursor *globalCursor() { return m_globalCursor; } + void destroyGlobalCursor(); + +private: + QPlatformCursor *m_globalCursor; }; +QT_END_NAMESPACE + #endif // QEGLFSKMSEGLDEVICE_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp index 28967d71ff..ddb2499751 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp @@ -41,6 +41,7 @@ #include "qeglfskmsegldeviceintegration.h" #include <QtPlatformSupport/private/qeglconvenience_p.h> #include "private/qeglfswindow_p.h" +#include "private/qeglfscursor_p.h" #include "qeglfskmsegldevice.h" #include "qeglfskmsscreen.h" #include <QLoggingCategory> @@ -193,8 +194,8 @@ void QEglJetsonTK1Window::resetSurface() m_format = q_glFormatFromConfig(display, m_config); qCDebug(qLcEglfsKmsDebug) << "Stream producer format is" << m_format; - const int w = cur_screen->geometry().width(); - const int h = cur_screen->geometry().height(); + const int w = cur_screen->rawGeometry().width(); + const int h = cur_screen->rawGeometry().height(); qCDebug(qLcEglfsKmsDebug, "Creating stream producer surface of size %dx%d", w, h); const EGLint stream_producer_attribs[] = { @@ -222,11 +223,6 @@ QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const return eglWindow; } -bool QEglFSKmsEglDeviceIntegration::separateScreens() const -{ - return true; -} - QEglFSKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice(const QString &devicePath) { Q_UNUSED(devicePath) @@ -263,4 +259,9 @@ bool QEglFSKmsEglDeviceIntegration::query_egl_device() return true; } +QPlatformCursor *QEglFSKmsEglDeviceIntegration::createCursor(QPlatformScreen *screen) const +{ + return separateScreens() ? new QEglFSCursor(screen) : nullptr; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h index f04c42267a..375c388548 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h @@ -61,12 +61,11 @@ public: bool supportsPBuffers() const Q_DECL_OVERRIDE; QEglFSWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE; - virtual bool separateScreens() const Q_DECL_OVERRIDE; - EGLDeviceEXT eglDevice() const { return m_egl_device; } protected: QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE; + QPlatformCursor *createCursor(QPlatformScreen *screen) const Q_DECL_OVERRIDE; private: bool setup_kms(); diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp index da1b577801..55d5941e5f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp @@ -39,10 +39,30 @@ #include "qeglfskmsegldevicescreen.h" #include "qeglfskmsegldevice.h" +#include <QGuiApplication> -QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) - : QEglFSKmsScreen(integration, device, output, position) +QT_BEGIN_NAMESPACE + +QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output) + : QEglFSKmsScreen(integration, device, output) +{ +} + +QEglFSKmsEglDeviceScreen::~QEglFSKmsEglDeviceScreen() { + const int remainingScreenCount = qGuiApp->screens().count(); + qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount); + if (!remainingScreenCount && !m_integration->separateScreens()) + static_cast<QEglFSKmsEglDevice *>(device())->destroyGlobalCursor(); +} + +QPlatformCursor *QEglFSKmsEglDeviceScreen::cursor() const +{ + // The base class creates a cursor via integration->createCursor() + // in its ctor. With separateScreens just use that. Otherwise + // there's a virtual desktop and the device has a global cursor + // and the base class has no dedicated cursor at all. + return m_integration->separateScreens() ? QEglFSScreen::cursor() : static_cast<QEglFSKmsEglDevice *>(device())->globalCursor(); } void QEglFSKmsEglDeviceScreen::waitForFlip() @@ -76,3 +96,5 @@ void QEglFSKmsEglDeviceScreen::waitForFlip() } } + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h index 0cd46e9f9d..c57f52c6b7 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h @@ -42,15 +42,21 @@ #include <qeglfskmsscreen.h> +QT_BEGIN_NAMESPACE + class QEglFSKmsEglDeviceScreen : public QEglFSKmsScreen { public: QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position); + QEglFSKmsOutput output); + ~QEglFSKmsEglDeviceScreen(); + + QPlatformCursor *cursor() const Q_DECL_OVERRIDE; void waitForFlip() Q_DECL_OVERRIDE; }; +QT_END_NAMESPACE + #endif // QEGLFSKMSEGLDEVICESCREEN_H diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro index 6dd857a4e4..464c64539f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro @@ -6,16 +6,10 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr INCLUDEPATH += $$PWD/../.. -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS - -CONFIG += link_pkgconfig -!contains(QT_CONFIG, no-pkg-config) { - PKGCONFIG += libdrm -} else { - LIBS += -ldrm -} +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 +QMAKE_USE += drm CONFIG += egl QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp index f4ffee569d..5944e8d51f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp @@ -159,7 +159,7 @@ static bool parseModeline(const QByteArray &text, drmModeModeInfoPtr mode) return true; } -QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos) +QEglFSKmsScreen *QEglFSKmsDevice::createScreenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, int *virtualIndex) { const QByteArray connectorName = nameForConnector(connector); @@ -173,8 +173,11 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr QSize configurationSize; drmModeModeInfo configurationModeline; - const QByteArray mode = m_integration->outputSettings().value(QString::fromUtf8(connectorName)) - .value(QStringLiteral("mode"), QStringLiteral("preferred")).toByteArray().toLower(); + auto userConfig = m_integration->outputSettings(); + auto userConnectorConfig = userConfig.value(QString::fromUtf8(connectorName)); + // default to the preferred mode unless overridden in the config + const QByteArray mode = userConnectorConfig.value(QStringLiteral("mode"), QStringLiteral("preferred")) + .toByteArray().toLower(); if (mode == "off") { configuration = OutputConfigOff; } else if (mode == "preferred") { @@ -189,6 +192,8 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr qWarning("Invalid mode \"%s\" for output %s", mode.constData(), connectorName.constData()); configuration = OutputConfigPreferred; } + if (virtualIndex) + *virtualIndex = userConnectorConfig.value(QStringLiteral("virtualIndex"), INT_MAX).toInt(); const uint32_t crtc_id = resources->crtcs[crtc]; @@ -287,18 +292,26 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr qCDebug(qLcEglfsKmsDebug) << "Selected mode" << selected_mode << ":" << width << "x" << height << '@' << refresh << "hz for output" << connectorName; } + + // physical size from connector < config values < env vars static const int width = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_WIDTH"); static const int height = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_HEIGHT"); - QSizeF size(width, height); - if (size.isEmpty()) { - size.setWidth(connector->mmWidth); - size.setHeight(connector->mmHeight); + QSizeF physSize(width, height); + if (physSize.isEmpty()) { + physSize = QSize(userConnectorConfig.value(QStringLiteral("physicalWidth")).toInt(), + userConnectorConfig.value(QStringLiteral("physicalHeight")).toInt()); + if (physSize.isEmpty()) { + physSize.setWidth(connector->mmWidth); + physSize.setHeight(connector->mmHeight); + } } + qCDebug(qLcEglfsKmsDebug) << "Physical size is" << physSize << "mm" << "for output" << connectorName; + QEglFSKmsOutput output = { QString::fromUtf8(connectorName), connector->connector_id, crtc_id, - size, + physSize, selected_mode, false, drmModeGetCrtc(m_dri_fd, crtc_id), @@ -310,7 +323,7 @@ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr m_crtc_allocator |= (1 << output.crtc_id); m_connector_allocator |= (1 << output.connector_id); - return createScreen(m_integration, this, output, pos); + return createScreen(m_integration, this, output); } drmModePropertyPtr QEglFSKmsDevice::connectorProperty(drmModeConnectorPtr connector, const QByteArray &name) @@ -342,6 +355,26 @@ QEglFSKmsDevice::~QEglFSKmsDevice() { } +struct OrderedScreen +{ + OrderedScreen() : screen(nullptr), index(-1) { } + OrderedScreen(QEglFSKmsScreen *screen, int index) : screen(screen), index(index) { } + QEglFSKmsScreen *screen; + int index; +}; + +QDebug operator<<(QDebug dbg, const OrderedScreen &s) +{ + QDebugStateSaver saver(dbg); + dbg.nospace() << "OrderedScreen(" << s.screen << " : " << s.index << ")"; + return dbg; +} + +static bool orderedScreenLessThan(const OrderedScreen &a, const OrderedScreen &b) +{ + return a.index < b.index; +} + void QEglFSKmsDevice::createScreens() { drmModeResPtr resources = drmModeGetResources(m_dri_fd); @@ -350,32 +383,49 @@ void QEglFSKmsDevice::createScreens() return; } - QEglFSKmsScreen *primaryScreen = Q_NULLPTR; - QList<QPlatformScreen *> siblings; - QPoint pos(0, 0); - QEglFSIntegration *integration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration()); + QVector<OrderedScreen> screens; for (int i = 0; i < resources->count_connectors; i++) { drmModeConnectorPtr connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]); if (!connector) continue; - QEglFSKmsScreen *screen = screenForConnector(resources, connector, pos); - if (screen) { - integration->addScreen(screen); - pos.rx() += screen->geometry().width(); - siblings << screen; - - if (!primaryScreen) - primaryScreen = screen; - } + int virtualIndex; + QEglFSKmsScreen *screen = createScreenForConnector(resources, connector, &virtualIndex); + if (screen) + screens.append(OrderedScreen(screen, virtualIndex)); drmModeFreeConnector(connector); } drmModeFreeResources(resources); + // Use stable sort to preserve the original order for outputs with unspecified indices. + std::stable_sort(screens.begin(), screens.end(), orderedScreenLessThan); + qCDebug(qLcEglfsKmsDebug) << "Sorted screen list:" << screens; + + QPoint pos(0, 0); + QList<QPlatformScreen *> siblings; + QEglFSIntegration *qpaIntegration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration()); + + for (const OrderedScreen &orderedScreen : screens) { + QEglFSKmsScreen *s = orderedScreen.screen; + // set up a horizontal or vertical virtual desktop + s->setVirtualPosition(pos); + if (m_integration->virtualDesktopLayout() == QEglFSKmsIntegration::VirtualDesktopLayoutVertical) + pos.ry() += s->geometry().height(); + else + pos.rx() += s->geometry().width(); + qCDebug(qLcEglfsKmsDebug) << "Adding screen" << s << "to QPA with geometry" << s->geometry(); + // The order in qguiapp's screens list will match the order set by + // virtualIndex. This is not only handy but also required since for instance + // evdevtouch relies on it when performing touch device - screen mapping. + qpaIntegration->addScreen(s); + siblings << s; + } + if (!m_integration->separateScreens()) { + // enable the virtual desktop Q_FOREACH (QPlatformScreen *screen, siblings) static_cast<QEglFSKmsScreen *>(screen)->setVirtualSiblings(siblings); } @@ -391,9 +441,9 @@ QString QEglFSKmsDevice::devicePath() const return m_path; } -QEglFSKmsScreen *QEglFSKmsDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position) +QEglFSKmsScreen *QEglFSKmsDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output) { - return new QEglFSKmsScreen(integration, device, output, position); + return new QEglFSKmsScreen(integration, device, output); } void QEglFSKmsDevice::setFd(int fd) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h index 041c063695..4aad2e0143 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h @@ -68,8 +68,7 @@ public: protected: virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position); + QEglFSKmsOutput output); void setFd(int fd); QEglFSKmsIntegration *m_integration; @@ -80,7 +79,7 @@ protected: quint32 m_connector_allocator; int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector); - QEglFSKmsScreen *screenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, QPoint pos); + QEglFSKmsScreen *createScreenForConnector(drmModeResPtr resources, drmModeConnectorPtr connector, int *virtualIndex); drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name); static void pageFlipHandler(int fd, diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp index 7389050efc..6c30e8f930 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp @@ -65,6 +65,7 @@ QEglFSKmsIntegration::QEglFSKmsIntegration() , m_hwCursor(false) , m_pbuffers(false) , m_separateScreens(false) + , m_virtualDesktopLayout(VirtualDesktopLayoutHorizontal) {} void QEglFSKmsIntegration::platformInit() @@ -149,6 +150,11 @@ bool QEglFSKmsIntegration::separateScreens() const return m_separateScreens; } +QEglFSKmsIntegration::VirtualDesktopLayout QEglFSKmsIntegration::virtualDesktopLayout() const +{ + return m_virtualDesktopLayout; +} + QMap<QString, QVariantMap> QEglFSKmsIntegration::outputSettings() const { return m_outputSettings; @@ -169,15 +175,15 @@ void QEglFSKmsIntegration::loadConfig() QFile file(QString::fromUtf8(json)); if (!file.open(QFile::ReadOnly)) { - qCDebug(qLcEglfsKmsDebug) << "Could not open config file" - << json << "for reading"; + qCWarning(qLcEglfsKmsDebug) << "Could not open config file" + << json << "for reading"; return; } const QJsonDocument doc = QJsonDocument::fromJson(file.readAll()); if (!doc.isObject()) { - qCDebug(qLcEglfsKmsDebug) << "Invalid config file" << json - << "- no top-level JSON object"; + qCWarning(qLcEglfsKmsDebug) << "Invalid config file" << json + << "- no top-level JSON object"; return; } @@ -188,6 +194,16 @@ void QEglFSKmsIntegration::loadConfig() m_devicePath = object.value(QLatin1String("device")).toString(); m_separateScreens = object.value(QLatin1String("separateScreens")).toBool(m_separateScreens); + const QString vdOriString = object.value(QLatin1String("virtualDesktopLayout")).toString(); + if (!vdOriString.isEmpty()) { + if (vdOriString == QLatin1String("horizontal")) + m_virtualDesktopLayout = VirtualDesktopLayoutHorizontal; + else if (vdOriString == QLatin1String("vertical")) + m_virtualDesktopLayout = VirtualDesktopLayoutVertical; + else + qCWarning(qLcEglfsKmsDebug) << "Unknown virtualDesktopOrientation value" << vdOriString; + } + const QJsonArray outputs = object.value(QLatin1String("outputs")).toArray(); for (int i = 0; i < outputs.size(); i++) { const QVariantMap outputSettings = outputs.at(i).toObject().toVariantMap(); @@ -207,6 +223,7 @@ void QEglFSKmsIntegration::loadConfig() << "\thwcursor:" << m_hwCursor << "\n" << "\tpbuffers:" << m_pbuffers << "\n" << "\tseparateScreens:" << m_separateScreens << "\n" + << "\tvirtualDesktopLayout:" << m_virtualDesktopLayout << "\n" << "\toutputs:" << m_outputSettings; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h index 81386881ff..ba49945715 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h @@ -56,6 +56,11 @@ Q_EGLFS_EXPORT Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) class Q_EGLFS_EXPORT QEglFSKmsIntegration : public QEglFSDeviceIntegration { public: + enum VirtualDesktopLayout { + VirtualDesktopLayoutHorizontal, + VirtualDesktopLayoutVertical + }; + QEglFSKmsIntegration(); void platformInit() Q_DECL_OVERRIDE; @@ -70,6 +75,7 @@ public: virtual bool hwCursor() const; virtual bool separateScreens() const; + virtual VirtualDesktopLayout virtualDesktopLayout() const; QMap<QString, QVariantMap> outputSettings() const; QEglFSKmsDevice *device() const; @@ -83,6 +89,7 @@ protected: bool m_hwCursor; bool m_pbuffers; bool m_separateScreens; + VirtualDesktopLayout m_virtualDesktopLayout; QString m_devicePath; QMap<QString, QVariantMap> m_outputSettings; }; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp index e6b256f6b2..f690cd668e 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp @@ -71,17 +71,15 @@ private: QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position) + QEglFSKmsOutput output) : QEglFSScreen(eglGetDisplay(device->nativeDisplay())) , m_integration(integration) , m_device(device) , m_output(output) - , m_pos(position) , m_powerState(PowerStateOn) , m_interruptHandler(new QEglFSKmsInterruptHandler(this)) { - m_siblings << this; + m_siblings << this; // gets overridden by QEglFSKmsDevice later if !separateScreens } QEglFSKmsScreen::~QEglFSKmsScreen() @@ -98,7 +96,14 @@ QEglFSKmsScreen::~QEglFSKmsScreen() delete m_interruptHandler; } -QRect QEglFSKmsScreen::geometry() const +void QEglFSKmsScreen::setVirtualPosition(const QPoint &pos) +{ + m_pos = pos; +} + +// Reimplement rawGeometry(), not geometry(). The base class implementation of +// geometry() calls rawGeometry() and may apply additional transforms. +QRect QEglFSKmsScreen::rawGeometry() const { const int mode = m_output.mode; return QRect(m_pos.x(), m_pos.y(), diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h index 9679f70260..2b6a0ffe6c 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h @@ -74,11 +74,13 @@ class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen public: QEglFSKmsScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, - QEglFSKmsOutput output, - QPoint position); + QEglFSKmsOutput output); ~QEglFSKmsScreen(); - QRect geometry() const Q_DECL_OVERRIDE; + void setVirtualPosition(const QPoint &pos); + + QRect rawGeometry() const Q_DECL_OVERRIDE; + int depth() const Q_DECL_OVERRIDE; QImage::Format format() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro index 1e58b5fdcd..6e32ca26d0 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro @@ -2,8 +2,8 @@ TARGET = qeglfs-mali-integration QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 INCLUDEPATH += $$PWD/../.. CONFIG += egl diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro index a53aac2041..16880535e3 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro @@ -5,7 +5,6 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr INCLUDEPATH += $$PWD/../.. CONFIG += egl DEFINES += LINUX=1 EGL_API_FB=1 -LIBS += -lGAL QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF SOURCES += $$PWD/qeglfsvivmain.cpp \ diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro index 38259f4a5d..374c5bba6b 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/eglfs_viv_wl.pro @@ -5,7 +5,6 @@ QT += core-private gui-private platformsupport-private eglfsdeviceintegration-pr INCLUDEPATH += $$PWD/../.. CONFIG += egl DEFINES += LINUX=1 EGL_API_FB=1 -LIBS += -lGAL QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF SOURCES += $$PWD/qeglfsvivwlmain.cpp \ diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro index 21af6eb736..10af57e487 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro @@ -2,13 +2,13 @@ TARGET = qeglfs-x11-integration QT += core-private gui-private platformsupport-private eglfsdeviceintegration-private -# Avoid X11 header collision -DEFINES += MESA_EGL_NO_X11_HEADERS +# Avoid X11 header collision, use generic EGL native types +DEFINES += QT_EGL_NO_X11 INCLUDEPATH += $$PWD/../.. CONFIG += egl -LIBS += -lX11 -lX11-xcb -lxcb +QMAKE_USE += xcb_xlib QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF SOURCES += $$PWD/qeglfsx11main.cpp \ diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp index 74a687b382..f9924fe5ce 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp @@ -281,12 +281,12 @@ EGLNativeWindowType QEglFSX11Integration::createNativeWindow(QPlatformWindow *pl xcb_flush(m_connection); - return m_window; + return qt_egl_cast<EGLNativeWindowType>(m_window); } void QEglFSX11Integration::destroyNativeWindow(EGLNativeWindowType window) { - xcb_destroy_window(m_connection, window); + xcb_destroy_window(m_connection, qt_egl_cast<xcb_window_t>(window)); } bool QEglFSX11Integration::hasCapability(QPlatformIntegration::Capability cap) const |